diff --git a/README.md b/README.md index 66191be..99f9b9d 100644 --- a/README.md +++ b/README.md @@ -402,7 +402,8 @@ When writing, it is also possible to specify a subtype: subsampling or loss of chromatic detail. - `YC`: converts RGB data into luminance (Y) and 2x2 subsampled chroma (RY, BY), cutting raw color data by ~50% for significantly smaller file - sizes. + sizes. **If the image does not have a height and width that are multiples + of 2, `RGB` is used.** > [!note] > When writing grayscale images, the subtype makes no difference. diff --git a/autotests/read/exr/alphatest_rgba.exr b/autotests/read/exr/alphatest_rgba.exr new file mode 100644 index 0000000..58ecc4b Binary files /dev/null and b/autotests/read/exr/alphatest_rgba.exr differ diff --git a/autotests/read/exr/alphatest_rgba.tif b/autotests/read/exr/alphatest_rgba.tif new file mode 100644 index 0000000..a434385 Binary files /dev/null and b/autotests/read/exr/alphatest_rgba.tif differ diff --git a/autotests/write/format/exr/Format_A2BGR30_Premultiplied.exr b/autotests/write/format/exr/Format_A2BGR30_Premultiplied.exr index 818b0d4..d755ff0 100644 Binary files a/autotests/write/format/exr/Format_A2BGR30_Premultiplied.exr and b/autotests/write/format/exr/Format_A2BGR30_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_A2RGB30_Premultiplied.exr b/autotests/write/format/exr/Format_A2RGB30_Premultiplied.exr index 818b0d4..d755ff0 100644 Binary files a/autotests/write/format/exr/Format_A2RGB30_Premultiplied.exr and b/autotests/write/format/exr/Format_A2RGB30_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_ARGB32.exr b/autotests/write/format/exr/Format_ARGB32.exr index eb67e3a..8d7436f 100644 Binary files a/autotests/write/format/exr/Format_ARGB32.exr and b/autotests/write/format/exr/Format_ARGB32.exr differ diff --git a/autotests/write/format/exr/Format_ARGB32_Premultiplied.exr b/autotests/write/format/exr/Format_ARGB32_Premultiplied.exr index a7c1052..01ee863 100644 Binary files a/autotests/write/format/exr/Format_ARGB32_Premultiplied.exr and b/autotests/write/format/exr/Format_ARGB32_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_ARGB4444_Premultiplied.exr b/autotests/write/format/exr/Format_ARGB4444_Premultiplied.exr index 1bae48b..db536d2 100644 Binary files a/autotests/write/format/exr/Format_ARGB4444_Premultiplied.exr and b/autotests/write/format/exr/Format_ARGB4444_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_ARGB6666_Premultiplied.exr b/autotests/write/format/exr/Format_ARGB6666_Premultiplied.exr index f480e31..a6f7650 100644 Binary files a/autotests/write/format/exr/Format_ARGB6666_Premultiplied.exr and b/autotests/write/format/exr/Format_ARGB6666_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_ARGB8555_Premultiplied.exr b/autotests/write/format/exr/Format_ARGB8555_Premultiplied.exr index 97de062..f98e61b 100644 Binary files a/autotests/write/format/exr/Format_ARGB8555_Premultiplied.exr and b/autotests/write/format/exr/Format_ARGB8555_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_ARGB8565_Premultiplied.exr b/autotests/write/format/exr/Format_ARGB8565_Premultiplied.exr index 8d6a3d7..b091787 100644 Binary files a/autotests/write/format/exr/Format_ARGB8565_Premultiplied.exr and b/autotests/write/format/exr/Format_ARGB8565_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_RGBA16FPx4.exr b/autotests/write/format/exr/Format_RGBA16FPx4.exr index 39d7213..2f5db4e 100644 Binary files a/autotests/write/format/exr/Format_RGBA16FPx4.exr and b/autotests/write/format/exr/Format_RGBA16FPx4.exr differ diff --git a/autotests/write/format/exr/Format_RGBA16FPx4_Premultiplied.exr b/autotests/write/format/exr/Format_RGBA16FPx4_Premultiplied.exr index d76ef76..9fe3d9a 100644 Binary files a/autotests/write/format/exr/Format_RGBA16FPx4_Premultiplied.exr and b/autotests/write/format/exr/Format_RGBA16FPx4_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_RGBA32FPx4.exr b/autotests/write/format/exr/Format_RGBA32FPx4.exr index c75c07f..2d09b69 100644 Binary files a/autotests/write/format/exr/Format_RGBA32FPx4.exr and b/autotests/write/format/exr/Format_RGBA32FPx4.exr differ diff --git a/autotests/write/format/exr/Format_RGBA32FPx4_Premultiplied.exr b/autotests/write/format/exr/Format_RGBA32FPx4_Premultiplied.exr index 7e6e352..2d09b69 100644 Binary files a/autotests/write/format/exr/Format_RGBA32FPx4_Premultiplied.exr and b/autotests/write/format/exr/Format_RGBA32FPx4_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_RGBA64.exr b/autotests/write/format/exr/Format_RGBA64.exr index 1c89768..2d92ff6 100644 Binary files a/autotests/write/format/exr/Format_RGBA64.exr and b/autotests/write/format/exr/Format_RGBA64.exr differ diff --git a/autotests/write/format/exr/Format_RGBA64_Premultiplied.exr b/autotests/write/format/exr/Format_RGBA64_Premultiplied.exr index 661592d..e36a799 100644 Binary files a/autotests/write/format/exr/Format_RGBA64_Premultiplied.exr and b/autotests/write/format/exr/Format_RGBA64_Premultiplied.exr differ diff --git a/autotests/write/format/exr/Format_RGBA8888.exr b/autotests/write/format/exr/Format_RGBA8888.exr index 5ba6004..9e5c469 100644 Binary files a/autotests/write/format/exr/Format_RGBA8888.exr and b/autotests/write/format/exr/Format_RGBA8888.exr differ diff --git a/autotests/write/format/exr/Format_RGBA8888_Premultiplied.exr b/autotests/write/format/exr/Format_RGBA8888_Premultiplied.exr index 4ed6669..1267019 100644 Binary files a/autotests/write/format/exr/Format_RGBA8888_Premultiplied.exr and b/autotests/write/format/exr/Format_RGBA8888_Premultiplied.exr differ diff --git a/src/imageformats/exr.cpp b/src/imageformats/exr.cpp index 7f723fc..8eccfd3 100644 --- a/src/imageformats/exr.cpp +++ b/src/imageformats/exr.cpp @@ -230,7 +230,7 @@ bool EXRHandler::canRead() const static QImage::Format imageFormat(const Imf::RgbaInputFile &file) { auto isRgba = file.channels() & Imf::RgbaChannels::WRITE_A; - return (isRgba ? QImage::Format_RGBA16FPx4 : QImage::Format_RGBX16FPx4); + return (isRgba ? QImage::Format_RGBA16FPx4_Premultiplied : QImage::Format_RGBX16FPx4); } /*! @@ -519,9 +519,9 @@ bool makePreview(const QImage &image, Imf::Array2D &pixels) QImage preview; if (w > h) { - preview = image.scaledToWidth(256).convertToFormat(QImage::Format_ARGB32); + preview = image.scaledToWidth(256).convertToFormat(QImage::Format_ARGB32_Premultiplied); } else { - preview = image.scaledToHeight(256).convertToFormat(QImage::Format_ARGB32); + preview = image.scaledToHeight(256).convertToFormat(QImage::Format_ARGB32_Premultiplied); } if (preview.isNull()) { return false; @@ -693,7 +693,8 @@ bool EXRHandler::write(const QImage &image) // write the EXR K_OStream ostr(device()); auto channelsType = image.hasAlphaChannel() ? Imf::RgbaChannels::WRITE_RGBA : Imf::RgbaChannels::WRITE_RGB; - if (m_subType == EXR_SUBFORMAT_YC) { + if (m_subType == EXR_SUBFORMAT_YC && !(width % 2) && !(height % 2)) { + // Works only with images with height and width that are multiples of 2. channelsType = channelsType == Imf::RgbaChannels::WRITE_RGBA ? Imf::RgbaChannels::WRITE_YCA : Imf::RgbaChannels::WRITE_YC; } if (image.format() == QImage::Format_Mono || @@ -707,7 +708,7 @@ bool EXRHandler::write(const QImage &image) pixels.resizeErase(EXR_LINES_PER_BLOCK, width); // convert the image and write into the stream - auto convFormat = image.hasAlphaChannel() ? QImage::Format_RGBA32FPx4 : QImage::Format_RGBX32FPx4; + auto convFormat = image.hasAlphaChannel() ? QImage::Format_RGBA32FPx4_Premultiplied : QImage::Format_RGBX32FPx4; ScanLineConverter slc(convFormat); slc.setDefaultSourceColorSpace(QColorSpace(QColorSpace::SRgb)); slc.setTargetColorSpace(QColorSpace(QColorSpace::SRgbLinear));