1 /* OpenCP Module Player
2 * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3 * copyright (c) 1987, by Steven A. Bennett
4 *
5 * GIF picture loader
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * revision history: (please note changes here)
22 * -doj980930 Dirk Jagdmann <doj@cubic.org>
23 * -initial release of this file
24 * the lzw decompression is Copyright (C) 1987, by Steven A. Bennett
25 * the header parsing was written according to the GIF87a specs from
26 * compuserve
27 * -fd990408 Felix Domke <tmbinc@gmx.net>
28 * -included hack to load GIF89a-pics
29 */
30
31 #define NO_CURSES
32 #include "config.h"
33 #include <stdlib.h>
34 #include "types.h"
35 #include "gif.h"
36
37 static const uint8_t *filedata=0; /* because we are lazy */
38 static const uint8_t *filedataEnd=0;
39 static uint8_t *image=0; /* because we are very lazy */
40 static uint16_t GIFimageHeight=0;
41 static int GIFimageInterlace=0; /* oh I am so lazy */
42 static int *interlaceTable=0; /* I'm so lame it hurts */
43 static int currentLine=0; /* my brain hurts */
44
get_byte(void)45 static /*inline*/ int get_byte(void)
46 {
47 if(filedata<filedataEnd)
48 return *filedata++;
49
50 return -1;
51 }
52
out_line(uint8_t * line,int len)53 static /*inline*/ int out_line(uint8_t *line, int len)
54 {
55 int i;
56
57 if(GIFimageInterlace)
58 {
59 if(currentLine<GIFimageHeight)
60 {
61 int offset=interlaceTable[currentLine++];
62 for(i=0; i<len; i++)
63 image[offset+i]=line[i];
64 return 0;
65 }
66 } else if(currentLine<GIFimageHeight)
67 {
68 currentLine++;
69 for(i=0; i<len; i++)
70 *image++=*line++;
71 return 0;
72 }
73
74 return -1;
75 }
76
77 static int bad_code_count=0;
78
79 /***************************************************************************
80 * DECODE.C - An LZW decoder for GIF
81 * Copyright (C) 1987, by Steven A. Bennett
82 *
83 * Permission is given by the author to freely redistribute and include
84 * this code in any program as long as this credit is given where due.
85 *
86 * In accordance with the above, I want to credit Steve Wilhite who wrote
87 * the code which this is heavily inspired by...
88 *
89 * GIF and 'Graphics Interchange Format' are trademarks (tm) of
90 * Compuserve, Incorporated, an H&R Block Company.
91 *
92 * Release Notes: This file contains a decoder routine for GIF images
93 * which is similar, structurally, to the original routine by Steve Wilhite.
94 * It is, however, somewhat noticably faster in most cases.
95 *
96 */
97 #define MAX_CODES 4095
98
99 /* Static variables */
100 static int16_t curr_size; /* The current code size */
101 static int16_t clear; /* Value for a clear code */
102 static int16_t ending; /* Value for a ending code */
103 static int16_t newcodes; /* First available code */
104 static int16_t top_slot; /* Highest code for current size */
105 static int16_t slot; /* Last read code */
106
107 /* The following static variables are used
108 * for seperating out codes
109 */
110 static int16_t navail_bytes = 0; /* # bytes left in block */
111 static int16_t nbits_left = 0; /* # bits left in current byte */
112 static uint8_t b1; /* Current byte */
113 static uint8_t byte_buff[257]; /* Current block */
114 static uint8_t *pbytes; /* Pointer to next byte in block */
115
116 static int32_t code_mask[13] =
117 {
118 0,
119 0x0001, 0x0003,
120 0x0007, 0x000F,
121 0x001F, 0x003F,
122 0x007F, 0x00FF,
123 0x01FF, 0x03FF,
124 0x07FF, 0x0FFF
125 };
126
127
128 /* This function initializes the decoder for reading a new image.
129 */
init_exp(int16_t size)130 static int16_t init_exp(int16_t size)
131 {
132 curr_size = size + 1;
133 top_slot = 1 << curr_size;
134 clear = 1 << size;
135 ending = clear + 1;
136 slot = newcodes = ending + 1;
137 navail_bytes = nbits_left = 0;
138 return 0;
139 }
140
141 /* get_next_code()
142 * - gets the next code from the GIF file. Returns the code, or else
143 * a negative number in case of file errors...
144 */
get_next_code(void)145 static int16_t get_next_code(void)
146 {
147 int i, x;
148 uint32_t ret;
149
150 if (nbits_left == 0)
151 {
152 if (navail_bytes <= 0)
153 {
154
155 /* Out of bytes in current block, so read next block
156 */
157 pbytes = byte_buff;
158 if ((navail_bytes = get_byte()) < 0)
159 return(navail_bytes);
160 else if (navail_bytes)
161 {
162 for (i = 0; i < navail_bytes; ++i)
163 {
164 if ((x = get_byte()) < 0)
165 return(x);
166 byte_buff[i] = x;
167 }
168 }
169 }
170 b1 = *pbytes++;
171 nbits_left = 8;
172 --navail_bytes;
173 }
174
175 ret = b1 >> (8 - nbits_left);
176 while (curr_size > nbits_left)
177 {
178 if (navail_bytes <= 0)
179 {
180
181 /* Out of bytes in current block, so read next block
182 */
183 pbytes = byte_buff;
184 if ((navail_bytes = get_byte()) < 0)
185 return(navail_bytes);
186 else if (navail_bytes)
187 {
188 for (i = 0; i < navail_bytes; ++i)
189 {
190 if ((x = get_byte()) < 0)
191 return x;
192 byte_buff[i] = x;
193 }
194 }
195 }
196 b1 = *pbytes++;
197 ret |= b1 << nbits_left;
198 nbits_left += 8;
199 --navail_bytes;
200 }
201 nbits_left -= curr_size;
202 ret &= code_mask[curr_size];
203 return (int16_t)ret;
204 }
205
206
207 /* The reason we have these seperated like this instead of using
208 * a structure like the original Wilhite code did, is because this
209 * stuff generally produces significantly faster code when compiled...
210 * This code is full of similar speedups... (For a good book on writing
211 * C for speed or for space optomisation, see Efficient C by Tom Plum,
212 * published by Plum-Hall Associates...)
213 */
214 static uint8_t stack[MAX_CODES + 1]; /* Stack for storing pixels */
215 static uint8_t suffix[MAX_CODES + 1]; /* Suffix table */
216 static uint16_t prefix[MAX_CODES + 1]; /* Prefix linked list */
217
218 /* WORD decoder(linewidth)
219 * WORD linewidth; * Pixels per line of image *
220 *
221 * - This function decodes an LZW image, according to the method used
222 * in the GIF spec. Every *linewidth* "characters" (ie. pixels) decoded
223 * will generate a call to out_line(), which is a user specific function
224 * to display a line of pixels. The function gets it's codes from
225 * get_next_code() which is responsible for reading blocks of data and
226 * seperating them into the proper size codes. Finally, get_byte() is
227 * the global routine to read the next byte from the GIF file.
228 *
229 * It is generally a good idea to have linewidth correspond to the actual
230 * width of a line (as specified in the Image header) to make your own
231 * code a bit simpler, but it isn't absolutely necessary.
232 *
233 * Returns: 0 if successful, else negative. (See ERRS.H)
234 *
235 */
236
decoder(int linewidth)237 static int decoder(int linewidth)
238 {
239 unsigned char *sp, *bufptr;
240 unsigned char *buf;
241 uint16_t code, fc, oc, bufcnt;
242 int c, size, ret;
243
244 /* Initialize for decoding a new image...
245 */
246 if ((size = get_byte()) < 0)
247 return(size);
248 if (size < 2 || 9 < size)
249 return(-1);
250 init_exp(size);
251
252 /* Initialize in case they forgot to put in a clear code.
253 * (This shouldn't happen, but we'll try and decode it anyway...)
254 */
255 oc = fc = 0;
256
257 /* Allocate space for the decode buffer
258 */
259 if ((buf = calloc(sizeof(unsigned char),linewidth + 1)) == 0)
260 return(-1);
261
262 /* Set up the stack pointer and decode buffer pointer
263 */
264 sp = stack;
265 bufptr = buf;
266 bufcnt = linewidth;
267
268 /* This is the main loop. For each code we get we pass through the
269 * linked list of prefix codes, pushing the corresponding "character" for
270 * each code onto the stack. When the list reaches a single "character"
271 * we push that on the stack too, and then start unstacking each
272 * character for output in the correct order. Special handling is
273 * included for the clear code, and the whole thing ends when we get
274 * an ending code.
275 */
276 while ((c = get_next_code()) != ending)
277 {
278
279 /* If we had a file error, return without completing the decode
280 */
281 if (c < 0)
282 {
283 free(buf);
284 return(0);
285 }
286
287 /* If the code is a clear code, reinitialize all necessary items.
288 */
289 if (c == clear)
290 {
291 curr_size = size + 1;
292 slot = newcodes;
293 top_slot = 1 << curr_size;
294
295 /* Continue reading codes until we get a non-clear code
296 * (Another unlikely, but possible case...)
297 */
298 while ((c = get_next_code()) == clear);
299
300 /* If we get an ending code immediately after a clear code
301 * (Yet another unlikely case), then break out of the loop.
302 */
303 if (c == ending)
304 break;
305
306 /* Finally, if the code is beyond the range of already set codes,
307 * (This one had better NOT happen... I have no idea what will
308 * result from this, but I doubt it will look good...) then set it
309 * to color zero.
310 */
311 if (c >= slot)
312 c = 0;
313
314 oc = fc = c;
315
316 /* And let us not forget to put the char into the buffer... And
317 * if, on the off chance, we were exactly one pixel from the end
318 * of the line, we have to send the buffer to the out_line()
319 * routine...
320 */
321 *bufptr++ = c;
322 if (--bufcnt == 0)
323 {
324 if ((ret = out_line(buf, linewidth)) < 0)
325 {
326 free(buf);
327 return(ret);
328 }
329 bufptr = buf;
330 bufcnt = linewidth;
331 }
332 } else {
333
334 /* In this case, it's not a clear code or an ending code, so
335 * it must be a code code... So we can now decode the code into
336 * a stack of character codes. (Clear as mud, right?)
337 */
338 code = c;
339
340 /* Here we go again with one of those off chances... If, on the
341 * off chance, the code we got is beyond the range of those already
342 * set up (Another thing which had better NOT happen...) we trick
343 * the decoder into thinking it actually got the last code read.
344 * (Hmmn... I'm not sure why this works... But it does...)
345 */
346 if (code >= slot)
347 {
348 if (code > slot)
349 ++bad_code_count;
350 code = oc;
351 *sp++ = fc;
352 }
353
354 /* Here we scan back along the linked list of prefixes, pushing
355 * helpless characters (ie. suffixes) onto the stack as we do so.
356 */
357 while (code >= newcodes)
358 {
359 *sp++ = suffix[code];
360 code = prefix[code];
361 }
362
363 /* Push the last character on the stack, and set up the new
364 * prefix and suffix, and if the required slot number is greater
365 * than that allowed by the current bit size, increase the bit
366 * size. (NOTE - If we are all full, we *don't* save the new
367 * suffix and prefix... I'm not certain if this is correct...
368 * it might be more proper to overwrite the last code...
369 */
370 *sp++ = code;
371 if (slot < top_slot)
372 {
373 suffix[slot] = fc = code;
374 prefix[slot++] = oc;
375 oc = c;
376 }
377 if (slot >= top_slot)
378 if (curr_size < 12)
379 {
380 top_slot <<= 1;
381 ++curr_size;
382 }
383
384 /* Now that we've pushed the decoded string (in reverse order)
385 * onto the stack, lets pop it off and put it into our decode
386 * buffer... And when the decode buffer is full, write another
387 * line...
388 */
389 while (sp > stack)
390 {
391 *bufptr++ = *(--sp);
392 if (--bufcnt == 0)
393 {
394 if ((ret = out_line(buf, linewidth)) < 0)
395 {
396 free(buf);
397 return(ret);
398 }
399 bufptr = buf;
400 bufcnt = linewidth;
401 }
402 }
403 }
404 }
405 ret = 0;
406 if (bufcnt != linewidth)
407 ret = out_line(buf, (linewidth - bufcnt));
408 free(buf);
409 return(ret);
410 }
411 /*************************************************************************/
412
GIF87read(unsigned char * fd,int filesize,unsigned char * pic,unsigned char * pal,const int picWidth,const int picHeight)413 int GIF87read(unsigned char *fd, int filesize, unsigned char *pic, unsigned char *pal, const int picWidth, const int picHeight)
414 {
415 int i;
416 uint8_t *GIFsignature;
417 uint16_t GIFscreenWidth;
418 uint16_t GIFscreenHeight;
419 uint8_t byte;
420 int GIFglobalColorMap;
421 /* int GIFcolorResolution; */
422 int GIFbitPerPixel;
423 /* uint8_t GIFbackground; */
424 uint16_t GIFimageLeft;
425 uint16_t GIFimageTop;
426 uint16_t GIFimageWidth;
427 int GIFimageColorMap;
428 int GIFimageBitPerPixel;
429
430 filedata=fd;
431 filedataEnd=filedata+filesize;
432
433 /************************************************************************
434 * process the header
435 ***********************************************************************/
436
437 /* check if file format is GIF87 */
438 GIFsignature=(unsigned char *)"GIF87a";
439 for(i=0; i<6; i++)
440 if(GIFsignature[i]!=*filedata++)
441 {
442 if (i==4)
443 continue;
444 return -1;
445 }
446
447 /* read the screen descriptor */
448 GIFscreenWidth=*filedata++;
449 GIFscreenWidth+=(*filedata++)<<8;
450
451 GIFscreenHeight=*filedata++;
452 GIFscreenHeight+=(*filedata++)<<8;
453
454 byte=*filedata++;
455 GIFglobalColorMap=byte&128;
456 #if 0
457 GIFcolorResolution=((byte&(64+32+16))>>4)+1;
458 #endif
459 GIFbitPerPixel=(byte&7)+1;
460
461 #if 0
462 GIFbackground=*filedata++;
463 #else
464 filedata++;
465 #endif
466
467 if(*filedata++!=0)
468 return -1;
469
470 /* read the global color map */
471 if(GIFglobalColorMap)
472 for(i=0; i<(1<<GIFbitPerPixel)*3; i++)
473 pal[i]=*filedata++;
474
475 /* read the image descriptor */
476 if(*filedata++!=',')
477 return -1;
478
479 GIFimageLeft=*filedata++;
480 GIFimageLeft+=(*filedata++)<<8;
481
482 GIFimageTop=*filedata++;
483 GIFimageTop+=(*filedata++)<<8;
484
485 GIFimageWidth=*filedata++;
486 GIFimageWidth+=(*filedata++)<<8;
487 if(GIFimageWidth!=picWidth)
488 return -1;
489
490 GIFimageHeight=*filedata++;
491 GIFimageHeight+=(*filedata++)<<8;
492 if(GIFimageHeight>picHeight)
493 GIFimageHeight=picHeight;
494
495 byte=*filedata++;
496 GIFimageColorMap=byte&128;
497 GIFimageInterlace=byte&64;
498 GIFimageBitPerPixel=(byte&7)+1;
499
500 if(GIFimageInterlace)
501 {
502 int z;
503 interlaceTable=calloc(sizeof(int), GIFimageHeight);
504 if(interlaceTable==0)
505 return -1;
506
507 z=0;
508 for(i=0; i<GIFimageHeight; i+=8)
509 interlaceTable[z++]=i*GIFimageWidth;
510 for(i=4; i<GIFimageHeight; i+=8)
511 interlaceTable[z++]=i*GIFimageWidth;
512 for(i=2; i<GIFimageHeight; i+=4)
513 interlaceTable[z++]=i*GIFimageWidth;
514 for(i=1; i<GIFimageHeight; i+=2)
515 interlaceTable[z++]=i*GIFimageWidth;
516 }
517
518 /* check for an GIF extension block */
519 if(*filedata=='!')
520 while(*filedata++!=0) ; /* skip this block */
521
522
523 /* read the local color map */
524 if(GIFimageColorMap)
525 for(i=0; i<(1<<GIFimageBitPerPixel)*3; i++)
526 pal[i]=*filedata++;
527
528 #if 0
529 fprintf("GIFscreenWidth: %i\n",GIFscreenWidth);
530 fprintf("GIFscreenHeight: %i\n",GIFscreenHeight);
531 fprintf("GIFglobalColorMap: %i\n",GIFglobalColorMap);
532 fprintf("GIFcolorResolution: %i\n",GIFcolorResolution);
533 fprintf("GIFbitPerPixel: %i\n",GIFbitPerPixel);
534 fprintf("GIFbackground: %i\n",GIFbackground);
535 fprintf("GIFimageLeft: %i\n",GIFimageLeft);
536 fprintf("GIFimageTop: %i\n",GIFimageTop);
537 fprintf("GIFimageWidth: %i\n",GIFimageWidth);
538 fprintf("GIFimageHeight: %i\n",GIFimageHeight);
539 fprintf("GIFimageColorMap: %i\n",GIFimageColorMap);
540 fprintf("GIFimageInterlace: %i\n",GIFimageInterlace);
541 fprintf("GIFimageBitPerPixel: %i\n",GIFimageBitPerPixel);
542 #endif
543
544 /* read the lzw compressed data */
545 currentLine=0;
546 image=pic;
547 if(decoder(GIFimageWidth)<0)
548 bad_code_count=-1;
549
550 if(GIFimageInterlace)
551 free(interlaceTable);
552 return bad_code_count;
553 }
554
GIF87_try_open_indexed(uint16_t * GIFimageWidth,uint16_t * GIFimageHeight,uint8_t ** data_indexed,uint8_t * pal_768,const uint8_t * src,int srclen)555 int GIF87_try_open_indexed(uint16_t *GIFimageWidth, uint16_t *GIFimageHeight, uint8_t **data_indexed, uint8_t *pal_768, const uint8_t *src, int srclen)
556 {
557 int i;
558 uint8_t *GIFsignature;
559 uint16_t GIFscreenWidth;
560 uint16_t GIFscreenHeight;
561 uint8_t byte;
562 int GIFglobalColorMap;
563 /* int GIFcolorResolution; */
564 int GIFbitPerPixel;
565 /* uint8_t GIFbackground; */
566 uint16_t GIFimageLeft;
567 uint16_t GIFimageTop;
568 int GIFimageColorMap;
569 int GIFimageBitPerPixel;
570
571 interlaceTable=0;
572
573 if (srclen < 6)
574 {
575 return -1;
576 }
577
578 filedata=src;
579 filedataEnd=filedata+srclen;
580
581 /************************************************************************
582 * process the header
583 ***********************************************************************/
584
585 /* check if file format is GIF87 */
586 GIFsignature=(unsigned char *)"GIF87a";
587 for(i=0; i<6; i++)
588 {
589 srclen--;
590 if(GIFsignature[i]!=*filedata++)
591 {
592 if (i==4)
593 continue;
594 return -1;
595 }
596 }
597
598 if (srclen < 7)
599 {
600 return -1;
601 }
602 /* read the screen descriptor */
603 GIFscreenWidth=*filedata++;
604 GIFscreenWidth+=(*filedata++)<<8;
605
606 GIFscreenHeight=*filedata++;
607 GIFscreenHeight+=(*filedata++)<<8;
608
609 byte=*filedata++;
610 GIFglobalColorMap=byte&128;
611 #if 0
612 GIFcolorResolution=((byte&(64+32+16))>>4)+1;
613 #endif
614 GIFbitPerPixel=(byte&7)+1;
615
616 #if 0
617 GIFbackground=*filedata++;
618 #else
619 filedata++;
620 #endif
621
622 if(*filedata++!=0)
623 return -1;
624
625 srclen -= 7;
626
627 if (srclen < ((1<<GIFbitPerPixel)*3))
628 {
629 return -1;
630 }
631
632 /* read the global color map */
633 if(GIFglobalColorMap)
634 for(i=0; i<(1<<GIFbitPerPixel)*3; i++)
635 pal_768[i]=*filedata++;
636
637 srclen -= (1<<GIFbitPerPixel)*3;
638
639 if (srclen < 10)
640 {
641 return -1;
642 }
643 /* read the image descriptor */
644 if(*filedata++!=',')
645 return -1;
646
647 GIFimageLeft=*filedata++;
648 GIFimageLeft+=(*filedata++)<<8;
649
650 GIFimageTop=*filedata++;
651 GIFimageTop+=(*filedata++)<<8;
652
653 *GIFimageWidth=*filedata++;
654 *GIFimageWidth+=(*filedata++)<<8;
655
656 if ((*GIFimageWidth) > 1920)
657 {
658 return -1;
659 }
660
661 *GIFimageHeight=*filedata++;
662 *GIFimageHeight+=(*filedata++)<<8;
663 if ((*GIFimageHeight) > 1080)
664 {
665 return -1;
666 }
667
668 byte=*filedata++;
669 GIFimageColorMap=byte&128;
670 GIFimageInterlace=byte&64;
671 GIFimageBitPerPixel=(byte&7)+1;
672
673 srclen -= 10;
674
675 if(GIFimageInterlace)
676 {
677 int z;
678 interlaceTable=calloc(sizeof(int), *GIFimageHeight);
679 if(interlaceTable==0)
680 return -1;
681
682 z=0;
683 for(i=0; i<*GIFimageHeight; i+=8)
684 interlaceTable[z++]=i*(*GIFimageWidth);
685 for(i=4; i<*GIFimageHeight; i+=8)
686 interlaceTable[z++]=i*(*GIFimageWidth);
687 for(i=2; i<*GIFimageHeight; i+=4)
688 interlaceTable[z++]=i*(*GIFimageWidth);
689 for(i=1; i<*GIFimageHeight; i+=2)
690 interlaceTable[z++]=i*(*GIFimageWidth);
691 }
692
693 if (srclen < 1)
694 {
695 free (interlaceTable);
696 interlaceTable=0;
697 return -1;
698 }
699 /* check for an GIF extension block */
700 if(*filedata=='!')
701 {/* skip this block */
702 srclen--;
703
704 while(1)
705 {
706 if (srclen < 1)
707 {
708 free (interlaceTable);
709 interlaceTable=0;
710 return -1;
711 }
712 if (*filedata++==0)
713 {
714 break;
715 }
716 }
717 }
718
719 /* read the local color map */
720 if(GIFimageColorMap)
721 {
722 if (srclen < (1<<GIFimageBitPerPixel)*3)
723 {
724 free (interlaceTable);
725 interlaceTable=0;
726 return -1;
727 }
728 for(i=0; i<(1<<GIFimageBitPerPixel)*3; i++)
729 pal_768[i]=*filedata++;
730 }
731
732 /* read the lzw compressed data */
733 currentLine=0;
734 image=*data_indexed=calloc(*GIFimageHeight, *GIFimageWidth);
735 if(decoder(*GIFimageWidth)<0)
736 bad_code_count=-1;
737
738 free(interlaceTable);
739 interlaceTable=0;
740
741 if (bad_code_count)
742 {
743 free(*data_indexed);
744 *data_indexed=0;
745 *GIFimageHeight=0;
746 *GIFimageWidth=0;
747 }
748 image=0;
749 GIFimageInterlace=0;
750 return bad_code_count;
751 }
752
GIF87_try_open_bgra(uint16_t * GIFimageWidth,uint16_t * GIFimageHeight,uint8_t ** data_bgra,const uint8_t * src,int srclen)753 int GIF87_try_open_bgra(uint16_t *GIFimageWidth,
754 uint16_t *GIFimageHeight,
755 uint8_t **data_bgra,
756 const uint8_t *src,
757 int srclen)
758 {
759 uint8_t *data_indexed = 0;
760 uint8_t pal_768[768];
761 int i;
762 uint8_t *in, *out;
763
764 *data_bgra = 0;
765
766 if (GIF87_try_open_indexed(GIFimageWidth, GIFimageHeight, &data_indexed, pal_768, src, srclen))
767 {
768 return -1;
769 }
770
771 *data_bgra = malloc(4 * (*GIFimageWidth) * (*GIFimageHeight));
772
773 in = data_indexed;
774 out = *data_bgra;
775 for (i=0; i < (*GIFimageWidth) * (*GIFimageHeight); i++)
776 {
777 *(out++) = pal_768[(*in)*3 + 2];
778 *(out++) = pal_768[(*in)*3 + 2];
779 *(out++) = pal_768[(*in)*3 + 2];
780 *(out++) = 255;
781 in++;
782 }
783
784 free (data_indexed);
785 return 0;
786 }
787