Added a setting which allows the user to ignore alpha data from TGA files. This is necessary when TGAs are created from certain programs that lie, saying they have an alpha channel, when they actually don't. Also, fixed usage of alpha data from color mapped TGA images. Some images were misread as having an alpha channel when they didn't, and some images were misread as not having an alpha channel, when they did.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5292 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber 2003-11-09 21:09:34 +00:00
parent f1d75a87bd
commit ee727d5674
5 changed files with 161 additions and 64 deletions

View File

@ -366,20 +366,40 @@ identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
}
uint8
tga_alphabits(TGAImageSpec &imagespec)
tga_alphabits(TGAFileHeader &filehead, TGAColorMapSpec &mapspec,
TGAImageSpec &imagespec, TGATranslatorSettings &settings)
{
uint8 nalpha;
if (imagespec.depth == 32)
// Some programs that generate 32-bit TGA files
// have an alpha channel, but have an incorrect
// descriptor which says there are no alpha bits.
// This logic is so that the alpha data can be
// obtained from TGA files that lie.
nalpha = 8;
else
nalpha = imagespec.descriptor & TGA_DESC_ALPHABITS;
if (settings.SetGetIgnoreAlpha())
return 0;
else {
uint8 nalpha;
if (filehead.imagetype == TGA_NOCOMP_COLORMAP ||
filehead.imagetype == TGA_RLE_COLORMAP) {
// color mapped images
if (mapspec.entrysize == 32)
nalpha = 8;
else if (mapspec.entrysize == 16)
nalpha = 1;
else
nalpha = 0;
} else {
// non-color mapped images
if (imagespec.depth == 32)
// Some programs that generate 32-bit TGA files
// have an alpha channel, but have an incorrect
// descriptor which says there are no alpha bits.
// This logic is so that the alpha data can be
// obtained from TGA files that lie.
nalpha = 8;
else
nalpha = imagespec.descriptor & TGA_DESC_ALPHABITS;
}
return nalpha;
return nalpha;
}
}
// ---------------------------------------------------------------
@ -1788,8 +1808,14 @@ pix_tganm_to_bits(uint8 *pbits, uint8 *ptga,
//
// outDestination, where the bits data will be written to
//
// filehead, image type info
//
// mapspec, color map info
//
// imagespec, width / height info
//
// settings, TGATranslator settings
//
//
// Postconditions:
//
@ -1799,14 +1825,16 @@ pix_tganm_to_bits(uint8 *pbits, uint8 *ptga,
// ---------------------------------------------------------------
status_t
translate_from_tganm_to_bits(BPositionIO *inSource,
BPositionIO *outDestination, TGAImageSpec &imagespec)
BPositionIO *outDestination, TGAFileHeader &filehead,
TGAColorMapSpec &mapspec, TGAImageSpec &imagespec,
TGATranslatorSettings &settings)
{
bool bvflip;
if (imagespec.descriptor & TGA_ORIGIN_VERT_BIT)
bvflip = false;
else
bvflip = true;
uint8 nalpha = tga_alphabits(imagespec);
uint8 nalpha = tga_alphabits(filehead, mapspec, imagespec, settings);
int32 bitsRowBytes = imagespec.width * 4;
uint8 tgaBytesPerPixel = (imagespec.depth / 8) +
((imagespec.depth % 8) ? 1 : 0);
@ -1878,8 +1906,14 @@ translate_from_tganm_to_bits(BPositionIO *inSource,
//
// outDestination, where the bits data will be written to
//
// filehead, image type info
//
// mapspec, color map info
//
// imagespec, width / height info
//
// settings, TGATranslator settings
//
//
// Postconditions:
//
@ -1889,7 +1923,9 @@ translate_from_tganm_to_bits(BPositionIO *inSource,
// ---------------------------------------------------------------
status_t
translate_from_tganmrle_to_bits(BPositionIO *inSource,
BPositionIO *outDestination, TGAImageSpec &imagespec)
BPositionIO *outDestination, TGAFileHeader &filehead,
TGAColorMapSpec &mapspec, TGAImageSpec &imagespec,
TGATranslatorSettings &settings)
{
status_t result = B_OK;
@ -1898,7 +1934,7 @@ translate_from_tganmrle_to_bits(BPositionIO *inSource,
bvflip = false;
else
bvflip = true;
uint8 nalpha = tga_alphabits(imagespec);
uint8 nalpha = tga_alphabits(filehead, mapspec, imagespec, settings);
int32 bitsRowBytes = imagespec.width * 4;
uint8 tgaBytesPerPixel = (imagespec.depth / 8) +
((imagespec.depth % 8) ? 1 : 0);
@ -2174,10 +2210,14 @@ translate_from_tgam_to_bits(BPositionIO *inSource,
//
// outDestination, where the bits data will be written to
//
// filehead, image type info
//
// mapspec, info about the color map (palette)
//
// imagespec, width / height info
//
// settings, TGATranslator settings
//
// pmap, color palette
//
//
@ -2189,8 +2229,9 @@ translate_from_tgam_to_bits(BPositionIO *inSource,
// ---------------------------------------------------------------
status_t
translate_from_tgamrle_to_bits(BPositionIO *inSource,
BPositionIO *outDestination, TGAColorMapSpec &mapspec,
TGAImageSpec &imagespec, uint8 *pmap)
BPositionIO *outDestination, TGAFileHeader &filehead,
TGAColorMapSpec &mapspec, TGAImageSpec &imagespec,
TGATranslatorSettings &settings, uint8 *pmap)
{
status_t result = B_OK;
@ -2199,19 +2240,7 @@ translate_from_tgamrle_to_bits(BPositionIO *inSource,
bvflip = false;
else
bvflip = true;
uint8 nalpha = 0;
switch (mapspec.entrysize) {
case 32:
nalpha = 8;
break;
case 16:
nalpha = 1;
break;
default:
nalpha = 0;
break;
}
uint8 nalpha = tga_alphabits(filehead, mapspec, imagespec, settings);
int32 bitsRowBytes = imagespec.width * 4;
uint8 tgaPalBytesPerPixel = (mapspec.entrysize / 8) +
((mapspec.entrysize % 8) ? 1 : 0);
@ -2413,7 +2442,7 @@ translate_from_tga(BPositionIO *inSource, ssize_t amtread, uint8 *read,
bitsHeader.rowBytes = imagespec.width * 4;
if (fileheader.imagetype != TGA_NOCOMP_BW &&
fileheader.imagetype != TGA_RLE_BW &&
tga_alphabits(imagespec))
tga_alphabits(fileheader, mapspec, imagespec, settings))
bitsHeader.colors = B_RGBA32;
else
bitsHeader.colors = B_RGB32;
@ -2437,7 +2466,7 @@ translate_from_tga(BPositionIO *inSource, ssize_t amtread, uint8 *read,
case TGA_NOCOMP_TRUECOLOR:
case TGA_NOCOMP_BW:
result = translate_from_tganm_to_bits(inSource,
outDestination, imagespec);
outDestination, fileheader, mapspec, imagespec, settings);
break;
case TGA_NOCOMP_COLORMAP:
@ -2448,12 +2477,12 @@ translate_from_tga(BPositionIO *inSource, ssize_t amtread, uint8 *read,
case TGA_RLE_TRUECOLOR:
case TGA_RLE_BW:
result = translate_from_tganmrle_to_bits(inSource,
outDestination, imagespec);
outDestination, fileheader, mapspec, imagespec, settings);
break;
case TGA_RLE_COLORMAP:
result = translate_from_tgamrle_to_bits(inSource,
outDestination, mapspec, imagespec, ptgapalette);
result = translate_from_tgamrle_to_bits(inSource, outDestination,
fileheader, mapspec, imagespec, settings, ptgapalette);
break;
default:

View File

@ -65,6 +65,8 @@ TGATranslatorSettings::TGATranslatorSettings()
fmsgSettings.AddBool(B_TRANSLATOR_EXT_DATA_ONLY, false);
fmsgSettings.AddBool(TGA_SETTING_RLE, false);
// RLE compression is off by default
fmsgSettings.AddBool(TGA_SETTING_IGNORE_ALPHA, false);
// Don't ignore the alpha channel in TGA files by default
}
// ---------------------------------------------------------------
@ -207,20 +209,22 @@ TGATranslatorSettings::LoadSettings(BMessage *pmsg)
if (pmsg) {
// Make certain that no TGA settings
// are missing from the file
bool bheaderOnly, bdataOnly, brle;
bool bheaderOnly, bdataOnly, brle, bignore;
flock.Lock();
result = pmsg->FindBool(B_TRANSLATOR_EXT_HEADER_ONLY, &bheaderOnly);
if (result != B_OK)
bheaderOnly = SetGetHeaderOnly();
result = pmsg->FindBool(B_TRANSLATOR_EXT_DATA_ONLY, &bdataOnly);
if (result != B_OK)
bdataOnly = SetGetDataOnly();
result = pmsg->FindBool(TGA_SETTING_RLE, &brle);
if (result != B_OK)
brle = SetGetRLE();
result = pmsg->FindBool(TGA_SETTING_IGNORE_ALPHA, &bignore);
if (result != B_OK)
bignore = SetGetIgnoreAlpha();
if (bheaderOnly && bdataOnly)
// "write header only" and "write data only"
@ -231,13 +235,14 @@ TGATranslatorSettings::LoadSettings(BMessage *pmsg)
result = fmsgSettings.ReplaceBool(
B_TRANSLATOR_EXT_HEADER_ONLY, bheaderOnly);
if (result == B_OK)
result = fmsgSettings.ReplaceBool(
B_TRANSLATOR_EXT_DATA_ONLY, bdataOnly);
if (result == B_OK)
result = fmsgSettings.ReplaceBool(TGA_SETTING_RLE, brle);
if (result == B_OK)
result = fmsgSettings.ReplaceBool(TGA_SETTING_IGNORE_ALPHA,
bignore);
}
flock.Unlock();
}
@ -304,7 +309,8 @@ TGATranslatorSettings::GetConfigurationMessage(BMessage *pmsg)
const char *kNames[] = {
B_TRANSLATOR_EXT_HEADER_ONLY,
B_TRANSLATOR_EXT_DATA_ONLY,
TGA_SETTING_RLE
TGA_SETTING_RLE,
TGA_SETTING_IGNORE_ALPHA
};
const int32 klen = sizeof(kNames) / sizeof(const char *);
int32 i;
@ -319,14 +325,14 @@ TGATranslatorSettings::GetConfigurationMessage(BMessage *pmsg)
result = pmsg->AddBool(B_TRANSLATOR_EXT_HEADER_ONLY,
SetGetHeaderOnly());
if (result == B_OK)
result = pmsg->AddBool(B_TRANSLATOR_EXT_DATA_ONLY,
SetGetDataOnly());
if (result == B_OK)
result = pmsg->AddBool(TGA_SETTING_RLE,
SetGetRLE());
result = pmsg->AddBool(TGA_SETTING_RLE, SetGetRLE());
if (result == B_OK)
result = pmsg->AddBool(TGA_SETTING_IGNORE_ALPHA,
SetGetIgnoreAlpha());
flock.Unlock();
}
@ -434,3 +440,35 @@ TGATranslatorSettings::SetGetRLE(bool *pbRLE)
return bprevValue;
}
// ---------------------------------------------------------------
// SetGetIgnoreAlpha
//
// Sets the state of the ignore alpha setting (if pbIgnoreAlpha
// is not NULL) and returns the previous value of the setting.
//
// If ignore alpha is true, the alpha channel from TGA images
// will not be included when they are converted to BBitmp images.
//
// Preconditions:
//
// Parameters: pbIgnoreAlpha pointer to bool which specifies
// the new ignore alpha setting
//
// Postconditions:
//
// Returns: the prior value of the ignore alpha setting
// ---------------------------------------------------------------
bool
TGATranslatorSettings::SetGetIgnoreAlpha(bool *pbIgnoreAlpha)
{
bool bprevValue;
flock.Lock();
fmsgSettings.FindBool(TGA_SETTING_IGNORE_ALPHA, &bprevValue);
if (pbIgnoreAlpha)
fmsgSettings.ReplaceBool(TGA_SETTING_IGNORE_ALPHA, *pbIgnoreAlpha);
flock.Unlock();
return bprevValue;
}

View File

@ -40,6 +40,7 @@
// TGA Translator Settings
#define TGA_SETTING_RLE "tga /rle"
#define TGA_SETTING_IGNORE_ALPHA "tga /ignore_alpha"
class TGATranslatorSettings {
public:
@ -67,9 +68,13 @@ public:
// specifiees if only the image data should be
// outputted
bool SetGetRLE(bool *pbRLE = NULL);
// sets /gets RLE setting
// sets / gets RLE setting
// specifies if RLE compression will be used
// when the TGATranslator creates TGA images
bool SetGetIgnoreAlpha(bool *pbIgnoreAlpha = NULL);
// sets / gets ignore alpha setting
// specifies whether or not TGATranslator uses
// the alpha data from TGA files
private:
~TGATranslatorSettings();

View File

@ -54,14 +54,23 @@ TGAView::TGAView(const BRect &frame, const char *name,
SetViewColor(220,220,220,0);
BMessage *pmsgRLE = new BMessage(CHANGE_RLE);
fpchkRLE = new BCheckBox(BRect(10, 45, 180, 62),
"Save with RLE Compression",
"Save with RLE Compression", pmsgRLE);
BMessage *pmsg;
int32 val;
pmsg = new BMessage(CHANGE_IGNORE_ALPHA);
fpchkIgnoreAlpha = new BCheckBox(BRect(10, 45, 180, 62),
"Ignore TGA alpha channel",
"Ignore TGA alpha channel", pmsg);
val = (psettings->SetGetIgnoreAlpha()) ? 1 : 0;
fpchkIgnoreAlpha->SetValue(val);
fpchkIgnoreAlpha->SetViewColor(ViewColor());
AddChild(fpchkIgnoreAlpha);
pmsg = new BMessage(CHANGE_RLE);
fpchkRLE = new BCheckBox(BRect(10, 67, 180, 84),
"Save with RLE Compression",
"Save with RLE Compression", pmsg);
val = (psettings->SetGetRLE()) ? 1 : 0;
fpchkRLE->SetValue(val);
fpchkRLE->SetViewColor(ViewColor());
AddChild(fpchkRLE);
@ -102,6 +111,7 @@ void
TGAView::AllAttached()
{
BMessenger msgr(this);
fpchkIgnoreAlpha->SetTarget(msgr);
fpchkRLE->SetTarget(msgr);
}
@ -121,16 +131,30 @@ TGAView::AllAttached()
void
TGAView::MessageReceived(BMessage *message)
{
if (message->what == CHANGE_RLE) {
bool bnewval;
if (fpchkRLE->Value())
bnewval = true;
else
bnewval = false;
fpsettings->SetGetRLE(&bnewval);
fpsettings->SaveSettings();
} else
BView::MessageReceived(message);
bool bnewval;
switch (message->what) {
case CHANGE_IGNORE_ALPHA:
if (fpchkIgnoreAlpha->Value())
bnewval = true;
else
bnewval = false;
fpsettings->SetGetIgnoreAlpha(&bnewval);
fpsettings->SaveSettings();
break;
case CHANGE_RLE:
if (fpchkRLE->Value())
bnewval = true;
else
bnewval = false;
fpsettings->SetGetRLE(&bnewval);
fpsettings->SaveSettings();
break;
default:
BView::MessageReceived(message);
break;
}
}
// ---------------------------------------------------------------

View File

@ -50,8 +50,9 @@ public:
virtual void Draw(BRect area);
// draws information about the TGATranslator
enum { CHANGE_RLE };
enum { CHANGE_RLE, CHANGE_IGNORE_ALPHA };
private:
BCheckBox *fpchkIgnoreAlpha;
BCheckBox *fpchkRLE;
TGATranslatorSettings *fpsettings;