Added support for more Be Bitmap types and cleaned up code in general
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@415 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -132,7 +132,7 @@ const translation_format *BMPTranslator::OutputFormats(int32 *out_count) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
|
status_t identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
|
||||||
ssize_t amtread, char *read)
|
ssize_t amtread, uint8 *read)
|
||||||
{
|
{
|
||||||
TranslatorBitmap header;
|
TranslatorBitmap header;
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ status_t identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
// copy portion of header already read in
|
// copy portion of header already read in
|
||||||
// read in the rest of the header
|
// read in the rest of the header
|
||||||
ssize_t size = sizeof(TranslatorBitmap) - amtread;
|
ssize_t size = sizeof(TranslatorBitmap) - amtread;
|
||||||
if (inSource->Read(((char *) &header) + amtread, size) != size)
|
if (inSource->Read(((uint8 *) &header) + amtread, size) != size)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
// convert to host byte order
|
// convert to host byte order
|
||||||
@@ -150,14 +150,24 @@ status_t identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
|
|
||||||
// check if header values are reasonable
|
// check if header values are reasonable
|
||||||
if (header.colors != B_RGB32 &&
|
if (header.colors != B_RGB32 &&
|
||||||
|
header.colors != B_RGB32_BIG &&
|
||||||
header.colors != B_RGBA32 &&
|
header.colors != B_RGBA32 &&
|
||||||
|
header.colors != B_RGBA32_BIG &&
|
||||||
header.colors != B_RGB24 &&
|
header.colors != B_RGB24 &&
|
||||||
|
header.colors != B_RGB24_BIG &&
|
||||||
header.colors != B_RGB16 &&
|
header.colors != B_RGB16 &&
|
||||||
|
header.colors != B_RGB16_BIG &&
|
||||||
header.colors != B_RGB15 &&
|
header.colors != B_RGB15 &&
|
||||||
|
header.colors != B_RGB15_BIG &&
|
||||||
header.colors != B_RGBA15 &&
|
header.colors != B_RGBA15 &&
|
||||||
|
header.colors != B_RGBA15_BIG &&
|
||||||
header.colors != B_CMAP8 &&
|
header.colors != B_CMAP8 &&
|
||||||
header.colors != B_GRAY8 &&
|
header.colors != B_GRAY8 &&
|
||||||
header.colors != B_GRAY1)
|
header.colors != B_GRAY1 &&
|
||||||
|
header.colors != B_CMYK32 &&
|
||||||
|
header.colors != B_CMY32 &&
|
||||||
|
header.colors != B_CMYA32 &&
|
||||||
|
header.colors != B_CMY24)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
if (header.rowBytes * (header.bounds.Height() + 1) > header.dataSize)
|
if (header.rowBytes * (header.bounds.Height() + 1) > header.dataSize)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -173,9 +183,9 @@ status_t identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
status_t identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
||||||
ssize_t amtread, char *read)
|
ssize_t amtread, uint8 *read)
|
||||||
{
|
{
|
||||||
char buf[40];
|
uint8 buf[40];
|
||||||
BMPFileHeader fileHeader;
|
BMPFileHeader fileHeader;
|
||||||
|
|
||||||
memcpy(buf, read, amtread);
|
memcpy(buf, read, amtread);
|
||||||
@@ -193,7 +203,7 @@ status_t identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
if (swap_data(B_UINT16_TYPE, &fileHeader.magic, sizeof(uint16),
|
if (swap_data(B_UINT16_TYPE, &fileHeader.magic, sizeof(uint16),
|
||||||
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
if (swap_data(B_UINT32_TYPE, ((char *) &fileHeader) + 2, 12,
|
if (swap_data(B_UINT32_TYPE, ((uint8 *) &fileHeader) + 2, 12,
|
||||||
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -242,7 +252,7 @@ status_t BMPTranslator::Identify(BPositionIO *inSource,
|
|||||||
if (outType != B_TRANSLATOR_BITMAP && outType != B_BMP_FORMAT)
|
if (outType != B_TRANSLATOR_BITMAP && outType != B_BMP_FORMAT)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
char ch[4];
|
uint8 ch[4];
|
||||||
uint32 nbits = B_TRANSLATOR_BITMAP;
|
uint32 nbits = B_TRANSLATOR_BITMAP;
|
||||||
uint16 nbm = 'MB';
|
uint16 nbm = 'MB';
|
||||||
|
|
||||||
@@ -273,8 +283,169 @@ status_t BMPTranslator::Identify(BPositionIO *inSource,
|
|||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for converting uncompressed BMP images with no palette to the Be Bitmap format
|
||||||
|
status_t translate_from_bits32_to_bmp(BPositionIO *inSource, BPositionIO *outDestination,
|
||||||
|
color_space fromspace, BMPInfoHeader &infoHeader)
|
||||||
|
{
|
||||||
|
int32 bitsBytesPerPixel = 0;
|
||||||
|
switch (fromspace) {
|
||||||
|
case B_RGB32:
|
||||||
|
case B_RGB32_BIG:
|
||||||
|
case B_RGBA32:
|
||||||
|
case B_RGBA32_BIG:
|
||||||
|
case B_CMY32:
|
||||||
|
case B_CMYA32:
|
||||||
|
case B_CMYK32:
|
||||||
|
bitsBytesPerPixel = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB24:
|
||||||
|
case B_RGB24_BIG:
|
||||||
|
case B_CMY24:
|
||||||
|
bitsBytesPerPixel = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB16:
|
||||||
|
case B_RGB16_BIG:
|
||||||
|
case B_RGBA15:
|
||||||
|
case B_RGBA15_BIG:
|
||||||
|
case B_RGB15:
|
||||||
|
case B_RGB15_BIG:
|
||||||
|
bitsBytesPerPixel = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
int32 bitsRowBytes = infoHeader.width * bitsBytesPerPixel;
|
||||||
|
int32 bmpBytesPerPixel = infoHeader.bitsperpixel / 8;
|
||||||
|
int32 padding = (infoHeader.width * bmpBytesPerPixel) % 4;
|
||||||
|
if (padding)
|
||||||
|
padding = 4 - padding;
|
||||||
|
int32 bmpRowBytes = (infoHeader.width * bmpBytesPerPixel) + padding;
|
||||||
|
uint32 bmppixrow = 0;
|
||||||
|
off_t bitsoffset = ((infoHeader.height - 1) * bitsRowBytes);
|
||||||
|
inSource->Seek(bitsoffset, SEEK_CUR);
|
||||||
|
uint8 *bmpRowData = new uint8[bmpRowBytes];
|
||||||
|
if (!bmpRowData)
|
||||||
|
return B_ERROR;
|
||||||
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
|
if (!bitsRowData) {
|
||||||
|
delete[] bmpRowData;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
memset(bmpRowData, 0, bmpRowBytes);
|
||||||
|
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
|
while (rd == bitsRowBytes) {
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < infoHeader.width; i++) {
|
||||||
|
uint8 *bitspixel, *bmppixel;
|
||||||
|
uint16 val;
|
||||||
|
switch (fromspace) {
|
||||||
|
case B_RGB32:
|
||||||
|
case B_RGBA32:
|
||||||
|
case B_RGB24:
|
||||||
|
memcpy(bmpRowData + (i * 3),
|
||||||
|
bitsRowData + (i * bitsBytesPerPixel), 3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB16:
|
||||||
|
case B_RGB16_BIG:
|
||||||
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
|
bmppixel = bmpRowData + (i * 3);
|
||||||
|
if (fromspace == B_RGB16)
|
||||||
|
val = bitspixel[0] + (bitspixel[1] << 8);
|
||||||
|
else
|
||||||
|
val = bitspixel[1] + (bitspixel[1] << 8);
|
||||||
|
bmppixel[0] = ((val & 0x1f) << 3) | ((val & 0x1f) >> 2);
|
||||||
|
bmppixel[1] = ((val & 0x7e0) >> 3) | ((val & 0x7e0) >> 9);
|
||||||
|
bmppixel[2] = ((val & 0xf800) >> 8) | ((val & 0xf800) >> 13);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB15:
|
||||||
|
case B_RGB15_BIG:
|
||||||
|
case B_RGBA15:
|
||||||
|
case B_RGBA15_BIG:
|
||||||
|
// NOTE: the alpha data for B_RGBA15 is ignored and discarded
|
||||||
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
|
bmppixel = bmpRowData + (i * 3);
|
||||||
|
if (fromspace == B_RGB15 || fromspace == B_RGBA15)
|
||||||
|
val = bitspixel[0] + (bitspixel[1] << 8);
|
||||||
|
else
|
||||||
|
val = bitspixel[1] + (bitspixel[0] << 8);
|
||||||
|
bmppixel[0] = ((val & 0x1f) << 3) | ((val & 0x1f) >> 2);
|
||||||
|
bmppixel[1] = ((val & 0x3e0) >> 2) | ((val & 0x3e0) >> 7);
|
||||||
|
bmppixel[2] = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB32_BIG:
|
||||||
|
case B_RGBA32_BIG:
|
||||||
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
|
bmppixel = bmpRowData + (i * 3);
|
||||||
|
bmppixel[0] = bitspixel[3];
|
||||||
|
bmppixel[1] = bitspixel[2];
|
||||||
|
bmppixel[2] = bitspixel[1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB24_BIG:
|
||||||
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
|
bmppixel = bmpRowData + (i * 3);
|
||||||
|
bmppixel[0] = bitspixel[2];
|
||||||
|
bmppixel[1] = bitspixel[1];
|
||||||
|
bmppixel[2] = bitspixel[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_CMYK32:
|
||||||
|
{
|
||||||
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
|
bmppixel = bmpRowData + (i * 3);
|
||||||
|
|
||||||
|
int32 comp = 255 - bitspixel[2] - bitspixel[3];
|
||||||
|
bmppixel[0] = (comp < 0) ? 0 : comp;
|
||||||
|
|
||||||
|
comp = 255 - bitspixel[1] - bitspixel[3];
|
||||||
|
bmppixel[1] = (comp < 0) ? 0 : comp;
|
||||||
|
|
||||||
|
comp = 255 - bitspixel[0] - bitspixel[3];
|
||||||
|
bmppixel[2] = (comp < 0) ? 0 : comp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_CMY32:
|
||||||
|
case B_CMYA32:
|
||||||
|
case B_CMY24:
|
||||||
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
|
bmppixel = bmpRowData + (i * 3);
|
||||||
|
bmppixel[0] = 255 - bitspixel[2];
|
||||||
|
bmppixel[1] = 255 - bitspixel[1];
|
||||||
|
bmppixel[2] = 255 - bitspixel[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} // switch (fromspace)
|
||||||
|
} // for for (uint32 i = 0; i < infoHeader.width; i++)
|
||||||
|
|
||||||
|
outDestination->Write(bmpRowData, bmpRowBytes);
|
||||||
|
bmppixrow++;
|
||||||
|
// if I've read all of the pixel data, break
|
||||||
|
// out of the loop so I don't try to read
|
||||||
|
// non-pixel data
|
||||||
|
if (bmppixrow == infoHeader.height)
|
||||||
|
break;
|
||||||
|
|
||||||
|
inSource->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
||||||
|
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
|
} // while (rd == bitsRowBytes)
|
||||||
|
|
||||||
|
delete[] bmpRowData;
|
||||||
|
delete[] bitsRowData;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
||||||
char *read, uint32 outType, BPositionIO *outDestination)
|
uint8 *read, uint32 outType, BPositionIO *outDestination)
|
||||||
{
|
{
|
||||||
TranslatorBitmap bitsHeader;
|
TranslatorBitmap bitsHeader;
|
||||||
|
|
||||||
@@ -282,7 +453,7 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
// copy portion of bitsHeader already read in
|
// copy portion of bitsHeader already read in
|
||||||
// read in the rest of the bitsHeader
|
// read in the rest of the bitsHeader
|
||||||
ssize_t size = sizeof(TranslatorBitmap) - amtread;
|
ssize_t size = sizeof(TranslatorBitmap) - amtread;
|
||||||
if (inSource->Read(((char *) &bitsHeader) + amtread, size) != size)
|
if (inSource->Read(((uint8 *) &bitsHeader) + amtread, size) != size)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
// convert to host byte order
|
// convert to host byte order
|
||||||
@@ -292,14 +463,24 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
|
|
||||||
// check if bitsHeader values are reasonable
|
// check if bitsHeader values are reasonable
|
||||||
if (bitsHeader.colors != B_RGB32 &&
|
if (bitsHeader.colors != B_RGB32 &&
|
||||||
|
bitsHeader.colors != B_RGB32_BIG &&
|
||||||
bitsHeader.colors != B_RGBA32 &&
|
bitsHeader.colors != B_RGBA32 &&
|
||||||
|
bitsHeader.colors != B_RGBA32_BIG &&
|
||||||
bitsHeader.colors != B_RGB24 &&
|
bitsHeader.colors != B_RGB24 &&
|
||||||
|
bitsHeader.colors != B_RGB24_BIG &&
|
||||||
bitsHeader.colors != B_RGB16 &&
|
bitsHeader.colors != B_RGB16 &&
|
||||||
|
bitsHeader.colors != B_RGB16_BIG &&
|
||||||
bitsHeader.colors != B_RGB15 &&
|
bitsHeader.colors != B_RGB15 &&
|
||||||
|
bitsHeader.colors != B_RGB15_BIG &&
|
||||||
bitsHeader.colors != B_RGBA15 &&
|
bitsHeader.colors != B_RGBA15 &&
|
||||||
|
bitsHeader.colors != B_RGBA15_BIG &&
|
||||||
bitsHeader.colors != B_CMAP8 &&
|
bitsHeader.colors != B_CMAP8 &&
|
||||||
bitsHeader.colors != B_GRAY8 &&
|
bitsHeader.colors != B_GRAY8 &&
|
||||||
bitsHeader.colors != B_GRAY1)
|
bitsHeader.colors != B_GRAY1 &&
|
||||||
|
bitsHeader.colors != B_CMYK32 &&
|
||||||
|
bitsHeader.colors != B_CMY32 &&
|
||||||
|
bitsHeader.colors != B_CMYA32 &&
|
||||||
|
bitsHeader.colors != B_CMY24)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
if (bitsHeader.rowBytes * (bitsHeader.bounds.Height() + 1) >
|
if (bitsHeader.rowBytes * (bitsHeader.bounds.Height() + 1) >
|
||||||
bitsHeader.dataSize)
|
bitsHeader.dataSize)
|
||||||
@@ -315,7 +496,7 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
sizeof(TranslatorBitmap)) != sizeof(TranslatorBitmap))
|
sizeof(TranslatorBitmap)) != sizeof(TranslatorBitmap))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
char buf[1024];
|
uint8 buf[1024];
|
||||||
ssize_t rd = inSource->Read(buf, 1024);
|
ssize_t rd = inSource->Read(buf, 1024);
|
||||||
while (rd > 0) {
|
while (rd > 0) {
|
||||||
outDestination->Write(buf, rd);
|
outDestination->Write(buf, rd);
|
||||||
@@ -349,8 +530,21 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
// determine fileSize / imagesize
|
// determine fileSize / imagesize
|
||||||
switch (bitsHeader.colors) {
|
switch (bitsHeader.colors) {
|
||||||
case B_RGB32:
|
case B_RGB32:
|
||||||
|
case B_RGB32_BIG:
|
||||||
case B_RGBA32:
|
case B_RGBA32:
|
||||||
|
case B_RGBA32_BIG:
|
||||||
case B_RGB24:
|
case B_RGB24:
|
||||||
|
case B_RGB24_BIG:
|
||||||
|
case B_RGB16:
|
||||||
|
case B_RGB16_BIG:
|
||||||
|
case B_RGB15:
|
||||||
|
case B_RGB15_BIG:
|
||||||
|
case B_RGBA15:
|
||||||
|
case B_RGBA15_BIG:
|
||||||
|
case B_CMYK32:
|
||||||
|
case B_CMY32:
|
||||||
|
case B_CMYA32:
|
||||||
|
case B_CMY24:
|
||||||
|
|
||||||
infoHeader.bitsperpixel = 24;
|
infoHeader.bitsperpixel = 24;
|
||||||
infoHeader.compression = BMP_NO_COMPRESS;
|
infoHeader.compression = BMP_NO_COMPRESS;
|
||||||
@@ -369,7 +563,7 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write out the BMP headers
|
// write out the BMP headers
|
||||||
char bmpheaders[54];
|
uint8 bmpheaders[54];
|
||||||
memcpy(bmpheaders, &fileHeader.magic, sizeof(uint16));
|
memcpy(bmpheaders, &fileHeader.magic, sizeof(uint16));
|
||||||
memcpy(bmpheaders + 2, &fileHeader.fileSize, sizeof(uint32));
|
memcpy(bmpheaders + 2, &fileHeader.fileSize, sizeof(uint32));
|
||||||
memcpy(bmpheaders + 6, &fileHeader.reserved, sizeof(uint32));
|
memcpy(bmpheaders + 6, &fileHeader.reserved, sizeof(uint32));
|
||||||
@@ -388,52 +582,37 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// write out the BMP pixel data
|
// write out the BMP pixel data
|
||||||
char *bmppixels = new char[infoHeader.imagesize];
|
|
||||||
if (!bmppixels)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
switch (bitsHeader.colors) {
|
switch (bitsHeader.colors) {
|
||||||
case B_RGB32:
|
case B_RGB32:
|
||||||
char bitspixel[4];
|
case B_RGB32_BIG:
|
||||||
int32 bytesperline = (infoHeader.width * 3) + padding;
|
case B_RGBA32:
|
||||||
int32 bitspixoffset = 0;
|
case B_RGBA32_BIG:
|
||||||
ssize_t bitsoffset = 0;
|
case B_RGB24:
|
||||||
ssize_t rd = inSource->Read(bitspixel, 4);
|
case B_RGB24_BIG:
|
||||||
while (rd > 0) {
|
case B_RGB16:
|
||||||
int32 bmpoffset = ((infoHeader.height -
|
case B_RGB16_BIG:
|
||||||
((bitsoffset / bitsHeader.rowBytes) + 1)) *
|
case B_RGB15:
|
||||||
bytesperline) + (bitspixoffset * 3);
|
case B_RGB15_BIG:
|
||||||
memcpy(bmppixels + bmpoffset, bitspixel, 3);
|
case B_RGBA15:
|
||||||
|
case B_RGBA15_BIG:
|
||||||
|
case B_CMYK32:
|
||||||
|
case B_CMY32:
|
||||||
|
case B_CMYA32:
|
||||||
|
case B_CMY24:
|
||||||
|
translate_from_bits32_to_bmp(inSource, outDestination,
|
||||||
|
bitsHeader.colors, infoHeader);
|
||||||
|
break;
|
||||||
|
|
||||||
bitspixoffset++;
|
default:
|
||||||
bitsoffset += rd;
|
|
||||||
if (!(bitsoffset % bitsHeader.rowBytes)) {
|
|
||||||
bitspixoffset = 0;
|
|
||||||
// put padding at the end of the line
|
|
||||||
if (padding) {
|
|
||||||
char chpadding[4] = { 0, 0, 0, 0 };
|
|
||||||
memcpy(bmppixels + bmpoffset + 3, chpadding,
|
|
||||||
padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
// after I've read the entire bitmap, make sure to bail
|
|
||||||
if (bitsoffset / bitsHeader.rowBytes ==
|
|
||||||
infoHeader.height)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rd = inSource->Read(bitspixel, 4);
|
|
||||||
}
|
|
||||||
outDestination->Write(bmppixels, infoHeader.imagesize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] bmppixels;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
} else
|
} else
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for converting uncompressed BMP images with no palette to the Be Bitmap format
|
||||||
status_t translate_from_bmpnpal_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
status_t translate_from_bmpnpal_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
||||||
int32 datasize, BMPInfoHeader &infoHeader)
|
int32 datasize, BMPInfoHeader &infoHeader)
|
||||||
{
|
{
|
||||||
@@ -446,10 +625,10 @@ status_t translate_from_bmpnpal_to_bits(BPositionIO *inSource, BPositionIO *outD
|
|||||||
uint32 bmppixrow = 0;
|
uint32 bmppixrow = 0;
|
||||||
off_t bmpoffset = ((infoHeader.height - 1) * bmpRowBytes);
|
off_t bmpoffset = ((infoHeader.height - 1) * bmpRowBytes);
|
||||||
inSource->Seek(bmpoffset, SEEK_CUR);
|
inSource->Seek(bmpoffset, SEEK_CUR);
|
||||||
char *bmpRowData = new char[bmpRowBytes];
|
uint8 *bmpRowData = new uint8[bmpRowBytes];
|
||||||
if (!bmpRowData)
|
if (!bmpRowData)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
char *bitsRowData = new char[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -479,334 +658,15 @@ status_t translate_from_bmpnpal_to_bits(BPositionIO *inSource, BPositionIO *outD
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t translate_from_bmp8r_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
// for converting palette-based uncompressed BMP images to the Be Bitmap format
|
||||||
int32 datasize, BMPInfoHeader &infoHeader, const char *palette)
|
|
||||||
{
|
|
||||||
uint8 count, index;
|
|
||||||
char *bitspixels = new char[datasize];
|
|
||||||
if (!bitspixels)
|
|
||||||
return B_ERROR;
|
|
||||||
memset(bitspixels, 0xffffffff, datasize);
|
|
||||||
|
|
||||||
int32 bitsRowBytes = infoHeader.width * 4;
|
|
||||||
uint32 bmppixcol = 0, bmppixrow = 0;
|
|
||||||
int32 bitsoffset = 0;
|
|
||||||
ssize_t rd = inSource->Read(&count, 1);
|
|
||||||
while (rd > 0) {
|
|
||||||
// repeated color
|
|
||||||
if (count) {
|
|
||||||
rd = inSource->Read(&index, 1);
|
|
||||||
if (rd != 1)
|
|
||||||
break;
|
|
||||||
for (uint8 i = 0; i < count; i++) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) * bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette + (index * 4), 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
// special code
|
|
||||||
} else {
|
|
||||||
uint8 code;
|
|
||||||
rd = inSource->Read(&code, 1);
|
|
||||||
if (rd != 1)
|
|
||||||
break;
|
|
||||||
switch (code) {
|
|
||||||
case 0:
|
|
||||||
// end of line
|
|
||||||
// if there are columns remaing on this
|
|
||||||
// line, set them to the color at index zero
|
|
||||||
while (bmppixcol != infoHeader.width) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// end of bitmap
|
|
||||||
if (bmppixcol == infoHeader.width) {
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bmppixrow < infoHeader.height) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
|
|
||||||
if (bmppixcol == infoHeader.width) {
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rd = 0;
|
|
||||||
// break out of while loop
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
// delta, wierd feature
|
|
||||||
uint8 x, dx, dy;
|
|
||||||
inSource->Read(&dx, 1);
|
|
||||||
inSource->Read(&dy, 1);
|
|
||||||
|
|
||||||
x = bmppixcol;
|
|
||||||
|
|
||||||
// set all pixels to the first entry in
|
|
||||||
// the palette, for the number of rows skipped
|
|
||||||
while (dy > 0) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
|
|
||||||
if (bmppixcol == infoHeader.width) {
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
dy--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get to the same column as where we started
|
|
||||||
while (x != bmppixcol) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// move over dx pixels
|
|
||||||
for (uint8 i = 0; i < dx; i++) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// code >= 3
|
|
||||||
default:
|
|
||||||
// read code uncompressed pixels
|
|
||||||
for (uint8 i = 0; i < code; i++) {
|
|
||||||
rd = inSource->Read(&index, 1);
|
|
||||||
if (rd != 1)
|
|
||||||
break;
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset,
|
|
||||||
palette + (index * 4), 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
// if odd number, there is junk padding
|
|
||||||
if (code % 2)
|
|
||||||
rd = inSource->Seek(1, SEEK_CUR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rd > 0)
|
|
||||||
rd = inSource->Read(&count, 1);
|
|
||||||
}
|
|
||||||
outDestination->Write(bitspixels, datasize);
|
|
||||||
|
|
||||||
delete[] bitspixels;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t translate_from_bmp4r_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
|
||||||
int32 datasize, BMPInfoHeader &infoHeader, const char *palette)
|
|
||||||
{
|
|
||||||
uint8 count, indices, index;
|
|
||||||
char *bitspixels = new char[datasize];
|
|
||||||
if (!bitspixels)
|
|
||||||
return B_ERROR;
|
|
||||||
memset(bitspixels, 0xffffffff, datasize);
|
|
||||||
|
|
||||||
int32 bitsRowBytes = infoHeader.width * 4;
|
|
||||||
uint32 bmppixcol = 0, bmppixrow = 0;
|
|
||||||
int32 bitsoffset = 0;
|
|
||||||
ssize_t rd = inSource->Read(&count, 1);
|
|
||||||
while (rd > 0) {
|
|
||||||
// repeated color
|
|
||||||
if (count) {
|
|
||||||
rd = inSource->Read(&indices, 1);
|
|
||||||
if (rd != 1)
|
|
||||||
break;
|
|
||||||
for (uint8 i = 0; i < count; i++) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) * bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
if (!(i % 2))
|
|
||||||
index = (indices>>4) & 0xf;
|
|
||||||
else
|
|
||||||
index = indices & 0xf;
|
|
||||||
memcpy(bitspixels + bitsoffset, palette + (index * 4), 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
// special code
|
|
||||||
} else {
|
|
||||||
uint8 code;
|
|
||||||
rd = inSource->Read(&code, 1);
|
|
||||||
if (rd != 1)
|
|
||||||
break;
|
|
||||||
switch (code) {
|
|
||||||
case 0:
|
|
||||||
// end of line
|
|
||||||
// if there are columns remaing on this
|
|
||||||
// line, set them to the color at index zero
|
|
||||||
while (bmppixcol != infoHeader.width) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// end of bitmap
|
|
||||||
if (bmppixcol == infoHeader.width) {
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bmppixrow < infoHeader.height) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
|
|
||||||
if (bmppixcol == infoHeader.width) {
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rd = 0;
|
|
||||||
// break out of while loop
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
// delta, wierd feature
|
|
||||||
uint8 x, dx, dy;
|
|
||||||
inSource->Read(&dx, 1);
|
|
||||||
inSource->Read(&dy, 1);
|
|
||||||
|
|
||||||
x = bmppixcol;
|
|
||||||
|
|
||||||
// set all pixels to the first entry in
|
|
||||||
// the palette, for the number of rows skipped
|
|
||||||
while (dy > 0) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
|
|
||||||
if (bmppixcol == infoHeader.width) {
|
|
||||||
bmppixcol = 0;
|
|
||||||
bmppixrow++;
|
|
||||||
dy--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get to the same column as where we started
|
|
||||||
while (x != bmppixcol) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// move over dx pixels
|
|
||||||
for (uint8 i = 0; i < dx; i++) {
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
memcpy(bitspixels + bitsoffset, palette, 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// code >= 3
|
|
||||||
default:
|
|
||||||
// read code uncompressed pixels
|
|
||||||
for (uint8 i = 0; i < code; i++) {
|
|
||||||
if (!(i % 2)) {
|
|
||||||
rd = inSource->Read(&indices, 1);
|
|
||||||
if (rd != 1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bitsoffset = ((infoHeader.height -
|
|
||||||
(bmppixrow + 1)) *
|
|
||||||
bitsRowBytes) +
|
|
||||||
(bmppixcol * 4);
|
|
||||||
if (!(i % 2))
|
|
||||||
index = (indices>>4) & 0xf;
|
|
||||||
else
|
|
||||||
index = indices & 0xf;
|
|
||||||
memcpy(bitspixels + bitsoffset,
|
|
||||||
palette + (index * 4), 3);
|
|
||||||
bmppixcol++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 padding;
|
|
||||||
padding = (((code + (code % 2)) / 2) % 2);
|
|
||||||
// if odd number, there is junk padding
|
|
||||||
if (padding)
|
|
||||||
inSource->Seek(padding, SEEK_CUR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rd > 0)
|
|
||||||
rd = inSource->Read(&count, 1);
|
|
||||||
}
|
|
||||||
outDestination->Write(bitspixels, datasize);
|
|
||||||
|
|
||||||
delete[] bitspixels;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t translate_from_bmppal_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
status_t translate_from_bmppal_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
||||||
int32 datasize, BMPInfoHeader &infoHeader, const char *palette)
|
int32 datasize, BMPInfoHeader &infoHeader, const uint8 *palette)
|
||||||
{
|
{
|
||||||
uint16 pixelsPerByte = 8 / infoHeader.bitsperpixel;
|
uint16 pixelsPerByte = 8 / infoHeader.bitsperpixel;
|
||||||
uint16 bitsPerPixel = infoHeader.bitsperpixel;
|
uint16 bitsPerPixel = infoHeader.bitsperpixel;
|
||||||
|
|
||||||
uint8 mask = 1;
|
uint8 mask = 1;
|
||||||
for (uint16 i = 0; i < bitsPerPixel; i++)
|
mask = (mask << bitsPerPixel) - 1;
|
||||||
mask *= 2;
|
|
||||||
mask -= 1;
|
|
||||||
|
|
||||||
int32 padding;
|
int32 padding;
|
||||||
if (!(infoHeader.width % pixelsPerByte))
|
if (!(infoHeader.width % pixelsPerByte))
|
||||||
@@ -823,11 +683,11 @@ status_t translate_from_bmppal_to_bits(BPositionIO *inSource, BPositionIO *outDe
|
|||||||
|
|
||||||
off_t bmpoffset = ((infoHeader.height - 1) * bmpRowBytes);
|
off_t bmpoffset = ((infoHeader.height - 1) * bmpRowBytes);
|
||||||
inSource->Seek(bmpoffset, SEEK_CUR);
|
inSource->Seek(bmpoffset, SEEK_CUR);
|
||||||
char *bmpRowData = new char[bmpRowBytes];
|
uint8 *bmpRowData = new uint8[bmpRowBytes];
|
||||||
if (!bmpRowData)
|
if (!bmpRowData)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
int32 bitsRowBytes = infoHeader.width * 4;
|
int32 bitsRowBytes = infoHeader.width * 4;
|
||||||
char *bitsRowData = new char[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -862,10 +722,182 @@ status_t translate_from_bmppal_to_bits(BPositionIO *inSource, BPositionIO *outDe
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
// for converting palette-based RLE BMP images to the Be Bitmap format
|
||||||
char *read, uint32 outType, BPositionIO *outDestination)
|
status_t translate_from_bmppalr_to_bits(BPositionIO *inSource, BPositionIO *outDestination,
|
||||||
|
int32 datasize, BMPInfoHeader &infoHeader, const uint8 *palette)
|
||||||
{
|
{
|
||||||
char buf[40];
|
uint16 pixelsPerByte = 8 / infoHeader.bitsperpixel;
|
||||||
|
uint16 bitsPerPixel = infoHeader.bitsperpixel;
|
||||||
|
uint8 mask = 1;
|
||||||
|
mask = (mask << bitsPerPixel) - 1;
|
||||||
|
|
||||||
|
uint8 count, indices, index;
|
||||||
|
uint8 *bitspixels = new uint8[datasize];
|
||||||
|
if (!bitspixels)
|
||||||
|
return B_ERROR;
|
||||||
|
memset(bitspixels, 0xffffffff, datasize);
|
||||||
|
|
||||||
|
int32 bitsRowBytes = infoHeader.width * 4;
|
||||||
|
uint32 bmppixcol = 0, bmppixrow = 0;
|
||||||
|
int32 bitsoffset = 0;
|
||||||
|
ssize_t rd = inSource->Read(&count, 1);
|
||||||
|
while (rd > 0) {
|
||||||
|
// repeated color
|
||||||
|
if (count) {
|
||||||
|
rd = inSource->Read(&indices, 1);
|
||||||
|
if (rd != 1)
|
||||||
|
break;
|
||||||
|
for (uint8 i = 0; i < count; i++) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) * bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
index = (indices >> (bitsPerPixel * ((pixelsPerByte - 1) - (i % pixelsPerByte)))) & mask;
|
||||||
|
memcpy(bitspixels + bitsoffset, palette + (index * 4), 3);
|
||||||
|
bmppixcol++;
|
||||||
|
}
|
||||||
|
// special code
|
||||||
|
} else {
|
||||||
|
uint8 code;
|
||||||
|
rd = inSource->Read(&code, 1);
|
||||||
|
if (rd != 1)
|
||||||
|
break;
|
||||||
|
switch (code) {
|
||||||
|
case 0:
|
||||||
|
// end of line
|
||||||
|
// if there are columns remaing on this
|
||||||
|
// line, set them to the color at index zero
|
||||||
|
while (bmppixcol != infoHeader.width) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) *
|
||||||
|
bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
memcpy(bitspixels + bitsoffset, palette, 3);
|
||||||
|
bmppixcol++;
|
||||||
|
}
|
||||||
|
bmppixcol = 0;
|
||||||
|
bmppixrow++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// end of bitmap
|
||||||
|
if (bmppixcol == infoHeader.width) {
|
||||||
|
bmppixcol = 0;
|
||||||
|
bmppixrow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bmppixrow < infoHeader.height) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) *
|
||||||
|
bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
memcpy(bitspixels + bitsoffset, palette, 3);
|
||||||
|
bmppixcol++;
|
||||||
|
|
||||||
|
if (bmppixcol == infoHeader.width) {
|
||||||
|
bmppixcol = 0;
|
||||||
|
bmppixrow++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rd = 0;
|
||||||
|
// break out of while loop
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// delta, wierd feature
|
||||||
|
uint8 x, dx, dy;
|
||||||
|
inSource->Read(&dx, 1);
|
||||||
|
inSource->Read(&dy, 1);
|
||||||
|
|
||||||
|
x = bmppixcol;
|
||||||
|
|
||||||
|
// set all pixels to the first entry in
|
||||||
|
// the palette, for the number of rows skipped
|
||||||
|
while (dy > 0) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) *
|
||||||
|
bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
memcpy(bitspixels + bitsoffset, palette, 3);
|
||||||
|
bmppixcol++;
|
||||||
|
|
||||||
|
if (bmppixcol == infoHeader.width) {
|
||||||
|
bmppixcol = 0;
|
||||||
|
bmppixrow++;
|
||||||
|
dy--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get to the same column as where we started
|
||||||
|
while (x != bmppixcol) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) *
|
||||||
|
bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
memcpy(bitspixels + bitsoffset, palette, 3);
|
||||||
|
bmppixcol++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move over dx pixels
|
||||||
|
for (uint8 i = 0; i < dx; i++) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) *
|
||||||
|
bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
memcpy(bitspixels + bitsoffset, palette, 3);
|
||||||
|
bmppixcol++;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// code >= 3
|
||||||
|
default:
|
||||||
|
// read code uncompressed indices
|
||||||
|
uint8 uncomp[256];
|
||||||
|
int32 padding;
|
||||||
|
if (!(code % pixelsPerByte))
|
||||||
|
padding = (code / pixelsPerByte) % 2;
|
||||||
|
else
|
||||||
|
padding = ((code + pixelsPerByte -
|
||||||
|
(code % pixelsPerByte)) / pixelsPerByte) % 2;
|
||||||
|
int32 uncompBytes = (code / pixelsPerByte) +
|
||||||
|
((code % pixelsPerByte) ? 1 : 0) + padding;
|
||||||
|
rd = inSource->Read(uncomp, uncompBytes);
|
||||||
|
if (rd != uncompBytes) {
|
||||||
|
rd = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (uint8 i = 0; i < code; i++) {
|
||||||
|
bitsoffset = ((infoHeader.height -
|
||||||
|
(bmppixrow + 1)) *
|
||||||
|
bitsRowBytes) +
|
||||||
|
(bmppixcol * 4);
|
||||||
|
indices = (uncomp + (i / pixelsPerByte))[0];
|
||||||
|
index = (indices >>
|
||||||
|
(bitsPerPixel * ((pixelsPerByte - 1) - (i % pixelsPerByte)))) & mask;
|
||||||
|
memcpy(bitspixels + bitsoffset,
|
||||||
|
palette + (index * 4), 3);
|
||||||
|
bmppixcol++;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rd > 0)
|
||||||
|
rd = inSource->Read(&count, 1);
|
||||||
|
}
|
||||||
|
outDestination->Write(bitspixels, datasize);
|
||||||
|
|
||||||
|
delete[] bitspixels;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
||||||
|
uint8 *read, uint32 outType, BPositionIO *outDestination)
|
||||||
|
{
|
||||||
|
uint8 buf[40];
|
||||||
BMPFileHeader fileHeader;
|
BMPFileHeader fileHeader;
|
||||||
|
|
||||||
memcpy(buf, read, amtread);
|
memcpy(buf, read, amtread);
|
||||||
@@ -883,7 +915,7 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
if (swap_data(B_UINT16_TYPE, &fileHeader.magic, 2,
|
if (swap_data(B_UINT16_TYPE, &fileHeader.magic, 2,
|
||||||
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
if (swap_data(B_UINT32_TYPE, ((char *) &fileHeader) + 2, 12,
|
if (swap_data(B_UINT32_TYPE, ((uint8 *) &fileHeader) + 2, 12,
|
||||||
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -919,12 +951,12 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
if (swap_data(B_UINT16_TYPE, &fileHeader.magic, sizeof(uint16),
|
if (swap_data(B_UINT16_TYPE, &fileHeader.magic, sizeof(uint16),
|
||||||
B_SWAP_HOST_TO_LENDIAN) != B_OK)
|
B_SWAP_HOST_TO_LENDIAN) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
if (swap_data(B_UINT32_TYPE, ((char *) &fileHeader) + 2, 12,
|
if (swap_data(B_UINT32_TYPE, ((uint8 *) &fileHeader) + 2, 12,
|
||||||
B_SWAP_HOST_TO_LENDIAN) != B_OK)
|
B_SWAP_HOST_TO_LENDIAN) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
if (outDestination->Write(&fileHeader.magic, 2) != 2)
|
if (outDestination->Write(&fileHeader.magic, 2) != 2)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
if (outDestination->Write(((char *) &fileHeader) + 2, 12) != 12)
|
if (outDestination->Write(((uint8 *) &fileHeader) + 2, 12) != 12)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// write out infoHeader
|
// write out infoHeader
|
||||||
@@ -935,7 +967,7 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
sizeof(BMPInfoHeader))
|
sizeof(BMPInfoHeader))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
char buf[1024];
|
uint8 buf[1024];
|
||||||
ssize_t rd = inSource->Read(buf, 1024);
|
ssize_t rd = inSource->Read(buf, 1024);
|
||||||
while (rd > 0) {
|
while (rd > 0) {
|
||||||
outDestination->Write(buf, rd);
|
outDestination->Write(buf, rd);
|
||||||
@@ -957,7 +989,7 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
bitsHeader.bounds.bottom = infoHeader.height - 1;
|
bitsHeader.bounds.bottom = infoHeader.height - 1;
|
||||||
|
|
||||||
// read in palette and/or skip non-BMP data
|
// read in palette and/or skip non-BMP data
|
||||||
char bmppalette[1024];
|
uint8 bmppalette[1024];
|
||||||
off_t nskip = 0;
|
off_t nskip = 0;
|
||||||
if (infoHeader.bitsperpixel == 1 ||
|
if (infoHeader.bitsperpixel == 1 ||
|
||||||
infoHeader.bitsperpixel == 4 ||
|
infoHeader.bitsperpixel == 4 ||
|
||||||
@@ -965,8 +997,7 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
|
|
||||||
if (!infoHeader.colorsused) {
|
if (!infoHeader.colorsused) {
|
||||||
infoHeader.colorsused = 1;
|
infoHeader.colorsused = 1;
|
||||||
for (int npow = 0; npow < infoHeader.bitsperpixel; npow++)
|
infoHeader.colorsused <<= infoHeader.bitsperpixel;
|
||||||
infoHeader.colorsused *= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inSource->Read(bmppalette, infoHeader.colorsused * 4) !=
|
if (inSource->Read(bmppalette, infoHeader.colorsused * 4) !=
|
||||||
@@ -1008,7 +1039,7 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
|
|
||||||
// 8 bit RLE compressed BMP
|
// 8 bit RLE compressed BMP
|
||||||
else if (infoHeader.compression == BMP_RLE8_COMPRESS)
|
else if (infoHeader.compression == BMP_RLE8_COMPRESS)
|
||||||
return translate_from_bmp8r_to_bits(inSource,
|
return translate_from_bmppalr_to_bits(inSource,
|
||||||
outDestination, datasize, infoHeader, bmppalette);
|
outDestination, datasize, infoHeader, bmppalette);
|
||||||
else
|
else
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -1021,7 +1052,7 @@ status_t translate_from_bmp(BPositionIO *inSource, ssize_t amtread,
|
|||||||
|
|
||||||
// 4 bit RLE compressed BMP
|
// 4 bit RLE compressed BMP
|
||||||
else if (infoHeader.compression == BMP_RLE4_COMPRESS)
|
else if (infoHeader.compression == BMP_RLE4_COMPRESS)
|
||||||
return translate_from_bmp4r_to_bits(inSource,
|
return translate_from_bmppalr_to_bits(inSource,
|
||||||
outDestination, datasize, infoHeader, bmppalette);
|
outDestination, datasize, infoHeader, bmppalette);
|
||||||
else
|
else
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -1049,7 +1080,7 @@ status_t BMPTranslator::Translate(BPositionIO *inSource,
|
|||||||
|
|
||||||
inSource->Seek(0, SEEK_SET);
|
inSource->Seek(0, SEEK_SET);
|
||||||
|
|
||||||
char ch[4];
|
uint8 ch[4];
|
||||||
uint32 nbits = B_TRANSLATOR_BITMAP;
|
uint32 nbits = B_TRANSLATOR_BITMAP;
|
||||||
uint16 nbm = 'MB';
|
uint16 nbm = 'MB';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user