From ee727d56746f9c002fde729bfb4c8198f0bb5afd Mon Sep 17 00:00:00 2001 From: Matthew Wilber Date: Sun, 9 Nov 2003 21:09:34 +0000 Subject: [PATCH] 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 --- .../tgatranslator/TGATranslator.cpp | 101 +++++++++++------- .../tgatranslator/TGATranslatorSettings.cpp | 58 ++++++++-- .../tgatranslator/TGATranslatorSettings.h | 7 +- .../translators/tgatranslator/TGAView.cpp | 56 +++++++--- .../translators/tgatranslator/TGAView.h | 3 +- 5 files changed, 161 insertions(+), 64 deletions(-) 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;