ReactOS  0.4.13-dev-563-g0561610
ungif.c
Go to the documentation of this file.
1 /*
2  * Gif extracting routines - derived from libungif
3  *
4  * Portions Copyright 2006 Mike McCormack
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 /*
22  * Original copyright notice:
23  *
24  * The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
25  *
26  * Permission is hereby granted, free of charge, to any person obtaining a copy
27  * of this software and associated documentation files (the "Software"), to deal
28  * in the Software without restriction, including without limitation the rights
29  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30  * copies of the Software, and to permit persons to whom the Software is
31  * furnished to do so, subject to the following conditions:
32  *
33  * The above copyright notice and this permission notice shall be included in
34  * all copies or substantial portions of the Software.
35  */
36 
37 
38 /******************************************************************************
39  * "Gif-Lib" - Yet another gif library.
40  *
41  * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990
42  ******************************************************************************
43  * The kernel of the GIF Decoding process can be found here.
44  ******************************************************************************
45  * History:
46  * 16 Jun 89 - Version 1.0 by Gershon Elber.
47  * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
48  *****************************************************************************/
49 
50 #include <stdlib.h>
51 #include <string.h>
52 
53 #include <stdarg.h>
54 #include "windef.h"
55 #include "winbase.h"
56 #include "ungif.h"
57 #include "wine/debug.h"
58 
60 
61 static void *ungif_alloc( size_t sz )
62 {
63  return HeapAlloc( GetProcessHeap(), 0, sz );
64 }
65 
66 static void *ungif_calloc( size_t num, size_t sz )
67 {
69 }
70 
71 static void *ungif_realloc( void *ptr, size_t sz )
72 {
73  return HeapReAlloc( GetProcessHeap(), 0, ptr, sz );
74 }
75 
76 static void ungif_free( void *ptr )
77 {
78  HeapFree( GetProcessHeap(), 0, ptr );
79 }
80 
81 #define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
82 #define LZ_BITS 12
83 
84 #define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
85 
86 typedef struct GifFilePrivateType {
87  GifWord BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
88  ClearCode, /* The CLEAR LZ code. */
89  EOFCode, /* The EOF LZ code. */
90  RunningCode, /* The next code algorithm can generate. */
91  RunningBits, /* The number of bits required to represent RunningCode. */
92  MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
93  LastCode, /* The code before the current code. */
94  CrntCode, /* Current algorithm code. */
95  StackPtr, /* For character stack (see below). */
96  CrntShiftState; /* Number of bits in CrntShiftDWord. */
97  unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
98  unsigned long PixelCount; /* Number of pixels in image. */
99  InputFunc Read; /* function to read gif input (TVT) */
100  GifByteType Buf[256]; /* Compressed input is buffered here. */
101  GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
102  GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
105 
106 /* avoid extra function call in case we use fread (TVT) */
107 #define READ(_gif,_buf,_len) \
108  ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len)
109 
110 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
111 static int DGifSetupDecompress(GifFileType *GifFile);
112 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen);
113 static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode);
114 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
115 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
116  GifByteType *NextByte);
117 
118 static int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension);
119 static int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock);
120 
121 /******************************************************************************
122  * Miscellaneous utility functions
123  *****************************************************************************/
124 
125 /* return smallest bitfield size n will fit in */
126 static int
127 BitSize(int n) {
128 
129  register int i;
130 
131  for (i = 1; i <= 8; i++)
132  if ((1 << i) >= n)
133  break;
134  return (i);
135 }
136 
137 /******************************************************************************
138  * Color map object functions
139  *****************************************************************************/
140 
141 /*
142  * Allocate a color map of given size; initialize with contents of
143  * ColorMap if that pointer is non-NULL.
144  */
145 static ColorMapObject *
146 MakeMapObject(int ColorCount,
147  const GifColorType * ColorMap) {
148 
150 
151  /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
152  * make the user know that or should we automatically round up instead? */
153  if (ColorCount != (1 << BitSize(ColorCount))) {
154  return NULL;
155  }
156 
157  Object = ungif_alloc(sizeof(ColorMapObject));
158  if (Object == NULL) {
159  return NULL;
160  }
161 
162  Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType));
163  if (Object->Colors == NULL) {
165  return NULL;
166  }
167 
168  Object->ColorCount = ColorCount;
169  Object->BitsPerPixel = BitSize(ColorCount);
170 
171  if (ColorMap) {
172  memcpy(Object->Colors, ColorMap, ColorCount * sizeof(GifColorType));
173  }
174 
175  return (Object);
176 }
177 
178 /*
179  * Free a color map object
180  */
181 static void
183 
184  if (Object != NULL) {
185  ungif_free(Object->Colors);
187  /*** FIXME:
188  * When we are willing to break API we need to make this function
189  * FreeMapObject(ColorMapObject **Object)
190  * and do this assignment to NULL here:
191  * *Object = NULL;
192  */
193  }
194 }
195 
196 static int
198  int Len,
199  const unsigned char ExtData[]) {
200 
201  ExtensionBlock *ep;
202 
203  if (New->ExtensionBlocks == NULL)
204  New->ExtensionBlocks = ungif_alloc(sizeof(ExtensionBlock));
205  else
206  New->ExtensionBlocks = ungif_realloc(New->ExtensionBlocks,
207  sizeof(ExtensionBlock) *
208  (New->ExtensionBlockCount + 1));
209 
210  if (New->ExtensionBlocks == NULL)
211  return (GIF_ERROR);
212 
213  ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
214 
215  ep->ByteCount=Len + 3;
216  ep->Bytes = ungif_alloc(ep->ByteCount + 3);
217  if (ep->Bytes == NULL)
218  return (GIF_ERROR);
219 
220  /* Extension Header */
221  ep->Bytes[0] = 0x21;
222  ep->Bytes[1] = New->Function;
223  ep->Bytes[2] = Len;
224 
225  if (ExtData) {
226  memcpy(ep->Bytes + 3, ExtData, Len);
227  ep->Function = New->Function;
228  }
229 
230  return (GIF_OK);
231 }
232 
233 static int
235  int Len,
236  const unsigned char ExtData[])
237 {
238  ExtensionBlock *ep;
239 
240  if (New->ExtensionBlocks == NULL)
241  return (GIF_ERROR);
242 
243  ep = &New->ExtensionBlocks[New->ExtensionBlockCount - 1];
244 
245  ep->Bytes = ungif_realloc(ep->Bytes, ep->ByteCount + Len + 1);
246  if (ep->Bytes == NULL)
247  return (GIF_ERROR);
248 
249  ep->Bytes[ep->ByteCount] = Len;
250 
251  if (ExtData)
252  memcpy(ep->Bytes + ep->ByteCount + 1, ExtData, Len);
253 
254  ep->ByteCount += Len + 1;
255 
256  return (GIF_OK);
257 }
258 
259 static void
261 {
262  ExtensionBlock *ep;
263 
264  if ((Extensions == NULL) || (Extensions->ExtensionBlocks == NULL)) {
265  return;
266  }
267  for (ep = Extensions->ExtensionBlocks;
269  ungif_free(ep->Bytes);
272 }
273 
274 /******************************************************************************
275  * Image block allocation functions
276 ******************************************************************************/
277 
278 static void
280 
281  SavedImage *sp;
282 
283  if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
284  return;
285  }
286  for (sp = GifFile->SavedImages;
287  sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
288  if (sp->ImageDesc.ColorMap) {
289  FreeMapObject(sp->ImageDesc.ColorMap);
290  sp->ImageDesc.ColorMap = NULL;
291  }
292 
293  ungif_free(sp->RasterBits);
294 
295  if (sp->Extensions.ExtensionBlocks)
296  FreeExtension(&sp->Extensions);
297  }
298  ungif_free(GifFile->SavedImages);
299  GifFile->SavedImages=NULL;
300 }
301 
302 /******************************************************************************
303  * This routine should be called before any other DGif calls. Note that
304  * this routine is called automatically from DGif file open routines.
305  *****************************************************************************/
306 static int
308 
309  int i, BitsPerPixel, SortFlag;
310  GifByteType Buf[3];
311 
312  /* Put the screen descriptor into the file: */
313  if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
314  DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
315  return GIF_ERROR;
316 
317  if (READ(GifFile, Buf, 3) != 3) {
318  return GIF_ERROR;
319  }
320  GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
321  SortFlag = (Buf[0] & 0x08) != 0;
322  BitsPerPixel = (Buf[0] & 0x07) + 1;
323  GifFile->SBackGroundColor = Buf[1];
324  GifFile->SAspectRatio = Buf[2];
325  if (Buf[0] & 0x80) { /* Do we have global color map? */
326 
327  GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
328  if (GifFile->SColorMap == NULL) {
329  return GIF_ERROR;
330  }
331 
332  /* Get the global color map: */
333  GifFile->SColorMap->SortFlag = SortFlag;
334  for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
335  if (READ(GifFile, Buf, 3) != 3) {
336  FreeMapObject(GifFile->SColorMap);
337  GifFile->SColorMap = NULL;
338  return GIF_ERROR;
339  }
340  GifFile->SColorMap->Colors[i].Red = Buf[0];
341  GifFile->SColorMap->Colors[i].Green = Buf[1];
342  GifFile->SColorMap->Colors[i].Blue = Buf[2];
343  }
344  } else {
345  GifFile->SColorMap = NULL;
346  }
347 
348  return GIF_OK;
349 }
350 
351 /******************************************************************************
352  * This routine should be called before any attempt to read an image.
353  *****************************************************************************/
354 static int
356  GifRecordType * Type) {
357 
358  GifByteType Buf;
359 
360  if (READ(GifFile, &Buf, 1) != 1) {
361  /* Wine-specific behavior: Native accepts broken GIF files that have no
362  * terminator, so we match this by treating EOF as a terminator. */
364  return GIF_OK;
365  }
366 
367  switch (Buf) {
368  case ',':
370  break;
371  case '!':
373  break;
374  case ';':
376  break;
377  default:
379  return GIF_ERROR;
380  }
381 
382  return GIF_OK;
383 }
384 
385 /******************************************************************************
386  * This routine should be called before any attempt to read an image.
387  * Note it is assumed the Image desc. header (',') has been read.
388  *****************************************************************************/
389 static int
391 
392  int i, BitsPerPixel, SortFlag;
393  GifByteType Buf[3];
394  GifFilePrivateType *Private = GifFile->Private;
395  SavedImage *sp;
396 
397  if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
398  DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
399  DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
400  DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
401  return GIF_ERROR;
402  if (READ(GifFile, Buf, 1) != 1) {
403  return GIF_ERROR;
404  }
405  BitsPerPixel = (Buf[0] & 0x07) + 1;
406  SortFlag = (Buf[0] & 0x20) != 0;
407  GifFile->Image.Interlace = (Buf[0] & 0x40);
408  if (Buf[0] & 0x80) { /* Does this image have local color map? */
409 
410  FreeMapObject(GifFile->Image.ColorMap);
411 
412  GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
413  if (GifFile->Image.ColorMap == NULL) {
414  return GIF_ERROR;
415  }
416 
417  /* Get the image local color map: */
418  GifFile->Image.ColorMap->SortFlag = SortFlag;
419  for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
420  if (READ(GifFile, Buf, 3) != 3) {
421  FreeMapObject(GifFile->Image.ColorMap);
422  GifFile->Image.ColorMap = NULL;
423  return GIF_ERROR;
424  }
425  GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
426  GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
427  GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
428  }
429  } else if (GifFile->Image.ColorMap) {
430  FreeMapObject(GifFile->Image.ColorMap);
431  GifFile->Image.ColorMap = NULL;
432  }
433 
434  if (GifFile->SavedImages) {
435  if ((GifFile->SavedImages = ungif_realloc(GifFile->SavedImages,
436  sizeof(SavedImage) *
437  (GifFile->ImageCount + 1))) == NULL) {
438  return GIF_ERROR;
439  }
440  } else {
441  if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) {
442  return GIF_ERROR;
443  }
444  }
445 
446  sp = &GifFile->SavedImages[GifFile->ImageCount];
447  sp->ImageDesc = GifFile->Image;
448  if (GifFile->Image.ColorMap != NULL) {
449  sp->ImageDesc.ColorMap = MakeMapObject(
450  GifFile->Image.ColorMap->ColorCount,
451  GifFile->Image.ColorMap->Colors);
452  if (sp->ImageDesc.ColorMap == NULL) {
453  return GIF_ERROR;
454  }
455  sp->ImageDesc.ColorMap->SortFlag = GifFile->Image.ColorMap->SortFlag;
456  }
457  sp->RasterBits = NULL;
458  sp->Extensions.ExtensionBlockCount = 0;
459  sp->Extensions.ExtensionBlocks = NULL;
460 
461  GifFile->ImageCount++;
462 
463  Private->PixelCount = (long)GifFile->Image.Width *
464  (long)GifFile->Image.Height;
465 
466  DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
467 
468  return GIF_OK;
469 }
470 
471 /******************************************************************************
472  * Get one full scanned line (Line) of length LineLen from GIF file.
473  *****************************************************************************/
474 static int
476  GifPixelType * Line,
477  int LineLen) {
478 
479  GifByteType *Dummy;
480  GifFilePrivateType *Private = GifFile->Private;
481 
482  if (!LineLen)
483  LineLen = GifFile->Image.Width;
484 
485  if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
486  return GIF_ERROR;
487  }
488 
489  if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
490  if (Private->PixelCount == 0) {
491  /* We probably would not be called any more, so lets clean
492  * everything before we return: need to flush out all rest of
493  * image until empty block (size 0) detected. We use GetCodeNext. */
494  do
495  if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
496  {
497  WARN("GIF is not properly terminated\n");
498  break;
499  }
500  while (Dummy != NULL) ;
501  }
502  return GIF_OK;
503  } else
504  return GIF_ERROR;
505 }
506 
507 /******************************************************************************
508  * Get an extension block (see GIF manual) from gif file. This routine only
509  * returns the first data block, and DGifGetExtensionNext should be called
510  * after this one until NULL extension is returned.
511  * The Extension should NOT be freed by the user (not dynamically allocated).
512  * Note it is assumed the Extension desc. header ('!') has been read.
513  *****************************************************************************/
514 static int
516  int *ExtCode,
517  GifByteType ** Extension) {
518 
519  GifByteType Buf;
520 
521  if (READ(GifFile, &Buf, 1) != 1) {
522  return GIF_ERROR;
523  }
524  *ExtCode = Buf;
525 
526  return DGifGetExtensionNext(GifFile, Extension);
527 }
528 
529 /******************************************************************************
530  * Get a following extension block (see GIF manual) from gif file. This
531  * routine should be called until NULL Extension is returned.
532  * The Extension should NOT be freed by the user (not dynamically allocated).
533  *****************************************************************************/
534 static int
536  GifByteType ** Extension) {
537 
538  GifByteType Buf;
539  GifFilePrivateType *Private = GifFile->Private;
540 
541  if (READ(GifFile, &Buf, 1) != 1) {
542  return GIF_ERROR;
543  }
544  if (Buf > 0) {
545  *Extension = Private->Buf; /* Use private unused buffer. */
546  (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
547  if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
548  return GIF_ERROR;
549  }
550  } else
551  *Extension = NULL;
552 
553  return GIF_OK;
554 }
555 
556 /******************************************************************************
557  * Get 2 bytes (word) from the given file:
558  *****************************************************************************/
559 static int
561  GifWord *Word) {
562 
563  unsigned char c[2];
564 
565  if (READ(GifFile, c, 2) != 2) {
566  return GIF_ERROR;
567  }
568 
569  *Word = (((unsigned int)c[1]) << 8) + c[0];
570  return GIF_OK;
571 }
572 
573 /******************************************************************************
574  * Continue to get the image code in compressed form. This routine should be
575  * called until NULL block is returned.
576  * The block should NOT be freed by the user (not dynamically allocated).
577  *****************************************************************************/
578 static int
580  GifByteType ** CodeBlock) {
581 
582  GifByteType Buf;
583  GifFilePrivateType *Private = GifFile->Private;
584 
585  if (READ(GifFile, &Buf, 1) != 1) {
586  return GIF_ERROR;
587  }
588 
589  if (Buf > 0) {
590  *CodeBlock = Private->Buf; /* Use private unused buffer. */
591  (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
592  if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
593  return GIF_ERROR;
594  }
595  } else {
596  *CodeBlock = NULL;
597  Private->Buf[0] = 0; /* Make sure the buffer is empty! */
598  Private->PixelCount = 0; /* And local info. indicate image read. */
599  }
600 
601  return GIF_OK;
602 }
603 
604 /******************************************************************************
605  * Setup the LZ decompression for this image:
606  *****************************************************************************/
607 static int
609 
610  int i, BitsPerPixel;
611  GifByteType CodeSize;
613  GifFilePrivateType *Private = GifFile->Private;
614 
615  READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
616  BitsPerPixel = CodeSize;
617 
618  Private->Buf[0] = 0; /* Input Buffer empty. */
619  Private->BitsPerPixel = BitsPerPixel;
620  Private->ClearCode = (1 << BitsPerPixel);
621  Private->EOFCode = Private->ClearCode + 1;
622  Private->RunningCode = Private->EOFCode + 1;
623  Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
624  Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
625  Private->StackPtr = 0; /* No pixels on the pixel stack. */
626  Private->LastCode = NO_SUCH_CODE;
627  Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
628  Private->CrntShiftDWord = 0;
629 
630  Prefix = Private->Prefix;
631  for (i = 0; i <= LZ_MAX_CODE; i++)
632  Prefix[i] = NO_SUCH_CODE;
633 
634  return GIF_OK;
635 }
636 
637 /******************************************************************************
638  * The LZ decompression routine:
639  * This version decompress the given gif file into Line of length LineLen.
640  * This routine can be called few times (one per scan line, for example), in
641  * order the complete the whole image.
642  *****************************************************************************/
643 static int
645  GifPixelType * Line,
646  int LineLen) {
647 
648  int i = 0;
649  int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
650  GifByteType *Stack, *Suffix;
652  GifFilePrivateType *Private = GifFile->Private;
653 
654  StackPtr = Private->StackPtr;
655  Prefix = Private->Prefix;
656  Suffix = Private->Suffix;
657  Stack = Private->Stack;
658  EOFCode = Private->EOFCode;
659  ClearCode = Private->ClearCode;
660  LastCode = Private->LastCode;
661 
662  if (StackPtr != 0) {
663  /* Let pop the stack off before continuing to read the gif file: */
664  while (StackPtr != 0 && i < LineLen)
665  Line[i++] = Stack[--StackPtr];
666  }
667 
668  while (i < LineLen) { /* Decode LineLen items. */
669  if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
670  return GIF_ERROR;
671 
672  if (CrntCode == EOFCode) {
673  /* Note, however, that usually we will not be here as we will stop
674  * decoding as soon as we got all the pixel, or EOF code will
675  * not be read at all, and DGifGetLine/Pixel clean everything. */
676  if (i != LineLen - 1 || Private->PixelCount != 0) {
677  return GIF_ERROR;
678  }
679  i++;
680  } else if (CrntCode == ClearCode) {
681  /* We need to start over again: */
682  for (j = 0; j <= LZ_MAX_CODE; j++)
683  Prefix[j] = NO_SUCH_CODE;
684  Private->RunningCode = Private->EOFCode + 1;
685  Private->RunningBits = Private->BitsPerPixel + 1;
686  Private->MaxCode1 = 1 << Private->RunningBits;
687  LastCode = Private->LastCode = NO_SUCH_CODE;
688  } else {
689  /* It's a regular code - if in pixel range simply add it to output
690  * stream, otherwise trace to codes linked list until the prefix
691  * is in pixel range: */
692  if (CrntCode < ClearCode) {
693  /* This is simple - its pixel scalar, so add it to output: */
694  Line[i++] = CrntCode;
695  } else {
696  /* It's a code to be traced: trace the linked list
697  * until the prefix is a pixel, while pushing the suffix
698  * pixels on our stack. If we done, pop the stack in reverse
699  * order (that's what stack is good for!) for output. */
700  if (Prefix[CrntCode] == NO_SUCH_CODE) {
701  /* Only allowed if CrntCode is exactly the running code:
702  * In that case CrntCode = XXXCode, CrntCode or the
703  * prefix code is last code and the suffix char is
704  * exactly the prefix of last code! */
705  if (CrntCode == Private->RunningCode - 2) {
706  CrntPrefix = LastCode;
707  Suffix[Private->RunningCode - 2] =
708  Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
709  LastCode,
710  ClearCode);
711  } else {
712  return GIF_ERROR;
713  }
714  } else
715  CrntPrefix = CrntCode;
716 
717  /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
718  * during the trace. As we might loop forever, in case of
719  * defective image, we count the number of loops we trace
720  * and stop if we got LZ_MAX_CODE. Obviously we cannot
721  * loop more than that. */
722  j = 0;
723  while (j++ <= LZ_MAX_CODE &&
724  CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
725  Stack[StackPtr++] = Suffix[CrntPrefix];
726  CrntPrefix = Prefix[CrntPrefix];
727  }
728  if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
729  return GIF_ERROR;
730  }
731  /* Push the last character on stack: */
732  Stack[StackPtr++] = CrntPrefix;
733 
734  /* Now lets pop all the stack into output: */
735  while (StackPtr != 0 && i < LineLen)
736  Line[i++] = Stack[--StackPtr];
737  }
738  if (LastCode != NO_SUCH_CODE) {
739  Prefix[Private->RunningCode - 2] = LastCode;
740 
741  if (CrntCode == Private->RunningCode - 2) {
742  /* Only allowed if CrntCode is exactly the running code:
743  * In that case CrntCode = XXXCode, CrntCode or the
744  * prefix code is last code and the suffix char is
745  * exactly the prefix of last code! */
746  Suffix[Private->RunningCode - 2] =
747  DGifGetPrefixChar(Prefix, LastCode, ClearCode);
748  } else {
749  Suffix[Private->RunningCode - 2] =
750  DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
751  }
752  }
753  LastCode = CrntCode;
754  }
755  }
756 
757  Private->LastCode = LastCode;
758  Private->StackPtr = StackPtr;
759 
760  return GIF_OK;
761 }
762 
763 /******************************************************************************
764  * Routine to trace the Prefixes linked list until we get a prefix which is
765  * not code, but a pixel value (less than ClearCode). Returns that pixel value.
766  * If image is defective, we might loop here forever, so we limit the loops to
767  * the maximum possible if image O.k. - LZ_MAX_CODE times.
768  *****************************************************************************/
769 static int
771  int Code,
772  int ClearCode) {
773 
774  int i = 0;
775 
776  while (Code > ClearCode && i++ <= LZ_MAX_CODE)
777  Code = Prefix[Code];
778  return Code;
779 }
780 
781 /******************************************************************************
782  * The LZ decompression input routine:
783  * This routine is responsible for the decompression of the bit stream from
784  * 8 bits (bytes) packets, into the real codes.
785  * Returns GIF_OK if read successfully.
786  *****************************************************************************/
787 static int
789  int *Code) {
790 
791  GifFilePrivateType *Private = GifFile->Private;
792 
793  GifByteType NextByte;
794  static const unsigned short CodeMasks[] = {
795  0x0000, 0x0001, 0x0003, 0x0007,
796  0x000f, 0x001f, 0x003f, 0x007f,
797  0x00ff, 0x01ff, 0x03ff, 0x07ff,
798  0x0fff
799  };
800  /* The image can't contain more than LZ_BITS per code. */
801  if (Private->RunningBits > LZ_BITS) {
802  return GIF_ERROR;
803  }
804 
805  while (Private->CrntShiftState < Private->RunningBits) {
806  /* Needs to get more bytes from input stream for next code: */
807  if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
808  return GIF_ERROR;
809  }
810  Private->CrntShiftDWord |=
811  ((unsigned long)NextByte) << Private->CrntShiftState;
812  Private->CrntShiftState += 8;
813  }
814  *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
815 
816  Private->CrntShiftDWord >>= Private->RunningBits;
817  Private->CrntShiftState -= Private->RunningBits;
818 
819  /* If code cannot fit into RunningBits bits, must raise its size. Note
820  * however that codes above 4095 are used for special signaling.
821  * If we're using LZ_BITS bits already and we're at the max code, just
822  * keep using the table as it is, don't increment Private->RunningCode.
823  */
824  if (Private->RunningCode < LZ_MAX_CODE + 2 &&
825  ++Private->RunningCode > Private->MaxCode1 &&
826  Private->RunningBits < LZ_BITS) {
827  Private->MaxCode1 <<= 1;
828  Private->RunningBits++;
829  }
830  return GIF_OK;
831 }
832 
833 /******************************************************************************
834  * This routines read one gif data block at a time and buffers it internally
835  * so that the decompression routine could access it.
836  * The routine returns the next byte from its internal buffer (or read next
837  * block in if buffer empty) and returns GIF_OK if successful.
838  *****************************************************************************/
839 static int
841  GifByteType * Buf,
842  GifByteType * NextByte) {
843 
844  if (Buf[0] == 0) {
845  /* Needs to read the next buffer - this one is empty: */
846  if (READ(GifFile, Buf, 1) != 1) {
847  return GIF_ERROR;
848  }
849  /* There shouldn't be any empty data blocks here as the LZW spec
850  * says the LZW termination code should come first. Therefore we
851  * shouldn't be inside this routine at that point.
852  */
853  if (Buf[0] == 0) {
854  return GIF_ERROR;
855  }
856  if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
857  return GIF_ERROR;
858  }
859  *NextByte = Buf[1];
860  Buf[1] = 2; /* We use now the second place as last char read! */
861  Buf[0]--;
862  } else {
863  *NextByte = Buf[Buf[1]++];
864  Buf[0]--;
865  }
866 
867  return GIF_OK;
868 }
869 
870 /******************************************************************************
871  * This routine reads an entire GIF into core, hanging all its state info off
872  * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
873  * first to initialize I/O. Its inverse is EGifSpew().
874  ******************************************************************************/
875 int
876 DGifSlurp(GifFileType * GifFile) {
877 
878  int ImageSize;
879  GifRecordType RecordType;
880  SavedImage *sp;
881  GifByteType *ExtData;
882  Extensions temp_save;
883 
884  temp_save.ExtensionBlocks = NULL;
885  temp_save.ExtensionBlockCount = 0;
886 
887  do {
888  if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
889  return (GIF_ERROR);
890 
891  switch (RecordType) {
893  if (DGifGetImageDesc(GifFile) == GIF_ERROR)
894  return (GIF_ERROR);
895 
896  sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
897  ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
898 
899  sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType));
900  if (sp->RasterBits == NULL) {
901  return GIF_ERROR;
902  }
903  if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
904  GIF_ERROR)
905  return (GIF_ERROR);
906  if (temp_save.ExtensionBlocks) {
907  sp->Extensions.ExtensionBlocks = temp_save.ExtensionBlocks;
908  sp->Extensions.ExtensionBlockCount = temp_save.ExtensionBlockCount;
909 
910  temp_save.ExtensionBlocks = NULL;
911  temp_save.ExtensionBlockCount = 0;
912 
913  /* FIXME: The following is wrong. It is left in only for
914  * backwards compatibility. Someday it should go away. Use
915  * the sp->ExtensionBlocks->Function variable instead. */
916  sp->Extensions.Function = sp->Extensions.ExtensionBlocks[0].Function;
917  }
918  break;
919 
921  {
922  int Function;
924 
925  if (DGifGetExtension(GifFile, &Function, &ExtData) == GIF_ERROR)
926  return (GIF_ERROR);
927 
928  if (GifFile->ImageCount || Function == GRAPHICS_EXT_FUNC_CODE)
929  Extensions = &temp_save;
930  else
931  Extensions = &GifFile->Extensions;
932 
934 
935  if (ExtData)
936  {
937  /* Create an extension block with our data */
938  if (AddExtensionBlock(Extensions, ExtData[0], &ExtData[1]) == GIF_ERROR)
939  return (GIF_ERROR);
940  }
941  else /* Empty extension block */
942  {
944  return (GIF_ERROR);
945  }
946 
947  while (ExtData != NULL) {
948  int Len;
949  GifByteType *Data;
950 
951  if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
952  return (GIF_ERROR);
953 
954  if (ExtData)
955  {
956  Len = ExtData[0];
957  Data = &ExtData[1];
958  }
959  else
960  {
961  Len = 0;
962  Data = NULL;
963  }
964 
966  return (GIF_ERROR);
967  }
968  break;
969  }
970 
972  break;
973 
974  default: /* Should be trapped by DGifGetRecordType */
975  break;
976  }
977  } while (RecordType != TERMINATE_RECORD_TYPE);
978 
979  /* Just in case the Gif has an extension block without an associated
980  * image... (Should we save this into a savefile structure with no image
981  * instead? Have to check if the present writing code can handle that as
982  * well.... */
983  if (temp_save.ExtensionBlocks)
984  FreeExtension(&temp_save);
985 
986  return (GIF_OK);
987 }
988 
989 /******************************************************************************
990  * GifFileType constructor with user supplied input function (TVT)
991  *****************************************************************************/
992 GifFileType *
993 DGifOpen(void *userData,
994  InputFunc readFunc) {
995 
996  unsigned char Buf[GIF_STAMP_LEN + 1];
997  GifFileType *GifFile;
998  GifFilePrivateType *Private;
999 
1000  GifFile = ungif_alloc(sizeof(GifFileType));
1001  if (GifFile == NULL) {
1002  return NULL;
1003  }
1004 
1005  memset(GifFile, '\0', sizeof(GifFileType));
1006 
1007  Private = ungif_alloc(sizeof(GifFilePrivateType));
1008  if (!Private) {
1009  ungif_free(GifFile);
1010  return NULL;
1011  }
1012 
1013  GifFile->Private = (void*)Private;
1014 
1015  Private->Read = readFunc; /* TVT */
1016  GifFile->UserData = userData; /* TVT */
1017 
1018  /* Lets see if this is a GIF file: */
1019  if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
1020  ungif_free(Private);
1021  ungif_free(GifFile);
1022  return NULL;
1023  }
1024 
1025  /* The GIF Version number is ignored at this time. Maybe we should do
1026  * something more useful with it. */
1027  Buf[GIF_STAMP_LEN] = 0;
1028  if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
1029  ungif_free(Private);
1030  ungif_free(GifFile);
1031  return NULL;
1032  }
1033 
1034  if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
1035  ungif_free(Private);
1036  ungif_free(GifFile);
1037  return NULL;
1038  }
1039 
1040  return GifFile;
1041 }
1042 
1043 /******************************************************************************
1044  * This routine should be called last, to close the GIF file.
1045  *****************************************************************************/
1046 int
1048 
1049  GifFilePrivateType *Private;
1050 
1051  if (GifFile == NULL)
1052  return GIF_ERROR;
1053 
1054  Private = GifFile->Private;
1055 
1056  if (GifFile->Image.ColorMap) {
1057  FreeMapObject(GifFile->Image.ColorMap);
1058  GifFile->Image.ColorMap = NULL;
1059  }
1060 
1061  if (GifFile->SColorMap) {
1062  FreeMapObject(GifFile->SColorMap);
1063  GifFile->SColorMap = NULL;
1064  }
1065 
1066  ungif_free(Private);
1067  Private = NULL;
1068 
1069  if (GifFile->SavedImages) {
1070  FreeSavedImages(GifFile);
1071  GifFile->SavedImages = NULL;
1072  }
1073 
1074  FreeExtension(&GifFile->Extensions);
1075 
1076  ungif_free(GifFile);
1077 
1078  return GIF_OK;
1079 }
int(* InputFunc)(GifFileType *, GifByteType *, int)
Definition: ungif.h:137
#define GIF_ERROR
Definition: ungif.h:55
GifWord EOFCode
Definition: ungif.c:87
static int DGifGetWord(GifFileType *GifFile, GifWord *Word)
Definition: ungif.c:560
static int AppendExtensionBlock(Extensions *New, int Len, const unsigned char ExtData[])
Definition: ungif.c:234
GifByteType Buf[256]
Definition: ungif.c:100
int ImageCount
Definition: ungif.h:121
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
unsigned long CrntShiftDWord
Definition: ungif.c:97
static void * ungif_calloc(size_t num, size_t sz)
Definition: ungif.c:66
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GifImageDesc Image
Definition: ungif.h:122
Type
Definition: Type.h:6
static void * ungif_alloc(size_t sz)
Definition: ungif.c:61
static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode)
Definition: ungif.c:770
ColorMapObject * SColorMap
Definition: ungif.h:119
GifByteType Stack[LZ_MAX_CODE]
Definition: ungif.c:101
GifWord Width
Definition: ungif.h:96
unsigned char GifPixelType
Definition: ungif.h:78
#define WARN(fmt,...)
Definition: debug.h:111
static int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type)
Definition: ungif.c:355
GifWord CrntShiftState
Definition: ungif.c:87
GLdouble n
Definition: glext.h:7729
#define New(t)
Definition: rtf.h:1086
GifWord StackPtr
Definition: ungif.c:87
static int BitSize(int n)
Definition: ungif.c:127
GifWord SColorResolution
Definition: ungif.h:115
unsigned int GifPrefixType
Definition: ungif.h:81
static void FreeSavedImages(GifFileType *GifFile)
Definition: ungif.c:279
GifWord SWidth
Definition: ungif.h:115
static void FreeExtension(Extensions *Extensions)
Definition: ungif.c:260
static ColorMapObject * MakeMapObject(int ColorCount, const GifColorType *ColorMap)
Definition: ungif.c:146
static int DGifGetScreenDesc(GifFileType *GifFile)
Definition: ungif.c:307
#define NO_SUCH_CODE
Definition: ungif.c:84
GifWord SAspectRatio
Definition: ungif.h:115
int Function
Definition: ungif.h:103
#define GIF_VERSION_POS
Definition: ungif.h:71
GifWord SBackGroundColor
Definition: ungif.h:115
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int DGifCloseFile(GifFileType *GifFile)
Definition: ungif.c:1047
int ByteCount
Definition: ungif.h:104
unsigned char GifByteType
Definition: ungif.h:80
GifByteType Red
Definition: ungif.h:85
#define READ(_gif, _buf, _len)
Definition: ungif.c:107
GifWord RunningCode
Definition: ungif.c:87
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
GifByteType Green
Definition: ungif.h:85
GifByteType Suffix[LZ_MAX_CODE+1]
Definition: ungif.c:102
static PVOID ptr
Definition: dispmode.c:27
ColorMapObject * ColorMap
Definition: ungif.h:98
static int DGifSetupDecompress(GifFileType *GifFile)
Definition: ungif.c:608
GifWord SHeight
Definition: ungif.h:115
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
Definition: ungif.c:644
static int DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
Definition: ungif.c:515
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define GIF_OK
Definition: ungif.h:56
GifWord BitsPerPixel
Definition: ungif.c:87
char * Bytes
Definition: ungif.h:105
ExtensionBlock * ExtensionBlocks
Definition: ungif.h:111
int Function
Definition: ungif.h:109
GifWord Height
Definition: ungif.h:96
void * Private
Definition: ungif.h:125
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int SortFlag
Definition: ungif.h:91
#define Code
Definition: deflate.h:80
GifWord Interlace
Definition: ungif.h:96
static int DGifDecompressInput(GifFileType *GifFile, int *Code)
Definition: ungif.c:788
GifWord MaxCode1
Definition: ungif.c:87
static int AddExtensionBlock(Extensions *New, int Len, const unsigned char ExtData[])
Definition: ungif.c:197
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned long PixelCount
Definition: ungif.c:98
Extensions Extensions
Definition: ungif.h:120
static int DGifGetImageDesc(GifFileType *GifFile)
Definition: ungif.c:390
void * UserData
Definition: ungif.h:124
static int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension)
Definition: ungif.c:535
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
Definition: ungif.c:840
const GLubyte * c
Definition: glext.h:8905
GLuint GLuint num
Definition: glext.h:9618
#define Len
Definition: deflate.h:82
static int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
Definition: ungif.c:475
GifFileType * DGifOpen(void *userData, InputFunc readFunc)
Definition: ungif.c:993
static IUnknown Object
Definition: main.c:512
Definition: ncftp.h:79
GifWord CrntCode
Definition: ungif.c:87
static void ungif_free(void *ptr)
Definition: ungif.c:76
int GifWord
Definition: ungif.h:82
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GIF_STAMP_LEN
Definition: ungif.h:70
GifWord Top
Definition: ungif.h:96
#define long
Definition: qsort.c:33
#define HeapReAlloc
Definition: compat.h:393
#define GRAPHICS_EXT_FUNC_CODE
Definition: ungif.h:142
GifWord RunningBits
Definition: ungif.c:87
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define GIF_STAMP
Definition: ungif.h:69
GifByteType Blue
Definition: ungif.h:85
int ExtensionBlockCount
Definition: ungif.h:110
struct SavedImage * SavedImages
Definition: ungif.h:123
GifWord ClearCode
Definition: ungif.c:87
int ColorCount
Definition: ungif.h:89
int DGifSlurp(GifFileType *GifFile)
Definition: ungif.c:876
struct GifFilePrivateType GifFilePrivateType
#define LZ_BITS
Definition: ungif.c:82
GifWord LastCode
Definition: ungif.c:87
static const WCHAR sp[]
Definition: suminfo.c:288
static void FreeMapObject(ColorMapObject *Object)
Definition: ungif.c:182
GifPrefixType Prefix[LZ_MAX_CODE+1]
Definition: ungif.c:103
#define LZ_MAX_CODE
Definition: ungif.c:81
#define memset(x, y, z)
Definition: compat.h:39
InputFunc Read
Definition: ungif.c:99
static void * ungif_realloc(void *ptr, size_t sz)
Definition: ungif.c:71
GifRecordType
Definition: ungif.h:128
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
#define HeapFree(x, y, z)
Definition: compat.h:394
GifWord Left
Definition: ungif.h:96
static int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock)
Definition: ungif.c:579
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GifColorType * Colors
Definition: ungif.h:92