int cache_h;
int cur_h;
int cur_w;
+ int disposal = 0;
+ int bg_val = 0;
DATA32 *ptr;
Gif_Frame *gif_frame = NULL;
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;
goto error;
}
}
-
if (!_find_frame(ie, cur_frame - 1, &new_frame))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
}
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)
+ 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 = 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));
}
- else
+ break;
+ case 2: /* Restore to background color */
+ memcpy(ptr, ptr_src, siz);
+ /* composite frames */
+ for (i = 0; i < cache_h; i++)
{
- 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);
+ 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);
+ }
+ }
+ }
}
- per += per_inc;
+ 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)))
+ {
+ for (j = 0; j < cache_w; j++)
+ {
+ *ptr = bg_val;
+ 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);
+ int i1, j1;
+ i1 = i -y;
- per += per_inc;
+ 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));
}
}