From: Jiyoun Park <jy0703.park@samsung.com>

Subject: [E-devel] [Patch] support Animation gif's disposal mode

I make patch support animation gif disposal mode.

Before, gif loader only decode & render based on previous frame. 

This patch can support "do not dispose mode" & "restore background
mode". 

So It solve after image problem of restore background mode.




SVN revision: 63716
This commit is contained in:
Jiyoun Park 2011-09-30 07:10:40 +00:00 committed by Carsten Haitzler
parent 5d4c95d975
commit c231bf108b
1 changed files with 159 additions and 37 deletions

View File

@ -209,6 +209,8 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
int cache_h;
int cur_h;
int cur_w;
int disposal = 0;
int bg_val = 0;
DATA32 *ptr;
Gif_Frame *gif_frame = NULL;
@ -282,6 +284,25 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
bg = gif->SBackGroundColor;
cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
if (!cmap)
{
DGifCloseFile(gif);
for (i = 0; i < h; i++)
{
free(rows[i]);
}
free(rows);
if (frame->data) free(frame->data);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
return EINA_FALSE;
}
/* get the background value */
r = cmap->Colors[bg].Red;
g = cmap->Colors[bg].Green;
b = cmap->Colors[bg].Blue;
bg_val = ARGB_JOIN(0xff, r, g, b);
per_inc = 100.0 / (((double)w) * h);
cur_h = h;
cur_w = w;
@ -314,7 +335,6 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
goto error;
}
}
if (!_find_frame(ie, cur_frame - 1, &new_frame))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
@ -322,51 +342,153 @@ _evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry
}
else
{
Gif_Frame *gif_frame = NULL;
ptr_src = new_frame->data;
memcpy(ptr, ptr_src, siz);
}
/* composite frames */
ptr = ptr + cache_w * y;
for (i = 0; i < cur_h; i++)
{
ptr = ptr + x;
for (j = 0; j < cur_w; j++)
if (new_frame->info)
{
if (rows[i][j] == alpha)
{
ptr++ ;
}
else
{
r = cmap->Colors[rows[i][j]].Red;
g = cmap->Colors[rows[i][j]].Green;
b = cmap->Colors[rows[i][j]].Blue;
*ptr++ = ARGB_JOIN(0xff, r, g, b);
}
per += per_inc;
gif_frame = (Gif_Frame *)(new_frame->info);
disposal = gif_frame->frame_info.disposal;
}
switch(disposal) /* we only support disposal flag 0,1,2 */
{
case 1: /* Do not dispose. need previous frame*/
memcpy(ptr, ptr_src, siz);
/* composite frames */
ptr = ptr + cache_w * y;
for (i = 0; i < cur_h; i++)
{
ptr = ptr + x;
for (j = 0; j < cur_w; j++)
{
if (rows[i][j] == alpha)
{
ptr++ ;
}
else
{
r = cmap->Colors[rows[i][j]].Red;
g = cmap->Colors[rows[i][j]].Green;
b = cmap->Colors[rows[i][j]].Blue;
*ptr++ = ARGB_JOIN(0xff, r, g, b);
}
per += per_inc;
}
ptr = ptr + (cache_w - (x + cur_w));
}
break;
case 2: /* Restore to background color */
memcpy(ptr, ptr_src, siz);
/* composite frames */
for (i = 0; i < cache_h; i++)
{
if ((i < y) || (i >= (y + cur_h)))
{
for (j = 0; j < cache_w; j++)
{
*ptr = bg_val;
ptr++;
}
}
else
{
int i1, j1;
i1 = i -y;
for (j = 0; j < cache_w; j++)
{
j1 = j - x;
if ((j < x) || (j >= (x + cur_w)))
{
*ptr = bg_val;
ptr++;
}
else
{
r = cmap->Colors[rows[i1][j1]].Red;
g = cmap->Colors[rows[i1][j1]].Green;
b = cmap->Colors[rows[i1][j1]].Blue;
*ptr++ = ARGB_JOIN(0xff, r, g, b);
}
}
}
}
break;
case 0: /* No disposal specified */
default:
memset(ptr, 0, siz);
for (i = 0; i < cache_h; i++)
{
if ((i < y) || (i >= (y + cur_h)))
{
for (j = 0; j < cache_w; j++)
{
*ptr = bg_val;
ptr++;
}
}
else
{
int i1, j1;
i1 = i -y;
for (j = 0; j < cache_w; j++)
{
j1 = j - x;
if ((j < x) || (j >= (x + cur_w)))
{
*ptr = bg_val;
ptr++;
}
else
{
r = cmap->Colors[rows[i1][j1]].Red;
g = cmap->Colors[rows[i1][j1]].Green;
b = cmap->Colors[rows[i1][j1]].Blue;
*ptr++ = ARGB_JOIN(0xff, r, g, b);
}
}
}
}
break;
}
ptr = ptr + (cache_w - (x + cur_w));
}
}
else
else /* first frame decoding */
{
ptr = ptr + cache_w * y;
for (i = 0; i < cur_h; i++)
/* fill background color */
for (i = 0; i < cache_h; i++)
{
ptr = ptr + x;
for (j = 0; j < cur_w; j++)
if ((i < y) || (i >= (y + cur_h)))
{
r = cmap->Colors[rows[i][j]].Red;
g = cmap->Colors[rows[i][j]].Green;
b = cmap->Colors[rows[i][j]].Blue;
*ptr++ = ARGB_JOIN(0xff, r, g, b);
per += per_inc;
for (j = 0; j < cache_w; j++)
{
*ptr = bg_val;
ptr++;
}
}
else
{
int i1, j1;
i1 = i -y;
for (j = 0; j < cache_w; j++)
{
j1 = j - x;
if ((j < x) || (j >= (x + cur_w)))
{
*ptr = bg_val;
ptr++;
}
else
{
r = cmap->Colors[rows[i1][j1]].Red;
g = cmap->Colors[rows[i1][j1]].Green;
b = cmap->Colors[rows[i1][j1]].Blue;
*ptr++ = ARGB_JOIN(0xff, r, g, b);
}
}
}
ptr = ptr + (cache_w - (x + cur_w));
}
}