diff --git a/data/debayer.frag b/data/debayer.frag index 7302e43..74f6517 100644 --- a/data/debayer.frag +++ b/data/debayer.frag @@ -62,15 +62,13 @@ main() // should be an uniform vec3 corrected = color - 0.02; - // Apply the color matrices - // vec3 corrected = color_matrix * color2; - +#ifdef COLORSPACE_RAW // Fast SRGB estimate. See https://mimosa-pudica.net/fast-gamma/ vec3 srgb_color = (vec3(1.138) * inversesqrt(corrected) - vec3(0.138)) * corrected; - // Slow SRGB estimate - // vec3 srgb_color = pow(color, vec3(1.0 / 2.2)); - gl_FragColor = vec4(srgb_color, 1); +#elif COLORSPACE_SRGB + gl_FragColor = vec4(color, 1); +#endif } diff --git a/src/gles2_debayer.c b/src/gles2_debayer.c index 94687ad..cd20671 100644 --- a/src/gles2_debayer.c +++ b/src/gles2_debayer.c @@ -23,7 +23,7 @@ struct _GLES2Debayer { }; GLES2Debayer * -gles2_debayer_new(int format) +gles2_debayer_new(int format, uint32_t colorspace) { uint32_t pixfmt = libmegapixels_format_to_v4l_pixfmt(format); if (pixfmt != V4L2_PIX_FMT_SBGGR8 && pixfmt != V4L2_PIX_FMT_SGBRG8 && @@ -37,12 +37,14 @@ gles2_debayer_new(int format) glGenFramebuffers(1, &frame_buffer); check_gl(); - char format_def[64]; + char format_def[96]; + bool is_srgb = colorspace == V4L2_COLORSPACE_SRGB; snprintf(format_def, - 64, - "#define CFA_%s\n#define BITS_%d\n", + 96, + "#define CFA_%s\n#define BITS_%d\n#define COLORSPACE_%s\n", libmegapixels_format_cfa(format), - libmegapixels_format_bits_per_pixel(format)); + libmegapixels_format_bits_per_pixel(format), + is_srgb ? "SRGB" : "RAW"); const GLchar *def[1] = { format_def }; diff --git a/src/gles2_debayer.h b/src/gles2_debayer.h index 330190b..1a21e09 100644 --- a/src/gles2_debayer.h +++ b/src/gles2_debayer.h @@ -5,7 +5,7 @@ typedef struct _GLES2Debayer GLES2Debayer; -GLES2Debayer *gles2_debayer_new(int format); +GLES2Debayer *gles2_debayer_new(int format, uint32_t colorspace); void gles2_debayer_free(GLES2Debayer *self); void gles2_debayer_use(GLES2Debayer *self); diff --git a/src/io_pipeline.c b/src/io_pipeline.c index 6e7445f..dad3fad 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -81,6 +81,7 @@ update_process_pipeline() .preview_width = state_io.preview_width, .preview_height = state_io.preview_height, .device_rotation = state_io.device_rotation, + .colorspace = state_io.colorspace, .gain.control = state_io.gain.control, .gain.auto_control = state_io.gain.auto_control, @@ -144,6 +145,7 @@ capture(MPPipeline *pipeline, const void *data) mp_camera_stop_capture(mpcamera); struct v4l2_format format = { 0 }; libmegapixels_select_mode(state_io.camera, state_io.mode_capture, &format); + state_io.colorspace = format.fmt.pix.colorspace; state_io.flush_pipeline = true; mp_camera_start_capture(mpcamera); @@ -326,6 +328,7 @@ on_frame(MPBuffer buffer, void *_data) struct v4l2_format format = { 0 }; libmegapixels_select_mode( state_io.camera, state_io.mode_preview, &format); + state_io.colorspace = format.fmt.pix.colorspace; state_io.flush_pipeline = true; mp_camera_start_capture(mpcamera); @@ -498,6 +501,7 @@ update_state(MPPipeline *pipeline, const mp_state_io *new_state) libmegapixels_select_mode(state_io.camera, state_io.mode_preview, &format); + state_io.colorspace = format.fmt.pix.colorspace; } mp_camera_start_capture(mpcamera); diff --git a/src/process_pipeline.c b/src/process_pipeline.c index ff03e42..722734b 100644 --- a/src/process_pipeline.c +++ b/src/process_pipeline.c @@ -927,7 +927,7 @@ on_output_changed(bool format_changed) if (gles2_debayer) gles2_debayer_free(gles2_debayer); - gles2_debayer = gles2_debayer_new(state_proc.mode->format); + gles2_debayer = gles2_debayer_new(state_proc.mode->format, state_proc.colorspace); check_gl(); gles2_debayer_use(gles2_debayer); @@ -990,6 +990,7 @@ update_state(MPPipeline *pipeline, const mp_state_proc *new_state) } state_proc.mode = new_state->camera->current_mode; + state_proc.colorspace = new_state->colorspace; state_proc.preview_width = new_state->preview_width; state_proc.preview_height = new_state->preview_height; diff --git a/src/state.h b/src/state.h index a3452b1..fd3d1a1 100644 --- a/src/state.h +++ b/src/state.h @@ -51,6 +51,7 @@ typedef struct state_io { int captures_remaining; bool flush_pipeline; int blank_frame_count; + uint32_t colorspace; // Control state controlstate gain; @@ -79,6 +80,7 @@ typedef struct state_proc { int counter; int preview_width; int preview_height; + uint32_t colorspace; // Device orientation in degrees int device_rotation;