a couple of fixes for determining transparent pixels with regard to dithering, new auto transparency mode (from alpha channel) replaces nonsense index mode (the index mode is nonsense, because there is no control over which color gets which index, therefor, the user is better of specifying the specific color, which is supported)
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14334 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user