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:
Matthew Wilber 2003-05-24 23:02:19 +00:00
parent c12232ddb5
commit 9edca8f79e

View File

@ -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();