moved the pixel conversion logic out of translate_from_bits_to_tgatc and into a new function (pix_bits_to_tga) in order to make the code easier to read and easier to add the option for saving as RLE compressed TGAs.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1166 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -647,6 +647,215 @@ TGATranslator::Identify(BPositionIO *inSource,
|
|||||||
return identify_tga_header(inSource, outInfo, 4, ch);
|
return identify_tga_header(inSource, outInfo, 4, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
pix_bits_to_tga(uint8 *pbits, uint8 *ptga, color_space fromspace,
|
||||||
|
uint16 width, const color_map *pmap)
|
||||||
|
{
|
||||||
|
status_t result = B_OK;
|
||||||
|
|
||||||
|
switch (fromspace) {
|
||||||
|
case B_RGBA32:
|
||||||
|
memcpy(ptga, pbits, width * 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGBA32_BIG:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[3];
|
||||||
|
ptga[1] = pbits[2];
|
||||||
|
ptga[2] = pbits[1];
|
||||||
|
ptga[3] = pbits[0];
|
||||||
|
|
||||||
|
ptga += 4;
|
||||||
|
pbits += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_CMYA32:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = 255 - pbits[2];
|
||||||
|
ptga[1] = 255 - pbits[1];
|
||||||
|
ptga[2] = 255 - pbits[0];
|
||||||
|
ptga[3] = pbits[3];
|
||||||
|
|
||||||
|
ptga += 4;
|
||||||
|
pbits += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB32:
|
||||||
|
case B_RGB24:
|
||||||
|
{
|
||||||
|
int32 bytes;
|
||||||
|
if (fromspace == B_RGB32)
|
||||||
|
bytes = 4;
|
||||||
|
else
|
||||||
|
bytes = 3;
|
||||||
|
|
||||||
|
while (width--) {
|
||||||
|
memcpy(ptga, pbits, 3);
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits += bytes;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_CMYK32:
|
||||||
|
{
|
||||||
|
int32 comp;
|
||||||
|
while (width--) {
|
||||||
|
comp = 255 - pbits[2] - pbits[3];
|
||||||
|
ptga[0] = (comp < 0) ? 0 : comp;
|
||||||
|
|
||||||
|
comp = 255 - pbits[1] - pbits[3];
|
||||||
|
ptga[1] = (comp < 0) ? 0 : comp;
|
||||||
|
|
||||||
|
comp = 255 - pbits[0] - pbits[3];
|
||||||
|
ptga[2] = (comp < 0) ? 0 : comp;
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_CMY32:
|
||||||
|
case B_CMY24:
|
||||||
|
{
|
||||||
|
int32 bytes;
|
||||||
|
if (fromspace == B_CMY32)
|
||||||
|
bytes = 4;
|
||||||
|
else
|
||||||
|
bytes = 3;
|
||||||
|
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = 255 - pbits[2];
|
||||||
|
ptga[1] = 255 - pbits[1];
|
||||||
|
ptga[2] = 255 - pbits[0];
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits += bytes;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_RGB16:
|
||||||
|
case B_RGB16_BIG:
|
||||||
|
{
|
||||||
|
// Expand to 24 bit because the TGA format handles
|
||||||
|
// 16 bit images differently than the Be Image Format
|
||||||
|
// which would cause a loss in quality
|
||||||
|
uint16 val;
|
||||||
|
while (width--) {
|
||||||
|
if (fromspace == B_RGB16)
|
||||||
|
val = pbits[0] + (pbits[1] << 8);
|
||||||
|
else
|
||||||
|
val = pbits[1] + (pbits[0] << 8);
|
||||||
|
|
||||||
|
ptga[0] =
|
||||||
|
((val & 0x1f) << 3) | ((val & 0x1f) >> 2);
|
||||||
|
ptga[1] =
|
||||||
|
((val & 0x7e0) >> 3) | ((val & 0x7e0) >> 9);
|
||||||
|
ptga[2] =
|
||||||
|
((val & 0xf800) >> 8) | ((val & 0xf800) >> 13);
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_RGBA15:
|
||||||
|
memcpy(ptga, pbits, 2 * width);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGBA15_BIG:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[1];
|
||||||
|
ptga[1] = pbits[0];
|
||||||
|
|
||||||
|
ptga += 2;
|
||||||
|
pbits += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB15:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[0];
|
||||||
|
ptga[1] = pbits[1] | 0x80;
|
||||||
|
// alpha bit is always 1
|
||||||
|
|
||||||
|
ptga += 2;
|
||||||
|
pbits += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB15_BIG:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[1];
|
||||||
|
ptga[1] = pbits[0] | 0x80;
|
||||||
|
// alpha bit is always 1
|
||||||
|
|
||||||
|
ptga += 2;
|
||||||
|
pbits += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB32_BIG:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[3];
|
||||||
|
ptga[1] = pbits[2];
|
||||||
|
ptga[2] = pbits[1];
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_RGB24_BIG:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[2];
|
||||||
|
ptga[1] = pbits[1];
|
||||||
|
ptga[2] = pbits[0];
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits += 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_CMAP8:
|
||||||
|
{
|
||||||
|
rgb_color c;
|
||||||
|
while (width--) {
|
||||||
|
c = pmap->color_list[pbits[0]];
|
||||||
|
ptga[0] = c.blue;
|
||||||
|
ptga[1] = c.green;
|
||||||
|
ptga[2] = c.red;
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_GRAY8:
|
||||||
|
while (width--) {
|
||||||
|
ptga[0] = pbits[0];
|
||||||
|
ptga[1] = pbits[0];
|
||||||
|
ptga[2] = pbits[0];
|
||||||
|
|
||||||
|
ptga += 3;
|
||||||
|
pbits++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = B_ERROR;
|
||||||
|
break;
|
||||||
|
} // switch (fromspace)
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// translate_from_bits_to_tgatc
|
// translate_from_bits_to_tgatc
|
||||||
//
|
//
|
||||||
@@ -725,146 +934,9 @@ BPositionIO *outDestination, color_space fromspace, TGAImageSpec &imagespec)
|
|||||||
const color_map *pmap = system_colors();
|
const color_map *pmap = system_colors();
|
||||||
while (rd == bitsRowBytes) {
|
while (rd == bitsRowBytes) {
|
||||||
|
|
||||||
for (uint32 i = 0; i < imagespec.width; i++) {
|
pix_bits_to_tga(bitsRowData, tgaRowData, fromspace,
|
||||||
uint8 *bitspixel, *tgapixel;
|
imagespec.width, pmap);
|
||||||
uint16 val;
|
// convert bits row to tga row
|
||||||
int32 comp;
|
|
||||||
switch (fromspace) {
|
|
||||||
case B_RGBA32:
|
|
||||||
memcpy(tgaRowData + (i * 4),
|
|
||||||
bitsRowData + (i * bitsBytesPerPixel), 4);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGBA32_BIG:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 4);
|
|
||||||
tgapixel[0] = bitspixel[3];
|
|
||||||
tgapixel[1] = bitspixel[2];
|
|
||||||
tgapixel[2] = bitspixel[1];
|
|
||||||
tgapixel[3] = bitspixel[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_CMYA32:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 4);
|
|
||||||
tgapixel[0] = 255 - bitspixel[2];
|
|
||||||
tgapixel[1] = 255 - bitspixel[1];
|
|
||||||
tgapixel[2] = 255 - bitspixel[0];
|
|
||||||
tgapixel[3] = bitspixel[3];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGB32:
|
|
||||||
case B_RGB24:
|
|
||||||
memcpy(tgaRowData + (i * 3),
|
|
||||||
bitsRowData + (i * bitsBytesPerPixel), 3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_CMYK32:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
|
|
||||||
comp = 255 - bitspixel[2] - bitspixel[3];
|
|
||||||
tgapixel[0] = (comp < 0) ? 0 : comp;
|
|
||||||
|
|
||||||
comp = 255 - bitspixel[1] - bitspixel[3];
|
|
||||||
tgapixel[1] = (comp < 0) ? 0 : comp;
|
|
||||||
|
|
||||||
comp = 255 - bitspixel[0] - bitspixel[3];
|
|
||||||
tgapixel[2] = (comp < 0) ? 0 : comp;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_CMY32:
|
|
||||||
case B_CMY24:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
tgapixel[0] = 255 - bitspixel[2];
|
|
||||||
tgapixel[1] = 255 - bitspixel[1];
|
|
||||||
tgapixel[2] = 255 - bitspixel[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGB16:
|
|
||||||
case B_RGB16_BIG:
|
|
||||||
// Expand to 24 bit because the TGA format handles
|
|
||||||
// 16 bit images differently than the Be Image Format
|
|
||||||
// which would cause a loss in quality
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
if (fromspace == B_RGB16)
|
|
||||||
val = bitspixel[0] + (bitspixel[1] << 8);
|
|
||||||
else
|
|
||||||
val = bitspixel[1] + (bitspixel[0] << 8);
|
|
||||||
|
|
||||||
tgapixel[0] =
|
|
||||||
((val & 0x1f) << 3) | ((val & 0x1f) >> 2);
|
|
||||||
tgapixel[1] =
|
|
||||||
((val & 0x7e0) >> 3) | ((val & 0x7e0) >> 9);
|
|
||||||
tgapixel[2] =
|
|
||||||
((val & 0xf800) >> 8) | ((val & 0xf800) >> 13);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGBA15:
|
|
||||||
memcpy(tgaRowData + (i * 2),
|
|
||||||
bitsRowData + (i * bitsBytesPerPixel), 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGBA15_BIG:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 2);
|
|
||||||
tgapixel[0] = bitspixel[1];
|
|
||||||
tgapixel[1] = bitspixel[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGB15:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 2);
|
|
||||||
tgapixel[0] = bitspixel[0];
|
|
||||||
tgapixel[1] = bitspixel[1] | 0x80;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGB15_BIG:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 2);
|
|
||||||
tgapixel[0] = bitspixel[1];
|
|
||||||
tgapixel[1] = bitspixel[0] | 0x80;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGB32_BIG:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
tgapixel[0] = bitspixel[3];
|
|
||||||
tgapixel[1] = bitspixel[2];
|
|
||||||
tgapixel[2] = bitspixel[1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_RGB24_BIG:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
tgapixel[0] = bitspixel[2];
|
|
||||||
tgapixel[1] = bitspixel[1];
|
|
||||||
tgapixel[2] = bitspixel[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_CMAP8:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
rgb_color c = pmap->color_list[bitspixel[0]];
|
|
||||||
tgapixel[0] = c.blue;
|
|
||||||
tgapixel[1] = c.green;
|
|
||||||
tgapixel[2] = c.red;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_GRAY8:
|
|
||||||
bitspixel = bitsRowData + (i * bitsBytesPerPixel);
|
|
||||||
tgapixel = tgaRowData + (i * 3);
|
|
||||||
tgapixel[0] = bitspixel[0];
|
|
||||||
tgapixel[1] = bitspixel[0];
|
|
||||||
tgapixel[2] = bitspixel[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
} // switch (fromspace)
|
|
||||||
} // for for (uint32 i = 0; i < imagespec.width; i++)
|
|
||||||
|
|
||||||
outDestination->Write(tgaRowData, tgaRowBytes);
|
outDestination->Write(tgaRowData, tgaRowBytes);
|
||||||
tgapixrow++;
|
tgapixrow++;
|
||||||
|
|||||||
Reference in New Issue
Block a user