Krita Source Code Documentation
Loading...
Searching...
No Matches
PsdPixelUtils Namespace Reference

Classes

struct  ChannelWritingInfo
 

Typedefs

using PixelFunc = std::function<void(int, const QMap<quint16, QByteArray> &, int, quint8 *)>
 

Functions

template<class Traits >
Traits::channels_type convertByteOrder (typename Traits::channels_type value)
 
template<>
float convertByteOrder< AlphaF32Traits > (float value)
 
template<>
quint16 convertByteOrder< AlphaU16Traits > (quint16 value)
 
template<>
quint8 convertByteOrder< AlphaU8Traits > (quint8 value)
 
template<>
quint16 convertByteOrder< KoBgrU16Traits > (quint16 value)
 
template<>
quint32 convertByteOrder< KoBgrU32Traits > (quint32 value)
 
template<>
quint8 convertByteOrder< KoBgrU8Traits > (quint8 value)
 
template<>
float convertByteOrder< KoCmykF32Traits > (float value)
 
template<>
quint16 convertByteOrder< KoCmykU16Traits > (quint16 value)
 
template<>
quint8 convertByteOrder< KoCmykU8Traits > (quint8 value)
 
template<>
quint16 convertByteOrder< KoGrayU16Traits > (quint16 value)
 
template<>
quint32 convertByteOrder< KoGrayU32Traits > (quint32 value)
 
template<>
quint8 convertByteOrder< KoGrayU8Traits > (quint8 value)
 
template<>
float convertByteOrder< KoLabF32Traits > (float value)
 
template<>
quint16 convertByteOrder< KoLabU16Traits > (quint16 value)
 
template<>
quint8 convertByteOrder< KoLabU8Traits > (quint8 value)
 
QMap< quint16, QByteArray > fetchChannelsBytes (QIODevice &io, QVector< ChannelInfo * > channelInfoRecords, int row, int width, int channelSize, bool processMasks)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void preparePixelForWrite (quint8 *dataPlane, int numPixels, int channelSize, int channelId, psd_color_mode colorMode)
 
void readAlphaMaskChannels (QIODevice &io, KisPaintDeviceSP device, int channelSize, const QRect &layerRect, QVector< ChannelInfo * > infoRecords, psd_byte_order byteOrder)
 
template<psd_byte_order byteOrder>
void readAlphaMaskChannelsImpl (QIODevice &io, KisPaintDeviceSP device, int channelSize, const QRect &layerRect, QVector< ChannelInfo * > infoRecords)
 
