PSDTranslator: Prepare PSDWriter for B_GRAY8 and B_CMAP8 colorspaces support
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
PSDWriter::PSDWriter(BPositionIO *stream)
|
PSDWriter::PSDWriter(BPositionIO *stream)
|
||||||
{
|
{
|
||||||
|
fAlphaChannel = -1;
|
||||||
fStream = stream;
|
fStream = stream;
|
||||||
fReady = false;
|
fReady = false;
|
||||||
|
|
||||||
@@ -33,9 +34,22 @@ PSDWriter::PSDWriter(BPositionIO *stream)
|
|||||||
bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
|
bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
|
||||||
fInRowBytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
|
fInRowBytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
|
||||||
fColorSpace = (color_space)B_BENDIAN_TO_HOST_INT32(header.colors);
|
fColorSpace = (color_space)B_BENDIAN_TO_HOST_INT32(header.colors);
|
||||||
if (fColorSpace != B_RGB32 && fColorSpace != B_RGBA32)
|
|
||||||
return;
|
switch (fColorSpace) {
|
||||||
fChannels = fColorSpace == B_RGB32 ? 3 : 4;
|
case B_GRAY8:
|
||||||
|
case B_CMAP8:
|
||||||
|
fChannels = 1;
|
||||||
|
break;
|
||||||
|
case B_RGBA32:
|
||||||
|
fChannels = 4;
|
||||||
|
fAlphaChannel = 3;
|
||||||
|
break;
|
||||||
|
case B_RGB32:
|
||||||
|
fChannels = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
fWidth = bounds.IntegerWidth() + 1;
|
fWidth = bounds.IntegerWidth() + 1;
|
||||||
fHeight = bounds.IntegerHeight() + 1;
|
fHeight = bounds.IntegerHeight() + 1;
|
||||||
@@ -79,52 +93,9 @@ PSDWriter::Encode(BPositionIO *target)
|
|||||||
if (!fReady)
|
if (!fReady)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
int32 channelSize = fWidth * fHeight;
|
status_t status = _LoadChannelsFromRGBA32();
|
||||||
|
if (status != B_OK)
|
||||||
fStream->Seek(fBitmapDataPos, SEEK_SET);
|
return status;
|
||||||
|
|
||||||
BDataArray psdChannel[4];
|
|
||||||
BDataArray psdByteCounts[4];
|
|
||||||
|
|
||||||
if (fCompression == PSD_COMPRESSED_RAW) {
|
|
||||||
for (int i = 0; i < channelSize; i++) {
|
|
||||||
uint8 rgba[4];
|
|
||||||
fStream->Read(rgba, sizeof(uint32));
|
|
||||||
psdChannel[0].Append((uint8)rgba[2]); // Red channel
|
|
||||||
psdChannel[1].Append((uint8)rgba[1]); // Green channel
|
|
||||||
psdChannel[2].Append((uint8)rgba[0]); // Blue channel
|
|
||||||
if (fChannels == 4)
|
|
||||||
psdChannel[3].Append((uint8)rgba[3]); // Alpha channel
|
|
||||||
}
|
|
||||||
} else if (fCompression == PSD_COMPRESSED_RLE) {
|
|
||||||
for (int32 h = 0; h < fHeight; h++) {
|
|
||||||
BDataArray lineData[4];
|
|
||||||
|
|
||||||
for (int32 w = 0; w < fWidth; w++) {
|
|
||||||
uint8 rgba[4];
|
|
||||||
fStream->Read(rgba, sizeof(uint32));
|
|
||||||
lineData[0].Append((uint8)rgba[2]); // Red channel
|
|
||||||
lineData[1].Append((uint8)rgba[1]); // Green channel
|
|
||||||
lineData[2].Append((uint8)rgba[0]); // Blue channel
|
|
||||||
if (fChannels == 4)
|
|
||||||
lineData[3].Append((uint8)rgba[3]); // Alpha channel
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int channelIdx = 0; channelIdx < fChannels; channelIdx++) {
|
|
||||||
BDataArray *packedLine = PackBits(lineData[channelIdx].Buffer(),
|
|
||||||
lineData[channelIdx].Length());
|
|
||||||
|
|
||||||
if (fVersion == PSD_FILE)
|
|
||||||
psdByteCounts[channelIdx].Append((uint16)packedLine->Length());
|
|
||||||
else
|
|
||||||
psdByteCounts[channelIdx].Append((uint32)packedLine->Length());
|
|
||||||
|
|
||||||
psdChannel[channelIdx].Append(*packedLine);
|
|
||||||
delete packedLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
return B_NO_TRANSLATOR;
|
|
||||||
|
|
||||||
// PSD header
|
// PSD header
|
||||||
BDataArray psdHeader(64);
|
BDataArray psdHeader(64);
|
||||||
@@ -256,7 +227,7 @@ PSDWriter::Encode(BPositionIO *target)
|
|||||||
|
|
||||||
|
|
||||||
BDataArray*
|
BDataArray*
|
||||||
PSDWriter::PackBits(uint8 *buff, int32 len)
|
PSDWriter::_PackBits(uint8 *buff, int32 len)
|
||||||
{
|
{
|
||||||
BDataArray *packedBits = new BDataArray();
|
BDataArray *packedBits = new BDataArray();
|
||||||
|
|
||||||
@@ -300,6 +271,60 @@ PSDWriter::PackBits(uint8 *buff, int32 len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PSDWriter::_LoadChannelsFromRGBA32(void)
|
||||||
|
{
|
||||||
|
if (fColorSpace != B_RGB32 && fColorSpace != B_RGBA32)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
int32 channelSize = fWidth * fHeight;
|
||||||
|
|
||||||
|
fStream->Seek(fBitmapDataPos, SEEK_SET);
|
||||||
|
|
||||||
|
if (fCompression == PSD_COMPRESSED_RAW) {
|
||||||
|
for (int i = 0; i < channelSize; i++) {
|
||||||
|
uint8 rgba[4];
|
||||||
|
fStream->Read(rgba, sizeof(uint32));
|
||||||
|
psdChannel[0].Append((uint8)rgba[2]); // Red channel
|
||||||
|
psdChannel[1].Append((uint8)rgba[1]); // Green channel
|
||||||
|
psdChannel[2].Append((uint8)rgba[0]); // Blue channel
|
||||||
|
if (fChannels == 4)
|
||||||
|
psdChannel[3].Append((uint8)rgba[3]); // Alpha channel
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
} else if (fCompression == PSD_COMPRESSED_RLE) {
|
||||||
|
for (int32 h = 0; h < fHeight; h++) {
|
||||||
|
BDataArray lineData[4];
|
||||||
|
|
||||||
|
for (int32 w = 0; w < fWidth; w++) {
|
||||||
|
uint8 rgba[4];
|
||||||
|
fStream->Read(rgba, sizeof(uint32));
|
||||||
|
lineData[0].Append((uint8)rgba[2]); // Red channel
|
||||||
|
lineData[1].Append((uint8)rgba[1]); // Green channel
|
||||||
|
lineData[2].Append((uint8)rgba[0]); // Blue channel
|
||||||
|
if (fChannels == 4)
|
||||||
|
lineData[3].Append((uint8)rgba[3]); // Alpha channel
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int channelIdx = 0; channelIdx < fChannels; channelIdx++) {
|
||||||
|
BDataArray *packedLine = _PackBits(lineData[channelIdx].Buffer(),
|
||||||
|
lineData[channelIdx].Length());
|
||||||
|
|
||||||
|
if (fVersion == PSD_FILE)
|
||||||
|
psdByteCounts[channelIdx].Append((uint16)packedLine->Length());
|
||||||
|
else
|
||||||
|
psdByteCounts[channelIdx].Append((uint32)packedLine->Length());
|
||||||
|
|
||||||
|
psdChannel[channelIdx].Append(*packedLine);
|
||||||
|
delete packedLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PSDWriter::_WriteInt64ToStream(BPositionIO *stream, int64 val)
|
PSDWriter::_WriteInt64ToStream(BPositionIO *stream, int64 val)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,15 +48,20 @@ private:
|
|||||||
uint8 val, size_t count);
|
uint8 val, size_t count);
|
||||||
void _WriteBlockToStream(BPositionIO *stream,
|
void _WriteBlockToStream(BPositionIO *stream,
|
||||||
uint8 *block, size_t count);
|
uint8 *block, size_t count);
|
||||||
|
|
||||||
BDataArray* PackBits(uint8 *buff, int32 len);
|
BDataArray* _PackBits(uint8 *buff, int32 len);
|
||||||
|
status_t _LoadChannelsFromRGBA32(void);
|
||||||
|
|
||||||
BPositionIO *fStream;
|
BPositionIO *fStream;
|
||||||
size_t fBitmapDataPos;
|
size_t fBitmapDataPos;
|
||||||
|
|
||||||
|
BDataArray psdChannel[4];
|
||||||
|
BDataArray psdByteCounts[4];
|
||||||
|
|
||||||
color_space fColorSpace;
|
color_space fColorSpace;
|
||||||
int32 fInRowBytes;
|
int32 fInRowBytes;
|
||||||
int16 fChannels;
|
int16 fChannels;
|
||||||
|
int16 fAlphaChannel;
|
||||||
int32 fWidth;
|
int32 fWidth;
|
||||||
int32 fHeight;
|
int32 fHeight;
|
||||||
int16 fCompression;
|
int16 fCompression;
|
||||||
|
|||||||
Reference in New Issue
Block a user