added more checking for corrupt headers, reduced code redundancy, made a number of small tweaks
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3304 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c12232ddb5
commit
9edca8f79e
@ -256,6 +256,84 @@ BMPTranslator::OutputFormats(int32 *out_count) const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// get_padding
|
||||||
|
//
|
||||||
|
// Returns number of bytes of padding required at the end of
|
||||||
|
// the row by the BMP format
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Preconditions: If bitsperpixel is zero, a division by zero
|
||||||
|
// will occur, which is bad
|
||||||
|
//
|
||||||
|
// Parameters: width, width of the row, in pixels
|
||||||
|
//
|
||||||
|
// bitsperpixel, bitdepth of the image
|
||||||
|
//
|
||||||
|
// Postconditions:
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
int32
|
||||||
|
get_padding(uint32 width, uint16 bitsperpixel)
|
||||||
|
{
|
||||||
|
int32 padding = 0;
|
||||||
|
|
||||||
|
if (bitsperpixel > 8) {
|
||||||
|
uint8 bytesPerPixel = bitsperpixel / 8;
|
||||||
|
padding = (width * bytesPerPixel) % 4;
|
||||||
|
} else {
|
||||||
|
uint8 pixelsPerByte = 8 / bitsperpixel;
|
||||||
|
if (!(width % pixelsPerByte))
|
||||||
|
padding = (width / pixelsPerByte) % 4;
|
||||||
|
else
|
||||||
|
padding = ((width + pixelsPerByte -
|
||||||
|
(width % pixelsPerByte)) /
|
||||||
|
pixelsPerByte) % 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (padding)
|
||||||
|
padding = 4 - padding;
|
||||||
|
|
||||||
|
return padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// get_rowbytes
|
||||||
|
//
|
||||||
|
// Returns number of bytes required to store a row of BMP pixels
|
||||||
|
// with a width of width and a bit depth of bitsperpixel.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Preconditions: If bitsperpixel is zero, a division by zero
|
||||||
|
// will occur, which is bad
|
||||||
|
//
|
||||||
|
// Parameters: width, width of the row, in pixels
|
||||||
|
//
|
||||||
|
// bitsperpixel, bitdepth of the image
|
||||||
|
//
|
||||||
|
// Postconditions:
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
int32
|
||||||
|
get_rowbytes(uint32 width, uint16 bitsperpixel)
|
||||||
|
{
|
||||||
|
int32 rowbytes = 0;
|
||||||
|
int32 padding = get_padding(width, bitsperpixel);
|
||||||
|
|
||||||
|
if (bitsperpixel > 8) {
|
||||||
|
uint8 bytesPerPixel = bitsperpixel / 8;
|
||||||
|
rowbytes = (width * bytesPerPixel) + padding;
|
||||||
|
} else {
|
||||||
|
uint8 pixelsPerByte = 8 / bitsperpixel;
|
||||||
|
rowbytes = (width / pixelsPerByte) +
|
||||||
|
((width % pixelsPerByte) ? 1 : 0) + padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowbytes;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// identify_bits_header
|
// identify_bits_header
|
||||||
//
|
//
|
||||||
@ -427,6 +505,9 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
(reinterpret_cast<uint8 *> (&fileHeader)) + 2, 12,
|
(reinterpret_cast<uint8 *> (&fileHeader)) + 2, 12,
|
||||||
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
B_SWAP_LENDIAN_TO_HOST) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (fileHeader.reserved != 0)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
uint32 headersize = 0;
|
uint32 headersize = 0;
|
||||||
if (inSource->Read(&headersize, 4) != 4)
|
if (inSource->Read(&headersize, 4) != 4)
|
||||||
@ -437,6 +518,10 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
|
|
||||||
if (headersize == sizeof(MSInfoHeader)) {
|
if (headersize == sizeof(MSInfoHeader)) {
|
||||||
// MS format
|
// MS format
|
||||||
|
|
||||||
|
if (fileHeader.dataOffset < 54)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
MSInfoHeader msheader;
|
MSInfoHeader msheader;
|
||||||
msheader.size = headersize;
|
msheader.size = headersize;
|
||||||
if (inSource->Read(
|
if (inSource->Read(
|
||||||
@ -469,11 +554,29 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
(msheader.bitsperpixel != 32 ||
|
(msheader.bitsperpixel != 32 ||
|
||||||
msheader.compression != BMP_NO_COMPRESS))
|
msheader.compression != BMP_NO_COMPRESS))
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
if (msheader.imagesize == 0 && msheader.compression)
|
if (!msheader.imagesize && msheader.compression)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
if (msheader.imagesize && fileHeader.fileSize <
|
||||||
|
fileHeader.dataOffset + msheader.imagesize)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
if (msheader.colorsimportant > msheader.colorsused)
|
if (msheader.colorsimportant > msheader.colorsused)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
// If file is uncompressed, calculate the size of the
|
||||||
|
// actual image data and use that to determine if
|
||||||
|
// fileHeader.fileSize, fileHeader.dataOffset
|
||||||
|
// and msheader.imagesize are reasonable values
|
||||||
|
if (msheader.compression == BMP_NO_COMPRESS) {
|
||||||
|
uint32 imagesize = get_rowbytes(msheader.width,
|
||||||
|
msheader.bitsperpixel) * msheader.height;
|
||||||
|
if (msheader.imagesize && msheader.imagesize !=
|
||||||
|
imagesize)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
if (fileHeader.fileSize < fileHeader.dataOffset +
|
||||||
|
imagesize)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
}
|
||||||
|
|
||||||
if (outInfo) {
|
if (outInfo) {
|
||||||
outInfo->type = B_BMP_FORMAT;
|
outInfo->type = B_BMP_FORMAT;
|
||||||
outInfo->group = B_TRANSLATOR_BITMAP;
|
outInfo->group = B_TRANSLATOR_BITMAP;
|
||||||
@ -514,6 +617,10 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
|
|
||||||
} else if (headersize == sizeof(OS2InfoHeader)) {
|
} else if (headersize == sizeof(OS2InfoHeader)) {
|
||||||
// OS/2 format
|
// OS/2 format
|
||||||
|
|
||||||
|
if (fileHeader.dataOffset < 26)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
OS2InfoHeader os2header;
|
OS2InfoHeader os2header;
|
||||||
os2header.size = headersize;
|
os2header.size = headersize;
|
||||||
if (inSource->Read(
|
if (inSource->Read(
|
||||||
@ -536,6 +643,15 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
os2header.bitsperpixel != 8 &&
|
os2header.bitsperpixel != 8 &&
|
||||||
os2header.bitsperpixel != 24)
|
os2header.bitsperpixel != 24)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
// Calculate the size of the actual image data
|
||||||
|
// and use that to determine if
|
||||||
|
// fileHeader.fileSize and fileHeader.dataOffset
|
||||||
|
// are reasonable values
|
||||||
|
uint32 imagesize = get_rowbytes(os2header.width,
|
||||||
|
os2header.bitsperpixel) * os2header.height;
|
||||||
|
if (fileHeader.fileSize < fileHeader.dataOffset + imagesize)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
if (outInfo) {
|
if (outInfo) {
|
||||||
outInfo->type = B_BMP_FORMAT;
|
outInfo->type = B_BMP_FORMAT;
|
||||||
@ -564,27 +680,19 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
pmsheader->colorsused = 0;
|
pmsheader->colorsused = 0;
|
||||||
pmsheader->colorsimportant = 0;
|
pmsheader->colorsimportant = 0;
|
||||||
|
|
||||||
int32 padding = 0;
|
|
||||||
// determine fileSize / imagesize
|
// determine fileSize / imagesize
|
||||||
switch (pmsheader->bitsperpixel) {
|
switch (pmsheader->bitsperpixel) {
|
||||||
case 24:
|
case 24:
|
||||||
{
|
|
||||||
if (pos2skip && fileHeader.dataOffset > 26)
|
if (pos2skip && fileHeader.dataOffset > 26)
|
||||||
(*pos2skip) = fileHeader.dataOffset - 26;
|
(*pos2skip) = fileHeader.dataOffset - 26;
|
||||||
|
|
||||||
uint8 bytesPerPixel = pmsheader->bitsperpixel / 8;
|
|
||||||
pfileheader->dataOffset = 54;
|
pfileheader->dataOffset = 54;
|
||||||
padding = (pmsheader->width * bytesPerPixel) % 4;
|
pmsheader->imagesize = get_rowbytes(pmsheader->width,
|
||||||
if (padding)
|
pmsheader->bitsperpixel) * pmsheader->height;
|
||||||
padding = 4 - padding;
|
|
||||||
pmsheader->imagesize =
|
|
||||||
((pmsheader->width * bytesPerPixel) + padding) *
|
|
||||||
pmsheader->height;
|
|
||||||
pfileheader->fileSize = pfileheader->dataOffset +
|
pfileheader->fileSize = pfileheader->dataOffset +
|
||||||
pmsheader->imagesize;
|
pmsheader->imagesize;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
case 4:
|
case 4:
|
||||||
@ -598,20 +706,9 @@ identify_bmp_header(BPositionIO *inSource, translator_info *outInfo,
|
|||||||
(*pos2skip) = fileHeader.dataOffset -
|
(*pos2skip) = fileHeader.dataOffset -
|
||||||
(26 + (ncolors * 3));
|
(26 + (ncolors * 3));
|
||||||
|
|
||||||
uint8 pixelsPerByte = 8 / pmsheader->bitsperpixel;
|
|
||||||
pfileheader->dataOffset = 54 + (ncolors * 4);
|
pfileheader->dataOffset = 54 + (ncolors * 4);
|
||||||
if (!(pmsheader->width % pixelsPerByte))
|
pmsheader->imagesize = get_rowbytes(pmsheader->width,
|
||||||
padding = (pmsheader->width / pixelsPerByte) % 4;
|
pmsheader->bitsperpixel) * pmsheader->height;
|
||||||
else
|
|
||||||
padding = ((pmsheader->width + pixelsPerByte -
|
|
||||||
(pmsheader->width % pixelsPerByte)) /
|
|
||||||
pixelsPerByte) % 4;
|
|
||||||
if (padding)
|
|
||||||
padding = 4 - padding;
|
|
||||||
pmsheader->imagesize =
|
|
||||||
((pmsheader->width / pixelsPerByte) +
|
|
||||||
((pmsheader->width % pixelsPerByte) ? 1 : 0) +
|
|
||||||
padding) * pmsheader->height;
|
|
||||||
pfileheader->fileSize = pfileheader->dataOffset +
|
pfileheader->fileSize = pfileheader->dataOffset +
|
||||||
pmsheader->imagesize;
|
pmsheader->imagesize;
|
||||||
|
|
||||||
@ -789,11 +886,9 @@ BPositionIO *outDestination, color_space fromspace, MSInfoHeader &msheader)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
int32 bitsRowBytes = msheader.width * bitsBytesPerPixel;
|
int32 bitsRowBytes = msheader.width * bitsBytesPerPixel;
|
||||||
int32 bmpBytesPerPixel = msheader.bitsperpixel / 8;
|
int32 padding = get_padding(msheader.width, msheader.bitsperpixel);
|
||||||
int32 padding = (msheader.width * bmpBytesPerPixel) % 4;
|
int32 bmpRowBytes =
|
||||||
if (padding)
|
get_rowbytes(msheader.width, msheader.bitsperpixel);
|
||||||
padding = 4 - padding;
|
|
||||||
int32 bmpRowBytes = (msheader.width * bmpBytesPerPixel) + padding;
|
|
||||||
uint32 bmppixrow = 0;
|
uint32 bmppixrow = 0;
|
||||||
off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
|
off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
|
||||||
inSource->Seek(bitsoffset, SEEK_CUR);
|
inSource->Seek(bitsoffset, SEEK_CUR);
|
||||||
@ -803,13 +898,18 @@ BPositionIO *outDestination, color_space fromspace, MSInfoHeader &msheader)
|
|||||||
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
for (int32 i = 1; i <= padding; i++)
|
memset(bmpRowData + (bmpRowBytes - padding), 0, padding);
|
||||||
bmpRowData[bmpRowBytes - i] = 0;
|
|
||||||
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
const color_map *pmap = system_colors();
|
const color_map *pmap = NULL;
|
||||||
while (rd == bitsRowBytes) {
|
if (fromspace == B_CMAP8) {
|
||||||
|
pmap = system_colors();
|
||||||
|
if (!pmap)
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
while (rd == static_cast<ssize_t>(bitsRowBytes)) {
|
||||||
|
|
||||||
for (uint32 i = 0; i < msheader.width; i++) {
|
for (uint32 i = 0; i < msheader.width; i++) {
|
||||||
uint8 *bitspixel, *bmppixel;
|
uint8 *bitspixel, *bmppixel;
|
||||||
@ -930,12 +1030,14 @@ BPositionIO *outDestination, color_space fromspace, MSInfoHeader &msheader)
|
|||||||
if (bmppixrow == msheader.height)
|
if (bmppixrow == msheader.height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
inSource->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
} // while (rd == bitsRowBytes)
|
} // while (rd == bitsRowBytes)
|
||||||
|
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
delete[] bitsRowData;
|
delete[] bitsRowData;
|
||||||
|
bitsRowData = NULL;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -968,11 +1070,9 @@ status_t
|
|||||||
translate_from_bits8_to_bmp8(BPositionIO *inSource,
|
translate_from_bits8_to_bmp8(BPositionIO *inSource,
|
||||||
BPositionIO *outDestination, int32 bitsRowBytes, MSInfoHeader &msheader)
|
BPositionIO *outDestination, int32 bitsRowBytes, MSInfoHeader &msheader)
|
||||||
{
|
{
|
||||||
int32 padding;
|
int32 padding = get_padding(msheader.width, msheader.bitsperpixel);
|
||||||
padding = msheader.width % 4;
|
int32 bmpRowBytes =
|
||||||
if (padding)
|
get_rowbytes(msheader.width, msheader.bitsperpixel);
|
||||||
padding = 4 - padding;
|
|
||||||
int32 bmpRowBytes = msheader.width + padding;
|
|
||||||
uint32 bmppixrow = 0;
|
uint32 bmppixrow = 0;
|
||||||
off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
|
off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
|
||||||
inSource->Seek(bitsoffset, SEEK_CUR);
|
inSource->Seek(bitsoffset, SEEK_CUR);
|
||||||
@ -982,15 +1082,13 @@ translate_from_bits8_to_bmp8(BPositionIO *inSource,
|
|||||||
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
memset(bmpRowData + (bmpRowBytes - padding), 0, padding);
|
||||||
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
while (rd == bitsRowBytes) {
|
while (rd == bitsRowBytes) {
|
||||||
memcpy(bmpRowData, bitsRowData, msheader.width);
|
memcpy(bmpRowData, bitsRowData, msheader.width);
|
||||||
if (padding) {
|
|
||||||
uint8 zeros[] = {0, 0, 0, 0};
|
|
||||||
memcpy(bmpRowData + msheader.width, zeros, padding);
|
|
||||||
}
|
|
||||||
outDestination->Write(bmpRowData, bmpRowBytes);
|
outDestination->Write(bmpRowData, bmpRowBytes);
|
||||||
bmppixrow++;
|
bmppixrow++;
|
||||||
// if I've read all of the pixel data, break
|
// if I've read all of the pixel data, break
|
||||||
@ -999,12 +1097,14 @@ translate_from_bits8_to_bmp8(BPositionIO *inSource,
|
|||||||
if (bmppixrow == msheader.height)
|
if (bmppixrow == msheader.height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
inSource->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
} // while (rd == bitsRowBytes)
|
} // while (rd == bitsRowBytes)
|
||||||
|
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
delete[] bitsRowData;
|
delete[] bitsRowData;
|
||||||
|
bitsRowData = NULL;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -1037,17 +1137,9 @@ status_t
|
|||||||
translate_from_bits1_to_bmp1(BPositionIO *inSource,
|
translate_from_bits1_to_bmp1(BPositionIO *inSource,
|
||||||
BPositionIO *outDestination, int32 bitsRowBytes, MSInfoHeader &msheader)
|
BPositionIO *outDestination, int32 bitsRowBytes, MSInfoHeader &msheader)
|
||||||
{
|
{
|
||||||
uint16 pixelsPerByte = 8 / msheader.bitsperpixel;
|
uint8 pixelsPerByte = 8 / msheader.bitsperpixel;
|
||||||
int32 padding;
|
int32 bmpRowBytes =
|
||||||
if (!(msheader.width % pixelsPerByte))
|
get_rowbytes(msheader.width, msheader.bitsperpixel);
|
||||||
padding = (msheader.width / pixelsPerByte) % 4;
|
|
||||||
else
|
|
||||||
padding = ((msheader.width + pixelsPerByte -
|
|
||||||
(msheader.width % pixelsPerByte)) / pixelsPerByte) % 4;
|
|
||||||
if (padding)
|
|
||||||
padding = 4 - padding;
|
|
||||||
int32 bmpRowBytes = (msheader.width / pixelsPerByte) +
|
|
||||||
((msheader.width % pixelsPerByte) ? 1 : 0) + padding;
|
|
||||||
uint32 bmppixrow = 0;
|
uint32 bmppixrow = 0;
|
||||||
off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
|
off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
|
||||||
inSource->Seek(bitsoffset, SEEK_CUR);
|
inSource->Seek(bitsoffset, SEEK_CUR);
|
||||||
@ -1057,13 +1149,13 @@ translate_from_bits1_to_bmp1(BPositionIO *inSource,
|
|||||||
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
while (rd == bitsRowBytes) {
|
while (rd == bitsRowBytes) {
|
||||||
uint32 bmppixcol = 0;
|
uint32 bmppixcol = 0;
|
||||||
for (int32 i = 0; i < bmpRowBytes; i++)
|
memset(bmpRowData, 0, bmpRowBytes);
|
||||||
bmpRowData[i] = 0;
|
|
||||||
for (int32 i = 0; (bmppixcol < msheader.width) &&
|
for (int32 i = 0; (bmppixcol < msheader.width) &&
|
||||||
(i < bitsRowBytes); i++) {
|
(i < bitsRowBytes); i++) {
|
||||||
// process each byte in the row
|
// process each byte in the row
|
||||||
@ -1093,12 +1185,14 @@ translate_from_bits1_to_bmp1(BPositionIO *inSource,
|
|||||||
if (bmppixrow == msheader.height)
|
if (bmppixrow == msheader.height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
inSource->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
rd = inSource->Read(bitsRowData, bitsRowBytes);
|
||||||
} // while (rd == bitsRowBytes)
|
} // while (rd == bitsRowBytes)
|
||||||
|
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
delete[] bitsRowData;
|
delete[] bitsRowData;
|
||||||
|
bitsRowData = NULL;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -1243,7 +1337,6 @@ translate_from_bits(BPositionIO *inSource, ssize_t amtread, uint8 *read,
|
|||||||
msheader.colorsused = 0;
|
msheader.colorsused = 0;
|
||||||
msheader.colorsimportant = 0;
|
msheader.colorsimportant = 0;
|
||||||
|
|
||||||
int32 padding = 0;
|
|
||||||
// determine fileSize / imagesize
|
// determine fileSize / imagesize
|
||||||
switch (bitsHeader.colors) {
|
switch (bitsHeader.colors) {
|
||||||
case B_RGB32:
|
case B_RGB32:
|
||||||
@ -1266,10 +1359,7 @@ translate_from_bits(BPositionIO *inSource, ssize_t amtread, uint8 *read,
|
|||||||
fileHeader.dataOffset = 54;
|
fileHeader.dataOffset = 54;
|
||||||
msheader.bitsperpixel = 24;
|
msheader.bitsperpixel = 24;
|
||||||
msheader.compression = BMP_NO_COMPRESS;
|
msheader.compression = BMP_NO_COMPRESS;
|
||||||
padding = (msheader.width * 3) % 4;
|
msheader.imagesize = get_rowbytes(msheader.width, 24) *
|
||||||
if (padding)
|
|
||||||
padding = 4 - padding;
|
|
||||||
msheader.imagesize = ((msheader.width * 3) + padding) *
|
|
||||||
msheader.height;
|
msheader.height;
|
||||||
fileHeader.fileSize = fileHeader.dataOffset +
|
fileHeader.fileSize = fileHeader.dataOffset +
|
||||||
msheader.imagesize;
|
msheader.imagesize;
|
||||||
@ -1284,11 +1374,8 @@ translate_from_bits(BPositionIO *inSource, ssize_t amtread, uint8 *read,
|
|||||||
fileHeader.dataOffset = 54 + (4 * 256);
|
fileHeader.dataOffset = 54 + (4 * 256);
|
||||||
msheader.bitsperpixel = 8;
|
msheader.bitsperpixel = 8;
|
||||||
msheader.compression = BMP_NO_COMPRESS;
|
msheader.compression = BMP_NO_COMPRESS;
|
||||||
padding = msheader.width % 4;
|
msheader.imagesize = get_rowbytes(msheader.width,
|
||||||
if (padding)
|
msheader.bitsperpixel) * msheader.height;
|
||||||
padding = 4 - padding;
|
|
||||||
msheader.imagesize = (msheader.width + padding) *
|
|
||||||
msheader.height;
|
|
||||||
fileHeader.fileSize = fileHeader.dataOffset +
|
fileHeader.fileSize = fileHeader.dataOffset +
|
||||||
msheader.imagesize;
|
msheader.imagesize;
|
||||||
|
|
||||||
@ -1301,16 +1388,8 @@ translate_from_bits(BPositionIO *inSource, ssize_t amtread, uint8 *read,
|
|||||||
fileHeader.dataOffset = 62;
|
fileHeader.dataOffset = 62;
|
||||||
msheader.bitsperpixel = 1;
|
msheader.bitsperpixel = 1;
|
||||||
msheader.compression = BMP_NO_COMPRESS;
|
msheader.compression = BMP_NO_COMPRESS;
|
||||||
if (!(msheader.width % 8))
|
msheader.imagesize = get_rowbytes(msheader.width,
|
||||||
padding = (msheader.width / 8) % 4;
|
msheader.bitsperpixel) * msheader.height;
|
||||||
else
|
|
||||||
padding = ((msheader.width + 8 -
|
|
||||||
(msheader.width % 8)) / 8) % 4;
|
|
||||||
if (padding)
|
|
||||||
padding = 4 - padding;
|
|
||||||
msheader.imagesize = ((msheader.width / 8) +
|
|
||||||
((msheader.width % 8) ? 1 : 0) + padding) *
|
|
||||||
msheader.height;
|
|
||||||
fileHeader.fileSize = fileHeader.dataOffset +
|
fileHeader.fileSize = fileHeader.dataOffset +
|
||||||
msheader.imagesize;
|
msheader.imagesize;
|
||||||
|
|
||||||
@ -1357,6 +1436,8 @@ translate_from_bits(BPositionIO *inSource, ssize_t amtread, uint8 *read,
|
|||||||
// write Be's system palette to the BMP file
|
// write Be's system palette to the BMP file
|
||||||
uint8 pal[1024] = { 0 };
|
uint8 pal[1024] = { 0 };
|
||||||
const color_map *pmap = system_colors();
|
const color_map *pmap = system_colors();
|
||||||
|
if (!pmap)
|
||||||
|
return B_ERROR;
|
||||||
for (int32 i = 0; i < 256; i++) {
|
for (int32 i = 0; i < 256; i++) {
|
||||||
uint8 *palent = pal + (i * 4);
|
uint8 *palent = pal + (i * 4);
|
||||||
rgb_color c = pmap->color_list[i];
|
rgb_color c = pmap->color_list[i];
|
||||||
@ -1432,11 +1513,8 @@ translate_from_bmpnpal_to_bits(BPositionIO *inSource,
|
|||||||
{
|
{
|
||||||
int32 bitsRowBytes = msheader.width * 4;
|
int32 bitsRowBytes = msheader.width * 4;
|
||||||
int32 bmpBytesPerPixel = msheader.bitsperpixel / 8;
|
int32 bmpBytesPerPixel = msheader.bitsperpixel / 8;
|
||||||
int32 padding = (msheader.width * bmpBytesPerPixel) % 4;
|
int32 bmpRowBytes =
|
||||||
if (padding)
|
get_rowbytes(msheader.width, msheader.bitsperpixel);
|
||||||
padding = 4 - padding;
|
|
||||||
int32 bmpRowBytes = (msheader.width * bmpBytesPerPixel) + padding;
|
|
||||||
uint32 bmppixrow = 0;
|
|
||||||
|
|
||||||
// Setup outDestination so that it can be written to
|
// Setup outDestination so that it can be written to
|
||||||
// from the end of the file to the beginning instead of
|
// from the end of the file to the beginning instead of
|
||||||
@ -1457,13 +1535,15 @@ translate_from_bmpnpal_to_bits(BPositionIO *inSource,
|
|||||||
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// perform the actual translation
|
// perform the actual translation
|
||||||
|
uint32 bmppixrow = 0;
|
||||||
memset(bitsRowData, 0xff, bitsRowBytes);
|
memset(bitsRowData, 0xff, bitsRowBytes);
|
||||||
ssize_t rd = inSource->Read(bmpRowData, bmpRowBytes);
|
ssize_t rd = inSource->Read(bmpRowData, bmpRowBytes);
|
||||||
while (rd == bmpRowBytes) {
|
while (rd == static_cast<ssize_t>(bmpRowBytes)) {
|
||||||
uint8 *pBitsPixel = bitsRowData;
|
uint8 *pBitsPixel = bitsRowData;
|
||||||
uint8 *pBmpPixel = bmpRowData;
|
uint8 *pBmpPixel = bmpRowData;
|
||||||
for (uint32 i = 0; i < msheader.width; i++) {
|
for (uint32 i = 0; i < msheader.width; i++) {
|
||||||
@ -1480,12 +1560,14 @@ translate_from_bmpnpal_to_bits(BPositionIO *inSource,
|
|||||||
if (bmppixrow == msheader.height)
|
if (bmppixrow == msheader.height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
outDestination->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
rd = inSource->Read(bmpRowData, bmpRowBytes);
|
rd = inSource->Read(bmpRowData, bmpRowBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
delete[] bitsRowData;
|
delete[] bitsRowData;
|
||||||
|
bitsRowData = NULL;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -1530,18 +1612,9 @@ translate_from_bmppal_to_bits(BPositionIO *inSource,
|
|||||||
|
|
||||||
uint8 mask = 1;
|
uint8 mask = 1;
|
||||||
mask = (mask << bitsPerPixel) - 1;
|
mask = (mask << bitsPerPixel) - 1;
|
||||||
|
|
||||||
int32 padding;
|
|
||||||
if (!(msheader.width % pixelsPerByte))
|
|
||||||
padding = (msheader.width / pixelsPerByte) % 4;
|
|
||||||
else
|
|
||||||
padding = ((msheader.width + pixelsPerByte -
|
|
||||||
(msheader.width % pixelsPerByte)) / pixelsPerByte) % 4;
|
|
||||||
if (padding)
|
|
||||||
padding = 4 - padding;
|
|
||||||
|
|
||||||
int32 bmpRowBytes = (msheader.width / pixelsPerByte) +
|
int32 bmpRowBytes =
|
||||||
((msheader.width % pixelsPerByte) ? 1 : 0) + padding;
|
get_rowbytes(msheader.width, msheader.bitsperpixel);
|
||||||
uint32 bmppixrow = 0;
|
uint32 bmppixrow = 0;
|
||||||
|
|
||||||
// Setup outDestination so that it can be written to
|
// Setup outDestination so that it can be written to
|
||||||
@ -1564,11 +1637,12 @@ translate_from_bmppal_to_bits(BPositionIO *inSource,
|
|||||||
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
uint8 *bitsRowData = new uint8[bitsRowBytes];
|
||||||
if (!bitsRowData) {
|
if (!bitsRowData) {
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
memset(bitsRowData, 0xff, bitsRowBytes);
|
memset(bitsRowData, 0xff, bitsRowBytes);
|
||||||
ssize_t rd = inSource->Read(bmpRowData, bmpRowBytes);
|
ssize_t rd = inSource->Read(bmpRowData, bmpRowBytes);
|
||||||
while (rd == bmpRowBytes) {
|
while (rd == static_cast<ssize_t>(bmpRowBytes)) {
|
||||||
for (uint32 i = 0; i < msheader.width; i++) {
|
for (uint32 i = 0; i < msheader.width; i++) {
|
||||||
uint8 indices = (bmpRowData + (i / pixelsPerByte))[0];
|
uint8 indices = (bmpRowData + (i / pixelsPerByte))[0];
|
||||||
uint8 index;
|
uint8 index;
|
||||||
@ -1587,12 +1661,14 @@ translate_from_bmppal_to_bits(BPositionIO *inSource,
|
|||||||
if (bmppixrow == msheader.height)
|
if (bmppixrow == msheader.height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
outDestination->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
rd = inSource->Read(bmpRowData, bmpRowBytes);
|
rd = inSource->Read(bmpRowData, bmpRowBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] bmpRowData;
|
delete[] bmpRowData;
|
||||||
|
bmpRowData = NULL;
|
||||||
delete[] bitsRowData;
|
delete[] bitsRowData;
|
||||||
|
bitsRowData = NULL;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -1731,7 +1807,7 @@ translate_from_bmppalr_to_bits(BPositionIO *inSource,
|
|||||||
bmppixcol = 0;
|
bmppixcol = 0;
|
||||||
bmppixrow++;
|
bmppixrow++;
|
||||||
if (bmppixrow < msheader.height)
|
if (bmppixrow < msheader.height)
|
||||||
outDestination->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// end of bitmap
|
// end of bitmap
|
||||||
@ -1742,8 +1818,7 @@ translate_from_bmppalr_to_bits(BPositionIO *inSource,
|
|||||||
bmppixcol = 0;
|
bmppixcol = 0;
|
||||||
bmppixrow++;
|
bmppixrow++;
|
||||||
if (bmppixrow < msheader.height)
|
if (bmppixrow < msheader.height)
|
||||||
outDestination->Seek(-(bitsRowBytes * 2),
|
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
SEEK_CUR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bmppixrow < msheader.height) {
|
while (bmppixrow < msheader.height) {
|
||||||
@ -1753,8 +1828,7 @@ translate_from_bmppalr_to_bits(BPositionIO *inSource,
|
|||||||
bmppixcol = 0;
|
bmppixcol = 0;
|
||||||
bmppixrow++;
|
bmppixrow++;
|
||||||
if (bmppixrow < msheader.height)
|
if (bmppixrow < msheader.height)
|
||||||
outDestination->Seek(-(bitsRowBytes * 2),
|
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
SEEK_CUR);
|
|
||||||
}
|
}
|
||||||
rd = 0;
|
rd = 0;
|
||||||
// break out of while loop
|
// break out of while loop
|
||||||
@ -1791,10 +1865,10 @@ translate_from_bmppalr_to_bits(BPositionIO *inSource,
|
|||||||
bmppixcol = 0;
|
bmppixcol = 0;
|
||||||
bmppixrow++;
|
bmppixrow++;
|
||||||
dy--;
|
dy--;
|
||||||
outDestination->Seek(-(bitsRowBytes * 2), SEEK_CUR);
|
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bmppixcol < (uint32) lastcol + dx) {
|
if (bmppixcol < static_cast<uint32>(lastcol + dx)) {
|
||||||
pixelcpy(bitsRowData + (bmppixcol * 4), defaultcolor,
|
pixelcpy(bitsRowData + (bmppixcol * 4), defaultcolor,
|
||||||
dx + lastcol - bmppixcol);
|
dx + lastcol - bmppixcol);
|
||||||
bmppixcol = dx + lastcol;
|
bmppixcol = dx + lastcol;
|
||||||
@ -1851,6 +1925,7 @@ translate_from_bmppalr_to_bits(BPositionIO *inSource,
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete[] bitsRowData;
|
delete[] bitsRowData;
|
||||||
|
bitsRowData = NULL;
|
||||||
|
|
||||||
if (!rd)
|
if (!rd)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -2189,6 +2264,9 @@ BMPTranslator::MakeConfigurationView(BMessage *ioExtension, BView **outView,
|
|||||||
|
|
||||||
BMPView *view = new BMPView(BRect(0, 0, 225, 175),
|
BMPView *view = new BMPView(BRect(0, 0, 225, 175),
|
||||||
"BMPTranslator Settings", B_FOLLOW_ALL, B_WILL_DRAW);
|
"BMPTranslator Settings", B_FOLLOW_ALL, B_WILL_DRAW);
|
||||||
|
if (!view)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
*outView = view;
|
*outView = view;
|
||||||
*outExtent = view->Bounds();
|
*outExtent = view->Bounds();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user