diff --git a/src/add-ons/translators/giftranslator/GIFSave.cpp b/src/add-ons/translators/giftranslator/GIFSave.cpp index 12d808d7eb..85aace7044 100644 --- a/src/add-ons/translators/giftranslator/GIFSave.cpp +++ b/src/add-ons/translators/giftranslator/GIFSave.cpp @@ -97,10 +97,9 @@ GIFSave::GIFSave(BBitmap *bitmap, BPositionIO *output) } } - palette->SetUseTransparent(prefs->usetransparent); if (prefs->usetransparent) { - if (prefs->usetransparentindex) { - palette->SetTransparentIndex(prefs->transparentindex); + if (prefs->usetransparentauto) { + palette->PrepareForAutoTransparency(); if (debug) printf("GIFSave::GIFSave() - Using transparent index %d\n", palette->TransparentIndex()); } else { @@ -329,27 +328,36 @@ GIFSave::NextPixel(int pixel) { int bpr = bitmap->BytesPerRow(); color_space cs = bitmap->ColorSpace(); - unsigned char r, g, b; + bool useAlphaForTransparency = prefs->usetransparentauto && cs == B_RGBA32 || cs == B_RGBA32_BIG; + unsigned char r, g, b, a; if (cs == B_RGB32 || cs == B_RGBA32) { b = gifbits[0]; g = gifbits[1]; r = gifbits[2]; + a = gifbits[3]; } else { + a = gifbits[0]; r = gifbits[1]; g = gifbits[2]; b = gifbits[3]; } gifbits += 4; pos += 4; + + if (!prefs->usetransparent || prefs->usetransparentauto || + r != prefs->transparentred || + g != prefs->transparentgreen || + b != prefs->transparentblue) { - if (prefs->usedithering) { - if (pixel % width == 0) { - red_side_error = green_side_error = blue_side_error = 0; + if (prefs->usedithering) { + if (pixel % width == 0) { + red_side_error = green_side_error = blue_side_error = 0; + } + b = min_c(255, max_c(0, b - blue_side_error)); + g = min_c(255, max_c(0, g - green_side_error)); + r = min_c(255, max_c(0, r - red_side_error)); } - b = min_c(255, max_c(0, b - blue_side_error)); - g = min_c(255, max_c(0, g - green_side_error)); - r = min_c(255, max_c(0, r - red_side_error)); } if (prefs->interlaced) { @@ -363,7 +371,7 @@ GIFSave::NextPixel(int pixel) gifbits = (unsigned char *)bitmap->Bits() + (bpr * row); } } - +/* unsigned int key = (r << 16) + (g << 8) + b; ColorCache *cc = (ColorCache *)hash->GetItem(key); if (cc == NULL) { @@ -406,7 +414,44 @@ GIFSave::NextPixel(int pixel) blue_error[x + 1] = (blue_total_error * one_sixteenth); } - return cc->index; + return cc->index;*/ + + int index = palette->IndexForColor(r, g, b, useAlphaForTransparency ? a : 255); + + if (index != palette->TransparentIndex() && prefs->usedithering) { + int x = pixel % width; + // Don't carry error on to next line when interlaced because + // that line won't be adjacent, hence error is meaningless + if (prefs->interlaced && x == width - 1) { + for (int32 y = -1; y < width + 1; y++) { + red_error[y] = 0; + green_error[y] = 0; + blue_error[y] = 0; + } + } + + int32 red_total_error = palette->pal[index].red - r; + int32 green_total_error = palette->pal[index].green - g; + int32 blue_total_error = palette->pal[index].blue - b; + + red_side_error = (red_error[x + 1] + (red_total_error * seven_sixteenth)) >> 15; + blue_side_error = (blue_error[x + 1] + (blue_total_error * seven_sixteenth)) >> 15; + green_side_error = (green_error[x + 1] + (green_total_error * seven_sixteenth)) >> 15; + + red_error[x - 1] += (red_total_error * three_sixteenth); + green_error[x - 1] += (green_total_error * three_sixteenth); + blue_error[x - 1] += (blue_total_error * three_sixteenth); + + red_error[x] += (red_total_error * five_sixteenth); + green_error[x] += (green_total_error * five_sixteenth); + blue_error[x] += (blue_total_error * five_sixteenth); + + red_error[x + 1] = (red_total_error * one_sixteenth); + green_error[x + 1] = (green_total_error * one_sixteenth); + blue_error[x + 1] = (blue_total_error * one_sixteenth); + } + + return index; } // InitFrame diff --git a/src/add-ons/translators/giftranslator/GIFView.cpp b/src/add-ons/translators/giftranslator/GIFView.cpp index 45734eda27..8b0be2c049 100644 --- a/src/add-ons/translators/giftranslator/GIFView.cpp +++ b/src/add-ons/translators/giftranslator/GIFView.cpp @@ -131,23 +131,16 @@ GIFView::GIFView(BRect rect, const char *name) // radio buttons r.top = fUseTransparentCB->Frame().bottom + 2; r.bottom = r.top + 10; - r.right = r.left + be_plain_font->StringWidth("Use index") + 20; - fUseTransparentIndexRB = new BRadioButton(r, "UseTransparentIndex", "Use index", - new BMessage(GV_USE_TRANSPARENT_INDEX)); - AddChild(fUseTransparentIndexRB); + r.right = r.left + be_plain_font->StringWidth("Automatic (from alpha channel)") + 20; + fUseTransparentAutoRB = new BRadioButton(r, "UseTransparentAuto", "Automatic (from alpha channel)", + new BMessage(GV_USE_TRANSPARENT_AUTO)); + AddChild(fUseTransparentAutoRB); - r.left = r.right + 1; - r.right = r.left + 30; - fTransparentIndexTC = new BTextControl(r, "TransparentIndex", "", "0", - new BMessage(GV_TRANSPARENT_INDEX)); - AddChild(fTransparentIndexTC); - fTransparentIndexTC->SetDivider(0); - - r.top = fUseTransparentIndexRB->Frame().bottom + 0; + r.top = fUseTransparentAutoRB->Frame().bottom + 0; r.bottom = r.top + 10; r.left = 10; - r.right = r.left + be_plain_font->StringWidth("Use rgb color") + 20; - fUseTransparentColorRB = new BRadioButton(r, "UseTransparentColor", "Use rgb color", + r.right = r.left + be_plain_font->StringWidth("Use RGB color") + 20; + fUseTransparentColorRB = new BRadioButton(r, "UseTransparentColor", "Use RGB color", new BMessage(GV_USE_TRANSPARENT_COLOR)); AddChild(fUseTransparentColorRB); @@ -172,24 +165,12 @@ GIFView::GIFView(BRect rect, const char *name) AddChild(fTransparentBlueTC); fTransparentBlueTC->SetDivider(0); - // align text controls - float diff = fTransparentRedTC->Frame().left - fTransparentIndexTC->Frame().left; - if (diff > 0) { - fTransparentIndexTC->MoveBy(diff, 0); - } else { - fTransparentRedTC->MoveBy(-diff, 0); - fTransparentGreenTC->MoveBy(-diff, 0); - fTransparentBlueTC->MoveBy(-diff, 0); - } - - BTextView *ti = fTransparentIndexTC->TextView(); BTextView *tr = fTransparentRedTC->TextView(); BTextView *tg = fTransparentGreenTC->TextView(); BTextView *tb = fTransparentBlueTC->TextView(); for (uint32 x = 0; x < 256; x++) { if (x < '0' || x > '9') { - ti->DisallowChar(x); tr->DisallowChar(x); tg->DisallowChar(x); tb->DisallowChar(x); @@ -251,27 +232,23 @@ GIFView::RestorePrefs() if (fGreyScaleMI->IsMarked()) fUseDitheringCB->SetValue(false); else fUseDitheringCB->SetValue(fPrefs->usedithering); fUseTransparentCB->SetValue(fPrefs->usetransparent); - fUseTransparentIndexRB->SetValue(fPrefs->usetransparentindex); - fUseTransparentColorRB->SetValue(!fPrefs->usetransparentindex); + fUseTransparentAutoRB->SetValue(fPrefs->usetransparentauto); + fUseTransparentColorRB->SetValue(!fPrefs->usetransparentauto); if (fPrefs->usetransparent) { - fUseTransparentIndexRB->SetEnabled(true); + fUseTransparentAutoRB->SetEnabled(true); fUseTransparentColorRB->SetEnabled(true); - fTransparentIndexTC->SetEnabled(fPrefs->usetransparentindex); - fTransparentRedTC->SetEnabled(!fPrefs->usetransparentindex); - fTransparentGreenTC->SetEnabled(!fPrefs->usetransparentindex); - fTransparentBlueTC->SetEnabled(!fPrefs->usetransparentindex); + fTransparentRedTC->SetEnabled(!fPrefs->usetransparentauto); + fTransparentGreenTC->SetEnabled(!fPrefs->usetransparentauto); + fTransparentBlueTC->SetEnabled(!fPrefs->usetransparentauto); } else { - fUseTransparentIndexRB->SetEnabled(false); + fUseTransparentAutoRB->SetEnabled(false); fUseTransparentColorRB->SetEnabled(false); - fTransparentIndexTC->SetEnabled(false); fTransparentRedTC->SetEnabled(false); fTransparentGreenTC->SetEnabled(false); fTransparentBlueTC->SetEnabled(false); } char temp[4]; - sprintf(temp, "%d", fPrefs->transparentindex); - fTransparentIndexTC->SetText(temp); sprintf(temp, "%d", fPrefs->transparentred); fTransparentRedTC->SetText(temp); sprintf(temp, "%d", fPrefs->transparentgreen); @@ -289,8 +266,7 @@ GIFView::AllAttached() fInterlacedCB->SetTarget(msgr); fUseDitheringCB->SetTarget(msgr); fUseTransparentCB->SetTarget(msgr); - fUseTransparentIndexRB->SetTarget(msgr); - fTransparentIndexTC->SetTarget(msgr); + fUseTransparentAutoRB->SetTarget(msgr); fUseTransparentColorRB->SetTarget(msgr); fTransparentRedTC->SetTarget(msgr); fTransparentGreenTC->SetTarget(msgr); @@ -348,34 +324,27 @@ GIFView::MessageReceived(BMessage *message) case GV_USE_TRANSPARENT: fPrefs->usetransparent = fUseTransparentCB->Value(); if (fPrefs->usetransparent) { - fUseTransparentIndexRB->SetEnabled(true); + fUseTransparentAutoRB->SetEnabled(true); fUseTransparentColorRB->SetEnabled(true); - fTransparentIndexTC->SetEnabled(fUseTransparentIndexRB->Value()); fTransparentRedTC->SetEnabled(fUseTransparentColorRB->Value()); fTransparentGreenTC->SetEnabled(fUseTransparentColorRB->Value()); fTransparentBlueTC->SetEnabled(fUseTransparentColorRB->Value()); } else { - fUseTransparentIndexRB->SetEnabled(false); + fUseTransparentAutoRB->SetEnabled(false); fUseTransparentColorRB->SetEnabled(false); - fTransparentIndexTC->SetEnabled(false); fTransparentRedTC->SetEnabled(false); fTransparentGreenTC->SetEnabled(false); fTransparentBlueTC->SetEnabled(false); } break; - case GV_USE_TRANSPARENT_INDEX: - fPrefs->usetransparentindex = true; - fTransparentIndexTC->SetEnabled(true); + case GV_USE_TRANSPARENT_AUTO: + fPrefs->usetransparentauto = true; fTransparentRedTC->SetEnabled(false); fTransparentGreenTC->SetEnabled(false); fTransparentBlueTC->SetEnabled(false); break; - case GV_TRANSPARENT_INDEX: - fPrefs->transparentindex = CheckInput(fTransparentIndexTC); - break; case GV_USE_TRANSPARENT_COLOR: - fPrefs->usetransparentindex = false; - fTransparentIndexTC->SetEnabled(false); + fPrefs->usetransparentauto = false; fTransparentRedTC->SetEnabled(true); fTransparentGreenTC->SetEnabled(true); fTransparentBlueTC->SetEnabled(true); diff --git a/src/add-ons/translators/giftranslator/GIFView.h b/src/add-ons/translators/giftranslator/GIFView.h index 404752d5bc..8a16dac703 100644 --- a/src/add-ons/translators/giftranslator/GIFView.h +++ b/src/add-ons/translators/giftranslator/GIFView.h @@ -35,8 +35,7 @@ class Prefs; #define GV_INTERLACED 'gvin' #define GV_USE_DITHERING 'gvud' #define GV_USE_TRANSPARENT 'gvut' -#define GV_USE_TRANSPARENT_INDEX 'gvui' -#define GV_TRANSPARENT_INDEX 'gvti' +#define GV_USE_TRANSPARENT_AUTO 'gvua' #define GV_USE_TRANSPARENT_COLOR 'gvuc' #define GV_TRANSPARENT_RED 'gvtr' #define GV_TRANSPARENT_GREEN 'gvtg' @@ -73,10 +72,9 @@ class GIFView : public BView { BCheckBox* fUseTransparentCB; BCheckBox* fUseDitheringCB; - BRadioButton* fUseTransparentIndexRB; + BRadioButton* fUseTransparentAutoRB; BRadioButton* fUseTransparentColorRB; - BTextControl* fTransparentIndexTC; BTextControl* fTransparentRedTC; BTextControl* fTransparentGreenTC; BTextControl* fTransparentBlueTC; diff --git a/src/add-ons/translators/giftranslator/Prefs.cpp b/src/add-ons/translators/giftranslator/Prefs.cpp index 1142d41038..64315b3e08 100644 --- a/src/add-ons/translators/giftranslator/Prefs.cpp +++ b/src/add-ons/translators/giftranslator/Prefs.cpp @@ -23,13 +23,19 @@ extern bool debug; -Prefs::Prefs() { - interlaced = usetransparent = usetransparentindex = false; - usedithering = true; - transparentindex = transparentred = transparentgreen = - transparentblue = palettemode = 0; - palette_size_in_bits = 8; - +// constructor +Prefs::Prefs() + : interlaced(false), + usetransparent(false), + usetransparentauto(false), + usedithering(false), + transparentred(0), + transparentgreen(0), + transparentblue(0), + palettemode(0), + palette_size_in_bits(8), + file(NULL) +{ BPath path; find_directory(B_USER_SETTINGS_DIRECTORY, &path); path.Append("GIFTranslator_settings"); @@ -45,7 +51,7 @@ Prefs::Prefs() { db = false; if (!GetBool("usetransparent", &usetransparent, &db)) return; db = false; - if (!GetBool("usetransparentindex", &usetransparentindex, &db)) return; + if (!GetBool("usetransparentauto", &usetransparentauto, &db)) return; db = true; if (!GetBool("usedithering", &usedithering, &db)) return; int di = 0; @@ -53,8 +59,6 @@ Prefs::Prefs() { di = 8; if (!GetInt("palettesize", &palette_size_in_bits, &di)) return; di = 0; - if (!GetInt("transparentindex", &transparentindex, &di)) return; - di = 0; if (!GetInt("transparentred", &transparentred, &di)) return; di = 0; if (!GetInt("transparentgreen", &transparentgreen, &di)) return; @@ -62,7 +66,16 @@ Prefs::Prefs() { if (!GetInt("transparentblue", &transparentblue, &di)) return; } -bool Prefs::GetInt(char *name, int *value, int *defaultvalue) { +// destructor +Prefs::~Prefs() +{ + delete file; +} + +// GetInt +bool +Prefs::GetInt(char *name, int *value, int *defaultvalue) +{ status_t err = file->ReadAttr(name, B_INT32_TYPE, 0, value, 4); if (err == B_ENTRY_NOT_FOUND) { *value = *defaultvalue; @@ -77,7 +90,10 @@ bool Prefs::GetInt(char *name, int *value, int *defaultvalue) { return true; } -bool Prefs::GetBool(char *name, bool *value, bool *defaultvalue) { +// GetBool +bool +Prefs::GetBool(char *name, bool *value, bool *defaultvalue) +{ status_t err = file->ReadAttr(name, B_BOOL_TYPE, 0, value, 1); if (err == B_ENTRY_NOT_FOUND) { *value = *defaultvalue; @@ -92,7 +108,10 @@ bool Prefs::GetBool(char *name, bool *value, bool *defaultvalue) { return true; } -bool Prefs::PutInt(char *name, int *value) { +// PutInt +bool +Prefs::PutInt(char *name, int *value) +{ status_t err = file->WriteAttr(name, B_INT32_TYPE, 0, value, 4); if (err < 0) { if (debug) printf("WriteAttr on %s died\n", name); @@ -101,7 +120,10 @@ bool Prefs::PutInt(char *name, int *value) { return true; } -bool Prefs::PutBool(char *name, bool *value) { +// PutBool +bool +Prefs::PutBool(char *name, bool *value) +{ status_t err = file->WriteAttr(name, B_BOOL_TYPE, 0, value, 1); if (err < 0) { if (debug) printf("WriteAttr on %s died\n", name); @@ -110,20 +132,18 @@ bool Prefs::PutBool(char *name, bool *value) { return true; } -void Prefs::Save() { +// Save +void +Prefs::Save() +{ if (!PutBool("interlaced", &interlaced)) return; if (!PutBool("usetransparent", &usetransparent)) return; - if (!PutBool("usetransparentindex", &usetransparentindex)) return; + if (!PutBool("usetransparentauto", &usetransparentauto)) return; if (!PutBool("usedithering", &usedithering)) return; if (!PutInt("palettemode", &palettemode)) return; if (!PutInt("palettesize", &palette_size_in_bits)) return; - if (!PutInt("transparentindex", &transparentindex)) return; if (!PutInt("transparentred", &transparentred)) return; if (!PutInt("transparentgreen", &transparentgreen)) return; if (!PutInt("transparentblue", &transparentblue)) return; } -Prefs::~Prefs() { - delete file; -} - diff --git a/src/add-ons/translators/giftranslator/Prefs.h b/src/add-ons/translators/giftranslator/Prefs.h index 7a1e357ca5..123eb11587 100644 --- a/src/add-ons/translators/giftranslator/Prefs.h +++ b/src/add-ons/translators/giftranslator/Prefs.h @@ -25,9 +25,9 @@ class Prefs { Prefs(); void Save(); ~Prefs(); - bool interlaced, usetransparent, usetransparentindex, + bool interlaced, usetransparent, usetransparentauto, usedithering; - int transparentindex, transparentred, transparentgreen, + int transparentred, transparentgreen, transparentblue, palettemode, palette_size_in_bits; private: bool GetInt(char *name, int *value, int *defaultvalue); diff --git a/src/add-ons/translators/giftranslator/SavePalette.cpp b/src/add-ons/translators/giftranslator/SavePalette.cpp index 164e442928..57e26d4f0f 100644 --- a/src/add-ons/translators/giftranslator/SavePalette.cpp +++ b/src/add-ons/translators/giftranslator/SavePalette.cpp @@ -180,8 +180,8 @@ SavePalette::SavePalette(int mode) fSize(0), fSizeInBits(8), fMode(mode), - fUseTransparent(false), - fTransparentIndex(0), + fTransparentMode(NO_TRANSPARENCY), + fTransparentIndex(-1), fBackgroundIndex(0), fFatalError(pal == NULL) { @@ -242,8 +242,8 @@ SavePalette::SavePalette(BBitmap *bitmap, int32 maxSizeInBits) fSize(0), fSizeInBits(0), fMode(OPTIMAL_PALETTE), - fUseTransparent(false), - fTransparentIndex(0), + fTransparentMode(fTransparentMode), + fTransparentIndex(-1), fBackgroundIndex(0), fFatalError(pal == NULL) { @@ -366,49 +366,93 @@ SavePalette::~SavePalette() // // standard mapping services once a palette is loaded uint8 -SavePalette::IndexForColor(uint8 red, uint8 green, uint8 blue) +SavePalette::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) { + if (fTransparentMode > NO_TRANSPARENCY && alpha < 128) + return fTransparentIndex; + uint8 index = 0; if (fMode == GREYSCALE_PALETTE) { index = (308 * red + 600 * green + 116 * blue) / 1024; + // avoid transparent index + if (fTransparentMode == AUTO_TRANSPARENCY && index == 1 && fTransparentIndex == 1) + index = 0; } else { int closestDistance = 255 * 255 * 3; - for (int i = 0; i < fSize && closestDistance != 0; i++) { - int rd = (int)red - (int)pal[i].red; - int gd = (int)green - (int)pal[i].green; - int bd = (int)blue - (int)pal[i].blue; - int distanceAtIndex = rd * rd + gd * gd + bd * bd; - if (distanceAtIndex < closestDistance) { - closestDistance = distanceAtIndex; - index = i; + if (fTransparentMode == AUTO_TRANSPARENCY) { + for (int i = 0; i < fTransparentIndex && closestDistance != 0; i++) { + int rd = (int)red - (int)pal[i].red; + int gd = (int)green - (int)pal[i].green; + int bd = (int)blue - (int)pal[i].blue; + int distanceAtIndex = rd * rd + gd * gd + bd * bd; + if (distanceAtIndex < closestDistance) { + closestDistance = distanceAtIndex; + index = i; + } + } + for (int i = fTransparentIndex + 1; i < fSize && closestDistance != 0; i++) { + int rd = (int)red - (int)pal[i].red; + int gd = (int)green - (int)pal[i].green; + int bd = (int)blue - (int)pal[i].blue; + int distanceAtIndex = rd * rd + gd * gd + bd * bd; + if (distanceAtIndex < closestDistance) { + closestDistance = distanceAtIndex; + index = i; + } + } + } else { + for (int i = 0; i < fSize && closestDistance != 0; i++) { + int rd = (int)red - (int)pal[i].red; + int gd = (int)green - (int)pal[i].green; + int bd = (int)blue - (int)pal[i].blue; + int distanceAtIndex = rd * rd + gd * gd + bd * bd; + if (distanceAtIndex < closestDistance) { + closestDistance = distanceAtIndex; + index = i; + } } } } return index; } -// SetUseTransparent -void -SavePalette::SetUseTransparent(bool use) -{ - fUseTransparent = use; -} - // SetTransparentIndex void -SavePalette::SetTransparentIndex(int index) +SavePalette::PrepareForAutoTransparency() { - fTransparentIndex = max_c(fSize - 1, index); + fTransparentMode = AUTO_TRANSPARENCY; + // TODO: in the SavePalette::SavePalette(BBitmap*), + // we don't use more colors than necessary, however, + // here we take a slot away for transparency, even if + // we might still have used less colors than the user + // wanted as a maximum + // NOTE: the last index + switch (fMode) { + case WEB_SAFE_PALETTE: + fTransparentIndex = 216; + fSize = 217; + break; + case BEOS_SYSTEM_PALETTE: + fTransparentIndex = 0; + break; + case GREYSCALE_PALETTE: + fTransparentIndex = 1; + break; + case OPTIMAL_PALETTE: + fTransparentIndex = fSize - 1; + break; + } } // SetTransparentColor void SavePalette::SetTransparentColor(uint8 red, uint8 green, uint8 blue) { - bool found = false; + fTransparentMode = COLOR_KEY_TRANSPARENCY; + bool found = false; // try direct hit first for (int i = 0; i < fSize; i++) { if (pal[i].red == red && diff --git a/src/add-ons/translators/giftranslator/SavePalette.h b/src/add-ons/translators/giftranslator/SavePalette.h index 9dba0ea0d6..90cf8e7d57 100644 --- a/src/add-ons/translators/giftranslator/SavePalette.h +++ b/src/add-ons/translators/giftranslator/SavePalette.h @@ -27,6 +27,12 @@ enum { OPTIMAL_PALETTE }; +enum { + NO_TRANSPARENCY = 0, + AUTO_TRANSPARENCY, + COLOR_KEY_TRANSPARENCY +}; + class SavePalette { public: SavePalette(int mode); @@ -37,14 +43,14 @@ class SavePalette { inline bool IsValid() const { return !fFatalError; } - uint8 IndexForColor(uint8 red, uint8 green, uint8 blue); + uint8 IndexForColor(uint8 red, uint8 green, + uint8 blue, uint8 alpha = 255); inline uint8 IndexForColor(const rgb_color& color); - void SetUseTransparent(bool use); inline bool UseTransparent() const - { return fUseTransparent; } + { return fTransparentMode > NO_TRANSPARENCY; } - void SetTransparentIndex(int index); + void PrepareForAutoTransparency(); inline int TransparentIndex() const { return fTransparentIndex; } void SetTransparentColor(uint8 red, @@ -65,7 +71,7 @@ class SavePalette { int fSize; int fSizeInBits; int fMode; - bool fUseTransparent; + uint32 fTransparentMode; int fTransparentIndex; int fBackgroundIndex; bool fFatalError; @@ -75,7 +81,7 @@ class SavePalette { inline uint8 SavePalette::IndexForColor(const rgb_color& color) { - return IndexForColor(color.red, color.green, color.blue); + return IndexForColor(color.red, color.green, color.blue, color.alpha); }