forked from enlightenment/efl
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:
parent
5d4c95d975
commit
c231bf108b
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue