diff --git a/src/io_pipeline.c b/src/io_pipeline.c index 4d8f671..78db658 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -75,6 +75,7 @@ update_process_pipeline() struct mp_process_pipeline_state pipeline_state = { .camera = state_io.camera, + .configuration = state_io.configuration, .burst_length = state_io.burst_length, .preview_width = state_io.preview_width, .preview_height = state_io.preview_height, @@ -454,7 +455,7 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state) init_controls(); } } - + state_io.configuration = state->configuration; state_io.burst_length = state->burst_length; state_io.preview_width = state->preview_width; state_io.preview_height = state->preview_height; diff --git a/src/io_pipeline.h b/src/io_pipeline.h index 9928e90..0842535 100644 --- a/src/io_pipeline.h +++ b/src/io_pipeline.h @@ -6,6 +6,7 @@ struct mp_io_pipeline_state { libmegapixels_camera *camera; + libmegapixels_devconfig *configuration; int burst_length; diff --git a/src/main.c b/src/main.c index b4a4de9..d9dd2c7 100644 --- a/src/main.c +++ b/src/main.c @@ -95,6 +95,7 @@ update_io_pipeline() { struct mp_io_pipeline_state io_state = { .camera = state.camera, + .configuration = state.configuration, .burst_length = state.burst_length, .preview_width = state.preview_width, .preview_height = state.preview_height, diff --git a/src/process_pipeline.c b/src/process_pipeline.c index 1015e8e..b1bd2b2 100644 --- a/src/process_pipeline.c +++ b/src/process_pipeline.c @@ -4,6 +4,7 @@ #include "io_pipeline.h" #include "main.h" #include "pipeline.h" +#include "state.h" #include "zbar_pipeline.h" #include #include @@ -25,6 +26,7 @@ static const float colormatrix_srgb[] = { 3.2409f, -1.5373f, -0.4986f, 0.0556f, -0.2039f, 1.0569f }; static MPPipeline *pipeline; +mp_state_proc state_proc; static char burst_dir[23]; @@ -33,17 +35,6 @@ static volatile int frames_processed = 0; static volatile int frames_received = 0; libmegapixels_camera *pr_camera; -libmegapixels_mode *mode; - -static int camera_rotation; - -static int burst_length; -static int captures_remaining = 0; - -static int preview_width; -static int preview_height; - -static int device_rotation; static int output_buffer_width = -1; static int output_buffer_height = -1; @@ -237,9 +228,7 @@ void mp_process_pipeline_start() { pipeline = mp_pipeline_new(); - mp_pipeline_invoke(pipeline, setup, NULL, 0); - mp_zbar_pipeline_start(); } @@ -247,7 +236,6 @@ void mp_process_pipeline_stop() { mp_pipeline_free(pipeline); - mp_zbar_pipeline_stop(); } @@ -442,17 +430,19 @@ process_image_for_preview(const uint8_t *image) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_LUMINANCE, - libmegapixels_mode_width_to_bytes(mode->format, mode->width) + - libmegapixels_mode_width_to_padding(mode->format, - mode->width), - mode->height, - 0, - GL_LUMINANCE, - GL_UNSIGNED_BYTE, - image); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_LUMINANCE, + libmegapixels_mode_width_to_bytes(state_proc.mode->format, + state_proc.mode->width) + + libmegapixels_mode_width_to_padding(state_proc.mode->format, + state_proc.mode->width), + state_proc.mode->height, + 0, + GL_LUMINANCE, + GL_UNSIGNED_BYTE, + image); check_gl(); gles2_debayer_process( @@ -480,7 +470,7 @@ process_image_for_preview(const uint8_t *image) // Create a thumbnail from the preview for the last capture GdkTexture *thumb = NULL; - if (captures_remaining == 1) { + if (state_proc.captures_remaining == 1) { printf("Making thumbnail\n"); size_t size = output_buffer_width * output_buffer_height * @@ -541,26 +531,27 @@ process_image_for_capture(const uint8_t *image, int count) // Define TIFF thumbnail TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1); - TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, mode->width >> 4); - TIFFSetField(tif, TIFFTAG_IMAGELENGTH, mode->height >> 4); + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, state_proc.mode->width >> 4); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, state_proc.mode->height >> 4); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField(tif, TIFFTAG_MAKE, "MAKE"); // TODO: fix - TIFFSetField(tif, TIFFTAG_MODEL, "MODEL"); + TIFFSetField(tif, TIFFTAG_MAKE, state_proc.configuration->make); + TIFFSetField(tif, TIFFTAG_MODEL, state_proc.configuration->model); + uint16_t orientation; - if (camera_rotation == 0) { - orientation = - mode->mirrored ? ORIENTATION_TOPRIGHT : ORIENTATION_TOPLEFT; - } else if (camera_rotation == 90) { - orientation = - mode->mirrored ? ORIENTATION_RIGHTBOT : ORIENTATION_LEFTBOT; - } else if (camera_rotation == 180) { - orientation = - mode->mirrored ? ORIENTATION_BOTLEFT : ORIENTATION_BOTRIGHT; + if (state_proc.device_rotation == 0) { + orientation = state_proc.mode->mirrored ? ORIENTATION_TOPRIGHT : + ORIENTATION_TOPLEFT; + } else if (state_proc.device_rotation == 90) { + orientation = state_proc.mode->mirrored ? ORIENTATION_RIGHTBOT : + ORIENTATION_LEFTBOT; + } else if (state_proc.device_rotation == 180) { + orientation = state_proc.mode->mirrored ? ORIENTATION_BOTLEFT : + ORIENTATION_BOTRIGHT; } else { - orientation = - mode->mirrored ? ORIENTATION_LEFTTOP : ORIENTATION_RIGHTTOP; + orientation = state_proc.mode->mirrored ? ORIENTATION_LEFTTOP : + ORIENTATION_RIGHTTOP; } TIFFSetField(tif, TIFFTAG_ORIENTATION, orientation); TIFFSetField(tif, TIFFTAG_DATETIME, datetime); @@ -574,98 +565,19 @@ process_image_for_capture(const uint8_t *image, int count) char uniquecameramodel[255]; sprintf(uniquecameramodel, "%s %s", - "MAKE", // TODO: fix - "MODEL"); + state_proc.configuration->make, + state_proc.configuration->model); TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, uniquecameramodel); - // Color matrices - /* - if (pr_camera->calibration.color_matrix_1[0]) { - TIFFSetField(tif, - TIFFTAG_COLORMATRIX1, - 9, - pr_camera->calibration.color_matrix_1); - } else if (pr_camera->colormatrix[0]) { - TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, pr_camera->colormatrix); - } else { - TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, colormatrix_srgb); - } - if (pr_camera->calibration.color_matrix_2[0]) { - TIFFSetField(tif, - TIFFTAG_COLORMATRIX2, - 9, - pr_camera->calibration.color_matrix_2); - } - - if (pr_camera->calibration.forward_matrix_1[0]) { - TIFFSetField(tif, - TIFFTAG_FORWARDMATRIX1, - 9, - pr_camera->calibration.forward_matrix_1); - } else if (pr_camera->forwardmatrix[0]) { - TIFFSetField(tif, TIFFTAG_FORWARDMATRIX1, 9, - pr_camera->forwardmatrix); - } - - if (pr_camera->calibration.forward_matrix_2[0]) { - TIFFSetField(tif, - TIFFTAG_FORWARDMATRIX2, - 9, - pr_camera->calibration.forward_matrix_2); - } - static const float neutral[] = { 1.0, 1.0, 1.0 }; TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral); - if (pr_camera->calibration.illuminant_1) { - TIFFSetField(tif, - TIFFTAG_CALIBRATIONILLUMINANT1, - pr_camera->calibration.illuminant_1); - } else { - TIFFSetField(tif, TIFFTAG_CALIBRATIONILLUMINANT1, 21); - } - - if (pr_camera->calibration.illuminant_2) { - TIFFSetField(tif, - TIFFTAG_CALIBRATIONILLUMINANT2, - pr_camera->calibration.illuminant_2); - } - - if (pr_camera->calibration.tone_curve_length) { - TIFFSetField(tif, - DCPTAG_PROFILE_TONE_CURVE, - pr_camera->calibration.tone_curve_length, - pr_camera->calibration.tone_curve); - } - - if (pr_camera->calibration.hue_sat_map_dims[0]) { - TIFFSetField(tif, - DCPTAG_PROFILE_HUE_SAT_MAP_DIMS, - 3, - pr_camera->calibration.hue_sat_map_dims); - TIFFSetField(tif, - DCPTAG_PROFILE_HUE_SAT_MAP_DATA_1, - pr_camera->calibration.hue_sat_map_dims[0] * - pr_camera->calibration.hue_sat_map_dims[1] * - pr_camera->calibration.hue_sat_map_dims[2] * 3, - pr_camera->calibration.hue_sat_map_data_1); - if (pr_camera->calibration.hue_sat_map_data_2 != NULL) { - TIFFSetField( - tif, - DCPTAG_PROFILE_HUE_SAT_MAP_DATA_2, - pr_camera->calibration.hue_sat_map_dims[0] * - pr_camera->calibration.hue_sat_map_dims[1] * - pr_camera->calibration.hue_sat_map_dims[2] * - 3, pr_camera->calibration.hue_sat_map_data_2); - } - } - */ TIFFSetField(tif, TIFFTAG_ANALOGBALANCE, 3, balance); // Write black thumbnail, only windows uses this { - unsigned char *buf = - (unsigned char *)calloc(1, (mode->width >> 4) * 3); - for (int row = 0; row < (mode->height >> 4); row++) { + unsigned char *buf = (unsigned char *)calloc( + 1, (state_proc.mode->width >> 4) * 3); + for (int row = 0; row < (state_proc.mode->height >> 4); row++) { TIFFWriteScanline(tif, buf, row, 0); } free(buf); @@ -674,11 +586,11 @@ process_image_for_capture(const uint8_t *image, int count) // Define main photo TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0); - TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, mode->width); - TIFFSetField(tif, TIFFTAG_IMAGELENGTH, mode->height); + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, state_proc.mode->width); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, state_proc.mode->height); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, - libmegapixels_format_bits_per_pixel(mode->format)); + libmegapixels_format_bits_per_pixel(state_proc.mode->format)); TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); @@ -692,11 +604,12 @@ process_image_for_capture(const uint8_t *image, int count) TIFFSetField(tif, TIFFTAG_CFAPATTERN, 4, - libmegapixels_format_cfa_pattern(mode->format)); + libmegapixels_format_cfa_pattern(state_proc.mode->format)); #endif printf("TIFF version %d\n", TIFFLIB_VERSION); int whitelevel = - (1 << libmegapixels_format_bits_per_pixel(mode->format)) - 1; + (1 << libmegapixels_format_bits_per_pixel(state_proc.mode->format)) - + 1; TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &whitelevel); TIFFCheckpointDirectory(tif); printf("Writing frame to %s\n", fname); @@ -704,19 +617,21 @@ process_image_for_capture(const uint8_t *image, int count) uint8_t *output_image = (uint8_t *)image; // Repack 10-bit image from sensor format into a sequencial format - if (libmegapixels_format_bits_per_pixel(mode->format) == 10) { - output_image = malloc(libmegapixels_mode_width_to_bytes( - mode->format, mode->width) * - mode->height); + if (libmegapixels_format_bits_per_pixel(state_proc.mode->format) == 10) { + output_image = malloc( + libmegapixels_mode_width_to_bytes(state_proc.mode->format, + state_proc.mode->width) * + state_proc.mode->height); - repack_image_sequencial(image, output_image, mode); + repack_image_sequencial(image, output_image, state_proc.mode); } - for (int row = 0; row < mode->height; row++) { + for (int row = 0; row < state_proc.mode->height; row++) { TIFFWriteScanline(tif, (void *)output_image + (row * libmegapixels_mode_width_to_bytes( - mode->format, mode->width)), + state_proc.mode->format, + state_proc.mode->width)), row, 0); } @@ -876,20 +791,21 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer) clock_t t1 = clock(); #endif - size_t size = - (libmegapixels_mode_width_to_bytes(mode->format, mode->width) + - libmegapixels_mode_width_to_padding(mode->format, mode->width)) * - mode->height; + size_t size = (libmegapixels_mode_width_to_bytes(state_proc.mode->format, + state_proc.mode->width) + + libmegapixels_mode_width_to_padding(state_proc.mode->format, + state_proc.mode->width)) * + state_proc.mode->height; uint8_t *image = malloc(size); memcpy(image, buffer->data, size); mp_io_pipeline_release_buffer(buffer->index); MPZBarImage *zbar_image = mp_zbar_image_new(image, - mode->format, - mode->width, - mode->height, - camera_rotation, - mode->mirrored); + state_proc.mode->format, + state_proc.mode->width, + state_proc.mode->height, + state_proc.device_rotation, + state_proc.mode->mirrored); mp_zbar_pipeline_process_image(mp_zbar_image_ref(zbar_image)); #ifdef PROFILE_PROCESS @@ -898,13 +814,13 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer) GdkTexture *thumb = process_image_for_preview(image); - if (captures_remaining > 0) { - int count = burst_length - captures_remaining; - --captures_remaining; + if (state_proc.captures_remaining > 0) { + int count = state_proc.burst_length - state_proc.captures_remaining; + --state_proc.captures_remaining; process_image_for_capture(image, count); - if (captures_remaining == 0) { + if (state_proc.captures_remaining == 0) { assert(thumb); process_capture_burst(thumb); } else { @@ -917,7 +833,7 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer) mp_zbar_image_unref(zbar_image); ++frames_processed; - if (captures_remaining == 0) { + if (state_proc.captures_remaining == 0) { is_capturing = false; } @@ -961,7 +877,7 @@ capture() strcpy(burst_dir, tempdir); - captures_remaining = burst_length; + state_proc.captures_remaining = state_proc.burst_length; } void @@ -975,10 +891,10 @@ mp_process_pipeline_capture() static void on_output_changed(bool format_changed) { - output_buffer_width = mode->width / 2; - output_buffer_height = mode->height / 2; + output_buffer_width = state_proc.mode->width / 2; + output_buffer_height = state_proc.mode->height / 2; - if (mode->rotation != 0 && mode->rotation != 180) { + if (state_proc.mode->rotation != 0 && state_proc.mode->rotation != 180) { int tmp = output_buffer_width; output_buffer_width = output_buffer_height; output_buffer_height = tmp; @@ -1004,7 +920,7 @@ on_output_changed(bool format_changed) if (gles2_debayer) gles2_debayer_free(gles2_debayer); - gles2_debayer = gles2_debayer_new(mode->format); + gles2_debayer = gles2_debayer_new(state_proc.mode->format); check_gl(); gles2_debayer_use(gles2_debayer); @@ -1013,9 +929,9 @@ on_output_changed(bool format_changed) gles2_debayer_configure(gles2_debayer, output_buffer_width, output_buffer_height, - mode->width, - mode->height, - mode->rotation, + state_proc.mode->width, + state_proc.mode->height, + state_proc.mode->rotation, 0, NULL, 0); @@ -1031,43 +947,46 @@ mod(int a, int b) static void update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state) { - const bool output_changed = - !libmegapixels_mode_equals(mode, state->camera->current_mode) || - preview_width != state->preview_width || - preview_height != state->preview_height || - device_rotation != state->device_rotation; + state_proc.configuration = state->configuration; + state_proc.camera = state->camera; - bool format_changed = mode == NULL; + const bool output_changed = + !libmegapixels_mode_equals(state_proc.mode, + state->camera->current_mode) || + state_proc.preview_width != state->preview_width || + state_proc.preview_height != state->preview_height || + state_proc.device_rotation != state->device_rotation; + + bool format_changed = state_proc.mode == NULL; if (!format_changed && - mode->v4l_pixfmt != state->camera->current_mode->v4l_pixfmt) { + state_proc.mode->v4l_pixfmt != state->camera->current_mode->v4l_pixfmt) { format_changed = true; } - if (mode == NULL) { - mode = state->camera->current_mode; + if (state_proc.mode == NULL) { + state_proc.mode = state->camera->current_mode; } - pr_camera = state->camera; - mode = state->camera->current_mode; + state_proc.mode = state->camera->current_mode; - preview_width = state->preview_width; - preview_height = state->preview_height; + state_proc.preview_width = state->preview_width; + state_proc.preview_height = state->preview_height; - device_rotation = state->device_rotation; + state_proc.device_rotation = state->device_rotation; + state_proc.burst_length = state->burst_length; - burst_length = state->burst_length; - - // gain_is_manual = state->gain_is_manual; - gain = state->gain; - gain_max = state->gain_max; - balance[0] = state->balance_red; - balance[2] = state->balance_blue; + state_proc.gain.manual = state->gain_is_manual; + state_proc.gain.value = state->gain; + state_proc.gain.max = state->gain_max; + state_proc.balance[0] = state->balance_red; + state_proc.balance[2] = state->balance_blue; exposure_is_manual = state->exposure_is_manual; exposure = state->exposure; if (output_changed) { - camera_rotation = mod(mode->rotation - device_rotation, 360); + state_proc.camera_rotation = mod( + state_proc.mode->rotation - state_proc.device_rotation, 360); on_output_changed(format_changed); } diff --git a/src/process_pipeline.h b/src/process_pipeline.h index b237bc8..5b53ca5 100644 --- a/src/process_pipeline.h +++ b/src/process_pipeline.h @@ -7,6 +7,7 @@ typedef struct _GdkSurface GdkSurface; struct mp_process_pipeline_state { libmegapixels_camera *camera; + libmegapixels_devconfig *configuration; int burst_length; diff --git a/src/state.h b/src/state.h index 1de92f1..34300d1 100644 --- a/src/state.h +++ b/src/state.h @@ -47,6 +47,7 @@ typedef struct cstate { } controlstate; typedef struct state_io { + libmegapixels_devconfig *configuration; libmegapixels_camera *camera; libmegapixels_mode *mode_capture; libmegapixels_mode *mode_preview; @@ -70,4 +71,27 @@ typedef struct state_io { int preview_width; int preview_height; int device_rotation; -} mp_state_io; \ No newline at end of file +} mp_state_io; + +typedef struct state_proc { + libmegapixels_devconfig *configuration; + libmegapixels_camera *camera; + libmegapixels_mode *mode; + + int burst_length; + int captures_remaining; + int preview_width; + int preview_height; + + // Device orientation in degrees + int device_rotation; + // Camera orientation as number + int camera_rotation; + + bool is_capturing; + + float balance[3]; + controlstate gain; + controlstate exposure; + controlstate focus; +} mp_state_proc; \ No newline at end of file