fixed Save As RLE and added Save As RLE support to low color images and removed some redundant code

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1365 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber 2002-10-04 01:46:42 +00:00
parent a7b41a964a
commit 0d5d2ca494

View File

@ -837,15 +837,11 @@ pix_bits_to_tga(uint8 *pbits, uint8 *ptga, color_space fromspace,
} }
case B_GRAY8: case B_GRAY8:
bytescopied = width * 3; // NOTE: this code assumes that the
while (width--) { // destination TGA color space is either
ptga[0] = pbits[0]; // 8 bit indexed color or 8 bit grayscale
ptga[1] = pbits[0]; bytescopied = width;
ptga[2] = pbits[0]; memcpy(ptga, pbits, bytescopied);
ptga += 3;
pbits++;
}
break; break;
default: default:
@ -878,7 +874,7 @@ copy_raw_packet(uint8 *ptga, uint8 *praw, uint8 count,
{ {
// copy packet header // copy packet header
// (made of type and count) // (made of type and count)
uint8 packethead = (count - 1); uint8 packethead = count - 1;
memcpy(ptga, &packethead, 1); memcpy(ptga, &packethead, 1);
ptga++; ptga++;
@ -893,7 +889,7 @@ pix_bits_to_tgarle(uint8 *pbits, uint8 *ptga, color_space fromspace,
if (width == 0) if (width == 0)
return B_ERROR; return B_ERROR;
uint32 pixel = 0, lastpixel = 0, nextpixel = 0; uint32 current = 0, next = 0, aftnext = 0;
uint16 nread = 0; uint16 nread = 0;
status_t result, bytescopied = 0; status_t result, bytescopied = 0;
uint8 *prawbuf, *praw; uint8 *prawbuf, *praw;
@ -903,51 +899,95 @@ pix_bits_to_tgarle(uint8 *pbits, uint8 *ptga, color_space fromspace,
return B_ERROR; return B_ERROR;
uint8 rlecount = 1, rawcount = 0; uint8 rlecount = 1, rawcount = 0;
bool bJustWroteRLE = false;
memcpy(&pixel, pbits, bitsBytesPerPixel); memcpy(&current, pbits, bitsBytesPerPixel);
pbits += bitsBytesPerPixel; pbits += bitsBytesPerPixel;
if (width == 1) {
result = copy_raw_packet(ptga, (uint8 *) &current, 1,
fromspace, pmap, bitsBytesPerPixel);
ptga += result;
bytescopied += result;
nread++;
// don't enter the while loop
} else {
memcpy(&next, pbits, bitsBytesPerPixel);
pbits += bitsBytesPerPixel;
nread++;
}
while (nread < width) { while (nread < width) {
if (nread < width - 1) { if (nread < width - 1) {
memcpy(&nextpixel, pbits, bitsBytesPerPixel); memcpy(&aftnext, pbits, bitsBytesPerPixel);
pbits += bitsBytesPerPixel; pbits += bitsBytesPerPixel;
} }
nread++; nread++;
if (nread > 1 && lastpixel == pixel) { // RLE Packet Creation
if (current == next && !bJustWroteRLE) {
rlecount++; rlecount++;
if (rlecount == 128 || nread == width || pixel != nextpixel) { if (next != aftnext || nread == width || rlecount == 128) {
result = copy_rle_packet(ptga, pixel, rlecount, result = copy_rle_packet(ptga, current, rlecount,
fromspace, pmap, bitsBytesPerPixel); fromspace, pmap, bitsBytesPerPixel);
ptga += result; ptga += result;
bytescopied += result; bytescopied += result;
rlecount = 1; rlecount = 1;
bJustWroteRLE = true;
} }
// RAW Packet Creation
} else { } else {
if ((nread < width && pixel != nextpixel) || nread == width) {
if (!bJustWroteRLE) {
// output the current pixel only if
// it was not just written out in an RLE packet
rawcount++; rawcount++;
memcpy(praw, &pixel, bitsBytesPerPixel); memcpy(praw, &current, bitsBytesPerPixel);
praw += bitsBytesPerPixel; praw += bitsBytesPerPixel;
} }
if (rawcount == 128 || nread == width || (pixel == nextpixel && rawcount > 0)) { if (nread == width) {
result = copy_raw_packet(ptga, // if in the last iteration of the loop,
prawbuf, rawcount, fromspace, pmap, // "next" will be the last pixel in the row,
bitsBytesPerPixel); // and will need to be written out for this
// special case
if (rawcount == 128) {
result = copy_raw_packet(ptga, prawbuf, rawcount,
fromspace, pmap, bitsBytesPerPixel);
ptga += result;
bytescopied += result;
praw = prawbuf;
rawcount = 0;
}
rawcount++;
memcpy(praw, &next, bitsBytesPerPixel);
praw += bitsBytesPerPixel;
}
if ((!bJustWroteRLE && next == aftnext) ||
nread == width || rawcount == 128) {
result = copy_raw_packet(ptga, prawbuf, rawcount,
fromspace, pmap, bitsBytesPerPixel);
ptga += result; ptga += result;
bytescopied += result; bytescopied += result;
rawcount = 0;
praw = prawbuf; praw = prawbuf;
rawcount = 0;
} }
bJustWroteRLE = false;
} }
lastpixel = pixel; current = next;
pixel = nextpixel; next = aftnext;
} }
delete[] prawbuf; delete[] prawbuf;
@ -1062,56 +1102,8 @@ translate_from_bits_to_tgatc(BPositionIO *inSource,
rd = inSource->Read(bitsRowData, bitsRowBytes); rd = inSource->Read(bitsRowData, bitsRowBytes);
} // while (rd == bitsRowBytes) } // while (rd == bitsRowBytes)
delete[] bitsRowData;
delete[] tgaRowData; delete[] tgaRowData;
delete[] bitsRowData;
return B_OK;
}
// ---------------------------------------------------------------
// translate_from_bits8_to_tga8
//
// Converts 8-bit Be Bitmaps ('bits') to the 8-bit TGA format
//
// Preconditions:
//
// Parameters: inSource, contains the bits data to convert
//
// outDestination, where the TGA data will be written
//
// bitsRowBytes, number of bytes in one row of
// bits data
//
// Postconditions:
//
// Returns: B_ERROR, if memory couldn't be allocated or another
// error occured
//
// B_OK, if no errors occurred
// ---------------------------------------------------------------
status_t
translate_from_bits8_to_tga8(BPositionIO *inSource,
BPositionIO *outDestination, int32 bitsRowBytes,
uint16 height, bool brle)
{
uint32 tgapixrow = 0;
uint8 *bitsRowData = new uint8[bitsRowBytes];
if (!bitsRowData)
return B_ERROR;
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
while (rd == bitsRowBytes) {
outDestination->Write(bitsRowData, bitsRowBytes);
tgapixrow++;
// 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 (tgapixrow == height)
break;
rd = inSource->Read(bitsRowData, bitsRowBytes);
}
delete[] bitsRowData;
return B_OK; return B_OK;
} }
@ -1145,16 +1137,37 @@ translate_from_bits1_to_tgabw(BPositionIO *inSource,
BPositionIO *outDestination, int32 bitsRowBytes, BPositionIO *outDestination, int32 bitsRowBytes,
TGAImageSpec &imagespec, bool brle) TGAImageSpec &imagespec, bool brle)
{ {
int32 tgaRowBytes = imagespec.width; uint8 tgaBytesPerPixel = 1;
int32 tgaRowBytes = (imagespec.width * tgaBytesPerPixel) +
(imagespec.width / 128) + ((imagespec.width % 128) ? 1 : 0);
uint32 tgapixrow = 0; uint32 tgapixrow = 0;
uint8 *tgaRowData = new uint8[tgaRowBytes]; uint8 *tgaRowData = new uint8[tgaRowBytes];
if (!tgaRowData) if (!tgaRowData)
return B_ERROR; return B_ERROR;
uint8 *bitsRowData = new uint8[bitsRowBytes];
if (!bitsRowData) { uint8 *medRowData = new uint8[imagespec.width];
if (!medRowData) {
delete[] tgaRowData; delete[] tgaRowData;
return B_ERROR; return B_ERROR;
} }
uint8 *bitsRowData = new uint8[bitsRowBytes];
if (!bitsRowData) {
delete[] medRowData;
delete[] tgaRowData;
return B_ERROR;
}
// conversion function pointer, points to either
// RLE or normal TGA conversion function
status_t (*convert_to_tga)(uint8 *pbits, uint8 *ptga,
color_space fromspace, uint16 width, const color_map *pmap,
int32 bitsBytesPerPixel);
if (brle)
convert_to_tga = pix_bits_to_tgarle;
else
convert_to_tga = pix_bits_to_tga;
ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes); ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
while (rd == bitsRowBytes) { while (rd == bitsRowBytes) {
uint32 tgapixcol = 0; uint32 tgapixcol = 0;
@ -1168,15 +1181,19 @@ translate_from_bits1_to_tgabw(BPositionIO *inSource,
// index and store that in the tgaRowData // index and store that in the tgaRowData
if (pixels & compbit) if (pixels & compbit)
// black // black
tgaRowData[tgapixcol] = 0; medRowData[tgapixcol] = 0;
else else
// white // white
tgaRowData[tgapixcol] = 255; medRowData[tgapixcol] = 255;
tgapixcol++; tgapixcol++;
} }
} }
status_t bytescopied;
bytescopied = convert_to_tga(medRowData, tgaRowData, B_GRAY8,
imagespec.width, NULL, 1);
outDestination->Write(tgaRowData, tgaRowBytes); outDestination->Write(tgaRowData, bytescopied);
tgapixrow++; tgapixrow++;
// if I've read all of the pixel data, break // if I've read all of the pixel data, break
// out of the loop so I don't try to read // out of the loop so I don't try to read
@ -1187,8 +1204,9 @@ translate_from_bits1_to_tgabw(BPositionIO *inSource,
rd = inSource->Read(bitsRowData, bitsRowBytes); rd = inSource->Read(bitsRowData, bitsRowBytes);
} // while (rd == bitsRowBytes) } // while (rd == bitsRowBytes)
delete[] tgaRowData;
delete[] bitsRowData; delete[] bitsRowData;
delete[] medRowData;
delete[] tgaRowData;
return B_OK; return B_OK;
} }
@ -1543,14 +1561,14 @@ translate_from_bits(BPositionIO *inSource, ssize_t amtread, uint8 *read,
if (outDestination->Write(pal, 1024) != 1024) if (outDestination->Write(pal, 1024) != 1024)
return B_ERROR; return B_ERROR;
result = translate_from_bits8_to_tga8(inSource, outDestination, result = translate_from_bits_to_tgatc(inSource, outDestination,
bitsHeader.rowBytes, imagespec.height, brle); B_GRAY8, imagespec, brle);
break; break;
} }
case B_GRAY8: case B_GRAY8:
result = translate_from_bits8_to_tga8(inSource, outDestination, result = translate_from_bits_to_tgatc(inSource, outDestination,
bitsHeader.rowBytes, imagespec.height, brle); B_GRAY8, imagespec, brle);
break; break;
case B_GRAY1: case B_GRAY1: