зеркало из https://github.com/mozilla/pjs.git
Bug 201568 GIF infrastructure cleanup and refactoring, r=pavlov, sr=tor a=sspitzer.
This commit is contained in:
Родитель
cfbb5671d6
Коммит
98ec0e0ad4
|
@ -281,7 +281,10 @@ NS_IMETHODIMP gfxImageFrame::SetImageData(const PRUint8 *aData, PRUint32 aLength
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(imgData + newOffset, aData, aLength);
|
||||
if (aData)
|
||||
memcpy(imgData + newOffset, aData, aLength);
|
||||
else
|
||||
memset(imgData + newOffset, 0, aLength);
|
||||
mImage->UnlockImagePixels(PR_FALSE);
|
||||
|
||||
PRInt32 row = (aOffset / row_stride);
|
||||
|
@ -377,7 +380,10 @@ NS_IMETHODIMP gfxImageFrame::SetAlphaData(const PRUint8 *aData, PRUint32 aLength
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(alphaData + offset, aData, aLength);
|
||||
if (aData)
|
||||
memcpy(alphaData + offset, aData, aLength);
|
||||
else
|
||||
memset(alphaData + offset, 0, aLength);
|
||||
mImage->UnlockImagePixels(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -647,21 +647,14 @@ PRStatus gif_write(gif_struct *gs, const PRUint8 *buf, PRUint32 len)
|
|||
|
||||
case gif_global_colormap:
|
||||
{
|
||||
GIF_RGB* map = (GIF_RGB*)PR_Calloc(gs->global_colormap_size,
|
||||
sizeof(GIF_RGB));
|
||||
PRUint8* map = (PRUint8*)PR_MALLOC(3 * gs->global_colormap_size);
|
||||
if (!map) {
|
||||
gs->state = gif_oom;
|
||||
break;
|
||||
}
|
||||
|
||||
gs->global_colormap = map;
|
||||
|
||||
for (int i = 0; i < gs->global_colormap_size; i++, map++)
|
||||
{
|
||||
map->red = *q++;
|
||||
map->green = *q++;
|
||||
map->blue = *q++;
|
||||
}
|
||||
memcpy(map, q, 3 * gs->global_colormap_size);
|
||||
|
||||
GETN(1, gif_image_start);
|
||||
}
|
||||
|
@ -957,21 +950,16 @@ PRStatus gif_write(gif_struct *gs, const PRUint8 *buf, PRUint32 len)
|
|||
|
||||
case gif_image_colormap:
|
||||
{
|
||||
GIF_RGB *map = gs->local_colormap;
|
||||
PRUint8 *map = gs->local_colormap;
|
||||
if (!map) {
|
||||
map = gs->local_colormap = (GIF_RGB*)PR_Calloc(gs->local_colormap_size,
|
||||
sizeof(GIF_RGB));
|
||||
map = gs->local_colormap = (PRUint8*)PR_MALLOC(3 * gs->local_colormap_size);
|
||||
if (!map) {
|
||||
gs->state = gif_oom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < gs->local_colormap_size; i++, map++) {
|
||||
map->red = *q++;
|
||||
map->green = *q++;
|
||||
map->blue = *q++;
|
||||
}
|
||||
memcpy(map, q, 3 * gs->local_colormap_size);
|
||||
|
||||
GETN(1, gif_lzw_start);
|
||||
}
|
||||
|
|
|
@ -82,32 +82,6 @@ typedef enum
|
|||
DISPOSE_OVERWRITE_PREVIOUS = 3 /* Save-under */
|
||||
} gdispose;
|
||||
|
||||
/* A RGB triplet representing a single pixel in the image's colormap
|
||||
(if present.) */
|
||||
typedef struct _GIF_RGB
|
||||
{
|
||||
PRUint8 red, green, blue, pad; /* Windows requires the fourth byte &
|
||||
many compilers pad it anyway. */
|
||||
} GIF_RGB;
|
||||
|
||||
/* Colormap information. */
|
||||
typedef struct _GIF_ColorMap {
|
||||
int32 num_colors; /* Number of colors in the colormap.
|
||||
A negative value can be used to denote a
|
||||
possibly non-unique set. */
|
||||
GIF_RGB *map; /* Colormap colors. */
|
||||
PRUint8 *index; /* NULL, if map is in index order. Otherwise
|
||||
specifies the indices of the map entries. */
|
||||
void *table; /* Lookup table for this colormap. Private to
|
||||
the Image Library. */
|
||||
} GIF_ColorMap;
|
||||
|
||||
/* An indexed RGB triplet. */
|
||||
typedef struct _GIF_IRGB {
|
||||
PRUint8 index;
|
||||
PRUint8 red, green, blue;
|
||||
} GIF_IRGB;
|
||||
|
||||
/* A GIF decoder's state */
|
||||
typedef struct gif_struct {
|
||||
void* clientptr;
|
||||
|
@ -157,7 +131,7 @@ typedef struct gif_struct {
|
|||
int is_local_colormap_defined;
|
||||
gdispose disposal_method; /* Restore to background, leave in place, etc.*/
|
||||
gdispose last_disposal_method;
|
||||
GIF_RGB *local_colormap; /* Per-image colormap */
|
||||
PRUint8 *local_colormap; /* Per-image colormap */
|
||||
int local_colormap_size; /* Size of local colormap array. */
|
||||
PRUint32 delay_time; /* Display time, in milliseconds,
|
||||
for this image in a multi-image GIF */
|
||||
|
@ -167,7 +141,7 @@ typedef struct gif_struct {
|
|||
int version; /* Either 89 for GIF89 or 87 for GIF87 */
|
||||
PRUintn screen_width; /* Logical screen width & height */
|
||||
PRUintn screen_height;
|
||||
GIF_RGB *global_colormap; /* Default colormap if local not supplied */
|
||||
PRUint8 *global_colormap; /* Default colormap if local not supplied */
|
||||
int global_colormap_size; /* Size of global colormap array. */
|
||||
int images_decoded; /* Counts images for multi-part GIFs */
|
||||
int destroy_pending; /* Stream has ended */
|
||||
|
|
|
@ -421,16 +421,17 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
|
||||
// XXX map the data into colors
|
||||
int cmapsize;
|
||||
GIF_RGB* cmap;
|
||||
PRUint8* cmap;
|
||||
cmapsize = decoder->mGIFStruct->global_colormap_size;
|
||||
cmap = decoder->mGIFStruct->global_colormap;
|
||||
|
||||
if(decoder->mGIFStruct->global_colormap &&
|
||||
decoder->mGIFStruct->screen_bgcolor < cmapsize) {
|
||||
gfx_color bgColor = 0;
|
||||
bgColor |= cmap[decoder->mGIFStruct->screen_bgcolor].red;
|
||||
bgColor |= cmap[decoder->mGIFStruct->screen_bgcolor].green << 8;
|
||||
bgColor |= cmap[decoder->mGIFStruct->screen_bgcolor].blue << 16;
|
||||
PRUint32 bgIndex = decoder->mGIFStruct->screen_bgcolor * 3;
|
||||
bgColor |= cmap[bgIndex];
|
||||
bgColor |= cmap[bgIndex + 1] << 8;
|
||||
bgColor |= cmap[bgIndex + 2] << 16;
|
||||
decoder->mImageFrame->SetBackgroundColor(bgColor);
|
||||
}
|
||||
if(decoder->mGIFStruct->local_colormap) {
|
||||
|
@ -438,96 +439,96 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
cmap = decoder->mGIFStruct->local_colormap;
|
||||
}
|
||||
|
||||
PRUint8* rgbRowIndex = decoder->mRGBLine;
|
||||
PRUint8* rowBufIndex = aRowBufPtr;
|
||||
|
||||
switch (format) {
|
||||
case gfxIFormats::RGB:
|
||||
{
|
||||
if (cmap) {// cmap could have null value if the global color table flag is 0
|
||||
while (rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
|
||||
#endif
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
++rowBufIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
memset(decoder->mRGBLine, 0, bpr);
|
||||
|
||||
for (int i=0; i<aDuplicateCount; i++)
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::BGR:
|
||||
{
|
||||
if (cmap) {// cmap could have null value if the global color table flag is 0
|
||||
while (rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
++rowBufIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
memset(decoder->mRGBLine, 0, bpr);
|
||||
|
||||
for (int i=0; i<aDuplicateCount; i++)
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A1:
|
||||
case gfxIFormats::BGR_A1:
|
||||
{
|
||||
memset(decoder->mRGBLine, 0, bpr);
|
||||
memset(decoder->mAlphaLine, 0, abpr);
|
||||
PRUint32 iwidth = (PRUint32)width;
|
||||
if (cmap) {// cmap could have null value if the global color table flag is 0
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
#else
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
|
||||
#endif
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
#endif
|
||||
decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7);
|
||||
} else {
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
rgbRowIndex+=4;
|
||||
#else
|
||||
rgbRowIndex+=3;
|
||||
#endif
|
||||
}
|
||||
|
||||
++rowBufIndex;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<aDuplicateCount; i++) {
|
||||
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine,
|
||||
if (!cmap) { // cmap could have null value if the global color table flag is 0
|
||||
for (int i = 0; i < aDuplicateCount; ++i) {
|
||||
if (format == gfxIFormats::RGB_A1 ||
|
||||
format == gfxIFormats::BGR_A1) {
|
||||
decoder->mImageFrame->SetAlphaData(nsnull,
|
||||
abpr, (aRowNumber+i)*abpr);
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
decoder->mImageFrame->SetImageData(nsnull,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
} else {
|
||||
PRUint8* rgbRowIndex = decoder->mRGBLine;
|
||||
PRUint8* rowBufIndex = aRowBufPtr;
|
||||
|
||||
switch (format) {
|
||||
case gfxIFormats::RGB:
|
||||
{
|
||||
while (rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
PRUint32 colorIndex = *rowBufIndex * 3;
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
|
||||
#endif
|
||||
*rgbRowIndex++ = cmap[colorIndex]; // red
|
||||
*rgbRowIndex++ = cmap[colorIndex + 1]; // green
|
||||
*rgbRowIndex++ = cmap[colorIndex + 2]; // blue
|
||||
++rowBufIndex;
|
||||
}
|
||||
for (int i=0; i<aDuplicateCount; i++) {
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gfxIFormats::BGR:
|
||||
{
|
||||
while (rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
PRUint32 colorIndex = *rowBufIndex * 3;
|
||||
*rgbRowIndex++ = cmap[colorIndex + 2]; // blue
|
||||
*rgbRowIndex++ = cmap[colorIndex + 1]; // green
|
||||
*rgbRowIndex++ = cmap[colorIndex]; // red
|
||||
++rowBufIndex;
|
||||
}
|
||||
for (int i = 0; i < aDuplicateCount; ++i) {
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gfxIFormats::RGB_A1:
|
||||
case gfxIFormats::BGR_A1:
|
||||
{
|
||||
memset(decoder->mRGBLine, 0, bpr);
|
||||
memset(decoder->mAlphaLine, 0, abpr);
|
||||
for (PRUint32 x = 0; x < (PRUint32)width; ++x) {
|
||||
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
|
||||
PRUint32 colorIndex = *rowBufIndex * 3;
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
*rgbRowIndex++ = cmap[colorIndex + 2]; // blue
|
||||
*rgbRowIndex++ = cmap[colorIndex + 1]; // green
|
||||
*rgbRowIndex++ = cmap[colorIndex]; // red
|
||||
#else
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
|
||||
#endif
|
||||
*rgbRowIndex++ = cmap[colorIndex]; // red
|
||||
*rgbRowIndex++ = cmap[colorIndex + 1]; // green
|
||||
*rgbRowIndex++ = cmap[colorIndex + 2]; // blue
|
||||
#endif
|
||||
decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7);
|
||||
} else {
|
||||
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||
rgbRowIndex+=4;
|
||||
#else
|
||||
rgbRowIndex+=3;
|
||||
#endif
|
||||
}
|
||||
++rowBufIndex;
|
||||
}
|
||||
for (int i=0; i<aDuplicateCount; i++) {
|
||||
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine,
|
||||
abpr, (aRowNumber+i)*abpr);
|
||||
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
|
||||
bpr, (aRowNumber+i)*bpr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
decoder->mCurrentRow = aRowNumber+aDuplicateCount-1;
|
||||
decoder->mCurrentRow = aRowNumber + aDuplicateCount - 1;
|
||||
decoder->mCurrentPass = aInterlacePass;
|
||||
if (aInterlacePass == 1)
|
||||
decoder->mLastFlushedPass = aInterlacePass; // interlaced starts at 1
|
||||
|
@ -535,5 +536,3 @@ int nsGIFDecoder2::HaveDecodedRow(
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче