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:
parent
a7b41a964a
commit
0d5d2ca494
@ -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(¤t, pbits, bitsBytesPerPixel);
|
||||||
pbits += bitsBytesPerPixel;
|
pbits += bitsBytesPerPixel;
|
||||||
|
if (width == 1) {
|
||||||
|
result = copy_raw_packet(ptga, (uint8 *) ¤t, 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, ¤t, 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:
|
||||||
|
Loading…
Reference in New Issue
Block a user