hrev46533 adds 2 changesets to branch 'master' old head: dd0bdb49dc5d2fdb37f29dd687cd2a406fd34ab7 new head: dc17c462e33a371a8f5ad672cf6d1a5e80536737 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=dc17c46+%5Edd0bdb4 ---------------------------------------------------------------------------- 0ba6a7e: PSDTranslator: fix types dc17c46: PSDTranslator: Add support for monochrome (1bit) and 16bit colors [ Gerasim Troeglazov <3dEyes@xxxxxxxxx> ] ---------------------------------------------------------------------------- 3 files changed, 138 insertions(+), 106 deletions(-) src/add-ons/translators/psd/PSDLoader.cpp | 209 ++++++++++++++---------- src/add-ons/translators/psd/PSDLoader.h | 33 ++-- src/add-ons/translators/psd/PSDTranslator.h | 2 +- ############################################################################ Commit: 0ba6a7e263434f8624fa9946d3c8adbb9742e2c4 URL: http://cgit.haiku-os.org/haiku/commit/?id=0ba6a7e Author: Gerasim Troeglazov <3dEyes@xxxxxxxxx> Date: Fri Dec 13 08:38:17 2013 UTC PSDTranslator: fix types ---------------------------------------------------------------------------- diff --git a/src/add-ons/translators/psd/PSDLoader.cpp b/src/add-ons/translators/psd/PSDLoader.cpp index d183022..f6ea17f 100644 --- a/src/add-ons/translators/psd/PSDLoader.cpp +++ b/src/add-ons/translators/psd/PSDLoader.cpp @@ -113,10 +113,10 @@ PSDLoader::ColorFormatName(void) } -int32 +psd_color_format PSDLoader::_ColorFormat(void) { - int32 format = PSD_COLOR_FORMAT_UNSUPPORTED; + psd_color_format format = PSD_COLOR_FORMAT_UNSUPPORTED; if (!fLoaded) return format; @@ -159,7 +159,7 @@ PSDLoader::_ColorFormat(void) } -int +status_t PSDLoader::Decode(BPositionIO *target) { if (!IsSupported()) @@ -235,7 +235,7 @@ PSDLoader::Decode(BPositionIO *target) uint8 *lineData = new uint8[fWidth * sizeof(uint32)]; - int32 colorFormat = _ColorFormat(); + psd_color_format colorFormat = _ColorFormat(); switch (colorFormat) { case PSD_COLOR_FORMAT_GRAY_8: diff --git a/src/add-ons/translators/psd/PSDLoader.h b/src/add-ons/translators/psd/PSDLoader.h index 01bcdb2..bcc677a 100644 --- a/src/add-ons/translators/psd/PSDLoader.h +++ b/src/add-ons/translators/psd/PSDLoader.h @@ -59,7 +59,7 @@ public: PSDLoader(BPositionIO *stream); ~PSDLoader(); - int Decode(BPositionIO *target); + status_t Decode(BPositionIO *target); bool IsLoaded(void); bool IsSupported(void); @@ -72,7 +72,7 @@ private: int8 _GetInt8FromStream(BPositionIO *in); void _SkipStreamBlock(BPositionIO *in, size_t count); - int32 _ColorFormat(void); + psd_color_format _ColorFormat(void); BPositionIO *fStream; uint8 *fStreamBuffer; ############################################################################ Revision: hrev46533 Commit: dc17c462e33a371a8f5ad672cf6d1a5e80536737 URL: http://cgit.haiku-os.org/haiku/commit/?id=dc17c46 Author: Gerasim Troeglazov <3dEyes@xxxxxxxxx> Date: Fri Dec 13 08:56:54 2013 UTC PSDTranslator: Add support for monochrome (1bit) and 16bit colors ---------------------------------------------------------------------------- diff --git a/src/add-ons/translators/psd/PSDLoader.cpp b/src/add-ons/translators/psd/PSDLoader.cpp index f6ea17f..cdb7e85 100644 --- a/src/add-ons/translators/psd/PSDLoader.cpp +++ b/src/add-ons/translators/psd/PSDLoader.cpp @@ -76,7 +76,7 @@ PSDLoader::IsSupported(void) if (fChannels < 0 || fChannels > 16) return false; - if (fDepth != 8) + if (fDepth > 16) return false; if (_ColorFormat() == PSD_COLOR_FORMAT_UNSUPPORTED) @@ -121,35 +121,38 @@ PSDLoader::_ColorFormat(void) return format; switch (fColorFormat) { + case PSD_COLOR_MODE_BITS: + format = PSD_COLOR_FORMAT_BITMAP; + break; case PSD_COLOR_MODE_RGB: if (fChannels == 3) - format = PSD_COLOR_FORMAT_RGB_8; - if (fChannels >= 4) - format = PSD_COLOR_FORMAT_RGB_A_8; + format = PSD_COLOR_FORMAT_RGB; + else if (fChannels >= 4) + format = PSD_COLOR_FORMAT_RGB_A; break; case PSD_COLOR_MODE_GRAYSCALE: if (fChannels == 1) - format = PSD_COLOR_FORMAT_GRAY_8; - if (fChannels == 2) - format = PSD_COLOR_FORMAT_GRAY_A_8; + format = PSD_COLOR_FORMAT_GRAY; + else if (fChannels == 2) + format = PSD_COLOR_FORMAT_GRAY_A; break; case PSD_COLOR_MODE_MULTICHANNEL: if (fChannels == 3) - format = PSD_COLOR_FORMAT_MULTICHANNEL_8; + format = PSD_COLOR_FORMAT_MULTICHANNEL; break; case PSD_COLOR_MODE_CMYK: if (fChannels == 3) - format = PSD_COLOR_FORMAT_MULTICHANNEL_8; - if (fChannels == 4) - format = PSD_COLOR_FORMAT_CMYK_8; - if (fChannels > 4) - format = PSD_COLOR_FORMAT_CMYK_A_8; + format = PSD_COLOR_FORMAT_MULTICHANNEL; + else if (fChannels == 4) + format = PSD_COLOR_FORMAT_CMYK; + else if (fChannels > 4) + format = PSD_COLOR_FORMAT_CMYK_A; break; case PSD_COLOR_MODE_LAB: if (fChannels == 3) - format = PSD_COLOR_FORMAT_LAB_8; - if (fChannels > 3) - format = PSD_COLOR_FORMAT_LAB_A_8; + format = PSD_COLOR_FORMAT_LAB; + else if (fChannels > 3) + format = PSD_COLOR_FORMAT_LAB_A; break; default: break; @@ -169,51 +172,64 @@ PSDLoader::Decode(BPositionIO *target) fStream->Seek(0, SEEK_SET); fStream->Read(fStreamBuffer, fStreamSize); + int32 depthBytes = fDepth / 8; + int32 rowBytes = (fWidth * fDepth) / 8; + int32 channelBytes = rowBytes * fHeight; + uint8 *imageData[5]; for (int i = 0; i < fChannels; i++) - imageData[i] = new uint8[fWidth * fHeight]; - - int pixelCount = fWidth * fHeight; + imageData[i] = new uint8[channelBytes]; - if (fCompression == PSD_COMPRESSED_RAW) { - for (int channelIdx = 0; channelIdx < fChannels; channelIdx++) { - uint8 *ptr = imageData[channelIdx]; - for (int i = 0; i < pixelCount; i++, ptr++) - *ptr = (uint8)fStreamBuffer[fStreamPos++]; + + switch (fCompression) { + case PSD_COMPRESSED_RAW: + { + for (int channelIdx = 0; channelIdx < fChannels; channelIdx++) { + uint8 *ptr = imageData[channelIdx]; + for (int i = 0; i < channelBytes; i++, ptr++) + *ptr = (uint8)fStreamBuffer[fStreamPos++]; + } + break; } - } - - if (fCompression == PSD_COMPRESSED_RLE) { - fStreamPos += fHeight * fChannels * 2; - for (int channelIdx = 0; channelIdx < fChannels; channelIdx++) { - uint8 *ptr = imageData[channelIdx]; - // Read the RLE data. - int count = 0; - while (count < pixelCount) { - uint8 len = (uint8)fStreamBuffer[fStreamPos++]; - if (len == 128) { - continue; - } else if (len < 128) { - len++; - count += len; - while (len) { - *ptr++ = (int8)fStreamBuffer[fStreamPos++]; - len--; - } - } else if (len > 128) { - int8 val = (int8)fStreamBuffer[fStreamPos++]; - len ^= 255; - len += 2; - count += len; - while (len) { - *ptr++ = val; - len--; + case PSD_COMPRESSED_RLE: + { + fStreamPos += fHeight * fChannels * 2; + for (int channelIdx = 0; channelIdx < fChannels; channelIdx++) { + uint8 *ptr = imageData[channelIdx]; + // Read the RLE data. + int count = 0; + while (count < channelBytes) { + uint8 len = (uint8)fStreamBuffer[fStreamPos++]; + if (len == 128) { + continue; + } else if (len < 128) { + len++; + count += len; + while (len) { + *ptr++ = (int8)fStreamBuffer[fStreamPos++]; + len--; + } + } else if (len > 128) { + int8 val = (int8)fStreamBuffer[fStreamPos++]; + len ^= 255; + len += 2; + count += len; + while (len) { + *ptr++ = val; + len--; + } } } } + break; } + default: + delete fStreamBuffer; + for (int i = 0; i < fChannels; i++) + delete imageData[i]; + return B_NO_TRANSLATOR; } - + delete fStreamBuffer; TranslatorBitmap bitsHeader; @@ -222,9 +238,18 @@ PSDLoader::Decode(BPositionIO *target) bitsHeader.bounds.top = 0; bitsHeader.bounds.right = fWidth - 1; bitsHeader.bounds.bottom = fHeight - 1; - bitsHeader.rowBytes = sizeof(uint32) * fWidth; - bitsHeader.colors = B_RGBA32; - bitsHeader.dataSize = bitsHeader.rowBytes * fHeight; + + psd_color_format colorFormat = _ColorFormat(); + + if (colorFormat == PSD_COLOR_FORMAT_BITMAP) { + bitsHeader.rowBytes = rowBytes; + bitsHeader.dataSize = channelBytes; + bitsHeader.colors = B_GRAY1; + } else { + bitsHeader.rowBytes = sizeof(uint32) * fWidth; + bitsHeader.colors = B_RGBA32; + bitsHeader.dataSize = bitsHeader.rowBytes * fHeight; + } if (swap_data(B_UINT32_TYPE, &bitsHeader, sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) != B_OK) { @@ -234,34 +259,40 @@ PSDLoader::Decode(BPositionIO *target) target->Write(&bitsHeader, sizeof(TranslatorBitmap)); uint8 *lineData = new uint8[fWidth * sizeof(uint32)]; - - psd_color_format colorFormat = _ColorFormat(); - + switch (colorFormat) { - case PSD_COLOR_FORMAT_GRAY_8: - case PSD_COLOR_FORMAT_GRAY_A_8: + case PSD_COLOR_FORMAT_BITMAP: + { + int32 rowBytes = (fWidth / 8 ) * fHeight; + for (int32 i = 0; i < rowBytes; i++) + imageData[0][i]^=255; + target->Write(imageData[0], rowBytes); + break; + } + case PSD_COLOR_FORMAT_GRAY: + case PSD_COLOR_FORMAT_GRAY_A: { - bool isAlpha = colorFormat == PSD_COLOR_FORMAT_GRAY_A_8; + bool isAlpha = colorFormat == PSD_COLOR_FORMAT_GRAY_A; uint8 *yCh = imageData[0]; uint8 *alphaCh = isAlpha ? imageData[1] : NULL; for (int h = 0; h < fHeight; h++) { uint8 *ptr = lineData; for (int w = 0; w < fWidth; w++) { - uint8 y = *yCh++; + uint8 y = *(yCh += depthBytes); *ptr++ = y; *ptr++ = y; *ptr++ = y; - *ptr++ = isAlpha ? *alphaCh++ : 255; + *ptr++ = isAlpha ? *(alphaCh += depthBytes) : 255; } target->Write(lineData, fWidth * sizeof(uint32)); } break; } - case PSD_COLOR_FORMAT_MULTICHANNEL_8: - case PSD_COLOR_FORMAT_RGB_8: - case PSD_COLOR_FORMAT_RGB_A_8: + case PSD_COLOR_FORMAT_MULTICHANNEL: + case PSD_COLOR_FORMAT_RGB: + case PSD_COLOR_FORMAT_RGB_A: { - bool isAlpha = colorFormat == PSD_COLOR_FORMAT_RGB_A_8; + bool isAlpha = colorFormat == PSD_COLOR_FORMAT_RGB_A; uint8 *rCh = imageData[0]; uint8 *gCh = imageData[1]; uint8 *bCh = imageData[2]; @@ -269,19 +300,19 @@ PSDLoader::Decode(BPositionIO *target) for (int h = 0; h < fHeight; h++) { uint8 *ptr = lineData; for (int w = 0; w < fWidth; w++) { - *ptr++ = *bCh++; - *ptr++ = *gCh++; - *ptr++ = *rCh++; - *ptr++ = isAlpha ? *alphaCh++ : 255; + *ptr++ = *(bCh += depthBytes); + *ptr++ = *(gCh += depthBytes); + *ptr++ = *(rCh += depthBytes); + *ptr++ = isAlpha ? *(alphaCh += depthBytes) : 255; } target->Write(lineData, fWidth * sizeof(uint32)); } break; } - case PSD_COLOR_FORMAT_CMYK_8: - case PSD_COLOR_FORMAT_CMYK_A_8: + case PSD_COLOR_FORMAT_CMYK: + case PSD_COLOR_FORMAT_CMYK_A: { - bool isAlpha = colorFormat == PSD_COLOR_FORMAT_CMYK_A_8; + bool isAlpha = colorFormat == PSD_COLOR_FORMAT_CMYK_A; uint8 *cCh = imageData[0]; uint8 *mCh = imageData[1]; uint8 *yCh = imageData[2]; @@ -290,23 +321,23 @@ PSDLoader::Decode(BPositionIO *target) for (int h = 0; h < fHeight; h++) { uint8 *ptr = lineData; for (int w = 0; w < fWidth; w++) { - double c = 1.0 - (*cCh++ / 255.0); - double m = 1.0 - (*mCh++ / 255.0); - double y = 1.0 - (*yCh++ / 255.0); - double k = 1.0 - (*kCh++ / 255.0); + double c = 1.0 - *(cCh += depthBytes) / 255.0; + double m = 1.0 - *(mCh += depthBytes) / 255.0; + double y = 1.0 - *(yCh += depthBytes) / 255.0; + double k = 1.0 - *(kCh += depthBytes) / 255.0; *ptr++ = (uint8)((1.0 - (y * (1.0 - k) + k)) * 255.0); *ptr++ = (uint8)((1.0 - (m * (1.0 - k) + k)) * 255.0); *ptr++ = (uint8)((1.0 - (c * (1.0 - k) + k)) * 255.0); - *ptr++ = alphaCh ? *alphaCh++ : 255; + *ptr++ = alphaCh ? *(alphaCh += depthBytes) : 255; } target->Write(lineData, fWidth * sizeof(uint32)); } break; } - case PSD_COLOR_FORMAT_LAB_8: - case PSD_COLOR_FORMAT_LAB_A_8: + case PSD_COLOR_FORMAT_LAB: + case PSD_COLOR_FORMAT_LAB_A: { - bool isAlpha = colorFormat == PSD_COLOR_FORMAT_LAB_A_8; + bool isAlpha = colorFormat == PSD_COLOR_FORMAT_LAB_A; uint8 *lCh = imageData[0]; uint8 *aCh = imageData[1]; uint8 *bCh = imageData[2]; @@ -314,9 +345,9 @@ PSDLoader::Decode(BPositionIO *target) for (int h = 0; h < fHeight; h++) { uint8 *ptr = lineData; for (int w = 0; w < fWidth; w++) { - double L = ((*lCh++) / 255.0) * 100.0; - double a = (*aCh++) - 128.0; - double b = (*bCh++) - 128.0; + double L = *(lCh += depthBytes) / 255.0 * 100.0; + double a = *(aCh += depthBytes) - 128.0; + double b = *(bCh += depthBytes) - 128.0; double Y = L * (1.0 / 116.0) + 16.0 / 116.0; double X = a * (1.0 / 500.0) + Y; @@ -352,7 +383,7 @@ PSDLoader::Decode(BPositionIO *target) *ptr++ = (uint8)(B * 255.0); *ptr++ = (uint8)(G * 255.0); *ptr++ = (uint8)(R * 255.0); - *ptr++ = isAlpha ? *alphaCh++ : 255; + *ptr++ = isAlpha ? *(alphaCh += depthBytes) : 255; } target->Write(lineData, fWidth * sizeof(uint32)); } diff --git a/src/add-ons/translators/psd/PSDLoader.h b/src/add-ons/translators/psd/PSDLoader.h index bcc677a..8e41a95 100644 --- a/src/add-ons/translators/psd/PSDLoader.h +++ b/src/add-ons/translators/psd/PSDLoader.h @@ -42,15 +42,16 @@ enum psd_color_mode { enum psd_color_format { PSD_COLOR_FORMAT_UNSUPPORTED, - PSD_COLOR_FORMAT_RGB_8, - PSD_COLOR_FORMAT_RGB_A_8, - PSD_COLOR_FORMAT_GRAY_8, - PSD_COLOR_FORMAT_GRAY_A_8, - PSD_COLOR_FORMAT_MULTICHANNEL_8, - PSD_COLOR_FORMAT_CMYK_8, - PSD_COLOR_FORMAT_CMYK_A_8, - PSD_COLOR_FORMAT_LAB_8, - PSD_COLOR_FORMAT_LAB_A_8 + PSD_COLOR_FORMAT_BITMAP, + PSD_COLOR_FORMAT_RGB, + PSD_COLOR_FORMAT_RGB_A, + PSD_COLOR_FORMAT_GRAY, + PSD_COLOR_FORMAT_GRAY_A, + PSD_COLOR_FORMAT_MULTICHANNEL, + PSD_COLOR_FORMAT_CMYK, + PSD_COLOR_FORMAT_CMYK_A, + PSD_COLOR_FORMAT_LAB, + PSD_COLOR_FORMAT_LAB_A }; @@ -58,11 +59,11 @@ class PSDLoader { public: PSDLoader(BPositionIO *stream); ~PSDLoader(); - + status_t Decode(BPositionIO *target); bool IsLoaded(void); bool IsSupported(void); - + BString ColorFormatName(void); private: @@ -71,14 +72,14 @@ private: uint8 _GetUInt8FromStream(BPositionIO *in); int8 _GetInt8FromStream(BPositionIO *in); void _SkipStreamBlock(BPositionIO *in, size_t count); - + psd_color_format _ColorFormat(void); BPositionIO *fStream; uint8 *fStreamBuffer; size_t fStreamSize; size_t fStreamPos; - + int32 fSignature; int16 fVersion; int16 fChannels; @@ -87,7 +88,7 @@ private: int16 fDepth; int16 fColorFormat; int16 fCompression; - + bool fLoaded; }; diff --git a/src/add-ons/translators/psd/PSDTranslator.h b/src/add-ons/translators/psd/PSDTranslator.h index 5b00972..38da193 100644 --- a/src/add-ons/translators/psd/PSDTranslator.h +++ b/src/add-ons/translators/psd/PSDTranslator.h @@ -21,7 +21,7 @@ #define DOCUMENT_COUNT "/documentCount" #define DOCUMENT_INDEX "/documentIndex" -#define PSD_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1, 1, 0) +#define PSD_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1, 1, 1) #define PSD_IMAGE_FORMAT 'PSD ' #define PSD_IN_QUALITY 0.5