PSDTranslator: Add simple parser for ImageResourcesSection for transparency support in Indexed color modes

This commit is contained in:
Gerasim Troeglazov 2013-12-15 06:01:40 +00:00
parent 1666d18503
commit 546a1bc793
4 changed files with 73 additions and 9 deletions

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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."
};