aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2023-05-21 23:30:29 +0200
committerPřemysl Eric Janouch <p@janouch.name>2023-05-26 13:30:22 +0200
commit0f1c61ae3325dda14be8f98ee7047ac5eda02108 (patch)
tree4492f4f1b9d88ef8dae5ca5694ce47a1ce63ce3f
parent0359ddf99f3940794d51c206a30d51eac4c2f1d2 (diff)
downloadfiv-0f1c61ae3325dda14be8f98ee7047ac5eda02108.tar.gz
fiv-0f1c61ae3325dda14be8f98ee7047ac5eda02108.tar.xz
fiv-0f1c61ae3325dda14be8f98ee7047ac5eda02108.zip
Extract all raw subimages as pages
And add missing colour management.
-rw-r--r--fiv-io.c84
1 files changed, 49 insertions, 35 deletions
diff --git a/fiv-io.c b/fiv-io.c
index df50d33..c4c61f4 100644
--- a/fiv-io.c
+++ b/fiv-io.c
@@ -1705,38 +1705,11 @@ fail:
#ifdef HAVE_LIBRAW // ---------------------------------------------------------
static cairo_surface_t *
-open_libraw(const char *data, gsize len, GError **error)
+load_libraw(libraw_data_t *iprc, GError **error)
{
- // https://github.com/LibRaw/LibRaw/issues/418
- libraw_data_t *iprc = libraw_init(
- LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
- if (!iprc) {
- set_error(error, "failed to obtain a LibRaw handle");
- return NULL;
- }
-
-#if 0
- // TODO(p): Consider setting this--the image is still likely to be
- // rendered suboptimally, so why not make it faster.
- iprc->params.half_size = 1;
-#endif
-
- // TODO(p): Check if we need to set anything for autorotation (sizes.flip).
- iprc->params.use_camera_wb = 1;
- iprc->params.output_color = 1; // sRGB, TODO(p): Is this used?
- iprc->params.output_bps = 8; // This should be the default value.
-
int err = 0;
- if ((err = libraw_open_buffer(iprc, (void *) data, len))) {
- set_error(error, libraw_strerror(err));
- libraw_close(iprc);
- return NULL;
- }
-
- // TODO(p): Do we need to check iprc->idata.raw_count? Maybe for TIFFs?
if ((err = libraw_unpack(iprc))) {
set_error(error, libraw_strerror(err));
- libraw_close(iprc);
return NULL;
}
@@ -1744,7 +1717,6 @@ open_libraw(const char *data, gsize len, GError **error)
// TODO(p): I'm not sure when this is necessary or useful yet.
if ((err = libraw_adjust_sizes_info_only(iprc))) {
set_error(error, libraw_strerror(err));
- libraw_close(iprc);
return NULL;
}
#endif
@@ -1752,7 +1724,6 @@ open_libraw(const char *data, gsize len, GError **error)
// TODO(p): Documentation says I should look at the code and do it myself.
if ((err = libraw_dcraw_process(iprc))) {
set_error(error, libraw_strerror(err));
- libraw_close(iprc);
return NULL;
}
@@ -1761,7 +1732,6 @@ open_libraw(const char *data, gsize len, GError **error)
libraw_processed_image_t *image = libraw_dcraw_make_mem_image(iprc, &err);
if (!image) {
set_error(error, libraw_strerror(err));
- libraw_close(iprc);
return NULL;
}
@@ -1769,7 +1739,6 @@ open_libraw(const char *data, gsize len, GError **error)
if (image->colors != 3 || image->bits != 8) {
set_error(error, "unexpected number of colours, or bit depth");
libraw_dcraw_clear_mem(image);
- libraw_close(iprc);
return NULL;
}
@@ -1781,7 +1750,6 @@ open_libraw(const char *data, gsize len, GError **error)
set_error(error, cairo_status_to_string(surface_status));
cairo_surface_destroy(surface);
libraw_dcraw_clear_mem(image);
- libraw_close(iprc);
return NULL;
}
@@ -1802,10 +1770,56 @@ open_libraw(const char *data, gsize len, GError **error)
cairo_surface_mark_dirty(surface);
libraw_dcraw_clear_mem(image);
- libraw_close(iprc);
return surface;
}
+static cairo_surface_t *
+open_libraw(
+ const char *data, gsize len, const FivIoOpenContext *ctx, GError **error)
+{
+ // https://github.com/LibRaw/LibRaw/issues/418
+ libraw_data_t *iprc = libraw_init(
+ LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
+ if (!iprc) {
+ set_error(error, "failed to obtain a LibRaw handle");
+ return NULL;
+ }
+
+ // TODO(p): Check if we need to set anything for autorotation (sizes.flip).
+ iprc->params.use_camera_wb = 1;
+ iprc->params.output_color = 1; // sRGB, TODO(p): Is this used?
+ iprc->params.output_bps = 8; // This should be the default value.
+
+ int err = 0;
+ cairo_surface_t *result = NULL, *result_tail = NULL;
+ if ((err = libraw_open_buffer(iprc, (const void *) data, len))) {
+ set_error(error, libraw_strerror(err));
+ goto out;
+ }
+ if (!try_append_page(load_libraw(iprc, error), &result, &result_tail) ||
+ ctx->first_frame_only)
+ goto out;
+
+ for (unsigned i = 1; i < iprc->idata.raw_count; i++) {
+ iprc->rawparams.shot_select = i;
+
+ // This library is terrible, we need to start again.
+ if ((err = libraw_open_buffer(iprc, (const void *) data, len))) {
+ set_error(error, libraw_strerror(err));
+ g_clear_pointer(&result, cairo_surface_destroy);
+ goto out;
+ }
+ if (!try_append_page(load_libraw(iprc, error), &result, &result_tail)) {
+ g_clear_pointer(&result, cairo_surface_destroy);
+ goto out;
+ }
+ }
+
+out:
+ libraw_close(iprc);
+ return fiv_io_profile_finalize(result, ctx->screen_profile);
+}
+
#endif // HAVE_LIBRAW ---------------------------------------------------------
#ifdef HAVE_RESVG // ----------------------------------------------------------
@@ -2811,7 +2825,7 @@ fiv_io_open_from_data(
break;
default:
#ifdef HAVE_LIBRAW // ---------------------------------------------------------
- if ((surface = open_libraw(data, len, error)))
+ if ((surface = open_libraw(data, len, ctx, error)))
break;
// TODO(p): We should try to pass actual processing errors through,