зеркало из https://github.com/mozilla/gecko-dev.git
Bug 369528 - SVG code not handing surface endianness properly. r+sr=roc
This commit is contained in:
Родитель
8d36248c77
Коммит
0307c2f9f6
|
@ -59,6 +59,7 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsSVGAnimatedInteger.h"
|
||||
#include "gfxColor.h"
|
||||
|
||||
nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
|
||||
{
|
||||
|
@ -938,9 +939,10 @@ nsSVGFEBlendElement::Filter(nsSVGFilterInstance *instance)
|
|||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||
PRUint32 targIndex = y * stride + 4 * x;
|
||||
PRUint32 qa = targetData[targIndex + 3];
|
||||
PRUint32 qb = sourceData[targIndex + 3];
|
||||
for (PRInt32 i = 0; i < 3; i++) {
|
||||
PRUint32 qa = targetData[targIndex + GFX_ARGB32_OFFSET_A];
|
||||
PRUint32 qb = sourceData[targIndex + GFX_ARGB32_OFFSET_A];
|
||||
for (PRInt32 i = PR_MIN(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R);
|
||||
i <= PR_MAX(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R); i++) {
|
||||
PRUint32 ca = targetData[targIndex + i];
|
||||
PRUint32 cb = sourceData[targIndex + i];
|
||||
PRUint32 val;
|
||||
|
@ -970,7 +972,7 @@ nsSVGFEBlendElement::Filter(nsSVGFilterInstance *instance)
|
|||
targetData[targIndex + i] = NS_STATIC_CAST(PRUint8, val);
|
||||
}
|
||||
PRUint32 alpha = 255 * 255 - (255 - qa) * (255 - qb);
|
||||
FAST_DIVIDE_BY_255(targetData[targIndex + 3], alpha);
|
||||
FAST_DIVIDE_BY_255(targetData[targIndex + GFX_ARGB32_OFFSET_A], alpha);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1285,17 +1287,22 @@ nsSVGFEColorMatrixElement::Filter(nsSVGFilterInstance *instance)
|
|||
|
||||
float col[4];
|
||||
for (int i = 0, row = 0; i < 4; i++, row += 5) {
|
||||
col[i] = sourceData[targIndex + 2] * colorMatrix[row + 0] +
|
||||
sourceData[targIndex + 1] * colorMatrix[row + 1] +
|
||||
sourceData[targIndex + 0] * colorMatrix[row + 2] +
|
||||
sourceData[targIndex + 3] * colorMatrix[row + 3] +
|
||||
255 * colorMatrix[row + 4];
|
||||
col[i] =
|
||||
sourceData[targIndex + GFX_ARGB32_OFFSET_R] * colorMatrix[row + 0] +
|
||||
sourceData[targIndex + GFX_ARGB32_OFFSET_G] * colorMatrix[row + 1] +
|
||||
sourceData[targIndex + GFX_ARGB32_OFFSET_B] * colorMatrix[row + 2] +
|
||||
sourceData[targIndex + GFX_ARGB32_OFFSET_A] * colorMatrix[row + 3] +
|
||||
255 * colorMatrix[row + 4];
|
||||
col[i] = PR_MIN(PR_MAX(0, col[i]), 255);
|
||||
}
|
||||
targetData[targIndex + 2] = NS_STATIC_CAST(PRUint8, col[0]);
|
||||
targetData[targIndex + 1] = NS_STATIC_CAST(PRUint8, col[1]);
|
||||
targetData[targIndex + 0] = NS_STATIC_CAST(PRUint8, col[2]);
|
||||
targetData[targIndex + 3] = NS_STATIC_CAST(PRUint8, col[3]);
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_R] =
|
||||
NS_STATIC_CAST(PRUint8, col[0]);
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_G] =
|
||||
NS_STATIC_CAST(PRUint8, col[1]);
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_B] =
|
||||
NS_STATIC_CAST(PRUint8, col[2]);
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_A] =
|
||||
NS_STATIC_CAST(PRUint8, col[3]);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1748,10 +1755,14 @@ nsSVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance)
|
|||
for (PRInt32 y = rect.y; y < rect.YMost(); y++)
|
||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRInt32 targIndex = y * stride + x * 4;
|
||||
targetData[targIndex] = tableB[sourceData[targIndex]];
|
||||
targetData[targIndex + 1] = tableG[sourceData[targIndex + 1]];
|
||||
targetData[targIndex + 2] = tableR[sourceData[targIndex + 2]];
|
||||
targetData[targIndex + 3] = tableA[sourceData[targIndex + 3]];
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_B] =
|
||||
tableB[sourceData[targIndex + GFX_ARGB32_OFFSET_B]];
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_G] =
|
||||
tableG[sourceData[targIndex + GFX_ARGB32_OFFSET_G]];
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_R] =
|
||||
tableR[sourceData[targIndex + GFX_ARGB32_OFFSET_R]];
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_A] =
|
||||
tableA[sourceData[targIndex + GFX_ARGB32_OFFSET_A]];
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3108,10 +3119,10 @@ nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance)
|
|||
FAST_DIVIDE_BY_255(g, unsigned(col[1]) * a);
|
||||
FAST_DIVIDE_BY_255(b, unsigned(col[2]) * a);
|
||||
|
||||
targetData[targIndex ] = b;
|
||||
targetData[targIndex + 1] = g;
|
||||
targetData[targIndex + 2] = r;
|
||||
targetData[targIndex + 3] = a;
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_B] = b;
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_G] = g;
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_R] = r;
|
||||
targetData[targIndex + GFX_ARGB32_OFFSET_A] = a;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -318,10 +318,11 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
|
||||
for (PRUint32 yy=0; yy<filterResY; yy++)
|
||||
for (PRUint32 xx=0; xx<filterResX; xx++) {
|
||||
alphaData[stride*yy + 4*xx] = 0;
|
||||
alphaData[stride*yy + 4*xx + 1] = 0;
|
||||
alphaData[stride*yy + 4*xx + 2] = 0;
|
||||
alphaData[stride*yy + 4*xx + 3] = data[stride*yy + 4*xx + 3];
|
||||
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_B] = 0;
|
||||
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_G] = 0;
|
||||
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_R] = 0;
|
||||
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_A] =
|
||||
data[stride*yy + 4*xx + 3];
|
||||
}
|
||||
|
||||
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha,
|
||||
|
|
|
@ -229,13 +229,14 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
|||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
/* linearRGB -> intensity */
|
||||
pixel[3] = (PRUint8)((pixel[2] * 0.2125 +
|
||||
pixel[1] * 0.7154 +
|
||||
pixel[0] * 0.0721) *
|
||||
(pixel[3] / 255.0) * aOpacity);
|
||||
pixel[0] = 255;
|
||||
pixel[1] = 255;
|
||||
pixel[2] = 255;
|
||||
PRUint8 alpha =
|
||||
NS_STATIC_CAST(PRUint8,
|
||||
(pixel[GFX_ARGB32_OFFSET_R] * 0.2125 +
|
||||
pixel[GFX_ARGB32_OFFSET_G] * 0.7154 +
|
||||
pixel[GFX_ARGB32_OFFSET_B] * 0.0721) *
|
||||
(pixel[GFX_ARGB32_OFFSET_A] / 255.0) * aOpacity);
|
||||
|
||||
memset(pixel, alpha, 4);
|
||||
}
|
||||
|
||||
cairo_pattern_t *retval = cairo_pattern_create_for_surface(image);
|
||||
|
|
|
@ -318,18 +318,18 @@ nsSVGUtils::UnPremultiplyImageDataAlpha(PRUint8 *data,
|
|||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
PRUint8 a = pixel[3];
|
||||
PRUint8 a = pixel[GFX_ARGB32_OFFSET_A];
|
||||
if (a == 255)
|
||||
continue;
|
||||
|
||||
if (a) {
|
||||
pixel[0] = (255 * pixel[0]) / a;
|
||||
pixel[1] = (255 * pixel[1]) / a;
|
||||
pixel[2] = (255 * pixel[2]) / a;
|
||||
pixel[GFX_ARGB32_OFFSET_B] = (255 * pixel[GFX_ARGB32_OFFSET_B]) / a;
|
||||
pixel[GFX_ARGB32_OFFSET_G] = (255 * pixel[GFX_ARGB32_OFFSET_G]) / a;
|
||||
pixel[GFX_ARGB32_OFFSET_R] = (255 * pixel[GFX_ARGB32_OFFSET_R]) / a;
|
||||
} else {
|
||||
pixel[0] = 0;
|
||||
pixel[1] = 0;
|
||||
pixel[2] = 0;
|
||||
pixel[GFX_ARGB32_OFFSET_B] = 0;
|
||||
pixel[GFX_ARGB32_OFFSET_G] = 0;
|
||||
pixel[GFX_ARGB32_OFFSET_R] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,13 +344,16 @@ nsSVGUtils::PremultiplyImageDataAlpha(PRUint8 *data,
|
|||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
PRUint8 a = pixel[3];
|
||||
PRUint8 a = pixel[GFX_ARGB32_OFFSET_A];
|
||||
if (a == 255)
|
||||
continue;
|
||||
|
||||
FAST_DIVIDE_BY_255(pixel[0], pixel[0] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[1], pixel[1] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[2], pixel[2] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[GFX_ARGB32_OFFSET_B],
|
||||
pixel[GFX_ARGB32_OFFSET_B] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[GFX_ARGB32_OFFSET_G],
|
||||
pixel[GFX_ARGB32_OFFSET_G] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[GFX_ARGB32_OFFSET_R],
|
||||
pixel[GFX_ARGB32_OFFSET_R] * a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,9 +367,12 @@ nsSVGUtils::ConvertImageDataToLinearRGB(PRUint8 *data,
|
|||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
pixel[0] = gsRGBToLinearRGBMap[pixel[0]];
|
||||
pixel[1] = gsRGBToLinearRGBMap[pixel[1]];
|
||||
pixel[2] = gsRGBToLinearRGBMap[pixel[2]];
|
||||
pixel[GFX_ARGB32_OFFSET_B] =
|
||||
gsRGBToLinearRGBMap[pixel[GFX_ARGB32_OFFSET_B]];
|
||||
pixel[GFX_ARGB32_OFFSET_G] =
|
||||
gsRGBToLinearRGBMap[pixel[GFX_ARGB32_OFFSET_G]];
|
||||
pixel[GFX_ARGB32_OFFSET_R] =
|
||||
gsRGBToLinearRGBMap[pixel[GFX_ARGB32_OFFSET_R]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,9 +386,12 @@ nsSVGUtils::ConvertImageDataFromLinearRGB(PRUint8 *data,
|
|||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
pixel[0] = glinearRGBTosRGBMap[pixel[0]];
|
||||
pixel[1] = glinearRGBTosRGBMap[pixel[1]];
|
||||
pixel[2] = glinearRGBTosRGBMap[pixel[2]];
|
||||
pixel[GFX_ARGB32_OFFSET_B] =
|
||||
glinearRGBTosRGBMap[pixel[GFX_ARGB32_OFFSET_B]];
|
||||
pixel[GFX_ARGB32_OFFSET_G] =
|
||||
glinearRGBTosRGBMap[pixel[GFX_ARGB32_OFFSET_G]];
|
||||
pixel[GFX_ARGB32_OFFSET_R] =
|
||||
glinearRGBTosRGBMap[pixel[GFX_ARGB32_OFFSET_R]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,21 @@ struct gfxMatrix;
|
|||
/* are we the child of a non-display container? */
|
||||
#define NS_STATE_SVG_NONDISPLAY_CHILD 0x20000000
|
||||
|
||||
/**
|
||||
* Byte offsets of channels in a native packed gfxColor or cairo image surface.
|
||||
*/
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
#define GFX_ARGB32_OFFSET_A 0
|
||||
#define GFX_ARGB32_OFFSET_R 1
|
||||
#define GFX_ARGB32_OFFSET_G 2
|
||||
#define GFX_ARGB32_OFFSET_B 3
|
||||
#else
|
||||
#define GFX_ARGB32_OFFSET_A 3
|
||||
#define GFX_ARGB32_OFFSET_R 2
|
||||
#define GFX_ARGB32_OFFSET_G 1
|
||||
#define GFX_ARGB32_OFFSET_B 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Checks the svg enable preference and if a renderer could
|
||||
* successfully be created. Declared as a function instead of a
|
||||
|
|
Загрузка…
Ссылка в новой задаче