template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void readAlphaMaskPixel (const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<psd_byte_order byteOrder>
void readAlphaMaskPixelCommon (int channelSize, const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
void readChannels (QIODevice &io, KisPaintDeviceSP device, psd_color_mode colorMode, int channelSize, const QRect &layerRect, QVector< ChannelInfo * > infoRecords, psd_byte_order byteOrder)
 
template<psd_byte_order byteOrder>
void readChannelsImpl (QIODevice &io, KisPaintDeviceSP device, psd_color_mode colorMode, int channelSize, const QRect &layerRect, QVector< ChannelInfo * > infoRecords)
 
template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
Traits::channels_type readChannelValue (const QMap< quint16, QByteArray > &channelBytes, quint16 channelId, int col, typename Traits::channels_type defaultValue)
 
template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void readCmykPixel (const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<psd_byte_order byteOrder>
void readCmykPixelCommon (int channelSize, const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
void readCommon (KisPaintDeviceSP dev, QIODevice &io, const QRect &layerRect, QVector< ChannelInfo * > infoRecords, int channelSize, PixelFunc pixelFunc, bool processMasks)
 
template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void readGrayPixel (const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<psd_byte_order byteOrder>
void readGrayPixelCommon (int channelSize, const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void readLabPixel (const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<psd_byte_order byteOrder>
void readLabPixelCommon (int channelSize, const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void readRgbPixel (const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<psd_byte_order byteOrder>
void readRgbPixelCommon (int channelSize, const QMap< quint16, QByteArray > &channelBytes, int col, quint8 *dstPtr)
 
template<class Traits >
quint8 truncateToOpacity (typename Traits::channels_type value)
 
template<>
quint8 truncateToOpacity< AlphaF32Traits > (typename AlphaF32Traits::channels_type value)
 
template<>
quint8 truncateToOpacity< AlphaU16Traits > (typename AlphaU16Traits::channels_type value)
 
template<>
quint8 truncateToOpacity< AlphaU8Traits > (typename AlphaU8Traits::channels_type value)
 
void writeChannelDataRLE (QIODevice &io, const quint8 *plane, const int channelSize, const QRect &rc, const qint64 sizeFieldOffset, const qint64 rleBlockOffset, const bool writeCompressionType, psd_byte_order byteOrder)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeChannelDataRLEImpl (QIODevice &io, const quint8 *plane, const int channelSize, const QRect &rc, const qint64 sizeFieldOffset, const qint64 rleBlockOffset, const bool writeCompressionType)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeChannelDataZIPImpl (QIODevice &io, const quint8 *plane, const int channelSize, const QRect &rc, const qint64 sizeFieldOffset, const bool writeCompressionType)
 
void writePixelDataCommon (QIODevice &io, KisPaintDeviceSP dev, const QRect &rc, psd_color_mode colorMode, int channelSize, bool alphaFirst, const bool writeCompressionType, QVector< ChannelWritingInfo > &writingInfoList, psd_compression_type compressionType, psd_byte_order byteOrder)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writePixelDataCommonImpl (QIODevice &io, KisPaintDeviceSP dev, const QRect &rc, psd_color_mode colorMode, int channelSize, bool alphaFirst, const bool writeCompressionType, QVector< ChannelWritingInfo > &writingInfoList, psd_compression_type compressionType)
 

Typedef Documentation

◆ PixelFunc

using PsdPixelUtils::PixelFunc = std::function<void(int, const QMap<quint16, QByteArray> &, int, quint8 *)>

Definition at line 334 of file psd_pixel_utils.cpp.

Function Documentation

◆ convertByteOrder()

template<class Traits >
Traits::channels_type PsdPixelUtils::convertByteOrder ( typename Traits::channels_type value)

◆ convertByteOrder< AlphaF32Traits >()

template<>
float PsdPixelUtils::convertByteOrder< AlphaF32Traits > ( float value)
inline

Definition at line 48 of file psd_pixel_utils.cpp.

49{
50 return qFromBigEndian((quint32)value);
51}
float value(const T *src, size_t ch)

References value().

◆ convertByteOrder< AlphaU16Traits >()

template<>
quint16 PsdPixelUtils::convertByteOrder< AlphaU16Traits > ( quint16 value)
inline

Definition at line 42 of file psd_pixel_utils.cpp.

43{
44 return qFromBigEndian((quint16)value);
45}

References value().

◆ convertByteOrder< AlphaU8Traits >()

template<>
quint8 PsdPixelUtils::convertByteOrder< AlphaU8Traits > ( quint8 value)
inline

Definition at line 36 of file psd_pixel_utils.cpp.

37{
38 return value;
39}

References value().

◆ convertByteOrder< KoBgrU16Traits >()

template<>
quint16 PsdPixelUtils::convertByteOrder< KoBgrU16Traits > ( quint16 value)
inline

Definition at line 78 of file psd_pixel_utils.cpp.

79{
80 return qFromBigEndian((quint16)value);
81}

References value().

◆ convertByteOrder< KoBgrU32Traits >()

template<>
quint32 PsdPixelUtils::convertByteOrder< KoBgrU32Traits > ( quint32 value)
inline

Definition at line 84 of file psd_pixel_utils.cpp.

85{
86 return qFromBigEndian((quint32)value);
87}

References value().

◆ convertByteOrder< KoBgrU8Traits >()

template<>
quint8 PsdPixelUtils::convertByteOrder< KoBgrU8Traits > ( quint8 value)
inline

Definition at line 72 of file psd_pixel_utils.cpp.

73{
74 return value;
75}

References value().

◆ convertByteOrder< KoCmykF32Traits >()

template<>
float PsdPixelUtils::convertByteOrder< KoCmykF32Traits > ( float value)
inline

Definition at line 102 of file psd_pixel_utils.cpp.

103{
104 return qFromBigEndian((quint32)value);
105}

References value().

◆ convertByteOrder< KoCmykU16Traits >()

template<>
quint16 PsdPixelUtils::convertByteOrder< KoCmykU16Traits > ( quint16 value)
inline

Definition at line 96 of file psd_pixel_utils.cpp.

97{
98 return qFromBigEndian((quint16)value);
99}

References value().

◆ convertByteOrder< KoCmykU8Traits >()

template<>
quint8 PsdPixelUtils::convertByteOrder< KoCmykU8Traits > ( quint8 value)
inline

Definition at line 90 of file psd_pixel_utils.cpp.

91{
92 return value;
93}

References value().

◆ convertByteOrder< KoGrayU16Traits >()

template<>
quint16 PsdPixelUtils::convertByteOrder< KoGrayU16Traits > ( quint16 value)
inline

Definition at line 60 of file psd_pixel_utils.cpp.

61{
62 return qFromBigEndian((quint16)value);
63}

References value().

◆ convertByteOrder< KoGrayU32Traits >()

template<>
quint32 PsdPixelUtils::convertByteOrder< KoGrayU32Traits > ( quint32 value)
inline

Definition at line 66 of file psd_pixel_utils.cpp.

67{
68 return qFromBigEndian((quint32)value);
69}

References value().

◆ convertByteOrder< KoGrayU8Traits >()

template<>
quint8 PsdPixelUtils::convertByteOrder< KoGrayU8Traits > ( quint8 value)
inline

Definition at line 54 of file psd_pixel_utils.cpp.

55{
56 return value;
57}

References value().

◆ convertByteOrder< KoLabF32Traits >()

template<>
float PsdPixelUtils::convertByteOrder< KoLabF32Traits > ( float value)
inline

Definition at line 120 of file psd_pixel_utils.cpp.

121{
122 return qFromBigEndian((quint32)value);
123}

References value().

◆ convertByteOrder< KoLabU16Traits >()

template<>
quint16 PsdPixelUtils::convertByteOrder< KoLabU16Traits > ( quint16 value)
inline

Definition at line 114 of file psd_pixel_utils.cpp.

115{
116 return qFromBigEndian((quint16)value);
117}

References value().

◆ convertByteOrder< KoLabU8Traits >()

template<>
quint8 PsdPixelUtils::convertByteOrder< KoLabU8Traits > ( quint8 value)
inline

Definition at line 108 of file psd_pixel_utils.cpp.

109{
110 return value;
111}

References value().

◆ fetchChannelsBytes()

QMap< quint16, QByteArray > PsdPixelUtils::fetchChannelsBytes ( QIODevice & io,
QVector< ChannelInfo * > channelInfoRecords,
int row,
int width,
int channelSize,
bool processMasks )

Definition at line 301 of file psd_pixel_utils.cpp.

302{
303 const int uncompressedLength = width * channelSize;
304
305 QMap<quint16, QByteArray> channelBytes;
306
307 Q_FOREACH (ChannelInfo *channelInfo, channelInfoRecords) {
308 // user supplied masks are ignored here
309 if (!processMasks && channelInfo->channelId < -1)
310 continue;
311
312 io.seek(channelInfo->channelDataStart + channelInfo->channelOffset);
313
315 channelBytes[channelInfo->channelId] = io.read(uncompressedLength);
316 channelInfo->channelOffset += uncompressedLength;
317 } else if (channelInfo->compressionType == psd_compression_type::RLE) {
318 int rleLength = channelInfo->rleRowLengths[row];
319 QByteArray compressedBytes = io.read(rleLength);
320 QByteArray uncompressedBytes = Compression::uncompress(uncompressedLength, compressedBytes, channelInfo->compressionType);
321 channelBytes.insert(channelInfo->channelId, uncompressedBytes);
322 channelInfo->channelOffset += rleLength;
323 } else {
324 QString error = QString("Unsupported Compression mode: %1")
325 .arg(static_cast<std::uint16_t>(channelInfo->compressionType));
326 dbgFile << "ERROR: fetchChannelsBytes:" << error;
328 }
329 }
330
331 return channelBytes;
332}
static QByteArray uncompress(int unpacked_len, QByteArray bytes, psd_compression_type compressionType, int row_size=0, int color_depth=0)
#define dbgFile
Definition kis_debug.h:53
@ RLE
Definition psd.h:41
@ Uncompressed
Definition psd.h:40
QVector< quint32 > rleRowLengths
psd_compression_type compressionType
quint64 channelDataStart

References ChannelInfo::channelDataStart, ChannelInfo::channelId, ChannelInfo::channelOffset, ChannelInfo::compressionType, dbgFile, RLE, ChannelInfo::rleRowLengths, Compression::uncompress(), and Uncompressed.

◆ preparePixelForWrite()

template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::preparePixelForWrite ( quint8 * dataPlane,
int numPixels,
int channelSize,
int channelId,
psd_color_mode colorMode )
inline

Definition at line 573 of file psd_pixel_utils.cpp.

574{
575 // if the bitdepth > 8, place the bytes in the right order
576 // if cmyk, invert the pixel value
577 if (channelSize == 1) {
578 if (channelId >= 0 && (colorMode == CMYK || colorMode == CMYK64)) {
579 for (int i = 0; i < numPixels; ++i) {
580 dataPlane[i] = 255 - dataPlane[i];
581 }
582 }
583 } else if (channelSize == 2) {
584 quint16 val;
585 for (int i = 0; i < numPixels; ++i) {
586 quint16 *pixelPtr = reinterpret_cast<quint16 *>(dataPlane) + i;
587
588 val = *pixelPtr;
589 if (byteOrder == psd_byte_order::psdBigEndian)
590 val = qFromBigEndian(val);
591 if (channelId >= 0 && (colorMode == CMYK || colorMode == CMYK64)) {
592 val = quint16_MAX - val;
593 }
594 *pixelPtr = val;
595 }
596 } else if (channelSize == 4) {
597 quint32 val;
598 for (int i = 0; i < numPixels; ++i) {
599 quint32 *pixelPtr = reinterpret_cast<quint32 *>(dataPlane) + i;
600
601 val = *pixelPtr;
602 if (byteOrder == psd_byte_order::psdBigEndian)
603 val = qFromBigEndian(val);
604 if (channelId >= 0 && (colorMode == CMYK || colorMode == CMYK64)) {
605 val = std::numeric_limits<quint32>::max() - val;
606 }
607 *pixelPtr = val;
608 }
609 }
610}
const quint16 quint16_MAX
Definition kis_global.h:25
@ CMYK64
Definition psd.h:62
@ CMYK
Definition psd.h:55

References CMYK, CMYK64, psdBigEndian, and quint16_MAX.

◆ readAlphaMaskChannels()

void KRITAPSD_EXPORT PsdPixelUtils::readAlphaMaskChannels ( QIODevice & io,
KisPaintDeviceSP device,
int channelSize,
const QRect & layerRect,
QVector< ChannelInfo * > infoRecords,
psd_byte_order byteOrder )

Definition at line 461 of file psd_pixel_utils.cpp.

467{
468 switch (byteOrder) {
470 return readAlphaMaskChannelsImpl<psd_byte_order::psdLittleEndian>(io, device, channelSize, layerRect, infoRecords);
471 default:
472 return readAlphaMaskChannelsImpl<psd_byte_order::psdBigEndian>(io, device, channelSize, layerRect, infoRecords);
473 }
474}

References psdLittleEndian.

◆ readAlphaMaskChannelsImpl()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readAlphaMaskChannelsImpl ( QIODevice & io,
KisPaintDeviceSP device,
int channelSize,
const QRect & layerRect,
QVector< ChannelInfo * > infoRecords )

Definition at line 455 of file psd_pixel_utils.cpp.

456{
457 KIS_SAFE_ASSERT_RECOVER_RETURN(infoRecords.size() == 1);
458 readCommon(device, io, layerRect, infoRecords, channelSize, &readAlphaMaskPixelCommon<byteOrder>, true);
459}
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
void readCommon(KisPaintDeviceSP dev, QIODevice &io, const QRect &layerRect, QVector< ChannelInfo * > infoRecords, int channelSize, PixelFunc pixelFunc, bool processMasks)

References KIS_SAFE_ASSERT_RECOVER_RETURN, and readCommon().

◆ readAlphaMaskPixel()

template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::readAlphaMaskPixel ( const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 147 of file psd_pixel_utils.cpp.

148{
149 using channels_type = typename Traits::channels_type;
150
151 const channels_type data = reinterpret_cast<const channels_type *>(channelBytes.first().constData())[col];
152 if (byteOrder == psd_byte_order::psdBigEndian) {
153 *dstPtr = truncateToOpacity<Traits>(convertByteOrder<Traits>(data));
154 } else {
155 *dstPtr = truncateToOpacity<Traits>(data);
156 }
157}

References psdBigEndian.

◆ readAlphaMaskPixelCommon()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readAlphaMaskPixelCommon ( int channelSize,
const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 290 of file psd_pixel_utils.cpp.

291{
292 if (channelSize == 1) {
293 readAlphaMaskPixel<AlphaU8Traits, byteOrder>(channelBytes, col, dstPtr);
294 } else if (channelSize == 2) {
295 readAlphaMaskPixel<AlphaU16Traits, byteOrder>(channelBytes, col, dstPtr);
296 } else if (channelSize == 4) {
297 readAlphaMaskPixel<AlphaF32Traits, byteOrder>(channelBytes, col, dstPtr);
298 }
299}

◆ readChannels()

void KRITAPSD_EXPORT PsdPixelUtils::readChannels ( QIODevice & io,
KisPaintDeviceSP device,
psd_color_mode colorMode,
int channelSize,
const QRect & layerRect,
QVector< ChannelInfo * > infoRecords,
psd_byte_order byteOrder )

Definition at line 438 of file psd_pixel_utils.cpp.

445{
446 switch (byteOrder) {
448 return readChannelsImpl<psd_byte_order::psdLittleEndian>(io, device, colorMode, channelSize, layerRect, infoRecords);
449 default:
450 return readChannelsImpl<psd_byte_order::psdBigEndian>(io, device, colorMode, channelSize, layerRect, infoRecords);
451 }
452}

References psdLittleEndian.

◆ readChannelsImpl()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readChannelsImpl ( QIODevice & io,
KisPaintDeviceSP device,
psd_color_mode colorMode,
int channelSize,
const QRect & layerRect,
QVector< ChannelInfo * > infoRecords )

Definition at line 407 of file psd_pixel_utils.cpp.

413{
414 switch (colorMode) {
415 case Grayscale:
416 readCommon(device, io, layerRect, infoRecords, channelSize, &readGrayPixelCommon<byteOrder>, false);
417 break;
418 case RGB:
419 readCommon(device, io, layerRect, infoRecords, channelSize, &readRgbPixelCommon<byteOrder>, false);
420 break;
421 case CMYK:
422 readCommon(device, io, layerRect, infoRecords, channelSize, &readCmykPixelCommon<byteOrder>, false);
423 break;
424 case Lab:
425 readCommon(device, io, layerRect, infoRecords, channelSize, &readLabPixelCommon<byteOrder>, false);
426 break;
427 case Bitmap:
428 case Indexed:
429 case MultiChannel:
430 case DuoTone:
432 default:
433 QString error = QString("Unsupported color mode: %1").arg(colorMode);
435 }
436}
@ Lab
Definition psd.h:58
@ RGB
Definition psd.h:54
@ DuoTone
Definition psd.h:57
@ COLORMODE_UNKNOWN
Definition psd.h:65
@ Indexed
Definition psd.h:53
@ MultiChannel
Definition psd.h:56
@ Grayscale
Definition psd.h:52
@ Bitmap
Definition psd.h:51

References Bitmap, CMYK, COLORMODE_UNKNOWN, DuoTone, Grayscale, Indexed, Lab, MultiChannel, readCommon(), and RGB.

◆ readChannelValue()

template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
Traits::channels_type PsdPixelUtils::readChannelValue ( const QMap< quint16, QByteArray > & channelBytes,
quint16 channelId,
int col,
typename Traits::channels_type defaultValue )
inline

Definition at line 161 of file psd_pixel_utils.cpp.

162{
163 using channels_type = typename Traits::channels_type;
164
165 if (channelBytes.contains(channelId)) {
166 const QByteArray &bytes = channelBytes[channelId];
167 if (col < bytes.size()) {
168 const channels_type data = reinterpret_cast<const channels_type *>(bytes.constData())[col];
169 if (byteOrder == psd_byte_order::psdBigEndian) {
170 return convertByteOrder<Traits>(data);
171 } else {
172 return data;
173 }
174 }
175
176 dbgFile << "col index out of range channelId: " << channelId << " col:" << col;
177 }
178
179 return defaultValue;
180}

References dbgFile, and psdBigEndian.

◆ readCmykPixel()

template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::readCmykPixel ( const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 211 of file psd_pixel_utils.cpp.

212{
213 using Pixel = typename Traits::Pixel;
214 using channels_type = typename Traits::channels_type;
215
216 const channels_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
217 Pixel *pixelPtr = reinterpret_cast<Pixel *>(dstPtr);
218
219 pixelPtr->cyan = unitValue - readChannelValue<Traits, byteOrder>(channelBytes, 0, col, unitValue);
220 pixelPtr->magenta = unitValue - readChannelValue<Traits, byteOrder>(channelBytes, 1, col, unitValue);
221 pixelPtr->yellow = unitValue - readChannelValue<Traits, byteOrder>(channelBytes, 2, col, unitValue);
222 pixelPtr->black = unitValue - readChannelValue<Traits, byteOrder>(channelBytes, 3, col, unitValue);
223 pixelPtr->alpha = readChannelValue<Traits, byteOrder>(channelBytes, -1, col, unitValue);
224}

◆ readCmykPixelCommon()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readCmykPixelCommon ( int channelSize,
const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 266 of file psd_pixel_utils.cpp.

267{
268 if (channelSize == 1) {
269 readCmykPixel<KoCmykU8Traits, byteOrder>(channelBytes, col, dstPtr);
270 } else if (channelSize == 2) {
271 readCmykPixel<KoCmykU16Traits, byteOrder>(channelBytes, col, dstPtr);
272 } else if (channelSize == 4) {
273 readCmykPixel<KoCmykF32Traits, byteOrder>(channelBytes, col, dstPtr);
274 }
275}

◆ readCommon()

void PsdPixelUtils::readCommon ( KisPaintDeviceSP dev,
QIODevice & io,
const QRect & layerRect,
QVector< ChannelInfo * > infoRecords,
int channelSize,
PixelFunc pixelFunc,
bool processMasks )

don't write-access the row right after the the end of the read area

Definition at line 336 of file psd_pixel_utils.cpp.

343{
344 KisOffsetKeeper keeper(io);
345
346 if (layerRect.isEmpty()) {
347 dbgFile << "Empty layer!";
348 return;
349 }
350
351 if (infoRecords.first()->compressionType == psd_compression_type::ZIP || infoRecords.first()->compressionType == psd_compression_type::ZIPWithPrediction) {
352 const int numPixels = channelSize * layerRect.width() * layerRect.height();
353
354 QMap<quint16, QByteArray> channelBytes;
355
356 Q_FOREACH (ChannelInfo *info, infoRecords) {
357 io.seek(info->channelDataStart);
358 QByteArray compressedBytes = io.read(info->channelDataLength);
359 QByteArray uncompressedBytes;
360
361 uncompressedBytes = Compression::uncompress(numPixels, compressedBytes, infoRecords.first()->compressionType, layerRect.width(), channelSize * 8);
362
363 if (uncompressedBytes.size() != numPixels) {
364 QString error = QString("Failed to unzip channel data: id = %1, compression = %2")
365 .arg(info->channelId)
366 .arg(static_cast<std::uint16_t>(info->compressionType));
367 dbgFile << "ERROR:" << error;
368 dbgFile << " " << ppVar(info->channelId);
369 dbgFile << " " << ppVar(info->channelDataStart);
370 dbgFile << " " << ppVar(info->channelDataLength);
371 dbgFile << " " << ppVar(info->compressionType);
373 }
374
375 channelBytes.insert(info->channelId, uncompressedBytes);
376 }
377
378 KisSequentialIterator it(dev, layerRect);
379 int col = 0;
380 while (it.nextPixel()) {
381 pixelFunc(channelSize, channelBytes, col, it.rawData());
382 col++;
383 }
384
385 } else {
386 KisHLineIteratorSP it = dev->createHLineIteratorNG(layerRect.left(), layerRect.top(), layerRect.width());
387 for (int i = 0; i < layerRect.height(); i++) {
388 QMap<quint16, QByteArray> channelBytes;
389
390 channelBytes = fetchChannelsBytes(io, infoRecords, i, layerRect.width(), channelSize, processMasks);
391
392 for (int col = 0; col < layerRect.width(); col++) {
393 pixelFunc(channelSize, channelBytes, col, it->rawData());
394 it->nextPixel();
395 }
396
399 if (i < layerRect.height() - 1) {
400 it->nextRow();
401 }
402 }
403 }
404}
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
#define ppVar(var)
Definition kis_debug.h:155
QMap< quint16, QByteArray > fetchChannelsBytes(QIODevice &io, QVector< ChannelInfo * > channelInfoRecords, int row, int width, int channelSize, bool processMasks)
@ ZIPWithPrediction
Definition psd.h:43
@ ZIP
Definition psd.h:42
quint64 channelDataLength

References ChannelInfo::channelDataLength, ChannelInfo::channelDataStart, ChannelInfo::channelId, ChannelInfo::compressionType, KisPaintDevice::createHLineIteratorNG(), dbgFile, fetchChannelsBytes(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), ppVar, KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), Compression::uncompress(), ZIP, and ZIPWithPrediction.

◆ readGrayPixel()

template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::readGrayPixel ( const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 183 of file psd_pixel_utils.cpp.

184{
185 using Pixel = typename Traits::Pixel;
186 using channels_type = typename Traits::channels_type;
187
188 const channels_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
189 Pixel *pixelPtr = reinterpret_cast<Pixel *>(dstPtr);
190
191 pixelPtr->gray = readChannelValue<Traits, byteOrder>(channelBytes, 0, col, unitValue);
192 pixelPtr->alpha = readChannelValue<Traits, byteOrder>(channelBytes, -1, col, unitValue);
193}

◆ readGrayPixelCommon()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readGrayPixelCommon ( int channelSize,
const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 254 of file psd_pixel_utils.cpp.

255{
256 if (channelSize == 1) {
257 readGrayPixel<KoGrayU8Traits, byteOrder>(channelBytes, col, dstPtr);
258 } else if (channelSize == 2) {
259 readGrayPixel<KoGrayU16Traits, byteOrder>(channelBytes, col, dstPtr);
260 } else if (channelSize == 4) {
261 readGrayPixel<KoGrayU32Traits, byteOrder>(channelBytes, col, dstPtr);
262 }
263}

◆ readLabPixel()

template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::readLabPixel ( const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 227 of file psd_pixel_utils.cpp.

228{
229 using Pixel = typename Traits::Pixel;
230 using channels_type = typename Traits::channels_type;
231
232 const channels_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
233 Pixel *pixelPtr = reinterpret_cast<Pixel *>(dstPtr);
234
235 pixelPtr->L = readChannelValue<Traits, byteOrder>(channelBytes, 0, col, unitValue);
236 pixelPtr->a = readChannelValue<Traits, byteOrder>(channelBytes, 1, col, unitValue);
237 pixelPtr->b = readChannelValue<Traits, byteOrder>(channelBytes, 2, col, unitValue);
238 pixelPtr->alpha = readChannelValue<Traits, byteOrder>(channelBytes, -1, col, unitValue);
239}

◆ readLabPixelCommon()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readLabPixelCommon ( int channelSize,
const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 278 of file psd_pixel_utils.cpp.

279{
280 if (channelSize == 1) {
281 readLabPixel<KoLabU8Traits, byteOrder>(channelBytes, col, dstPtr);
282 } else if (channelSize == 2) {
283 readLabPixel<KoLabU16Traits, byteOrder>(channelBytes, col, dstPtr);
284 } else if (channelSize == 4) {
285 readLabPixel<KoLabF32Traits, byteOrder>(channelBytes, col, dstPtr);
286 }
287}

◆ readRgbPixel()

template<class Traits , psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::readRgbPixel ( const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 196 of file psd_pixel_utils.cpp.

197{
198 using Pixel = typename Traits::Pixel;
199 using channels_type = typename Traits::channels_type;
200
201 const channels_type unitValue = KoColorSpaceMathsTraits<channels_type>::unitValue;
202 Pixel *pixelPtr = reinterpret_cast<Pixel *>(dstPtr);
203
204 pixelPtr->blue = readChannelValue<Traits, byteOrder>(channelBytes, 2, col, unitValue);
205 pixelPtr->green = readChannelValue<Traits, byteOrder>(channelBytes, 1, col, unitValue);
206 pixelPtr->red = readChannelValue<Traits, byteOrder>(channelBytes, 0, col, unitValue);
207 pixelPtr->alpha = readChannelValue<Traits, byteOrder>(channelBytes, -1, col, unitValue);
208}

◆ readRgbPixelCommon()

template<psd_byte_order byteOrder>
void PsdPixelUtils::readRgbPixelCommon ( int channelSize,
const QMap< quint16, QByteArray > & channelBytes,
int col,
quint8 * dstPtr )

Definition at line 242 of file psd_pixel_utils.cpp.

243{
244 if (channelSize == 1) {
245 readRgbPixel<KoBgrU8Traits, byteOrder>(channelBytes, col, dstPtr);
246 } else if (channelSize == 2) {
247 readRgbPixel<KoBgrU16Traits, byteOrder>(channelBytes, col, dstPtr);
248 } else if (channelSize == 4) {
249 readRgbPixel<KoBgrU16Traits, byteOrder>(channelBytes, col, dstPtr);
250 }
251}

◆ truncateToOpacity()

template<class Traits >
quint8 PsdPixelUtils::truncateToOpacity ( typename Traits::channels_type value)
inline

◆ truncateToOpacity< AlphaF32Traits >()

template<>
quint8 PsdPixelUtils::truncateToOpacity< AlphaF32Traits > ( typename AlphaF32Traits::channels_type value)
inline

Definition at line 141 of file psd_pixel_utils.cpp.

142{
143 return static_cast<quint8>(value * 255U);
144}

References value().

◆ truncateToOpacity< AlphaU16Traits >()

template<>
quint8 PsdPixelUtils::truncateToOpacity< AlphaU16Traits > ( typename AlphaU16Traits::channels_type value)
inline

Definition at line 135 of file psd_pixel_utils.cpp.

136{
137 return value >> 8;
138}

References value().

◆ truncateToOpacity< AlphaU8Traits >()

template<>
quint8 PsdPixelUtils::truncateToOpacity< AlphaU8Traits > ( typename AlphaU8Traits::channels_type value)
inline

Definition at line 129 of file psd_pixel_utils.cpp.

130{
131 return value;
132}

References value().

◆ writeChannelDataRLE()

void KRITAPSD_EXPORT PsdPixelUtils::writeChannelDataRLE ( QIODevice & io,
const quint8 * plane,
const int channelSize,
const QRect & rc,
const qint64 sizeFieldOffset,
const qint64 rleBlockOffset,
const bool writeCompressionType,
psd_byte_order byteOrder )

Definition at line 555 of file psd_pixel_utils.cpp.

563{
564 switch (byteOrder) {
566 return writeChannelDataRLEImpl<psd_byte_order::psdLittleEndian>(io, plane, channelSize, rc, sizeFieldOffset, rleBlockOffset, writeCompressionType);
567 default:
568 return writeChannelDataRLEImpl(io, plane, channelSize, rc, sizeFieldOffset, rleBlockOffset, writeCompressionType);
569 }
570}
void writeChannelDataRLEImpl(QIODevice &io, const quint8 *plane, const int channelSize, const QRect &rc, const qint64 sizeFieldOffset, const qint64 rleBlockOffset, const bool writeCompressionType)

References psdLittleEndian, and writeChannelDataRLEImpl().

◆ writeChannelDataRLEImpl()

template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::writeChannelDataRLEImpl ( QIODevice & io,
const quint8 * plane,
const int channelSize,
const QRect & rc,
const qint64 sizeFieldOffset,
const qint64 rleBlockOffset,
const bool writeCompressionType )

Definition at line 477 of file psd_pixel_utils.cpp.

484{
486 QScopedPointer<Pusher> channelBlockSizeExternalTag;
487 if (sizeFieldOffset >= 0) {
488 channelBlockSizeExternalTag.reset(new Pusher(io, 0, sizeFieldOffset));
489 }
490
491 if (writeCompressionType) {
492 SAFE_WRITE_EX(byteOrder, io, static_cast<quint16>(psd_compression_type::RLE));
493 }
494
495 const bool externalRleBlock = rleBlockOffset >= 0;
496
497 // the start of RLE sizes block
498 const qint64 channelRLESizePos = externalRleBlock ? rleBlockOffset : io.pos();
499
500 {
501 QScopedPointer<KisOffsetKeeper> rleOffsetKeeper;
502
503 if (externalRleBlock) {
504 rleOffsetKeeper.reset(new KisOffsetKeeper(io));
505 io.seek(rleBlockOffset);
506 }
507
508 // write zero's for the channel lengths block
509 for (int i = 0; i < rc.height(); ++i) {
510 // XXX: choose size for PSB!
511 const quint16 fakeRLEBLockSize = 0;
512 SAFE_WRITE_EX(byteOrder, io, fakeRLEBLockSize);
513 }
514 }
515
516 const int stride = channelSize * rc.width();
517 for (qint32 row = 0; row < rc.height(); ++row) {
518 QByteArray uncompressed = QByteArray::fromRawData((const char *)plane + row * stride, stride);
519 QByteArray compressed = Compression::compress(uncompressed, psd_compression_type::RLE);
520
521 KisAslWriterUtils::OffsetStreamPusher<quint16, byteOrder> rleExternalTag(io, 0, channelRLESizePos + row * static_cast<qint64>(sizeof(quint16)));
522
523 if (io.write(compressed) != compressed.size()) {
524 throw KisAslWriterUtils::ASLWriteException("Failed to write image data");
525 }
526 }
527}
static QByteArray compress(QByteArray bytes, psd_compression_type compressionType, int row_size=0, int color_depth=0)
#define SAFE_WRITE_EX(byteOrder, device, varname)

References Compression::compress(), RLE, and SAFE_WRITE_EX.

◆ writeChannelDataZIPImpl()

template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::writeChannelDataZIPImpl ( QIODevice & io,
const quint8 * plane,
const int channelSize,
const QRect & rc,
const qint64 sizeFieldOffset,
const bool writeCompressionType )

Definition at line 530 of file psd_pixel_utils.cpp.

536{
538 QScopedPointer<Pusher> channelBlockSizeExternalTag;
539 if (sizeFieldOffset >= 0) {
540 channelBlockSizeExternalTag.reset(new Pusher(io, 0, sizeFieldOffset));
541 }
542
543 if (writeCompressionType) {
544 SAFE_WRITE_EX(byteOrder, io, static_cast<quint16>(psd_compression_type::ZIP));
545 }
546
547 QByteArray uncompressed(reinterpret_cast<const char *>(plane), rc.width() * rc.height() * channelSize);
548 QByteArray compressed(Compression::compress(uncompressed, psd_compression_type::ZIP));
549
550 if (compressed.size() == 0 || io.write(compressed) != compressed.size()) {
551 throw KisAslWriterUtils::ASLWriteException("Failed to write image data");
552 }
553}

References Compression::compress(), SAFE_WRITE_EX, and ZIP.

◆ writePixelDataCommon()

void KRITAPSD_EXPORT PsdPixelUtils::writePixelDataCommon ( QIODevice & io,
KisPaintDeviceSP dev,
const QRect & rc,
psd_color_mode colorMode,
int channelSize,
bool alphaFirst,
const bool writeCompressionType,
QVector< ChannelWritingInfo > & writingInfoList,
psd_compression_type compressionType,
psd_byte_order byteOrder )

Definition at line 709 of file psd_pixel_utils.cpp.

719{
720 switch (byteOrder) {
722 return writePixelDataCommonImpl<psd_byte_order::psdLittleEndian>(io,
723 dev,
724 rc,
725 colorMode,
726 channelSize,
727 alphaFirst,
728 writeCompressionType,
729 writingInfoList,
730 compressionType);
731 default:
732 return writePixelDataCommonImpl(io, dev, rc, colorMode, channelSize, alphaFirst, writeCompressionType, writingInfoList, compressionType);
733 }
734}
void writePixelDataCommonImpl(QIODevice &io, KisPaintDeviceSP dev, const QRect &rc, psd_color_mode colorMode, int channelSize, bool alphaFirst, const bool writeCompressionType, QVector< ChannelWritingInfo > &writingInfoList, psd_compression_type compressionType)

References psdLittleEndian, and writePixelDataCommonImpl().

◆ writePixelDataCommonImpl()

template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void PsdPixelUtils::writePixelDataCommonImpl ( QIODevice & io,
KisPaintDeviceSP dev,
const QRect & rc,
psd_color_mode colorMode,
int channelSize,
bool alphaFirst,
const bool writeCompressionType,
QVector< ChannelWritingInfo > & writingInfoList,
psd_compression_type compressionType )

Definition at line 613 of file psd_pixel_utils.cpp.

622{
623 // Empty rects must be processed separately on a higher level!
624 KIS_ASSERT_RECOVER_RETURN(!rc.isEmpty());
625
626 QVector<quint8 *> tmp = dev->readPlanarBytes(rc.x() - dev->x(), rc.y() - dev->y(), rc.width(), rc.height());
627 const KoColorSpace *colorSpace = dev->colorSpace();
628
629 QVector<quint8 *> planes;
630
631 { // prepare 'planes' array
632
633 quint8 *alphaPlanePtr = 0;
634
635 const QList<KoChannelInfo *> origChannels = colorSpace->channels();
636 Q_FOREACH (KoChannelInfo *ch, KoChannelInfo::displayOrderSorted(origChannels)) {
637 int channelIndex = KoChannelInfo::displayPositionToChannelIndex(ch->displayPosition(), origChannels);
638
639 quint8 *holder = 0;
640 std::swap(holder, tmp[channelIndex]);
641
642 if (ch->channelType() == KoChannelInfo::ALPHA) {
643 std::swap(holder, alphaPlanePtr);
644 } else {
645 planes.append(holder);
646 }
647 }
648
649 if (alphaPlanePtr) {
650 if (alphaFirst) {
651 planes.insert(0, alphaPlanePtr);
652 KIS_ASSERT_RECOVER_NOOP(writingInfoList.first().channelId == -1);
653 } else {
654 planes.append(alphaPlanePtr);
655 KIS_ASSERT_RECOVER_NOOP((writingInfoList.size() == planes.size() - 1) || (writingInfoList.last().channelId == -1));
656 }
657 }
658
659 // now planes are holding pointers to quint8 arrays
660 tmp.clear();
661 }
662
663 KIS_ASSERT_RECOVER_RETURN(planes.size() >= writingInfoList.size());
664
665 const int numPixels = rc.width() * rc.height();
666
667 // write down the planes
668
669 try {
670 for (int i = 0; i < writingInfoList.size(); i++) {
671 const ChannelWritingInfo &info = writingInfoList[i];
672
673 dbgFile << "\tWriting channel" << i << "psd channel id" << info.channelId;
674
675 // WARNING: Pixel data is ALWAYS in big endian!!!
676 preparePixelForWrite<psd_byte_order::psdBigEndian>(planes[i], numPixels, channelSize, info.channelId, colorMode);
677
678 dbgFile << "\t\tchannel start" << ppVar(io.pos()) << ", compression type" << compressionType;
679
680 switch (compressionType) {
683 writeChannelDataZIPImpl<byteOrder>(io, planes[i], channelSize, rc, info.sizeFieldOffset, writeCompressionType);
684 break;
685 }
687 default: {
688 writeChannelDataRLEImpl<byteOrder>(io, planes[i], channelSize, rc, info.sizeFieldOffset, info.rleBlockOffset, writeCompressionType);
689 break;
690 }
691 }
692 }
693
695 Q_FOREACH (quint8 *plane, planes) {
696 delete[] plane;
697 }
698 planes.clear();
699
701 }
702
703 Q_FOREACH (quint8 *plane, planes) {
704 delete[] plane;
705 }
706 planes.clear();
707}
QVector< quint8 * > readPlanarBytes(qint32 x, qint32 y, qint32 w, qint32 h) const
const KoColorSpace * colorSpace() const
@ ALPHA
The channel represents the opacity of a pixel.
enumChannelType channelType() const
static int displayPositionToChannelIndex(int displayPosition, const QList< KoChannelInfo * > &channels)
static QList< KoChannelInfo * > displayOrderSorted(const QList< KoChannelInfo * > &channels)
qint32 displayPosition() const
QList< KoChannelInfo * > channels
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
#define PREPEND_METHOD(msg)
Definition kis_debug.h:172

References KoChannelInfo::ALPHA, PsdPixelUtils::ChannelWritingInfo::channelId, KoColorSpace::channels, KoChannelInfo::channelType(), KisPaintDevice::colorSpace(), dbgFile, KoChannelInfo::displayOrderSorted(), KoChannelInfo::displayPosition(), KoChannelInfo::displayPositionToChannelIndex(), KIS_ASSERT_RECOVER_NOOP, KIS_ASSERT_RECOVER_RETURN, ppVar, PREPEND_METHOD, KisPaintDevice::readPlanarBytes(), RLE, PsdPixelUtils::ChannelWritingInfo::rleBlockOffset, PsdPixelUtils::ChannelWritingInfo::sizeFieldOffset, KisPaintDevice::x(), KisPaintDevice::y(), ZIP, and ZIPWithPrediction.