diff --git a/src/openexr-thumbnailer.cpp b/src/openexr-thumbnailer.cpp index dcc09ff..fcb8cf2 100644 --- a/src/openexr-thumbnailer.cpp +++ b/src/openexr-thumbnailer.cpp @@ -15,10 +15,13 @@ #include #include #include +#include #include #include +#define USE_PREVIEW + double to_sRGB(double rgb_color) { const double a = 0.055; @@ -30,50 +33,68 @@ double to_sRGB(double rgb_color) unsigned char *load_exr(const char *path, int *width, int *height) { - // MyStream stream(buffer, size, "test"); - Imf::Array2D pixels; - Imf::RgbaInputFile f(path); - Imath::Box2i dw = f.dataWindow(); - int w = dw.max.x - dw.min.x + 1; - int h = dw.max.y - dw.min.y + 1; - *width = w; - *height = h; + unsigned char *img = nullptr; + +#ifdef USE_PREVIEW + if (f.header().hasPreviewImage()) { + const Imf::PreviewImage &preview = f.header().previewImage(); + *width = preview.width(); + *height = preview.height(); + img = new unsigned char[3 * (*width) * (*height)]; + + for (int i = 0; i < (*width) * (*height); i++) { + img[3*i + 0] = preview.pixels()[i].r; + img[3*i + 1] = preview.pixels()[i].g; + img[3*i + 2] = preview.pixels()[i].b; + } + } else { +#endif // USE_PREVIEW + Imf::Array2D pixels; - pixels.resizeErase(h, w); - f.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * w, 1, w); - f.readPixels(dw.min.y, dw.max.y); + Imath::Box2i dw = f.dataWindow(); + int w = dw.max.x - dw.min.x + 1; + int h = dw.max.y - dw.min.y + 1; + *width = w; + *height = h; + img = new unsigned char[3 * w * h]; - // Check if there is specific chromaticities tied to the color representation in this part. - const Imf::ChromaticitiesAttribute *c = f.header().findTypedAttribute("chromaticities"); + pixels.resizeErase(h, w); + f.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * w, 1, w); + f.readPixels(dw.min.y, dw.max.y); - Imf::Chromaticities chromaticities; + // Check if there is specific chromaticities tied to the color representation in this part. + const Imf::ChromaticitiesAttribute *c = f.header().findTypedAttribute("chromaticities"); - if (c != nullptr) { - chromaticities = c->value(); - } + Imf::Chromaticities chromaticities; - // Handle custom chromaticities - Imath::M44f RGB_XYZ = Imf::RGBtoXYZ(chromaticities, 1.f); - Imath::M44f XYZ_RGB = Imf::XYZtoRGB(Imf::Chromaticities(), 1.f); + if (c != nullptr) { + chromaticities = c->value(); + } + + // Handle custom chromaticities + Imath::M44f RGB_XYZ = Imf::RGBtoXYZ(chromaticities, 1.f); + Imath::M44f XYZ_RGB = Imf::XYZtoRGB(Imf::Chromaticities(), 1.f); - Imath::M44f conversionMatrix = RGB_XYZ * XYZ_RGB; + Imath::M44f conversionMatrix = RGB_XYZ * XYZ_RGB; - unsigned char *img = new unsigned char[3 * w * h]; - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - Imath::V3f rgb(pixels[y][x].r, pixels[y][x].g, pixels[y][x].b); - rgb *= conversionMatrix; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + Imath::V3f rgb(pixels[y][x].r, pixels[y][x].g, pixels[y][x].b); + rgb *= conversionMatrix; - img[3*(y*w + x) + 0] = - (unsigned char)(255.0*std::min(1.0, std::max(0.0, to_sRGB(rgb.x)))); - img[3*(y*w + x) + 1] = - (unsigned char)(255.0*std::min(1.0, std::max(0.0, to_sRGB(rgb.y)))); - img[3*(y*w + x) + 2] = - (unsigned char)(255.0*std::min(1.0, std::max(0.0, to_sRGB(rgb.z)))); + img[3*(y*w + x) + 0] = + (unsigned char)(255.0*std::min(1.0, std::max(0.0, to_sRGB(rgb.x)))); + img[3*(y*w + x) + 1] = + (unsigned char)(255.0*std::min(1.0, std::max(0.0, to_sRGB(rgb.y)))); + img[3*(y*w + x) + 2] = + (unsigned char)(255.0*std::min(1.0, std::max(0.0, to_sRGB(rgb.z)))); + } } +#ifdef USE_PREVIEW } +#endif // USE_PREVIEW return img; } @@ -103,5 +124,8 @@ extern "C" GdkPixbuf *file_to_pixbuf(const char *path, GError **error) free_buff, NULL); + // The pointer must remain valid, + // do not: `delete[] pixels;` + return pixbuf; }