зеркало из 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 "nsIDocument.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsSVGAnimatedInteger.h"
|
#include "nsSVGAnimatedInteger.h"
|
||||||
|
#include "gfxColor.h"
|
||||||
|
|
||||||
nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
|
nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
|
||||||
{
|
{
|
||||||
|
@ -938,9 +939,10 @@ nsSVGFEBlendElement::Filter(nsSVGFilterInstance *instance)
|
||||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||||
PRUint32 targIndex = y * stride + 4 * x;
|
PRUint32 targIndex = y * stride + 4 * x;
|
||||||
PRUint32 qa = targetData[targIndex + 3];
|
PRUint32 qa = targetData[targIndex + GFX_ARGB32_OFFSET_A];
|
||||||
PRUint32 qb = sourceData[targIndex + 3];
|
PRUint32 qb = sourceData[targIndex + GFX_ARGB32_OFFSET_A];
|
||||||
for (PRInt32 i = 0; i < 3; i++) {
|
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 ca = targetData[targIndex + i];
|
||||||
PRUint32 cb = sourceData[targIndex + i];
|
PRUint32 cb = sourceData[targIndex + i];
|
||||||
PRUint32 val;
|
PRUint32 val;
|
||||||
|
@ -970,7 +972,7 @@ nsSVGFEBlendElement::Filter(nsSVGFilterInstance *instance)
|
||||||
targetData[targIndex + i] = NS_STATIC_CAST(PRUint8, val);
|
targetData[targIndex + i] = NS_STATIC_CAST(PRUint8, val);
|
||||||
}
|
}
|
||||||
PRUint32 alpha = 255 * 255 - (255 - qa) * (255 - qb);
|
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;
|
return NS_OK;
|
||||||
|
@ -1285,17 +1287,22 @@ nsSVGFEColorMatrixElement::Filter(nsSVGFilterInstance *instance)
|
||||||
|
|
||||||
float col[4];
|
float col[4];
|
||||||
for (int i = 0, row = 0; i < 4; i++, row += 5) {
|
for (int i = 0, row = 0; i < 4; i++, row += 5) {
|
||||||
col[i] = sourceData[targIndex + 2] * colorMatrix[row + 0] +
|
col[i] =
|
||||||
sourceData[targIndex + 1] * colorMatrix[row + 1] +
|
sourceData[targIndex + GFX_ARGB32_OFFSET_R] * colorMatrix[row + 0] +
|
||||||
sourceData[targIndex + 0] * colorMatrix[row + 2] +
|
sourceData[targIndex + GFX_ARGB32_OFFSET_G] * colorMatrix[row + 1] +
|
||||||
sourceData[targIndex + 3] * colorMatrix[row + 3] +
|
sourceData[targIndex + GFX_ARGB32_OFFSET_B] * colorMatrix[row + 2] +
|
||||||
255 * colorMatrix[row + 4];
|
sourceData[targIndex + GFX_ARGB32_OFFSET_A] * colorMatrix[row + 3] +
|
||||||
|
255 * colorMatrix[row + 4];
|
||||||
col[i] = PR_MIN(PR_MAX(0, col[i]), 255);
|
col[i] = PR_MIN(PR_MAX(0, col[i]), 255);
|
||||||
}
|
}
|
||||||
targetData[targIndex + 2] = NS_STATIC_CAST(PRUint8, col[0]);
|
targetData[targIndex + GFX_ARGB32_OFFSET_R] =
|
||||||
targetData[targIndex + 1] = NS_STATIC_CAST(PRUint8, col[1]);
|
NS_STATIC_CAST(PRUint8, col[0]);
|
||||||
targetData[targIndex + 0] = NS_STATIC_CAST(PRUint8, col[2]);
|
targetData[targIndex + GFX_ARGB32_OFFSET_G] =
|
||||||
targetData[targIndex + 3] = NS_STATIC_CAST(PRUint8, col[3]);
|
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;
|
return NS_OK;
|
||||||
|
@ -1748,10 +1755,14 @@ nsSVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance)
|
||||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++)
|
for (PRInt32 y = rect.y; y < rect.YMost(); y++)
|
||||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||||
PRInt32 targIndex = y * stride + x * 4;
|
PRInt32 targIndex = y * stride + x * 4;
|
||||||
targetData[targIndex] = tableB[sourceData[targIndex]];
|
targetData[targIndex + GFX_ARGB32_OFFSET_B] =
|
||||||
targetData[targIndex + 1] = tableG[sourceData[targIndex + 1]];
|
tableB[sourceData[targIndex + GFX_ARGB32_OFFSET_B]];
|
||||||
targetData[targIndex + 2] = tableR[sourceData[targIndex + 2]];
|
targetData[targIndex + GFX_ARGB32_OFFSET_G] =
|
||||||
targetData[targIndex + 3] = tableA[sourceData[targIndex + 3]];
|
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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -3108,10 +3119,10 @@ nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance)
|
||||||
FAST_DIVIDE_BY_255(g, unsigned(col[1]) * a);
|
FAST_DIVIDE_BY_255(g, unsigned(col[1]) * a);
|
||||||
FAST_DIVIDE_BY_255(b, unsigned(col[2]) * a);
|
FAST_DIVIDE_BY_255(b, unsigned(col[2]) * a);
|
||||||
|
|
||||||
targetData[targIndex ] = b;
|
targetData[targIndex + GFX_ARGB32_OFFSET_B] = b;
|
||||||
targetData[targIndex + 1] = g;
|
targetData[targIndex + GFX_ARGB32_OFFSET_G] = g;
|
||||||
targetData[targIndex + 2] = r;
|
targetData[targIndex + GFX_ARGB32_OFFSET_R] = r;
|
||||||
targetData[targIndex + 3] = a;
|
targetData[targIndex + GFX_ARGB32_OFFSET_A] = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,10 +318,11 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
||||||
|
|
||||||
for (PRUint32 yy=0; yy<filterResY; yy++)
|
for (PRUint32 yy=0; yy<filterResY; yy++)
|
||||||
for (PRUint32 xx=0; xx<filterResX; xx++) {
|
for (PRUint32 xx=0; xx<filterResX; xx++) {
|
||||||
alphaData[stride*yy + 4*xx] = 0;
|
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_B] = 0;
|
||||||
alphaData[stride*yy + 4*xx + 1] = 0;
|
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_G] = 0;
|
||||||
alphaData[stride*yy + 4*xx + 2] = 0;
|
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_R] = 0;
|
||||||
alphaData[stride*yy + 4*xx + 3] = data[stride*yy + 4*xx + 3];
|
alphaData[stride*yy + 4*xx + GFX_ARGB32_OFFSET_A] =
|
||||||
|
data[stride*yy + 4*xx + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha,
|
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha,
|
||||||
|
|
|
@ -229,13 +229,14 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
||||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||||
|
|
||||||
/* linearRGB -> intensity */
|
/* linearRGB -> intensity */
|
||||||
pixel[3] = (PRUint8)((pixel[2] * 0.2125 +
|
PRUint8 alpha =
|
||||||
pixel[1] * 0.7154 +
|
NS_STATIC_CAST(PRUint8,
|
||||||
pixel[0] * 0.0721) *
|
(pixel[GFX_ARGB32_OFFSET_R] * 0.2125 +
|
||||||
(pixel[3] / 255.0) * aOpacity);
|
pixel[GFX_ARGB32_OFFSET_G] * 0.7154 +
|
||||||
pixel[0] = 255;
|
pixel[GFX_ARGB32_OFFSET_B] * 0.0721) *
|
||||||
pixel[1] = 255;
|
(pixel[GFX_ARGB32_OFFSET_A] / 255.0) * aOpacity);
|
||||||
pixel[2] = 255;
|
|
||||||
|
memset(pixel, alpha, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_pattern_t *retval = cairo_pattern_create_for_surface(image);
|
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++) {
|
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||||
|
|
||||||
PRUint8 a = pixel[3];
|
PRUint8 a = pixel[GFX_ARGB32_OFFSET_A];
|
||||||
if (a == 255)
|
if (a == 255)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (a) {
|
if (a) {
|
||||||
pixel[0] = (255 * pixel[0]) / a;
|
pixel[GFX_ARGB32_OFFSET_B] = (255 * pixel[GFX_ARGB32_OFFSET_B]) / a;
|
||||||
pixel[1] = (255 * pixel[1]) / a;
|
pixel[GFX_ARGB32_OFFSET_G] = (255 * pixel[GFX_ARGB32_OFFSET_G]) / a;
|
||||||
pixel[2] = (255 * pixel[2]) / a;
|
pixel[GFX_ARGB32_OFFSET_R] = (255 * pixel[GFX_ARGB32_OFFSET_R]) / a;
|
||||||
} else {
|
} else {
|
||||||
pixel[0] = 0;
|
pixel[GFX_ARGB32_OFFSET_B] = 0;
|
||||||
pixel[1] = 0;
|
pixel[GFX_ARGB32_OFFSET_G] = 0;
|
||||||
pixel[2] = 0;
|
pixel[GFX_ARGB32_OFFSET_R] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,13 +344,16 @@ nsSVGUtils::PremultiplyImageDataAlpha(PRUint8 *data,
|
||||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||||
|
|
||||||
PRUint8 a = pixel[3];
|
PRUint8 a = pixel[GFX_ARGB32_OFFSET_A];
|
||||||
if (a == 255)
|
if (a == 255)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FAST_DIVIDE_BY_255(pixel[0], pixel[0] * a);
|
FAST_DIVIDE_BY_255(pixel[GFX_ARGB32_OFFSET_B],
|
||||||
FAST_DIVIDE_BY_255(pixel[1], pixel[1] * a);
|
pixel[GFX_ARGB32_OFFSET_B] * a);
|
||||||
FAST_DIVIDE_BY_255(pixel[2], pixel[2] * 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++) {
|
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||||
|
|
||||||
pixel[0] = gsRGBToLinearRGBMap[pixel[0]];
|
pixel[GFX_ARGB32_OFFSET_B] =
|
||||||
pixel[1] = gsRGBToLinearRGBMap[pixel[1]];
|
gsRGBToLinearRGBMap[pixel[GFX_ARGB32_OFFSET_B]];
|
||||||
pixel[2] = gsRGBToLinearRGBMap[pixel[2]];
|
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++) {
|
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||||
|
|
||||||
pixel[0] = glinearRGBTosRGBMap[pixel[0]];
|
pixel[GFX_ARGB32_OFFSET_B] =
|
||||||
pixel[1] = glinearRGBTosRGBMap[pixel[1]];
|
glinearRGBTosRGBMap[pixel[GFX_ARGB32_OFFSET_B]];
|
||||||
pixel[2] = glinearRGBTosRGBMap[pixel[2]];
|
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? */
|
/* are we the child of a non-display container? */
|
||||||
#define NS_STATE_SVG_NONDISPLAY_CHILD 0x20000000
|
#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
|
* Checks the svg enable preference and if a renderer could
|
||||||
* successfully be created. Declared as a function instead of a
|
* successfully be created. Declared as a function instead of a
|
||||||
|
|
Загрузка…
Ссылка в новой задаче