Bug 714937 - Replace GFX_PACKED_PIXEL with an inline function. r=jrmuizel

This commit is contained in:
Luqman Aden 2012-09-06 01:31:29 -04:00
parent 1971f62b7e
commit 46d1c6ded1
7 changed files with 42 additions and 34 deletions

View File

@ -2060,7 +2060,7 @@ GLContext::ReadPixelsIntoImageSurface(gfxImageSurface* dest)
GLint alphaBits = 0; GLint alphaBits = 0;
fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits); fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits);
if (!alphaBits) { if (!alphaBits) {
const uint32_t alphaMask = GFX_PACKED_PIXEL_NO_PREMULTIPLY(0xff,0,0,0); const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0);
uint32_t* itr = (uint32_t*)dest->Data(); uint32_t* itr = (uint32_t*)dest->Data();
uint32_t testPixel = *itr; uint32_t testPixel = *itr;

View File

@ -11,6 +11,8 @@
#include "prbit.h" // for PR_ROTATE_(LEFT,RIGHT)32 #include "prbit.h" // for PR_ROTATE_(LEFT,RIGHT)32
#include "prio.h" // for ntohl #include "prio.h" // for ntohl
#include "mozilla/Attributes.h" // for MOZ_ALWAYS_INLINE
#define GFX_UINT32_FROM_BPTR(pbptr,i) (((uint32_t*)(pbptr))[i]) #define GFX_UINT32_FROM_BPTR(pbptr,i) (((uint32_t*)(pbptr))[i])
#if defined(IS_BIG_ENDIAN) #if defined(IS_BIG_ENDIAN)
@ -91,34 +93,40 @@
(((((unsigned)(v)) << 8) + ((unsigned)(v)) + 255) >> 16) (((((unsigned)(v)) << 8) + ((unsigned)(v)) + 255) >> 16)
/** /**
* Fast premultiply macro * Fast premultiply
* *
* equivalent to (((c)*(a))/255) * equivalent to (((c)*(a))/255)
*/ */
#define GFX_PREMULTIPLY(c,a) GFX_DIVIDE_BY_255((c)*(a)) PRUint8 MOZ_ALWAYS_INLINE gfxPreMultiply(PRUint8 c, PRUint8 a) {
return GFX_DIVIDE_BY_255((c)*(a));
}
/** /**
* Macro to pack the 4 8-bit channels (A,R,G,B) * Pack the 4 8-bit channels (A,R,G,B)
* into a 32-bit packed premultiplied pixel.
*
* The checks for 0 alpha or max alpha ensure that the
* compiler selects the quicked calculation when alpha is constant.
*/
#define GFX_PACKED_PIXEL(a,r,g,b) \
((a) == 0x00) ? 0x00000000 : \
((a) == 0xFF) ? ((0xFF << 24) | ((r) << 16) | ((g) << 8) | (b)) \
: ((a) << 24) | \
(GFX_PREMULTIPLY(r,a) << 16) | \
(GFX_PREMULTIPLY(g,a) << 8) | \
(GFX_PREMULTIPLY(b,a))
/**
* Macro to pack the 4 8-bit channels (A,R,G,B)
* into a 32-bit packed NON-premultiplied pixel. * into a 32-bit packed NON-premultiplied pixel.
*/ */
#define GFX_PACKED_PIXEL_NO_PREMULTIPLY(a,r,g,b) \ PRUint32 MOZ_ALWAYS_INLINE
(((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) gfxPackedPixelNoPreMultiply(PRUint8 a, PRUint8 r, PRUint8 g, PRUint8 b) {
return (((a) << 24) | ((r) << 16) | ((g) << 8) | (b));
}
/**
* Pack the 4 8-bit channels (A,R,G,B)
* into a 32-bit packed premultiplied pixel.
*/
PRUint32 MOZ_ALWAYS_INLINE
gfxPackedPixel(PRUint8 a, PRUint8 r, PRUint8 g, PRUint8 b) {
if (a == 0x00)
return 0x00000000;
else if (a == 0xFF) {
return gfxPackedPixelNoPreMultiply(a, r, g, b);
} else {
return ((a) << 24) |
(gfxPreMultiply(r,a) << 16) |
(gfxPreMultiply(g,a) << 8) |
(gfxPreMultiply(b,a));
}
}
/** /**
* A color value, storing red, green, blue and alpha components. * A color value, storing red, green, blue and alpha components.

View File

@ -103,7 +103,7 @@ private:
*/ */
static inline void SetPixel(uint32_t*& aDecoded, uint8_t aRed, uint8_t aGreen, uint8_t aBlue, uint8_t aAlpha = 0xFF) static inline void SetPixel(uint32_t*& aDecoded, uint8_t aRed, uint8_t aGreen, uint8_t aBlue, uint8_t aAlpha = 0xFF)
{ {
*aDecoded++ = GFX_PACKED_PIXEL(aAlpha, aRed, aGreen, aBlue); *aDecoded++ = gfxPackedPixel(aAlpha, aRed, aGreen, aBlue);
} }
static inline void SetPixel(uint32_t*& aDecoded, uint8_t idx, colorTable* aColors) static inline void SetPixel(uint32_t*& aDecoded, uint8_t idx, colorTable* aColors)

View File

@ -558,7 +558,7 @@ static void ConvertColormap(uint32_t *aColormap, uint32_t aColors)
// NB: can't use 32-bit reads, they might read off the end of the buffer // NB: can't use 32-bit reads, they might read off the end of the buffer
for (; (NS_PTR_TO_UINT32(from) & 0x3) && c; --c) { for (; (NS_PTR_TO_UINT32(from) & 0x3) && c; --c) {
from -= 3; from -= 3;
*--to = GFX_PACKED_PIXEL(0xFF, from[0], from[1], from[2]); *--to = gfxPackedPixel(0xFF, from[0], from[1], from[2]);
} }
// bulk copy of pixels. // bulk copy of pixels.
@ -573,7 +573,7 @@ static void ConvertColormap(uint32_t *aColormap, uint32_t aColors)
// NB: can't use 32-bit reads, they might read off the end of the buffer // NB: can't use 32-bit reads, they might read off the end of the buffer
while (c--) { while (c--) {
from -= 3; from -= 3;
*--to = GFX_PACKED_PIXEL(0xFF, from[0], from[1], from[2]); *--to = gfxPackedPixel(0xFF, from[0], from[1], from[2]);
} }
} }

