From 111eeb92adcea24142d0c36aed216585157ee891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Thu, 17 Jun 2021 23:41:50 +0200 Subject: [PATCH] feat: add loading progress bar --- image-viewer/include/image_loader.h | 13 +++++++++---- image-viewer/src/image_loader.c | 24 ++++++++++++++++-------- image-viewer/src/image_viewer.c | 9 ++++++++- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/image-viewer/include/image_loader.h b/image-viewer/include/image_loader.h index cb080dce046fe6ee0af7218aacefa607500e30f1..b02cbaf450edc21007b17d8d893fd2dac88ab5c3 100644 --- a/image-viewer/include/image_loader.h +++ b/image-viewer/include/image_loader.h @@ -3,11 +3,16 @@ #include "image.h" -image_error_t image_loader_load(image_t *image); +typedef void (*image_load_callback)(void *state, double process); -image_error_t image_loader_load_ppm(image_t *image); -image_error_t image_loader_load_jpeg(image_t *image); -image_error_t image_loader_load_png(image_t *image); +image_error_t image_loader_load(image_t *image, image_load_callback callback, void *state); + +image_error_t image_loader_load_ppm(image_t *image, + image_load_callback callback, void *state); +image_error_t image_loader_load_jpeg(image_t *image, + image_load_callback callback, void *state); +image_error_t image_loader_load_png(image_t *image, + image_load_callback callback, void *state); image_error_t image_deduce_type(image_t *image); diff --git a/image-viewer/src/image_loader.c b/image-viewer/src/image_loader.c index dc5649f1121a07c555902338cf09b6be3dd6e0cd..dbeddb2a7e16019cdb0ea0c281576752c718f7b2 100644 --- a/image-viewer/src/image_loader.c +++ b/image-viewer/src/image_loader.c @@ -11,7 +11,7 @@ #define BUFFER_LENGTH 4 -image_error_t image_loader_load(image_t *image) { +image_error_t image_loader_load(image_t *image, image_load_callback callback, void *state) { image_error_t error = image_deduce_type(image); if (error != IMERR_SUCCESS) { return error; @@ -19,11 +19,11 @@ image_error_t image_loader_load(image_t *image) { switch (image->type) { case IMG_PPM: - return image_loader_load_ppm(image); + return image_loader_load_ppm(image, callback, state); case IMG_JPG: - return image_loader_load_jpeg(image); + return image_loader_load_jpeg(image, callback, state); case IMG_PNG: - return image_loader_load_png(image); + return image_loader_load_png(image, callback, state); case IMG_UNKNOWN: return IMERR_UNKNOWN_FORMAT; } @@ -42,7 +42,8 @@ image_error_t image_error_from_errno() { } } -image_error_t image_loader_load_ppm(image_t *image) { +image_error_t image_loader_load_ppm(image_t *image, + image_load_callback callback, void *state) { FILE *file = fopen(image->path, "r"); if (file == NULL) { return image_error_from_errno(); @@ -73,14 +74,16 @@ image_error_t image_loader_load_ppm(image_t *image) { } image->pixels[i] = raw_pixel_onebit_convert_to_display(pixel, max); + callback(state, (double)i / (image->height * image->width)); } fclose(file); return IMERR_SUCCESS; } - -image_error_t image_loader_load_jpeg(image_t *image) { +image_error_t image_loader_load_jpeg(image_t *image, + image_load_callback callback, + void *state) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; @@ -114,6 +117,7 @@ image_error_t image_loader_load_jpeg(image_t *image) { while (cinfo.output_scanline < cinfo.output_height) { row_pointer[0] = &out[cinfo.output_scanline * cinfo.image_width * 2]; jpeg_read_scanlines(&cinfo, row_pointer, 1); + callback(state, (double)cinfo.output_scanline / cinfo.output_height); } jpeg_finish_decompress(&cinfo); @@ -124,7 +128,8 @@ image_error_t image_loader_load_jpeg(image_t *image) { return IMERR_SUCCESS; } -image_error_t image_loader_load_png(image_t *image) { +image_error_t image_loader_load_png(image_t *image, + image_load_callback callback, void *state) { FILE *infile = fopen(image->path, "r"); if (infile == NULL) { return image_error_from_errno(); @@ -184,6 +189,7 @@ image_error_t image_loader_load_png(image_t *image) { for (int i = 0; i < image->height; i++) { row_pointers[i] = malloc(png_get_rowbytes(png, info)); + callback(state, 0.5 * ((double)i / image->height)); } png_read_image(png, row_pointers); @@ -210,6 +216,8 @@ image_error_t image_loader_load_png(image_t *image) { pixels[y * image->width + x].fields.g = ((double)px[1] * alpha / coef) * DISPLAY_MAX_GREEN; pixels[y * image->width + x].fields.b = ((double)px[2] * alpha / coef) * DISPLAY_MAX_BLUE; } + + callback(state, 0.5 + 0.5 * ((double)y / image->height)); } image->pixels = pixels; diff --git a/image-viewer/src/image_viewer.c b/image-viewer/src/image_viewer.c index 1dfbd53c1c066921caedd697385d05b3f78524b5..c101638fd46ada7f876594f14f7d942a7b078b7c 100644 --- a/image-viewer/src/image_viewer.c +++ b/image-viewer/src/image_viewer.c @@ -17,7 +17,13 @@ #define MAX_ZOOM 10 #define MIN_ZOOM 0.02 +void loader_callback(void *state, double p) { + mzapo_ledstrip_t *ledstrip = (mzapo_ledstrip_t*)state; + ledstrip_progress_bar_step(ledstrip, p * LED_STRIP_COUNT); +} + image_viewer_t image_viewer_create(char *filename, display_t *display, logger_t *logger, mzapo_ledstrip_t ledstrip) { + image_viewer_t viewer = { .display = display, .image = image_create(filename), @@ -28,7 +34,8 @@ image_viewer_t image_viewer_create(char *filename, display_t *display, logger_t .ledstrip = ledstrip, }; - viewer.error = image_loader_load(&viewer.image); + viewer.error = image_loader_load(&viewer.image, loader_callback, &ledstrip); + ledstrip_clear(&ledstrip); if (viewer.error == IMERR_SUCCESS) { viewer.image_region =