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:
parent
f1d75a87bd
commit
ee727d5674
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user