From 938b8126b5662033c99b6c237362baaa503a92ca Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Sat, 7 Nov 2020 18:11:12 +0800 Subject: [PATCH] No longer descease color depth to 8 for 16 bit uncompressed PSD files --- .../psd/argb16-raw-affinityphoto-1.8.5.png | Bin 628 -> 983 bytes .../psd/rgb16-raw-affinityphoto-1.8.5.png | Bin 534 -> 827 bytes src/imageformats/psd.cpp | 49 ++++++++---------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/autotests/read/psd/argb16-raw-affinityphoto-1.8.5.png b/autotests/read/psd/argb16-raw-affinityphoto-1.8.5.png index 5b23d15b8820473e6193a0d57a3d3ac934eeb780..9af91c1fc92f7674b15912cec0ac2e6d3255dc9c 100644 GIT binary patch delta 954 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 bIllnsnnxKZbU~p2000R9NkvXXu0mjf))sJF delta 501 zcmVKlut+$aTLctE2|P}7cWw= z2f>4(MW=-5A|!MW^rp~7i9&>~k!OPr9$P%sNijQk*$l+>qQZ*c1cI7n%Wg&N!nV2F zA6HrZc2IF#r`?$ymq2_B!|%O$?|tU`oR6TB78=yrm?Wj5dfleD zk(=;4ra-q6E0XkKLZi2}own#BNwQLq{z7ddz(pT79}^lR`{!7K@tjL7)LsQ>=%D^C z@BB`-sJx0A-@)3~O7#_feLMQPy~%$@facyq-^29>B-j51@Dy`ZWVi5Mu$fyFz=@sZ zNd{8k-1BqFfW;v;0v7S`TjIuP0B-aV39^+q7K}{uejIP5O@P%Tn{DBlW(SVk?`wM5 zq#qv(RGF+0AhW69BP|YTcSotHrXDI1wBKEljXBu)$>cp6I{7-!;9S4)VmjzK)UNS(jcE+!Y{|4~a9lZA+b1)|Xysmz)KUOgAZi~zc r%&tk6J3x+tlY;tVt`+2Q0e{_JsF8)Xo+SGL00000NkvXXu0mjfMmYAD diff --git a/src/imageformats/psd.cpp b/src/imageformats/psd.cpp index d06d044..767119d 100644 --- a/src/imageformats/psd.cpp +++ b/src/imageformats/psd.cpp @@ -104,14 +104,9 @@ static void skip_section(QDataStream &s) s.skipRawData(section_length); } -static quint8 readPixel_u16(QDataStream &stream) { - quint16 pixel; - stream >> pixel; - return pixel / (1 << 8); -} - -static int readPixel_u8(QDataStream &stream) { - quint8 pixel; +template +static Trait readPixel(QDataStream &stream) { + Trait pixel; stream >> pixel; return pixel; } @@ -156,23 +151,18 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img) quint32 channel_num = header.channel_count; - QImage::Format fmt = QImage::Format_RGB32; + QImage::Format fmt = header.depth == 8 ? QImage::Format_RGB32 + : QImage::Format_RGBX64; // Clear the image. if (channel_num >= 4) { // Enable alpha. - fmt = QImage::Format_ARGB32; + fmt = header.depth == 8 ? QImage::Format_ARGB32 + : QImage::Format_RGBA64; // Ignore the other channels. channel_num = 4; } - if (compression == 1 && header.depth == 16) { - fmt = QImage::Format_RGBX64; - if (channel_num >= 4) { - fmt = QImage::Format_RGBA64; - } - } - img = QImage(header.width, header.height, fmt); if (img.isNull()) { qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(header.width, header.height); @@ -181,9 +171,10 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img) img.fill(qRgb(0,0,0)); const quint32 pixel_count = header.height * header.width; + const quint32 channel_size = pixel_count * header.depth / 8; // Verify this, as this is used to write into the memory of the QImage - if (pixel_count > img.sizeInBytes() / sizeof(QRgb)) { + if (pixel_count > img.sizeInBytes() / (header.depth == 8 ? sizeof(QRgb) : sizeof(QRgba64))) { qWarning() << "Invalid pixel count!" << pixel_count << "bytes available:" << img.sizeInBytes(); return false; } @@ -220,13 +211,13 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img) bool success = false; if (header.depth == 8) { success = decodeRLEData(RLEVariant::PackBits, stream, - image_data, pixel_count, - &readPixel_u8, updaters[channel]); + image_data, channel_size, + &readPixel, updaters[channel]); } else if (header.depth == 16) { QRgba64 *image_data = reinterpret_cast(img.bits()); success = decodeRLEData(RLEVariant::PackBits16, stream, - image_data, pixel_count * 2, - &readPixel_u8, updaters64[channel]); + image_data, channel_size, + &readPixel, updaters64[channel]); } if (!success) { @@ -236,11 +227,15 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img) } } else { for (unsigned short channel = 0; channel < channel_num; channel++) { - for (unsigned i = 0; i < pixel_count; ++i) { - image_data[i] = updaters[channel]( - image_data[i], - header.depth == 8 ? readPixel_u8(stream) - : readPixel_u16(stream)); + if (header.depth == 8) { + for (unsigned i = 0; i < pixel_count; ++i) { + image_data[i] = updaters[channel](image_data[i], readPixel(stream)); + } + } else if (header.depth == 16) { + QRgba64 *image_data = reinterpret_cast(img.bits()); + for (unsigned i = 0; i < pixel_count; ++i) { + image_data[i] = updaters64[channel](image_data[i], readPixel(stream)); + } } // make sure we didn't try to read past the end of the stream if (stream.status() != QDataStream::Ok) {