#51179 blending calculations were incorrect (dividing by 256 instead of 255).
r=brendan, sr=roc
This commit is contained in:
Родитель
e99a242b69
Коммит
30513bad4f
|
@ -47,6 +47,24 @@ typedef PRUint32 nscolor;
|
|||
#define NS_GET_B(_rgba) ((PRUint8) (((_rgba) >> 16) & 0xff))
|
||||
#define NS_GET_A(_rgba) ((PRUint8) (((_rgba) >> 24) & 0xff))
|
||||
|
||||
// Fast approximate division by 255. It has the property that
|
||||
// for all 0 <= n <= 255*255, FAST_DIVIDE_BY_255(n) == n/255.
|
||||
// But it only uses two adds and two shifts instead of an
|
||||
// integer division (which is expensive on many processors).
|
||||
//
|
||||
// equivalent to target=v/255
|
||||
#define FAST_DIVIDE_BY_255(target,v) \
|
||||
PR_BEGIN_MACRO \
|
||||
unsigned tmp_ = v; \
|
||||
target = ((tmp_ << 8) + tmp_ + 255) >> 16; \
|
||||
PR_END_MACRO
|
||||
|
||||
// Blending macro
|
||||
//
|
||||
// equivalent to target=(bg*(255-alpha)+fg*alpha)/255
|
||||
#define MOZ_BLEND(target, bg, fg, alpha) \
|
||||
FAST_DIVIDE_BY_255(target, (bg)*(255-(alpha)) + (fg)*(alpha))
|
||||
|
||||
// Translate a hex string to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
// This accepts only 3, 6 or 9 digits
|
||||
|
|
|
@ -379,8 +379,6 @@ findIndex24(unsigned mask)
|
|||
}
|
||||
}
|
||||
|
||||
// blending macro
|
||||
#define MOZ_BLEND(bg, fg, alpha) (((bg)*(255-(alpha)) + (fg)*(alpha))/255)
|
||||
|
||||
// 32-bit (888) truecolor convert/composite function
|
||||
void
|
||||
|
@ -414,9 +412,9 @@ nsImageGTK::DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
|||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=4, targetRow+=3, imageRow+=3, alphaRow++) {
|
||||
unsigned alpha = *alphaRow;
|
||||
targetRow[0] = MOZ_BLEND(baseRow[redIndex], imageRow[0], alpha);
|
||||
targetRow[1] = MOZ_BLEND(baseRow[greenIndex], imageRow[1], alpha);
|
||||
targetRow[2] = MOZ_BLEND(baseRow[blueIndex], imageRow[2], alpha);
|
||||
MOZ_BLEND(targetRow[0], baseRow[redIndex], imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1], baseRow[greenIndex], imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2], baseRow[blueIndex], imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -449,9 +447,9 @@ nsImageGTK::DrawComposited24(PRBool isLSB, PRBool flipBytes,
|
|||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=3, targetRow+=3, imageRow+=3, alphaRow++) {
|
||||
unsigned alpha = *alphaRow;
|
||||
targetRow[0] = MOZ_BLEND(baseRow[redIndex], imageRow[0], alpha);
|
||||
targetRow[1] = MOZ_BLEND(baseRow[greenIndex], imageRow[1], alpha);
|
||||
targetRow[2] = MOZ_BLEND(baseRow[blueIndex], imageRow[2], alpha);
|
||||
MOZ_BLEND(targetRow[0], baseRow[redIndex], imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1], baseRow[greenIndex], imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2], baseRow[blueIndex], imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,15 +497,15 @@ nsImageGTK::DrawComposited16(PRBool isLSB, PRBool flipBytes,
|
|||
} else
|
||||
pix = *((short *)baseRow);
|
||||
unsigned alpha = *alphaRow;
|
||||
targetRow[0] =
|
||||
MOZ_BLEND(redScale[(pix&visual->red_mask)>>visual->red_shift],
|
||||
imageRow[0], alpha);
|
||||
targetRow[1] =
|
||||
MOZ_BLEND(greenScale[(pix&visual->green_mask)>>visual->green_shift],
|
||||
imageRow[1], alpha);
|
||||
targetRow[2] =
|
||||
MOZ_BLEND(blueScale[(pix&visual->blue_mask)>>visual->blue_shift],
|
||||
imageRow[2], alpha);
|
||||
MOZ_BLEND(targetRow[0],
|
||||
redScale[(pix&visual->red_mask)>>visual->red_shift],
|
||||
imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1],
|
||||
greenScale[(pix&visual->green_mask)>>visual->green_shift],
|
||||
imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2],
|
||||
blueScale[(pix&visual->blue_mask)>>visual->blue_shift],
|
||||
imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -649,9 +647,9 @@ nsImageGTK::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
|||
|
||||
for (unsigned i=0; i<width; i++) {
|
||||
unsigned alpha = alphaRow[i];
|
||||
targetRow[3*i] = MOZ_BLEND(targetRow[3*i], imageRow[3*i], alpha);
|
||||
targetRow[3*i+1] = MOZ_BLEND(targetRow[3*i+1], imageRow[3*i+1], alpha);
|
||||
targetRow[3*i+2] = MOZ_BLEND(targetRow[3*i+2], imageRow[3*i+2], alpha);
|
||||
MOZ_BLEND(targetRow[3*i], targetRow[3*i], imageRow[3*i], alpha);
|
||||
MOZ_BLEND(targetRow[3*i+1], targetRow[3*i+1], imageRow[3*i+1], alpha);
|
||||
MOZ_BLEND(targetRow[3*i+2], targetRow[3*i+2], imageRow[3*i+2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ PRUint32 pixSColor,pixSSColor;
|
|||
s2 = s1;
|
||||
d2 = d1;
|
||||
for(x = 0; x < aNumbytes; x++){
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
FAST_DIVIDE_BY_255(temp1,((*d2)*val1)+((*s2)*val2));
|
||||
if(temp1>255){
|
||||
temp1 = 255;
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ PRUint32 pixSColor,pixSSColor;
|
|||
|
||||
if((pixSColor!=srccolor) || (pixSSColor!=secsrccolor)) {
|
||||
for(i=0;i<4;i++){
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
FAST_DIVIDE_BY_255(temp1,((*d2)*val1)+((*s2)*val2));
|
||||
if(temp1>255){
|
||||
temp1 = 255;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ PRUint32 pixSColor,pixSSColor;
|
|||
s2 = s1;
|
||||
d2 = d1;
|
||||
for(x = 0; x < aNumbytes; x++){
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
FAST_DIVIDE_BY_255(temp1,((*d2)*val1)+((*s2)*val2));
|
||||
if(temp1>255){
|
||||
temp1 = 255;
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ PRUint32 pixSColor,pixSSColor;
|
|||
|
||||
if((pixSColor!=srccolor) || (pixSSColor!=secsrccolor)) {
|
||||
for(i=0;i<3;i++){
|
||||
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
|
||||
FAST_DIVIDE_BY_255(temp1,((*d2)*val1)+((*s2)*val2));
|
||||
if(temp1>255){
|
||||
temp1 = 255;
|
||||
}
|
||||
|
@ -487,17 +487,17 @@ PRInt16 dspan,sspan,span;
|
|||
if ((stemp != srccolor) || (sstemp != secsrccolor)) {
|
||||
dtemp = *d2;
|
||||
|
||||
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
|
||||
FAST_DIVIDE_BY_255(red, RED16(dtemp) * val1 + RED16(stemp) * val2);
|
||||
|
||||
if (red > 255)
|
||||
red = 255;
|
||||
|
||||
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
|
||||
FAST_DIVIDE_BY_255(green, GREEN16(dtemp) * val1 + GREEN16(stemp) * val2);
|
||||
|
||||
if (green > 255)
|
||||
green = 255;
|
||||
|
||||
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
|
||||
FAST_DIVIDE_BY_255(blue, BLUE16(dtemp) * val1 + BLUE16(stemp) * val2);
|
||||
|
||||
if (blue > 255)
|
||||
blue = 255;
|
||||
|
@ -523,17 +523,17 @@ PRInt16 dspan,sspan,span;
|
|||
stemp = *s2;
|
||||
dtemp = *d2;
|
||||
|
||||
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
|
||||
FAST_DIVIDE_BY_255(red, RED16(dtemp) * val1 + RED16(stemp) * val2);
|
||||
|
||||
if (red > 255)
|
||||
red = 255;
|
||||
|
||||
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
|
||||
FAST_DIVIDE_BY_255(green, GREEN16(dtemp) * val1 + GREEN16(stemp) * val2);
|
||||
|
||||
if (green > 255)
|
||||
green = 255;
|
||||
|
||||
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
|
||||
FAST_DIVIDE_BY_255(blue, BLUE16(dtemp) * val1 + BLUE16(stemp) * val2);
|
||||
|
||||
if (blue > 255)
|
||||
blue = 255;
|
||||
|
|
|
@ -362,9 +362,12 @@ void nsImageWin::CreateImageWithAlphaBits(HDC TheHDC)
|
|||
|
||||
for (int x = 0; x < mBHead->biWidth;
|
||||
x++, imageWithAlphaRow += 4, imageRow++, alphaRow++) {
|
||||
imageWithAlphaRow[0] = (mColorMap->Index[3 * (*imageRow)] * *alphaRow) >> 8;
|
||||
imageWithAlphaRow[1] = (mColorMap->Index[3 * (*imageRow) + 1] * *alphaRow) >> 8;
|
||||
imageWithAlphaRow[2] = (mColorMap->Index[3 * (*imageRow) + 2] * *alphaRow) >> 8;
|
||||
FAST_DIVIDE_BY_255(imageWithAlphaRow[0],
|
||||
mColorMap->Index[3 * (*imageRow)] * *alphaRow);
|
||||
FAST_DIVIDE_BY_255(imageWithAlphaRow[1],
|
||||
mColorMap->Index[3 * (*imageRow) + 1] * *alphaRow);
|
||||
FAST_DIVIDE_BY_255(imageWithAlphaRow[2],
|
||||
mColorMap->Index[3 * (*imageRow) + 2] * *alphaRow);
|
||||
imageWithAlphaRow[3] = *alphaRow;
|
||||
}
|
||||
}
|
||||
|
@ -376,9 +379,9 @@ void nsImageWin::CreateImageWithAlphaBits(HDC TheHDC)
|
|||
|
||||
for (int x = 0; x < mBHead->biWidth;
|
||||
x++, imageWithAlphaRow += 4, imageRow += 3, alphaRow++) {
|
||||
imageWithAlphaRow[0] = (imageRow[0] * *alphaRow) >> 8;
|
||||
imageWithAlphaRow[1] = (imageRow[1] * *alphaRow) >> 8;
|
||||
imageWithAlphaRow[2] = (imageRow[2] * *alphaRow) >> 8;
|
||||
FAST_DIVIDE_BY_255(imageWithAlphaRow[0], imageRow[0] * *alphaRow);
|
||||
FAST_DIVIDE_BY_255(imageWithAlphaRow[1], imageRow[1] * *alphaRow);
|
||||
FAST_DIVIDE_BY_255(imageWithAlphaRow[2], imageRow[2] * *alphaRow);
|
||||
imageWithAlphaRow[3] = *alphaRow;
|
||||
}
|
||||
}
|
||||
|
@ -557,12 +560,10 @@ void nsImageWin::DrawComposited24(unsigned char *aBits, int aX, int aY, int aWid
|
|||
|
||||
for (int x = 0; x < aWidth;
|
||||
x++, targetRow += 3, imageRow += 3, alphaRow++) {
|
||||
targetRow[0] =
|
||||
(targetRow[0] * (255 - *alphaRow) + imageRow[0] * *alphaRow) >> 8;
|
||||
targetRow[1] =
|
||||
(targetRow[1] * (255 - *alphaRow) + imageRow[1] * *alphaRow) >> 8;
|
||||
targetRow[2] =
|
||||
(targetRow[2] * (255 - *alphaRow) + imageRow[2] * *alphaRow) >> 8;
|
||||
unsigned alpha = *alphaRow;
|
||||
MOZ_BLEND(targetRow[0], targetRow[0], imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1], targetRow[1], imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2], targetRow[2], imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -329,6 +329,7 @@ findIndex24(unsigned mask)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// 32-bit (888) truecolor convert/composite function
|
||||
void nsImageXlib::DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
|
@ -358,12 +359,10 @@ void nsImageXlib::DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
|||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=4, targetRow+=3, imageRow+=3, alphaRow++)
|
||||
{
|
||||
targetRow[0] = (unsigned(baseRow[redIndex]) * (255-*alphaRow) +
|
||||
unsigned(imageRow[0]) * *alphaRow) >> 8;
|
||||
targetRow[1] = (unsigned(baseRow[greenIndex]) * (255-*alphaRow) +
|
||||
unsigned(imageRow[1]) * *alphaRow) >> 8;
|
||||
targetRow[2] = (unsigned(baseRow[blueIndex]) * (255-*alphaRow) +
|
||||
unsigned(imageRow[2]) * *alphaRow) >> 8;
|
||||
unsigned alpha = *alphaRow;
|
||||
MOZ_BLEND(targetRow[0], baseRow[redIndex], imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1], baseRow[greenIndex], imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2], baseRow[blueIndex], imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -395,15 +394,10 @@ nsImageXlib::DrawComposited24(PRBool isLSB, PRBool flipBytes,
|
|||
|
||||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=3, targetRow+=3, imageRow+=3, alphaRow++) {
|
||||
targetRow[0] =
|
||||
(unsigned(baseRow[redIndex]) * (255-*alphaRow) +
|
||||
unsigned(imageRow[0]) * *alphaRow) >> 8;
|
||||
targetRow[1] =
|
||||
(unsigned(baseRow[greenIndex]) * (255-*alphaRow) +
|
||||
unsigned(imageRow[1]) * *alphaRow) >> 8;
|
||||
targetRow[2] =
|
||||
(unsigned(baseRow[blueIndex]) * (255-*alphaRow) +
|
||||
unsigned(imageRow[2]) * *alphaRow) >> 8;
|
||||
unsigned alpha = *alphaRow;
|
||||
MOZ_BLEND(targetRow[0], baseRow[redIndex], imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1], baseRow[greenIndex], imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2], baseRow[blueIndex], imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,21 +446,20 @@ nsImageXlib::DrawComposited16(PRBool isLSB, PRBool flipBytes,
|
|||
pix = *((short *)tmp);
|
||||
} else
|
||||
pix = *((short *)baseRow);
|
||||
targetRow[0] =
|
||||
(redScale[(pix&visual->red_mask) >>
|
||||
xlib_get_shift_from_mask(visual->red_mask)] *
|
||||
(255-*alphaRow) + unsigned(imageRow[0]) * *alphaRow) >> 8;
|
||||
targetRow[1] =
|
||||
(greenScale[(pix&visual->green_mask) >>
|
||||
xlib_get_shift_from_mask(visual->green_mask)] *
|
||||
(255-*alphaRow) + unsigned(imageRow[1]) * *alphaRow) >> 8;
|
||||
targetRow[2] =
|
||||
(blueScale[(pix&visual->blue_mask) >>
|
||||
xlib_get_shift_from_mask(visual->blue_mask)] *
|
||||
(255-*alphaRow) + unsigned(imageRow[2]) * *alphaRow) >> 8;
|
||||
unsigned alpha = *alphaRow;
|
||||
MOZ_BLEND(targetRow[0],
|
||||
redScale[(pix&visual->red_mask)>>visual->red_shift],
|
||||
imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1],
|
||||
greenScale[(pix&visual->green_mask)>>visual->green_shift],
|
||||
imageRow[1], alpha);
|
||||
MOZ_BLEND(targetRow[2],
|
||||
blueScale[(pix&visual->blue_mask)>>visual->blue_shift],
|
||||
imageRow[2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generic convert/composite function
|
||||
void
|
||||
nsImageXlib::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
|
@ -584,12 +577,10 @@ nsImageXlib::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
|||
unsigned char *imageRow = mImageBits +(y+offsetY)*mRowBytes+3*offsetX;
|
||||
unsigned char *alphaRow = mAlphaBits +(y+offsetY)*mAlphaRowBytes+offsetX;
|
||||
for (unsigned i=0; i<width; i++) {
|
||||
targetRow[3*i] = (unsigned(targetRow[3*i])*(255-alphaRow[i]) +
|
||||
unsigned(imageRow[3*i])*alphaRow[i])>>8;
|
||||
targetRow[3*i+1] = (unsigned(targetRow[3*i+1])*(255-alphaRow[i]) +
|
||||
unsigned(imageRow[3*i+1])*alphaRow[i])>>8;
|
||||
targetRow[3*i+2] = (unsigned(targetRow[3*i+2])*(255-alphaRow[i]) +
|
||||
unsigned(imageRow[3*i+2])*alphaRow[i])>>8;
|
||||
unsigned alpha = alphaRow[i];
|
||||
MOZ_BLEND(targetRow[3*i], targetRow[3*i], imageRow[3*i], alpha);
|
||||
MOZ_BLEND(targetRow[3*i+1], targetRow[3*i+1], imageRow[3*i+1], alpha);
|
||||
MOZ_BLEND(targetRow[3*i+2], targetRow[3*i+2], imageRow[3*i+2], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче