10 #if GFX_USE_GDISP && GDISP_NEED_IMAGE && GDISP_NEED_IMAGE_GIF
15 #define GDISP_IMAGE_GIF_EOF ((gdispImageError)-1)
16 #define GDISP_IMAGE_GIF_LOOP ((gdispImageError)-2)
18 #define GIF_MAX_CODE_BITS 12
19 #define GIF_CODE_MAX ((1<<GIF_MAX_CODE_BITS)-1)
20 #define GIF_CODE_FLUSH (GIF_CODE_MAX+1)
21 #define GIF_CODE_FIRST (GIF_CODE_MAX+2)
22 #define GIF_CODE_NONE (GIF_CODE_MAX+3)
25 static const gU16 GifBitMask[] = {
26 0x0000, 0x0001, 0x0003, 0x0007,
27 0x000f, 0x001f, 0x003f, 0x007f,
28 0x00ff, 0x01ff, 0x03ff, 0x07ff,
33 typedef struct gifimgdecode {
48 gU16 prefix[1<<GIF_MAX_CODE_BITS];
49 gU8 suffix[1<<GIF_MAX_CODE_BITS];
50 gU8 stack[1<<GIF_MAX_CODE_BITS];
54 typedef struct gifimgframe {
59 #define GIFL_TRANSPARENT 0x01
60 #define GIFL_DISPOSECLEAR 0x02
61 #define GIFL_DISPOSEREST 0x04
62 #define GIFL_INTERLACE 0x08
72 typedef struct gifimgcache {
76 struct gifimgcache *next;
80 typedef struct gifimgdispose {
87 typedef struct gdispImagePrivate_GIF {
90 #define GIF_LOOPFOREVER 0x02
97 gifimgcache * curcache;
98 gifimgdecode * decode;
100 gifimgdispose dispose;
102 } gdispImagePrivate_GIF;
110 gdispImagePrivate_GIF * priv;
111 gifimgdecode * decode;
114 priv = (gdispImagePrivate_GIF *)img->priv;
117 if (!(decode = (gifimgdecode *)gdispImageAlloc(img,
sizeof(gifimgdecode)+priv->frame.palsize*
sizeof(
gColor))))
118 return GDISP_IMAGE_ERR_NOMEMORY;
124 if (priv->frame.palsize) {
126 decode->maxpixel = priv->frame.palsize-1;
127 decode->palette = (
gColor *)(decode+1);
129 for(cnt = 0; cnt < priv->frame.palsize; cnt++) {
130 if (
gfileRead(img->f, &decode->buf, 3) != 3)
132 decode->palette[cnt] =
RGB2COLOR(decode->buf[0], decode->buf[1], decode->buf[2]);
134 }
else if (priv->palette) {
136 decode->maxpixel = priv->palsize-1;
137 decode->palette = priv->palette;
145 if (
gfileRead(img->f, &decode->bitsperpixel, 1) != 1 || decode->bitsperpixel >= GIF_MAX_CODE_BITS)
147 decode->code_clear = 1 << decode->bitsperpixel;
148 decode->code_eof = decode->code_clear + 1;
149 decode->code_max = decode->code_clear + 2;
150 decode->code_last = GIF_CODE_NONE;
151 decode->bitspercode = decode->bitsperpixel+1;
152 decode->maxcodesz = 1 << decode->bitspercode;
153 decode->shiftbits = 0;
154 decode->shiftdata = 0;
155 decode->stackcnt = 0;
156 for(cnt = 0; cnt <= GIF_CODE_MAX; cnt++)
157 decode->prefix[cnt] = GIF_CODE_NONE;
160 priv->decode = decode;
161 return GDISP_IMAGE_ERR_OK;
164 gdispImageFree(img, decode,
sizeof(gifimgdecode)+priv->frame.palsize*
sizeof(
gColor));
165 return GDISP_IMAGE_ERR_BADDATA;
173 static void stopDecodeGif(
gImage *img) {
174 gdispImagePrivate_GIF * priv;
176 priv = (gdispImagePrivate_GIF *)img->priv;
180 gdispImageFree(img, (
void *)priv->decode,
sizeof(gifimgdecode)+priv->frame.palsize*
sizeof(
gColor));
185 static gU16 getPrefixGif(gifimgdecode *decode, gU16 code) {
188 for(i=0; code > decode->code_clear && i <= GIF_CODE_MAX; i++, code = decode->prefix[code]) {
189 if (code > GIF_CODE_MAX)
190 return GIF_CODE_NONE;
204 static gU16 getBytesGif(
gImage *img) {
205 gdispImagePrivate_GIF * priv;
206 gifimgdecode * decode;
211 priv = (gdispImagePrivate_GIF *)img->priv;
212 decode = priv->decode;
216 if (decode->code_last == decode->code_eof)
219 while(cnt <
sizeof(decode->buf)) {
221 if (decode->stackcnt > 0) {
222 decode->buf[cnt++] = decode->stack[--decode->stackcnt];
227 while (decode->shiftbits < decode->bitspercode) {
229 if ((!decode->blocksz && (
gfileRead(img->f, &decode->blocksz, 1) != 1 || !decode->blocksz))
232 decode->code_last = decode->code_eof;
237 decode->shiftdata |= ((
unsigned long)bdata) << decode->shiftbits;
238 decode->shiftbits += 8;
240 code = decode->shiftdata & GifBitMask[decode->bitspercode];
241 decode->shiftdata >>= decode->bitspercode;
242 decode->shiftbits -= decode->bitspercode;
249 if (decode->code_max < GIF_CODE_MAX + 2 && ++decode->code_max > decode->maxcodesz && decode->bitspercode < GIF_MAX_CODE_BITS) {
250 decode->maxcodesz <<= 1;
251 decode->bitspercode++;
255 if (code == decode->code_eof) {
259 }
while (
gfileRead(img->f, &decode->blocksz, 1) == 1 && decode->blocksz);
262 decode->code_last = decode->code_eof;
266 if (code == decode->code_clear) {
268 for(prefix = 0; prefix <= GIF_CODE_MAX; prefix++)
269 decode->prefix[prefix] = GIF_CODE_NONE;
270 decode->code_max = decode->code_eof + 1;
271 decode->bitspercode = decode->bitsperpixel + 1;
272 decode->maxcodesz = 1 << decode->bitspercode;
273 decode->code_last = GIF_CODE_NONE;
277 if (code < decode->code_clear) {
279 decode->buf[cnt++] = code;
287 if (decode->prefix[code] != GIF_CODE_NONE)
296 else if (code == decode->code_max - 2 && decode->stackcnt <
sizeof(decode->stack)) {
297 prefix = decode->code_last;
298 decode->suffix[decode->code_max - 2] = decode->stack[decode->stackcnt++] = getPrefixGif(decode, decode->code_last);
307 while (decode->stackcnt <
sizeof(decode->stack) && prefix > decode->code_clear && prefix <= GIF_CODE_MAX) {
308 decode->stack[decode->stackcnt++] = decode->suffix[prefix];
309 prefix = decode->prefix[prefix];
311 if (decode->stackcnt >=
sizeof(decode->stack) || prefix > GIF_CODE_MAX)
315 decode->stack[decode->stackcnt++] = prefix;
318 if (decode->code_last != GIF_CODE_NONE && decode->prefix[decode->code_max - 2] == GIF_CODE_NONE) {
319 decode->prefix[decode->code_max - 2] = decode->code_last;
325 decode->suffix[decode->code_max - 2] = getPrefixGif(decode, code == decode->code_max - 2 ? decode->code_last : code);
327 decode->code_last = code;
338 gdispImagePrivate_GIF * priv;
343 priv = (gdispImagePrivate_GIF *)img->priv;
346 priv->dispose.flags = priv->frame.flags;
347 priv->dispose.paltrans = priv->frame.paltrans;
348 priv->dispose.x = priv->frame.x;
349 priv->dispose.y = priv->frame.y;
350 priv->dispose.width = priv->frame.width;
351 priv->dispose.height = priv->frame.height;
354 for(cache=priv->cache; cache && cache->frame.posstart <=
gfileGetPos(img->f); cache=cache->next) {
355 if (cache->frame.posstart ==
gfileGetPos(img->f)) {
356 priv->frame = cache->frame;
357 priv->curcache = cache;
358 return GDISP_IMAGE_ERR_OK;
365 priv->frame.flags = 0;
366 priv->frame.delay = 0;
367 priv->frame.palsize = 0;
371 if (
gfileRead(img->f, &blocktype, 1) != 1)
372 return GDISP_IMAGE_ERR_BADDATA;
377 if (
gfileRead(img->f, priv->buf, 9) != 9)
378 return GDISP_IMAGE_ERR_BADDATA;
379 priv->frame.x = gdispImageGetAlignedLE16(priv->buf, 0);
380 priv->frame.y = gdispImageGetAlignedLE16(priv->buf, 2);
381 priv->frame.width = gdispImageGetAlignedLE16(priv->buf, 4);
382 priv->frame.height = gdispImageGetAlignedLE16(priv->buf, 6);
383 if (((gU8 *)priv->buf)[8] & 0x80)
384 priv->frame.palsize = 2 << (((gU8 *)priv->buf)[8] & 0x07);
385 if (((gU8 *)priv->buf)[8] & 0x40)
386 priv->frame.flags |= GIFL_INTERLACE;
390 priv->frame.posimg = priv->frame.pospal+priv->frame.palsize*3;
391 priv->frame.posend = 0;
394 if (priv->frame.posstart != priv->frame0pos)
395 img->flags |= GDISP_IMAGE_FLG_ANIMATED;
396 return GDISP_IMAGE_ERR_OK;
400 if (
gfileRead(img->f, &blocktype, 1) != 1)
401 return GDISP_IMAGE_ERR_BADDATA;
406 if (
gfileRead(img->f, priv->buf, 6) != 6)
407 return GDISP_IMAGE_ERR_BADDATA;
409 if (((gU8 *)priv->buf)[0] != 4 || ((gU8 *)priv->buf)[5] != 0)
410 return GDISP_IMAGE_ERR_BADDATA;
412 switch(((gU8 *)priv->buf)[1] & 0x1C) {
413 case 0x00:
case 0x04:
break;
414 case 0x08: priv->frame.flags |= GIFL_DISPOSECLEAR;
break;
415 case 0x0C:
case 0x10: priv->frame.flags |= GIFL_DISPOSEREST;
break;
416 default:
return GDISP_IMAGE_ERR_UNSUPPORTED;
418 if (((gU8 *)priv->buf)[1] & 0x01) {
419 priv->frame.flags |= GIFL_TRANSPARENT;
420 img->flags |= GDISP_IMAGE_FLG_TRANSPARENT;
422 if (((gU8 *)priv->buf)[1] & 0x02)
423 img->flags |= GDISP_IMAGE_FLG_MULTIPAGE;
425 img->flags &= ~GDISP_IMAGE_FLG_MULTIPAGE;
427 priv->frame.delay = gdispImageGetAlignedLE16(priv->buf, 2);
428 priv->frame.paltrans = ((gU8 *)priv->buf)[4];
433 if (priv->flags & GIF_LOOP)
436 if (
gfileRead(img->f, priv->buf, 16) != 16)
437 return GDISP_IMAGE_ERR_BADDATA;
439 if (((gU8 *)priv->buf)[0] != 11 && ((gU8 *)priv->buf)[12] != 3)
440 return GDISP_IMAGE_ERR_BADDATA;
442 if (((gU8 *)priv->buf)[1] ==
'N' && ((gU8 *)priv->buf)[2] ==
'E' && ((gU8 *)priv->buf)[3] ==
'T'
443 && ((gU8 *)priv->buf)[4] ==
'S' && ((gU8 *)priv->buf)[5] ==
'C' && ((gU8 *)priv->buf)[6] ==
'A'
444 && ((gU8 *)priv->buf)[7] ==
'P' && ((gU8 *)priv->buf)[8] ==
'E' && ((gU8 *)priv->buf)[9] ==
'2'
445 && ((gU8 *)priv->buf)[10] ==
'.' && ((gU8 *)priv->buf)[11] ==
'0') {
446 if (((gU8 *)priv->buf)[13] == 1) {
447 priv->loops = gdispImageGetAlignedLE16(priv->buf, 14);
448 priv->flags |= GIF_LOOP;
450 priv->flags |= GIF_LOOPFOREVER;
459 if (blocktype <= 0x7F)
460 return GDISP_IMAGE_ERR_UNSUPPORTED;
467 return GDISP_IMAGE_ERR_BADDATA;
478 if (!(priv->flags & GIF_LOOP))
479 return GDISP_IMAGE_GIF_EOF;
480 if (!(priv->flags & GIF_LOOPFOREVER)) {
482 return GDISP_IMAGE_GIF_EOF;
488 return GDISP_IMAGE_GIF_LOOP;
491 return GDISP_IMAGE_ERR_UNSUPPORTED;
496 void gdispImageClose_GIF(
gImage *img) {
497 gdispImagePrivate_GIF * priv;
499 gifimgcache * ncache;
501 priv = (gdispImagePrivate_GIF *)img->priv;
506 ncache = cache->next;
507 gdispImageFree(img, (
void *)cache,
sizeof(gifimgcache)+cache->frame.width*cache->frame.height+cache->frame.palsize*
sizeof(
gColor));
511 gdispImageFree(img, (
void *)priv->palette, priv->palsize*
sizeof(
gColor));
512 gdispImageFree(img, (
void *)priv,
sizeof(gdispImagePrivate_GIF));
518 gdispImagePrivate_GIF *priv;
524 return GDISP_IMAGE_ERR_BADFORMAT;
528 if (hdr[0] !=
'G' || hdr[1] !=
'I' || hdr[2] !=
'F'
529 || hdr[3] !=
'8' || (hdr[4] !=
'7' && hdr[4] !=
'9') || hdr[5] !=
'a')
530 return GDISP_IMAGE_ERR_BADFORMAT;
536 if (!(img->priv = gdispImageAlloc(img,
sizeof(gdispImagePrivate_GIF))))
537 return GDISP_IMAGE_ERR_NOMEMORY;
540 priv = (gdispImagePrivate_GIF *)img->priv;
544 priv->frame.flags = 0;
552 if (
gfileRead(img->f, priv->buf, 7) != 7)
555 img->width = gdispImageGetAlignedLE16(priv->buf, 0);
557 img->height = gdispImageGetAlignedLE16(priv->buf, 2);
558 if (((gU8 *)priv->buf)[4] & 0x80) {
560 priv->palsize = 2 << (((gU8 *)priv->buf)[4] & 0x07);
562 if (!(priv->palette = (
gColor *)gdispImageAlloc(img, priv->palsize*
sizeof(
gColor))))
565 for(aword = 0; aword < priv->palsize; aword++) {
566 if (
gfileRead(img->f, &priv->buf, 3) != 3)
568 priv->palette[aword] =
RGB2COLOR(((gU8 *)priv->buf)[0], ((gU8 *)priv->buf)[1], ((gU8 *)priv->buf)[2]);
571 priv->bgcolor = ((gU8 *)priv->buf)[5];
577 switch(initFrameGif(img)) {
578 case GDISP_IMAGE_ERR_OK:
579 img->type = GDISP_IMAGE_TYPE_GIF;
580 return GDISP_IMAGE_ERR_OK;
581 case GDISP_IMAGE_ERR_UNSUPPORTED:
582 gdispImageClose_GIF(img);
583 return GDISP_IMAGE_ERR_UNSUPPORTED;
584 case GDISP_IMAGE_ERR_NOMEMORY:
586 gdispImageClose_GIF(img);
587 return GDISP_IMAGE_ERR_NOMEMORY;
588 case GDISP_IMAGE_GIF_EOF:
589 case GDISP_IMAGE_GIF_LOOP:
590 case GDISP_IMAGE_ERR_BADDATA:
593 gdispImageClose_GIF(img);
594 return GDISP_IMAGE_ERR_BADDATA;
599 gdispImagePrivate_GIF * priv;
601 gifimgdecode * decode;
608 priv = (gdispImagePrivate_GIF *)img->priv;
610 return GDISP_IMAGE_ERR_OK;
613 if (!(cache = (gifimgcache *)gdispImageAlloc(img,
sizeof(gifimgcache) + priv->frame.palsize*
sizeof(
gColor) + priv->frame.width*priv->frame.height)))
614 return GDISP_IMAGE_ERR_NOMEMORY;
618 cache->frame = priv->frame;
619 cache->imagebits = (gU8 *)(cache+1) + cache->frame.palsize*
sizeof(
gColor);
623 switch(startDecodeGif(img)) {
624 case GDISP_IMAGE_ERR_OK:
break;
625 case GDISP_IMAGE_ERR_NOMEMORY:
goto nomemcleanup;
626 case GDISP_IMAGE_ERR_BADDATA:
627 default:
goto baddatacleanup;
629 decode = priv->decode;
632 if (cache->frame.palsize) {
633 cache->palette = (
gColor *)(cache+1);
636 for(cnt = 0; cnt < cache->frame.palsize; cnt++)
637 cache->palette[cnt] = decode->palette[cnt];
639 cache->palette = priv->palette;
644 if (cache->frame.flags & GIFL_INTERLACE) {
646 for(p=cache->imagebits, my=0; my < cache->frame.height; my+=8, p += cache->frame.width*7) {
647 for(mx=0; mx < cache->frame.width; mx++) {
649 if (!(cnt = getBytesGif(img))) {
651 if (decode->code_last != decode->code_eof)
653 while(cnt <
sizeof(decode->buf))
654 decode->buf[cnt++] = (cache->frame.flags & GIFL_TRANSPARENT) ? cache->frame.paltrans : 0;
663 for(p=cache->imagebits+cache->frame.width*4, my=4; my < cache->frame.height; my+=8, p += cache->frame.width*7) {
664 for(mx=0; mx < cache->frame.width; mx++) {
666 if (!(cnt = getBytesGif(img))) {
668 if (decode->code_last != decode->code_eof)
670 while(cnt <
sizeof(decode->buf))
671 decode->buf[cnt++] = (cache->frame.flags & GIFL_TRANSPARENT) ? cache->frame.paltrans : 0;
680 for(p=cache->imagebits+cache->frame.width*2, my=2; my < cache->frame.height; my+=4, p += cache->frame.width*3) {
681 for(mx=0; mx < cache->frame.width; mx++) {
683 if (!(cnt = getBytesGif(img))) {
685 if (decode->code_last != decode->code_eof)
687 while(cnt <
sizeof(decode->buf))
688 decode->buf[cnt++] = (cache->frame.flags & GIFL_TRANSPARENT) ? cache->frame.paltrans : 0;
697 for(p=cache->imagebits+cache->frame.width, my=1; my < cache->frame.height; my+=2, p += cache->frame.width) {
698 for(mx=0; mx < cache->frame.width; mx++) {
700 if (!(cnt = getBytesGif(img))) {
702 if (decode->code_last != decode->code_eof)
704 while(cnt <
sizeof(decode->buf))
705 decode->buf[cnt++] = (cache->frame.flags & GIFL_TRANSPARENT) ? cache->frame.paltrans : 0;
716 for(my=0; my < cache->frame.height; my++) {
717 for(mx=0; mx < cache->frame.width; mx++) {
719 if (!(cnt = getBytesGif(img))) {
721 if (decode->code_last != decode->code_eof)
723 while(cnt <
sizeof(decode->buf))
724 decode->buf[cnt++] = (cache->frame.flags & GIFL_TRANSPARENT) ? cache->frame.paltrans : 0;
734 while(getBytesGif(img));
735 priv->frame.posend = cache->frame.posend =
gfileGetPos(img->f);
738 priv->curcache = cache;
741 else if (priv->cache->frame.posstart > cache->frame.posstart) {
742 cache->next = priv->cache;
747 for(pc = priv->cache; pc; pc = pc->next) {
748 if (!pc->next || pc->next->frame.posstart > cache->frame.posstart) {
749 cache->next = pc->next;
756 return GDISP_IMAGE_ERR_OK;
760 gdispImageFree(img, cache,
sizeof(gifimgcache) + priv->frame.palsize*
sizeof(
gColor) + priv->frame.width*priv->frame.height);
761 return GDISP_IMAGE_ERR_NOMEMORY;
765 gdispImageFree(img, cache,
sizeof(gifimgcache) + priv->frame.palsize*
sizeof(
gColor) + priv->frame.width*priv->frame.height);
766 return GDISP_IMAGE_ERR_BADDATA;
770 gdispImagePrivate_GIF * priv;
771 gifimgdecode * decode;
777 priv = (gdispImagePrivate_GIF *)img->priv;
780 if (priv->dispose.flags & (GIFL_DISPOSECLEAR|GIFL_DISPOSEREST)) {
782 mx = priv->dispose.x;
783 my = priv->dispose.y;
784 fx = priv->dispose.x+priv->dispose.width;
785 fy = priv->dispose.y+priv->dispose.height;
786 if (sx > mx) mx = sx;
787 if (sy > my) my = sy;
788 if (sx+cx <= fx) fx = sx+cx;
789 if (sy+cy <= fy) fy = sy+cy;
790 if (fx > mx && fy > my) {
795 if (((priv->dispose.flags & GIFL_TRANSPARENT) ) || priv->bgcolor >= priv->palsize)
798 gdispGFillArea(g, x+mx-sx, y+my-sy, fx-mx, fy-my, priv->palette[priv->bgcolor]);
803 fx = priv->frame.x+priv->frame.width;
804 fy = priv->frame.y+priv->frame.height;
805 if (sx >= fx || sy >= fy || sx+cx < priv->frame.x || sy+cy < priv->frame.y)
return GDISP_IMAGE_ERR_OK;
806 if (sx < priv->frame.x) { mx = priv->frame.x - sx; x += mx; cx -= mx; sx = priv->frame.x; }
807 if (sy < priv->frame.y) { my = priv->frame.y - sy; y += my; cy -= my; sy = priv->frame.y; }
808 if (sx+cx > fx) cx = fx-sx;
809 if (sy+cy > fy) cy = fy-sy;
812 sx -= priv->frame.x; sy -= priv->frame.y;
817 if (priv->curcache) {
820 cache = priv->curcache;
821 q = cache->imagebits+priv->frame.width*sy+sx;
823 for(my=sy; my < fy; my++, q += priv->frame.width - cx) {
824 for(gcnt=0, mx=sx, cnt=0; mx < fx; mx++) {
826 if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) {
830 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
831 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
835 priv->buf[gcnt++] = cache->palette[col];
838 gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
845 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]);
break;
846 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
break;
850 return GDISP_IMAGE_ERR_OK;
854 switch(startDecodeGif(img)) {
855 case GDISP_IMAGE_ERR_OK:
break;
856 case GDISP_IMAGE_ERR_NOMEMORY:
return GDISP_IMAGE_ERR_NOMEMORY;
857 case GDISP_IMAGE_ERR_BADDATA:
858 default:
return GDISP_IMAGE_ERR_BADDATA;
860 decode = priv->decode;
864 if (priv->frame.flags & GIFL_INTERLACE) {
866 for(my=0; my < priv->frame.height; my+=8) {
867 for(gcnt=0, mx=0; mx < priv->frame.width; mx++, q++, cnt--) {
869 if (!(cnt = getBytesGif(img))) {
871 if (decode->code_last != decode->code_eof)
878 if (my >= sy && my < fy && mx >= sx && mx < fx) {
880 if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) {
884 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
885 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
889 priv->buf[gcnt++] = decode->palette[col];
892 gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
900 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
901 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
907 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]);
break;
908 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
break;
912 for(my=4; my < priv->frame.height; my+=8) {
913 for(gcnt=0, mx=0; mx < priv->frame.width; mx++, q++, cnt--) {
915 if (!(cnt = getBytesGif(img))) {
917 if (decode->code_last != decode->code_eof)
924 if (my >= sy && my < fy && mx >= sx && mx < fx) {
926 if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) {
930 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
931 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
935 priv->buf[gcnt++] = decode->palette[col];
938 gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
946 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
947 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
953 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]);
break;
954 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
break;
958 for(my=2; my < priv->frame.height; my+=4) {
959 for(gcnt=0, mx=0; mx < priv->frame.width; mx++, q++, cnt--) {
961 if (!(cnt = getBytesGif(img))) {
963 if (decode->code_last != decode->code_eof)
970 if (my >= sy && my < fy && mx >= sx && mx < fx) {
972 if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) {
976 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
977 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
981 priv->buf[gcnt++] = decode->palette[col];
984 gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
992 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
993 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
999 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]);
break;
1000 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
break;
1004 for(my=1; my < priv->frame.height; my+=2) {
1005 for(gcnt=0, mx=0; mx < priv->frame.width; mx++, q++, cnt--) {
1007 if (!(cnt = getBytesGif(img))) {
1009 if (decode->code_last != decode->code_eof)
1010 goto baddatacleanup;
1016 if (my >= sy && my < fy && mx >= sx && mx < fx) {
1018 if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) {
1022 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
1023 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
1027 priv->buf[gcnt++] = decode->palette[col];
1030 gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
1038 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
1039 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
1045 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]);
break;
1046 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
break;
1051 for(my=0; my < priv->frame.height; my++) {
1052 for(gcnt=0, mx=0; mx < priv->frame.width; mx++, q++, cnt--) {
1054 if (!(cnt = getBytesGif(img))) {
1056 if (decode->code_last != decode->code_eof)
1057 goto baddatacleanup;
1063 if (my >= sy && my < fy && mx >= sx && mx < fx) {
1065 if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) {
1069 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
1070 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
1074 priv->buf[gcnt++] = decode->palette[col];
1077 gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
1085 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0;
break;
1086 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0;
break;
1092 case 1:
gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]);
break;
1093 default:
gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
break;
1098 while (getBytesGif(img));
1102 return GDISP_IMAGE_ERR_OK;
1106 return GDISP_IMAGE_ERR_BADDATA;
1109 gDelay gdispImageNext_GIF(
gImage *img) {
1110 gdispImagePrivate_GIF * priv;
1114 priv = (gdispImagePrivate_GIF *)img->priv;
1117 delay = (gDelay)priv->frame.delay * 10;
1120 if (!priv->frame.posend) {
1124 if (
gfileRead(img->f, &blocksz, 1) != 1)
1125 return gDelayForever;
1137 for(blocksz=0; blocksz < 2; blocksz++) {
1138 switch(initFrameGif(img)) {
1139 case GDISP_IMAGE_ERR_OK:
1141 case GDISP_IMAGE_GIF_LOOP:
1143 case GDISP_IMAGE_GIF_EOF:
1144 case GDISP_IMAGE_ERR_BADDATA:
1145 case GDISP_IMAGE_ERR_NOMEMORY:
1146 case GDISP_IMAGE_ERR_UNSUPPORTED:
1148 return gDelayForever;
1151 return gDelayForever;
GDISP image support routines header file.
#define RGB2COLOR(r, g, b)
Convert red, green, blue (each 0 to 255) into a color value.
COLOR_TYPE gColor
The color type definition.
#define GDISP_IMAGE_GIF_BLIT_BUFFER_SIZE
The GIF blit buffer size.
void gdispGDrawPixel(GDisplay *g, gCoord x, gCoord y, gColor color)
Set a pixel in the specified color.
void gdispGBlitArea(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gCoord srcx, gCoord srcy, gCoord srccx, const gPixel *buffer)
Fill an area using the supplied bitmap.
gColor gPixel
The pixel format.
void gdispGFillArea(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gColor color)
Fill an area with a color.
gI16 gCoord
The type for a coordinate or length on the screen.
gBool gfileSetPos(GFILE *f, gFileSize pos)
Set the position of the read/write cursor.
gMemSize gfileRead(GFILE *f, void *buf, gMemSize len)
Read from file.
gFileSize gfileGetPos(GFILE *f)
Get the current position of the read/write cursor.
gU16 gdispImageError
An image error code.
The structure for an image.