View File

@ -609,7 +609,7 @@ nsJPEGDecoder::OutputScanlines(bool* suspend)
// copy as bytes until source pointer is 32-bit-aligned // copy as bytes until source pointer is 32-bit-aligned
for (; (NS_PTR_TO_UINT32(sampleRow) & 0x3) && idx; --idx) { for (; (NS_PTR_TO_UINT32(sampleRow) & 0x3) && idx; --idx) {
*imageRow++ = GFX_PACKED_PIXEL(0xFF, sampleRow[0], sampleRow[1], sampleRow[2]); *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1], sampleRow[2]);
sampleRow += 3; sampleRow += 3;
} }
@ -624,7 +624,7 @@ nsJPEGDecoder::OutputScanlines(bool* suspend)
// copy remaining pixel(s) // copy remaining pixel(s)
while (idx--) { while (idx--) {
// 32-bit read of final pixel will exceed buffer, so read bytes // 32-bit read of final pixel will exceed buffer, so read bytes
*imageRow++ = GFX_PACKED_PIXEL(0xFF, sampleRow[0], sampleRow[1], sampleRow[2]); *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1], sampleRow[2]);
sampleRow += 3; sampleRow += 3;
} }
} }

View File

@ -727,7 +727,7 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
// copy as bytes until source pointer is 32-bit-aligned // copy as bytes until source pointer is 32-bit-aligned
for (; (NS_PTR_TO_UINT32(line) & 0x3) && idx; --idx) { for (; (NS_PTR_TO_UINT32(line) & 0x3) && idx; --idx) {
*cptr32++ = GFX_PACKED_PIXEL(0xFF, line[0], line[1], line[2]); *cptr32++ = gfxPackedPixel(0xFF, line[0], line[1], line[2]);
line += 3; line += 3;
} }
@ -742,7 +742,7 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
// copy remaining pixel(s) // copy remaining pixel(s)
while (idx--) { while (idx--) {
// 32-bit read of final pixel will exceed buffer, so read bytes // 32-bit read of final pixel will exceed buffer, so read bytes
*cptr32++ = GFX_PACKED_PIXEL(0xFF, line[0], line[1], line[2]); *cptr32++ = gfxPackedPixel(0xFF, line[0], line[1], line[2]);
line += 3; line += 3;
} }
} }
@ -751,14 +751,14 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
{ {
if (!decoder->mDisablePremultipliedAlpha) { if (!decoder->mDisablePremultipliedAlpha) {
for (uint32_t x=width; x>0; --x) { for (uint32_t x=width; x>0; --x) {
*cptr32++ = GFX_PACKED_PIXEL(line[3], line[0], line[1], line[2]); *cptr32++ = gfxPackedPixel(line[3], line[0], line[1], line[2]);
if (line[3] != 0xff) if (line[3] != 0xff)
rowHasNoAlpha = false; rowHasNoAlpha = false;
line += 4; line += 4;
} }
} else { } else {
for (uint32_t x=width; x>0; --x) { for (uint32_t x=width; x>0; --x) {
*cptr32++ = GFX_PACKED_PIXEL_NO_PREMULTIPLY(line[3], line[0], line[1], line[2]); *cptr32++ = gfxPackedPixelNoPreMultiply(line[3], line[0], line[1], line[2]);
if (line[3] != 0xff) if (line[3] != 0xff)
rowHasNoAlpha = false; rowHasNoAlpha = false;
line += 4; line += 4;

View File

@ -354,9 +354,9 @@ nsJPEGEncoder::ConvertRGBARow(const uint8_t* aSrc, uint8_t* aDest,
uint8_t* pixelOut = &aDest[x * 3]; uint8_t* pixelOut = &aDest[x * 3];
uint8_t alpha = pixelIn[3]; uint8_t alpha = pixelIn[3];
pixelOut[0] = GFX_PREMULTIPLY(pixelIn[0], alpha); pixelOut[0] = gfxPreMultiply(pixelIn[0], alpha);
pixelOut[1] = GFX_PREMULTIPLY(pixelIn[1], alpha); pixelOut[1] = gfxPreMultiply(pixelIn[1], alpha);
pixelOut[2] = GFX_PREMULTIPLY(pixelIn[2], alpha); pixelOut[2] = gfxPreMultiply(pixelIn[2], alpha);
} }
} }