diff --git a/src/add-ons/translators/psd/PSDLoader.cpp b/src/add-ons/translators/psd/PSDLoader.cpp index b08bc20cac..4cfbab4d3c 100644 --- a/src/add-ons/translators/psd/PSDLoader.cpp +++ b/src/add-ons/translators/psd/PSDLoader.cpp @@ -23,7 +23,7 @@ PSDLoader::PSDLoader(BPositionIO *src) fStream->Seek(0, SEEK_SET); fSignature = _GetInt32FromStream(fStream); - if (fSignature != 0x38425053) + if (fSignature != 0x38425053) // 8BPS return; fVersion = _GetInt16FromStream(fStream); @@ -41,9 +41,11 @@ PSDLoader::PSDLoader(BPositionIO *src) fColorModeDataPos = fStream->Position(); _SkipStreamBlock(fStream, fColorModeDataSize); - // Skip image resources - _SkipStreamBlock(fStream, _GetInt32FromStream(fStream)); - // Skip reserved data + fImageResourceSectionSize = _GetInt32FromStream(fStream); + fImageResourceSectionPos = fStream->Position(); + _SkipStreamBlock(fStream, fImageResourceSectionSize); + + // Skip [layer and mask] block _SkipStreamBlock(fStream, _GetInt32FromStream(fStream)); fCompression = _GetInt16FromStream(fStream); @@ -288,6 +290,9 @@ PSDLoader::Decode(BPositionIO *target) uint8 *colorData = new uint8[fColorModeDataSize]; fStream->Seek(fColorModeDataPos, SEEK_SET); fStream->Read(colorData, fColorModeDataSize); + + if (_ParseImageResources() != B_OK) + fTransparentIndex = 256; uint8 *redPalette = colorData; uint8 *greenPalette = colorData + paletteSize; @@ -300,7 +305,7 @@ PSDLoader::Decode(BPositionIO *target) *ptr++ = bluePalette[c]; *ptr++ = greenPalette[c]; *ptr++ = redPalette[c]; - *ptr++ = 255; + *ptr++ = c == fTransparentIndex ? 0 : 255; } target->Write(lineData, fWidth * sizeof(uint32)); } @@ -481,3 +486,55 @@ PSDLoader::_SkipStreamBlock(BPositionIO *in, size_t count) { in->Seek(count, SEEK_CUR); } + + +status_t +PSDLoader::_ParseImageResources(void) +{ + if (!fLoaded && fImageResourceSectionSize == 0) + return B_ERROR; + + size_t currentPos = fStream->Position(); + fStream->Seek(fImageResourceSectionPos, SEEK_SET); + + while (fStream->Position() < currentPos + fImageResourceSectionSize) { + int32 resBlockSignature = _GetInt32FromStream(fStream); + if (resBlockSignature != 0x3842494D) // 8BIM + return B_ERROR; + + uint16 resID = _GetInt16FromStream(fStream); + + BString resName, name; + int nameLength = 0; + while (true) { + int charData = _GetUInt8FromStream(fStream); + nameLength++; + if (charData == 0) { + if (nameLength % 2 == 1) { + _GetUInt8FromStream(fStream); + nameLength++; + } + break; + } else + name += charData; + resName = name; + } + + uint32 resSize = _GetInt32FromStream(fStream); + + if (resSize % 2 == 1) + resSize++; + + switch (resID) { + case 0x0417: + fTransparentIndex = _GetInt16FromStream(fStream); + break; + default: + _SkipStreamBlock(fStream, resSize); + } + } + + fStream->Seek(currentPos, SEEK_SET); + + return B_OK; +} diff --git a/src/add-ons/translators/psd/PSDLoader.h b/src/add-ons/translators/psd/PSDLoader.h index 76f2d672a5..e7dcb2568a 100644 --- a/src/add-ons/translators/psd/PSDLoader.h +++ b/src/add-ons/translators/psd/PSDLoader.h @@ -75,6 +75,8 @@ private: uint8 _GetUInt8FromStream(BPositionIO *in); int8 _GetInt8FromStream(BPositionIO *in); void _SkipStreamBlock(BPositionIO *in, size_t count); + + status_t _ParseImageResources(void); psd_color_format _ColorFormat(void); @@ -85,7 +87,10 @@ private: size_t fColorModeDataSize; size_t fColorModeDataPos; - + + size_t fImageResourceSectionSize; + size_t fImageResourceSectionPos; + int32 fSignature; int16 fVersion; int16 fChannels; @@ -95,6 +100,8 @@ private: int16 fColorFormat; int16 fCompression; + uint16 fTransparentIndex; + bool fLoaded; }; diff --git a/src/add-ons/translators/psd/PSDTranslator.h b/src/add-ons/translators/psd/PSDTranslator.h index 59f708ec7f..6b45838836 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, 2) +#define PSD_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(1, 1, 3) #define PSD_IMAGE_FORMAT 'PSD ' #define PSD_IN_QUALITY 0.5 diff --git a/src/add-ons/translators/psd/PSDTranslator.rdef b/src/add-ons/translators/psd/PSDTranslator.rdef index 5c500f6792..3b8d4c7ea7 100644 --- a/src/add-ons/translators/psd/PSDTranslator.rdef +++ b/src/add-ons/translators/psd/PSDTranslator.rdef @@ -7,9 +7,9 @@ resource app_signature "application/x-vnd.Haiku-PSDTranslator"; resource app_version { major = 1, middle = 1, - minor = 2, + minor = 3, variety = 0, internal = 0, - short_info = "1.1.2", + short_info = "1.1.3", long_info = "Haiku PSDTranslator Add-Ons." };