added support for converting 1-bit Be Bitmap files to 1-bit BMP files
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@450 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -52,7 +52,7 @@ translation_format gInputFormats[] = {
|
|||||||
BMP_QUALITY,
|
BMP_QUALITY,
|
||||||
BMP_CAPABILITY,
|
BMP_CAPABILITY,
|
||||||
"image/x-bmp",
|
"image/x-bmp",
|
||||||
"BMP image, MS format"
|
"BMP image"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ translation_format gOutputFormats[] = {
|
|||||||
BMP_QUALITY,
|
BMP_QUALITY,
|
||||||
BMP_CAPABILITY,
|
BMP_CAPABILITY,
|
||||||
"image/x-bmp",
|
"image/x-bmp",
|
||||||
"BMP image, MS format"
|
"BMP image"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ status_t BMPTranslator::Identify(BPositionIO *inSource,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for converting uncompressed BMP images with no palette to the Be Bitmap format
|
// for converting uncompressed BMP images with no palette to the Be Bitmap format
|
||||||
status_t translate_from_bits32_to_bmp(BPositionIO *inSource, BPositionIO *outDestination,
|
status_t translate_from_bits_to_bmp24(BPositionIO *inSource, BPositionIO *outDestination,
|
||||||
color_space fromspace, BMPInfoHeader &infoHeader)
|
color_space fromspace, BMPInfoHeader &infoHeader)
|
||||||
{
|
{
|
||||||
int32 bitsBytesPerPixel = 0;
|
int32 bitsBytesPerPixel = 0;
|
||||||
@@ -372,7 +372,7 @@ status_t translate_from_bits32_to_bmp(BPositionIO *inSource, BPositionIO *outDes
|
|||||||
case B_RGB15_BIG:
|
case B_RGB15_BIG:
|
||||||
case B_RGBA15:
|
case B_RGBA15:
|
||||||
case B_RGBA15_BIG:
|
case B_RGBA15_BIG:
|
||||||
// NOTE: the alpha data for B_RGBA15 is ignored and discarded
|
// NOTE: the alpha data for B_RGBA15* is ignored and discarded
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
||||||
bmppixel = bmpRowData + (i * 3);
|
bmppixel = bmpRowData + (i * 3);
|
||||||
if (fromspace == B_RGB15 || fromspace == B_RGBA15)
|
if (fromspace == B_RGB15 || fromspace == B_RGBA15)
|
||||||
@@ -467,6 +467,67 @@ status_t translate_from_bits32_to_bmp(BPositionIO *inSource, BPositionIO *outDes
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for converting uncompressed BMP images with no palette to the Be Bitmap format
|
||||||
|
status_t translate_from_bits1_to_bmp(BPositionIO *inSource, BPositionIO *outDestination,
|
||||||
|
int32 bitsRowBytes, BMPInfoHeader &infoHeader)
|
||||||
|
{
|
||||||
|
uint16 pixelsPerByte = 8 / infoHeader.bitsperpixel;
|
||||||
|
int32 padding;
|
||||||
|
if (!(infoHeader.width % pixelsPerByte))
|
||||||
|
padding = (infoHeader.width / pixelsPerByte) % 4;
|
||||||
|
else
|
||||||
|
padding = ((infoHeader.width + pixelsPerByte -
|
||||||
|
(infoHeader.width % pixelsPerByte)) / pixelsPerByte) % 4;
|
||||||
|
if (padding)
|
||||||
|
padding = 4 - padding;
|
||||||
|
int32 bmpRowBytes = (infoHeader.width / pixelsPerByte) +
|
||||||
|
((infoHeader.width % pixelsPerByte) ? 1 : 0) + 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;
|
||||||
|
}
|
||||||
|
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
|
while (rd == bitsRowBytes) {
|
||||||
|
uint32 bmppixcol = 0;
|
||||||
|
memset(bmpRowData, 0, bmpRowBytes);
|
||||||
|
for (int32 i = 0; (bmppixcol < infoHeader.width) && (i < bitsRowBytes); i++) {
|
||||||
|
// process each byte in the row
|
||||||
|
uint8 pixels = bitsRowData[i];
|
||||||
|
for (uint8 compbit = 128; (bmppixcol < infoHeader.width) && compbit; compbit >>= 1) {
|
||||||
|
// for each bit in the current byte, convert to a BMP palette index and
|
||||||
|
// store that in the bmpRowData
|
||||||
|
uint8 index = pixels & compbit;
|
||||||
|
// 1 == black, 0 == white
|
||||||
|
bmpRowData[bmppixcol / pixelsPerByte] |= index << (7 - (bmppixcol % pixelsPerByte));
|
||||||
|
bmppixcol++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
uint8 *read, uint32 outType, BPositionIO *outDestination)
|
uint8 *read, uint32 outType, BPositionIO *outDestination)
|
||||||
{
|
{
|
||||||
@@ -537,7 +598,6 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
BMPFileHeader fileHeader;
|
BMPFileHeader fileHeader;
|
||||||
fileHeader.magic = 'MB';
|
fileHeader.magic = 'MB';
|
||||||
fileHeader.reserved = 0;
|
fileHeader.reserved = 0;
|
||||||
fileHeader.dataOffset = 54;
|
|
||||||
|
|
||||||
BMPInfoHeader infoHeader;
|
BMPInfoHeader infoHeader;
|
||||||
infoHeader.size = 40;
|
infoHeader.size = 40;
|
||||||
@@ -570,7 +630,8 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
case B_CMY32:
|
case B_CMY32:
|
||||||
case B_CMYA32:
|
case B_CMYA32:
|
||||||
case B_CMY24:
|
case B_CMY24:
|
||||||
|
|
||||||
|
fileHeader.dataOffset = 54;
|
||||||
infoHeader.bitsperpixel = 24;
|
infoHeader.bitsperpixel = 24;
|
||||||
infoHeader.compression = BMP_NO_COMPRESS;
|
infoHeader.compression = BMP_NO_COMPRESS;
|
||||||
padding = (infoHeader.width * 3) % 4;
|
padding = (infoHeader.width * 3) % 4;
|
||||||
@@ -583,6 +644,25 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case B_GRAY1:
|
||||||
|
|
||||||
|
fileHeader.dataOffset = 62;
|
||||||
|
infoHeader.bitsperpixel = 1;
|
||||||
|
infoHeader.compression = BMP_NO_COMPRESS;
|
||||||
|
if (!(infoHeader.width % 8))
|
||||||
|
padding = (infoHeader.width / 8) % 4;
|
||||||
|
else
|
||||||
|
padding = ((infoHeader.width + 8 -
|
||||||
|
(infoHeader.width % 8)) / 8) % 4;
|
||||||
|
if (padding)
|
||||||
|
padding = 4 - padding;
|
||||||
|
infoHeader.imagesize = ((infoHeader.width / 8) + ((infoHeader.width % 8) ? 1 : 0) + padding) *
|
||||||
|
infoHeader.height;
|
||||||
|
fileHeader.fileSize = fileHeader.dataOffset +
|
||||||
|
infoHeader.imagesize;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
}
|
}
|
||||||
@@ -626,15 +706,24 @@ status_t translate_from_bits(BPositionIO *inSource, ssize_t amtread,
|
|||||||
case B_CMY32:
|
case B_CMY32:
|
||||||
case B_CMYA32:
|
case B_CMYA32:
|
||||||
case B_CMY24:
|
case B_CMY24:
|
||||||
translate_from_bits32_to_bmp(inSource, outDestination,
|
return translate_from_bits_to_bmp24(inSource, outDestination,
|
||||||
bitsHeader.colors, infoHeader);
|
bitsHeader.colors, infoHeader);
|
||||||
break;
|
|
||||||
|
case B_GRAY1:
|
||||||
|
{
|
||||||
|
const uint32 monopal[] = { 0x00ffffff, 0x00000000 };
|
||||||
|
if (outDestination->Write(monopal, 8) != 8)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return translate_from_bits1_to_bmp(inSource, outDestination,
|
||||||
|
bitsHeader.rowBytes, infoHeader);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_NO_TRANSLATOR;
|
||||||
} else
|
} else
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user