From 35ff3efbbcb9dbb1aff614ca7bdc4978c731b817 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Sun, 13 Aug 2023 22:19:22 +0000 Subject: [PATCH] hdr: improve precision - Improve the precision of HDR format (it is a floating point format) by using the RGBA32FPx4 image format. --- README.md | 3 ++- autotests/read/hdr/rgb-landscape.png | Bin 1219 -> 2858 bytes autotests/read/hdr/rgb-portrait.png | Bin 1165 -> 2856 bytes autotests/read/hdr/rgb.png | Bin 1113 -> 2761 bytes src/imageformats/hdr.cpp | 25 ++++++++++--------------- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6de786d..3c2df74 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,12 @@ image formats. The following image formats have read-only support: - Animated Windows cursors (ani) +- Camera RAW images (arw, cr2, cr3, dcs, dng, ...) - Gimp (xcf) - OpenEXR (exr) - Photoshop documents (psd, psb, pdd, psdt) +- Radiance HDR (hdr) - Sun Raster (ras) -- Camera RAW images (arw, cr2, cr3, dcs, dng, ...) - Quite OK Image format (qoi) The following image formats have read and write support: diff --git a/autotests/read/hdr/rgb-landscape.png b/autotests/read/hdr/rgb-landscape.png index 1da6ff1013a337793f1d8f1db37ecc09eb36d09c..4a96be12ac3b2431dac955543be4263542b6b4cc 100755 GIT binary patch literal 2858 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 IM6N<$g8vv!@Bjb+ delta 1211 zcmV;s1VsC)7Q+dU7=H)?0000j|LM~J000SaNLh0L01sgR01sgSs6VG^000DaNklHJQx$ z&GXDT?|UYvq);f}|19!v8`!ScwX1v{*$lEUG%+fYWr9rFu&G83A%rI>PA_G{>4dJ@ z`Gj4qP3rnxZ<2_Hp7zKf600V4UWTfPFo?%NBw^E=io|Ev=!-#2j2Sa!(}|u_`*!>Y zXjfNSepXM4u7Bln%+z1;)SkU@N1p2OggejmoG*_IezIiaNo4ZFc4eWZ@^UcbdY1j^ z*S!@hQ&gep8IRBkLKIyQxe!37(v9mV&v1b)RcmV4?tIKA>u=S$7= zR~noV-G3naD|@^8UL{9b(;)++vL_mQv#X&?BvLJU-1f47%h6{S6>fv?;_*w?+GsAf zT4XsfZD+v(21o{M99aXY_%#3d+v=roZWkk*IO*&fkT?l>AeDnwFeFxIKv?9`1ZhK% z3E5o4MdGh7A&vvbK>`7!hj$o&17vW3bkmg`et$1Gs|1$j{6{*R2EY1%%s~bL_=hwJ zkhbW|MdJUn2DXx}#7mz$<4a$Z{ZF`^AF-StU?|5Hl~22oRV5QIp9ysz_Zb+j;?|(}HupG~SDR7Z~o*!>DDN zPk$RA&mxdA%qNiZ-6qx4I28gNdYg4at(Zy*^nfvQ$cTV7GhZdJl>%va7 z<5i=C88K3Ot8E7@HNP!BbsKf4qlfMcM(X<6*t^ddgtxeeP4j7=3yIQjL;cF0=)8qAtxW}bf2AK#tmCZA|Yv7r_8&}+O?8T+lA~7qpi)x*ZOa`0F#`NI Z^*746s$Rk6w*LSC002ovPDHLkV1lClQ-S~h diff --git a/autotests/read/hdr/rgb-portrait.png b/autotests/read/hdr/rgb-portrait.png index 129cb9868b66fc6563541af35a3ed82b78e96659..1acc495065181ee665b1f32b4a7b9f71280522c7 100644 GIT binary patch literal 2856 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 W?X$YckzVfr0000`W>%;G%nX~i zswK7C>#LA5V3t{LS2}V{iUPcEVg{V7I4fXZP@A_=0OVglc<0x&J#gLvsk>iGAA$G=I5~dp*>w9= zl2=<_(_4T>t_Zf^%WqTOoo-^aiJ=d;YSG{R{D^<@0c}w@b%2f~761SM32;bRa{vGi z!vFvd!vV){sAK>D00(qQO+^Ri2N(_|C#QdEd;kCe{ApBJbXZMHI%98bE@5PEVr4FP zZEyeq0001ZoQ+gXkDD+Mz3;EE*h_l|2C~&EC}E|NY#V85D-vm|-W(W$6^t$0SxA0; z4au@m1Zg>8&wFn^JTud$T99N18f{=p%b8^%n$E1(FOd_85OVtcC}DN{u}+S=WRhA> z!QHg>YbF?If@)Tj%CBb@N%;nR^WR)!3$+lvn^~)a(!fv%k}#Smv|3Rn3i!G~MQ(mIxOg4P4O=4%v={rZxMCYhfcAJHraE5CluxmTGkCY}IN9<+MhL$E63Sdxb zWq58cPvl&4mGc3Yoq5o)i8hLE$IDnRbG{6J4lr9&FNy5U!}d|2rdjLFAbOcfFWyYW zZw0E>2LU(+#rHCS#hakx0egzD_?nSS%KcMfkyj%DVe|2)Wo~nx+X*DCF}1g#rM^n#M56B*P#yH-`{FKCh}6 zJDrMxaa|ok2q8pK2<38iyJ0vSBpHvZY9?bCio)|0mC5kDqSV)CvxZ?9w{H1-*(^c~ zgRx<#s@u(R00^-xNh(SN<3&qhrO2_umHq(6lR8(&?6#4?k3t0|yvJmgnXwD*+}ZJf6#! z-R}Cs$Btd^y?K-4Zam+0+3k+U+uKi`?CLswy0S8n=<9p^_1RgclcEqxBt}PHdu`o1 zQJkJ`X{oNhbSWH;#bo)(CrR>y4?g*1!-lG=bQ+;oU){A!k~%v(J6V=t?hWI<43t)V zbaZeK;LxGB-&WPBsf`DgILtEow+F?Kp-86lc(Zss^mV;GLhWNbF{UzOtT3kCWQb8}yP6%0;K zM@qoW^vbnxKpEJB@~+pi^mx%TfKPbBj2!}awI4YKTT2tujg)}M2^XqsV2vaYVV zSrh@PsyMDtXlOtPq1sx40AQHK9^RJ$igGvrIy$<#08Eo07-oFj>Fn%O6vMFDR<8z# z#r%GR00IF~bi0R#b^Vb?u3ZDL+YO_-`t#4F6VE=|)HF49`Lfq5wIvdUfiXf)JW*ZU z-5m_}^t|u_Lff{rwyJ6@hB3g<5XZUQ$>jX}&!fSh*Bksb!yv@6_4NQgZ9wUscba=eR&%%^H_Wk`5juNxMA|xa+H`qnL{Q<6@c@cC99o&K4k)YhIl zCCeNa4p&wJER>3MSX@FZ%P@-4-QC*S-w)t$jE&K>Buz~@9H~@yH-Kpdg8&5a^fvz8^eEEdbfVhqEw0|Q>K z$CLi;qmL$&0|Tp9H#NoMKA$96+5Z=?Gy|q72nbC~?AYP;o;!zeEEbRFavo1U&+{z% z$}0c>b#-M)E{lZ$n5JP6L?UtL&dlB;M_hmV$C?Wl*4JY<~YA9iyW&Gb1CpoM{#cWl1iJ#a&2}C~AJbz2D_J)^g){qWR*F zu-92_3uZEz4EtkE)3o+>j-x1-t1Q`Xz~U~%^MZhJTVGq7^G|j={})-NY4*>u?DZN3 zLNtvr#$^dEi^UnpW<^mDMn?ARdFGj`R~e>h5&#PDqAcrM{Qey~SeEBGt}MxAu>9SK z5I|LxAOHjcQ&S@&C2LjH%9Vb<^|Pqu0dO3~>Gac2&&~Dsvurf_@y8|m#*GyfH8mV3 zid(jn&Vb5M{U$6QC3GDi6pBP7>C~F{9%?&TvR8!mM5MEuH#ar{EPPj6gT(=8T0Sp| zw{Ks%w0CdvuY7=OM-tO+TYv<>`{8Cj* z_TJv^ZiXpcEk|#8mN-^bQp|4;r6bQr8|u_xNN P00000NkvXXu0mjf1g$lC delta 1104 zcmV-W1h4za71;=o7=H)?0002|8116~000SaNLh0L02Uq{tKP4uE~|a7 z0&@+QLv^RG-+z{8`a+5BGks?(lEa^^czKeX{Fx*TMD>nHt(Xec133HOUXSRRki%#en*_R9_t>tUqcBht_ z63!2i%(PEw|9mM^VCSz#+y6Y9->${^f|c)V5No(ckAG-Qt|P1%)mb+eAf@fHv1;c` z0stjbSiRpBPrR32ncVB0JDi#yS%{nURi=+k=v|${@AqqKRNRuy`ZTFwAa2ZnFTBXcOSYORdw=0ntA1XNJQehR!g3LSp)t~4wCa5B z)l>1_qoKoJFSTNxflX!Oqz{4GEd@9>le~BHWbpe7T?Y@ANDGT?l>LDcmF(yrv2gR4hmQrC zubiJu**2Z8RHDp)aoM1+DiLTq=4t(O`hVtB!7(WZpxq)rpY9Hxo?#|kuP2w245M4- zgEU6kEmC}LM~9bF0)iB1w29!llt$VK@~UrY=%uS-3xI&tdPGv>tp$Lf(uc_66oAU6 zR{Hl8EkJg&FRq@GmVX7Xue@4TUj~u35@1`1F8D{j=>SkZ #include #include #include #include -#include #include @@ -27,15 +27,6 @@ namespace // Private. #define MINELEN 8 // minimum 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 // if 'first' is true the first byte is already read 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; } -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++) { // 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); } - 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; } } @@ -95,7 +90,7 @@ static bool LoadHDR(QDataStream &s, const int width, const int height, QImage &i uchar code; // Create dst image. - img = imageAlloc(width, height, QImage::Format_RGB32); + img = imageAlloc(width, height, QImage::Format_RGBX32FPx4); if (img.isNull()) { qCDebug(HDRPLUGIN) << "Couldn't create image with size" << width << height << "and format RGB32"; return false; @@ -106,7 +101,7 @@ static bool LoadHDR(QDataStream &s, const int width, const int height, QImage &i uchar *image = (uchar *)lineArray.data(); for (int cline = 0; cline < height; cline++) { - QRgb *scanline = (QRgb *)img.scanLine(cline); + auto scanline = (float *)img.scanLine(cline); // determine scanline type if ((width < MINELEN) || (MAXELEN < width)) {