Skip to content

Commit

Permalink
Use preview when available in the header #4
Browse files Browse the repository at this point in the history
  • Loading branch information
afichet committed May 27, 2021
1 parent f287e01 commit 09a4445
Showing 1 changed file with 56 additions and 32 deletions.
88 changes: 56 additions & 32 deletions src/openexr-thumbnailer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
#include <OpenEXR/ImfRgbaFile.h>
#include <OpenEXR/ImfArray.h>
#include <OpenEXR/ImfHeader.h>
#include <OpenEXR/ImfPreviewImage.h>
#include <OpenEXR/ImfChromaticitiesAttribute.h>

#include <cmath>

#define USE_PREVIEW

double to_sRGB(double rgb_color)
{
const double a = 0.055;
Expand All @@ -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<Imf::Rgba> 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<Imf::Rgba> 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<Imf::ChromaticitiesAttribute>("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<Imf::ChromaticitiesAttribute>("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;
}
Expand Down Expand Up @@ -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;
}

0 comments on commit 09a4445

Please sign in to comment.