diff --git a/src/add-ons/translators/tgatranslator/TGATranslator.cpp b/src/add-ons/translators/tgatranslator/TGATranslator.cpp index a820f854cc..46d38dc7ba 100644 --- a/src/add-ons/translators/tgatranslator/TGATranslator.cpp +++ b/src/add-ons/translators/tgatranslator/TGATranslator.cpp @@ -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: diff --git a/src/add-ons/translators/tgatranslator/TGATranslatorSettings.cpp b/src/add-ons/translators/tgatranslator/TGATranslatorSettings.cpp index f3a3a6c06a..2064335fb9 100644 --- a/src/add-ons/translators/tgatranslator/TGATranslatorSettings.cpp +++ b/src/add-ons/translators/tgatranslator/TGATranslatorSettings.cpp @@ -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; +} diff --git a/src/add-ons/translators/tgatranslator/TGATranslatorSettings.h b/src/add-ons/translators/tgatranslator/TGATranslatorSettings.h index 9ab87d9c52..6a19091793 100644 --- a/src/add-ons/translators/tgatranslator/TGATranslatorSettings.h +++ b/src/add-ons/translators/tgatranslator/TGATranslatorSettings.h @@ -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(); diff --git a/src/add-ons/translators/tgatranslator/TGAView.cpp b/src/add-ons/translators/tgatranslator/TGAView.cpp index 7ee5b6b10a..2ab0e96800 100644 --- a/src/add-ons/translators/tgatranslator/TGAView.cpp +++ b/src/add-ons/translators/tgatranslator/TGAView.cpp @@ -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; + } } // --------------------------------------------------------------- diff --git a/src/add-ons/translators/tgatranslator/TGAView.h b/src/add-ons/translators/tgatranslator/TGAView.h index 3a51fd0c6d..65ffaaf564 100644 --- a/src/add-ons/translators/tgatranslator/TGAView.h +++ b/src/add-ons/translators/tgatranslator/TGAView.h @@ -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;