hdr: improve precision

- Improve the precision of HDR format (it is a floating point format) by using the RGBA32FPx4 image format.
This commit is contained in:
Mirco Miranda 2023-08-13 22:19:22 +00:00 committed by Albert Astals Cid
parent 7a0d95af92
commit 35ff3efbbc
5 changed files with 12 additions and 16 deletions

View File

@ -14,11 +14,12 @@ image formats.
The following image formats have read-only support: The following image formats have read-only support:
- Animated Windows cursors (ani) - Animated Windows cursors (ani)
- Camera RAW images (arw, cr2, cr3, dcs, dng, ...)
- Gimp (xcf) - Gimp (xcf)
- OpenEXR (exr) - OpenEXR (exr)
- Photoshop documents (psd, psb, pdd, psdt) - Photoshop documents (psd, psb, pdd, psdt)
- Radiance HDR (hdr)
- Sun Raster (ras) - Sun Raster (ras)
- Camera RAW images (arw, cr2, cr3, dcs, dng, ...)
- Quite OK Image format (qoi) - Quite OK Image format (qoi)
The following image formats have read and write support: The following image formats have read and write support:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -9,11 +9,11 @@
#include "hdr_p.h" #include "hdr_p.h"
#include "util_p.h" #include "util_p.h"
#include <QColorSpace>
#include <QDataStream> #include <QDataStream>
#include <QImage> #include <QImage>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QRegularExpressionMatch> #include <QRegularExpressionMatch>
#include <QColorSpace>
#include <QDebug> #include <QDebug>
@ -27,15 +27,6 @@ namespace // Private.
#define MINELEN 8 // minimum scanline length for encoding #define MINELEN 8 // minimum scanline length for encoding
#define MAXELEN 0x7fff // maximum scanline length for encoding #define MAXELEN 0x7fff // maximum scanline length for encoding
static inline uchar ClipToByte(float value)
{
if (value > 255.0f) {
return 255;
}
// else if (value < 0.0f) return 0; // we know value is positive.
return uchar(value);
}
// read an old style line from the hdr image file // read an old style line from the hdr image file
// if 'first' is true the first byte is already read // if 'first' is true the first byte is already read
static bool Read_Old_Line(uchar *image, int width, QDataStream &s) static bool Read_Old_Line(uchar *image, int width, QDataStream &s)
@ -70,7 +61,7 @@ static bool Read_Old_Line(uchar *image, int width, QDataStream &s)
return true; return true;
} }
static void RGBE_To_QRgbLine(uchar *image, QRgb *scanline, int width) static void RGBE_To_QRgbLine(uchar *image, float *scanline, int width)
{ {
for (int j = 0; j < width; j++) { for (int j = 0; j < width; j++) {
// v = ldexp(1.0, int(image[3]) - 128); // v = ldexp(1.0, int(image[3]) - 128);
@ -82,8 +73,12 @@ static void RGBE_To_QRgbLine(uchar *image, QRgb *scanline, int width)
v = 1.0f / float(1 << -e); v = 1.0f / float(1 << -e);
} }
scanline[j] = qRgb(ClipToByte(float(image[0]) * v), ClipToByte(float(image[1]) * v), ClipToByte(float(image[2]) * v)); auto j4 = j * 4;
auto vn = v / 255.0f;
scanline[j4] = std::min(float(image[0]) * vn, 1.0f);
scanline[j4 + 1] = std::min(float(image[1]) * vn, 1.0f);
scanline[j4 + 2] = std::min(float(image[2]) * vn, 1.0f);
scanline[j4 + 3] = 1.0f;
image += 4; image += 4;
} }
} }
@ -95,7 +90,7 @@ static bool LoadHDR(QDataStream &s, const int width, const int height, QImage &i
uchar code; uchar code;
// Create dst image. // Create dst image.
img = imageAlloc(width, height, QImage::Format_RGB32); img = imageAlloc(width, height, QImage::Format_RGBX32FPx4);
if (img.isNull()) { if (img.isNull()) {
qCDebug(HDRPLUGIN) << "Couldn't create image with size" << width << height << "and format RGB32"; qCDebug(HDRPLUGIN) << "Couldn't create image with size" << width << height << "and format RGB32";
return false; return false;
@ -106,7 +101,7 @@ static bool LoadHDR(QDataStream &s, const int width, const int height, QImage &i
uchar *image = (uchar *)lineArray.data(); uchar *image = (uchar *)lineArray.data();
for (int cline = 0; cline < height; cline++) { for (int cline = 0; cline < height; cline++) {
QRgb *scanline = (QRgb *)img.scanLine(cline); auto scanline = (float *)img.scanLine(cline);
// determine scanline type // determine scanline type
if ((width < MINELEN) || (MAXELEN < width)) { if ((width < MINELEN) || (MAXELEN < width)) {