Coverage Report

Created: 2025-06-13 06:08

/src/giflib-code/dgif_lib.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
3
dgif_lib.c - GIF decoding
4
5
The functions here and in egif_lib.c are partitioned carefully so that
6
if you only require one of read and write capability, only one of these
7
two modules will be linked.  Preserve this property!
8
9
*****************************************************************************/
10
// SPDX-License-Identifier: MIT
11
// SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond <esr@thyrsus.com>
12
13
#include <fcntl.h>
14
#include <limits.h>
15
#include <stdint.h>
16
#include <stdio.h>
17
#include <stdlib.h>
18
#include <string.h>
19
20
#ifdef _WIN32
21
#include <io.h>
22
#else
23
#include <unistd.h>
24
#endif /* _WIN32 */
25
26
#include "gif_lib.h"
27
#include "gif_lib_private.h"
28
29
/* compose unsigned little endian value */
30
150k
#define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
31
32
/* avoid extra function call in case we use fread (TVT) */
33
468k
static int InternalRead(GifFileType *gif, GifByteType *buf, int len) {
34
  // fprintf(stderr, "### Read: %d\n", len);
35
468k
  return (((GifFilePrivateType *)gif->Private)->Read
36
468k
              ? ((GifFilePrivateType *)gif->Private)->Read(gif, buf, len)
37
468k
              : fread(buf, 1, len,
38
0
                      ((GifFilePrivateType *)gif->Private)->File));
39
468k
}
40
41
static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
42
static int DGifSetupDecompress(GifFileType *GifFile);
43
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
44
                              int LineLen);
45
static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code,
46
                             int ClearCode);
47
static int DGifDecompressInput(GifFileType *GifFile, int *Code);
48
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
49
                             GifByteType *NextByte);
50
51
/******************************************************************************
52
 Open a new GIF file for read, given by its name.
53
 Returns dynamically allocated GifFileType pointer which serves as the GIF
54
 info record.
55
******************************************************************************/
56
0
GifFileType *DGifOpenFileName(const char *FileName, int *Error) {
57
0
  int FileHandle;
58
0
  GifFileType *GifFile;
59
60
0
  if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
61
0
    if (Error != NULL) {
62
0
      *Error = D_GIF_ERR_OPEN_FAILED;
63
0
    }
64
0
    return NULL;
65
0
  }
66
67
0
  GifFile = DGifOpenFileHandle(FileHandle, Error);
68
0
  return GifFile;
69
0
}
70
71
/******************************************************************************
72
 Update a new GIF file, given its file handle.
73
 Returns dynamically allocated GifFileType pointer which serves as the GIF
74
 info record.
75
******************************************************************************/
76
0
GifFileType *DGifOpenFileHandle(int FileHandle, int *Error) {
77
0
  char Buf[GIF_STAMP_LEN + 1];
78
0
  GifFileType *GifFile;
79
0
  GifFilePrivateType *Private;
80
0
  FILE *f;
81
82
0
  GifFile = (GifFileType *)malloc(sizeof(GifFileType));
83
0
  if (GifFile == NULL) {
84
0
    if (Error != NULL) {
85
0
      *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
86
0
    }
87
0
    (void)close(FileHandle);
88
0
    return NULL;
89
0
  }
90
91
0
  /*@i1@*/ memset(GifFile, '\0', sizeof(GifFileType));
92
93
  /* Belt and suspenders, in case the null pointer isn't zero */
94
0
  GifFile->SavedImages = NULL;
95
0
  GifFile->SColorMap = NULL;
96
97
0
  Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
98
0
  if (Private == NULL) {
99
0
    if (Error != NULL) {
100
0
      *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
101
0
    }
102
0
    (void)close(FileHandle);
103
0
    free((char *)GifFile);
104
0
    return NULL;
105
0
  }
106
107
0
  /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType));
108
109
#ifdef _WIN32
110
  _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
111
#endif                                  /* _WIN32 */
112
113
0
  f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
114
115
  /*@-mustfreeonly@*/
116
0
  GifFile->Private = (void *)Private;
117
0
  Private->FileHandle = FileHandle;
118
0
  Private->File = f;
119
0
  Private->FileState = FILE_STATE_READ;
120
0
  Private->Read = NULL;     /* don't use alternate input method (TVT) */
121
0
  GifFile->UserData = NULL; /* TVT */
122
  /*@=mustfreeonly@*/
123
124
  /* Let's see if this is a GIF file: */
125
  /* coverity[check_return] */
126
0
  if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) !=
127
0
      GIF_STAMP_LEN) {
128
0
    if (Error != NULL) {
129
0
      *Error = D_GIF_ERR_READ_FAILED;
130
0
    }
131
0
    (void)fclose(f);
132
0
    free((char *)Private);
133
0
    free((char *)GifFile);
134
0
    return NULL;
135
0
  }
136
137
  /* Check for GIF prefix at start of file */
138
0
  Buf[GIF_STAMP_LEN] = 0;
139
0
  if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
140
0
    if (Error != NULL) {
141
0
      *Error = D_GIF_ERR_NOT_GIF_FILE;
142
0
    }
143
0
    (void)fclose(f);
144
0
    free((char *)Private);
145
0
    free((char *)GifFile);
146
0
    return NULL;
147
0
  }
148
149
0
  if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
150
0
    (void)fclose(f);
151
0
    free((char *)Private);
152
0
    free((char *)GifFile);
153
0
    return NULL;
154
0
  }
155
156
0
  GifFile->Error = 0;
157
158
  /* What version of GIF? */
159
0
  Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9');
160
161
0
  return GifFile;
162
0
}
163
164
/******************************************************************************
165
 GifFileType constructor with user supplied input function (TVT)
166
******************************************************************************/
167
960
GifFileType *DGifOpen(void *userData, InputFunc readFunc, int *Error) {
168
960
  char Buf[GIF_STAMP_LEN + 1];
169
960
  GifFileType *GifFile;
170
960
  GifFilePrivateType *Private;
171
172
960
  GifFile = (GifFileType *)malloc(sizeof(GifFileType));
173
960
  if (GifFile == NULL) {
174
0
    if (Error != NULL) {
175
0
      *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
176
0
    }
177
0
    return NULL;
178
0
  }
179
180
960
  memset(GifFile, '\0', sizeof(GifFileType));
181
182
  /* Belt and suspenders, in case the null pointer isn't zero */
183
960
  GifFile->SavedImages = NULL;
184
960
  GifFile->SColorMap = NULL;
185
186
960
  Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
187
960
  if (!Private) {
188
0
    if (Error != NULL) {
189
0
      *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
190
0
    }
191
0
    free((char *)GifFile);
192
0
    return NULL;
193
0
  }
194
960
  /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType));
195
196
960
  GifFile->Private = (void *)Private;
197
960
  Private->FileHandle = 0;
198
960
  Private->File = NULL;
199
960
  Private->FileState = FILE_STATE_READ;
200
201
960
  Private->Read = readFunc;     /* TVT */
202
960
  GifFile->UserData = userData; /* TVT */
203
204
  /* Lets see if this is a GIF file: */
205
  /* coverity[check_return] */
206
960
  if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) !=
207
960
      GIF_STAMP_LEN) {
208
0
    if (Error != NULL) {
209
0
      *Error = D_GIF_ERR_READ_FAILED;
210
0
    }
211
0
    free((char *)Private);
212
0
    free((char *)GifFile);
213
0
    return NULL;
214
0
  }
215
216
  /* Check for GIF prefix at start of file */
217
960
  Buf[GIF_STAMP_LEN] = '\0';
218
960
  if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
219
0
    if (Error != NULL) {
220
0
      *Error = D_GIF_ERR_NOT_GIF_FILE;
221
0
    }
222
0
    free((char *)Private);
223
0
    free((char *)GifFile);
224
0
    return NULL;
225
0
  }
226
227
960
  if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
228
18
    free((char *)Private);
229
18
    free((char *)GifFile);
230
18
    if (Error != NULL) {
231
18
      *Error = D_GIF_ERR_NO_SCRN_DSCR;
232
18
    }
233
18
    return NULL;
234
18
  }
235
236
942
  GifFile->Error = 0;
237
238
  /* What version of GIF? */
239
942
  Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9');
240
241
942
  return GifFile;
242
960
}
243
244
/******************************************************************************
245
 This routine should be called before any other DGif calls. Note that
246
 this routine is called automatically from DGif file open routines.
247
******************************************************************************/
248
960
int DGifGetScreenDesc(GifFileType *GifFile) {
249
960
  int BitsPerPixel;
250
960
  bool SortFlag;
251
960
  GifByteType Buf[3];
252
960
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
253
254
960
  if (!IS_READABLE(Private)) {
255
    /* This file was NOT open for reading: */
256
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
257
0
    return GIF_ERROR;
258
0
  }
259
260
  /* Put the screen descriptor into the file: */
261
960
  if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
262
960
      DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) {
263
0
    return GIF_ERROR;
264
0
  }
265
266
960
  if (InternalRead(GifFile, Buf, 3) != 3) {
267
2
    GifFile->Error = D_GIF_ERR_READ_FAILED;
268
2
    GifFreeMapObject(GifFile->SColorMap);
269
2
    GifFile->SColorMap = NULL;
270
2
    return GIF_ERROR;
271
2
  }
272
958
  GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
273
958
  SortFlag = (Buf[0] & 0x08) != 0;
274
958
  BitsPerPixel = (Buf[0] & 0x07) + 1;
275
958
  GifFile->SBackGroundColor = Buf[1];
276
958
  GifFile->AspectByte = Buf[2];
277
958
  if (Buf[0] & 0x80) { /* Do we have global color map? */
278
45
    int i;
279
280
45
    GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
281
45
    if (GifFile->SColorMap == NULL) {
282
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
283
0
      return GIF_ERROR;
284
0
    }
285
286
    /* Get the global color map: */
287
45
    GifFile->SColorMap->SortFlag = SortFlag;
288
440
    for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
289
      /* coverity[check_return] */
290
411
      if (InternalRead(GifFile, Buf, 3) != 3) {
291
16
        GifFreeMapObject(GifFile->SColorMap);
292
16
        GifFile->SColorMap = NULL;
293
16
        GifFile->Error = D_GIF_ERR_READ_FAILED;
294
16
        return GIF_ERROR;
295
16
      }
296
395
      GifFile->SColorMap->Colors[i].Red = Buf[0];
297
395
      GifFile->SColorMap->Colors[i].Green = Buf[1];
298
395
      GifFile->SColorMap->Colors[i].Blue = Buf[2];
299
395
    }
300
913
  } else {
301
913
    GifFile->SColorMap = NULL;
302
913
  }
303
304
  /*
305
   * No check here for whether the background color is in range for the
306
   * screen color map.  Possibly there should be.
307
   */
308
309
942
  return GIF_OK;
310
958
}
311
312
0
const char *DGifGetGifVersion(GifFileType *GifFile) {
313
0
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
314
315
0
  if (Private->gif89) {
316
0
    return GIF89_STAMP;
317
0
  } else {
318
0
    return GIF87_STAMP;
319
0
  }
320
0
}
321
322
/******************************************************************************
323
 This routine should be called before any attempt to read an image.
324
******************************************************************************/
325
40.8k
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type) {
326
40.8k
  GifByteType Buf;
327
40.8k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
328
329
40.8k
  if (!IS_READABLE(Private)) {
330
    /* This file was NOT open for reading: */
331
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
332
0
    return GIF_ERROR;
333
0
  }
334
335
  /* coverity[check_return] */
336
40.8k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
337
11
    GifFile->Error = D_GIF_ERR_READ_FAILED;
338
11
    return GIF_ERROR;
339
11
  }
340
341
  // fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf);
342
40.8k
  switch (Buf) {
343
37.0k
  case DESCRIPTOR_INTRODUCER:
344
37.0k
    *Type = IMAGE_DESC_RECORD_TYPE;
345
37.0k
    break;
346
3.45k
  case EXTENSION_INTRODUCER:
347
3.45k
    *Type = EXTENSION_RECORD_TYPE;
348
3.45k
    break;
349
201
  case TERMINATOR_INTRODUCER:
350
201
    *Type = TERMINATE_RECORD_TYPE;
351
201
    break;
352
104
  default:
353
104
    *Type = UNDEFINED_RECORD_TYPE;
354
104
    GifFile->Error = D_GIF_ERR_WRONG_RECORD;
355
104
    return GIF_ERROR;
356
40.8k
  }
357
358
40.7k
  return GIF_OK;
359
40.8k
}
360
361
37.0k
int DGifGetImageHeader(GifFileType *GifFile) {
362
37.0k
  unsigned int BitsPerPixel;
363
37.0k
  GifByteType Buf[3];
364
37.0k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
365
366
37.0k
  if (!IS_READABLE(Private)) {
367
    /* This file was NOT open for reading: */
368
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
369
0
    return GIF_ERROR;
370
0
  }
371
372
37.0k
  if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
373
37.0k
      DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
374
37.0k
      DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
375
37.0k
      DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) {
376
12
    return GIF_ERROR;
377
12
  }
378
37.0k
  if (InternalRead(GifFile, Buf, 1) != 1) {
379
1
    GifFile->Error = D_GIF_ERR_READ_FAILED;
380
1
    GifFreeMapObject(GifFile->Image.ColorMap);
381
1
    GifFile->Image.ColorMap = NULL;
382
1
    return GIF_ERROR;
383
1
  }
384
37.0k
  BitsPerPixel = (Buf[0] & 0x07) + 1;
385
37.0k
  GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
386
387
  /* Setup the colormap */
388
37.0k
  if (GifFile->Image.ColorMap) {
389
450
    GifFreeMapObject(GifFile->Image.ColorMap);
390
450
    GifFile->Image.ColorMap = NULL;
391
450
  }
392
  /* Does this image have local color map? */
393
37.0k
  if (Buf[0] & 0x80) {
394
501
    unsigned int i;
395
396
501
    GifFile->Image.ColorMap =
397
501
        GifMakeMapObject(1 << BitsPerPixel, NULL);
398
501
    if (GifFile->Image.ColorMap == NULL) {
399
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
400
0
      return GIF_ERROR;
401
0
    }
402
403
    /* Get the image local color map: */
404
2.22k
    for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
405
      /* coverity[check_return] */
406
1.74k
      if (InternalRead(GifFile, Buf, 3) != 3) {
407
24
        GifFreeMapObject(GifFile->Image.ColorMap);
408
24
        GifFile->Error = D_GIF_ERR_READ_FAILED;
409
24
        GifFile->Image.ColorMap = NULL;
410
24
        return GIF_ERROR;
411
24
      }
412
1.72k
      GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
413
1.72k
      GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
414
1.72k
      GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
415
1.72k
    }
416
501
  }
417
418
37.0k
  Private->PixelCount =
419
37.0k
      (long)GifFile->Image.Width * (long)GifFile->Image.Height;
420
421
  /* Reset decompress algorithm parameters. */
422
37.0k
  return DGifSetupDecompress(GifFile);
423
37.0k
}
424
425
/******************************************************************************
426
 This routine should be called before any attempt to read an image.
427
 Note it is assumed the Image desc. header has been read.
428
******************************************************************************/
429
37.0k
int DGifGetImageDesc(GifFileType *GifFile) {
430
37.0k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
431
37.0k
  SavedImage *sp;
432
433
37.0k
  if (!IS_READABLE(Private)) {
434
    /* This file was NOT open for reading: */
435
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
436
0
    return GIF_ERROR;
437
0
  }
438
439
37.0k
  if (DGifGetImageHeader(GifFile) == GIF_ERROR) {
440
89
    return GIF_ERROR;
441
89
  }
442
443
36.9k
  if (GifFile->SavedImages) {
444
36.3k
    SavedImage *new_saved_images = (SavedImage *)reallocarray(
445
36.3k
        GifFile->SavedImages, (GifFile->ImageCount + 1),
446
36.3k
        sizeof(SavedImage));
447
36.3k
    if (new_saved_images == NULL) {
448
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
449
0
      return GIF_ERROR;
450
0
    }
451
36.3k
    GifFile->SavedImages = new_saved_images;
452
36.3k
  } else {
453
569
    if ((GifFile->SavedImages =
454
569
             (SavedImage *)malloc(sizeof(SavedImage))) == NULL) {
455
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
456
0
      return GIF_ERROR;
457
0
    }
458
569
  }
459
460
36.9k
  sp = &GifFile->SavedImages[GifFile->ImageCount];
461
36.9k
  memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
462
36.9k
  if (GifFile->Image.ColorMap != NULL) {
463
469
    sp->ImageDesc.ColorMap =
464
469
        GifMakeMapObject(GifFile->Image.ColorMap->ColorCount,
465
469
                         GifFile->Image.ColorMap->Colors);
466
469
    if (sp->ImageDesc.ColorMap == NULL) {
467
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
468
0
      return GIF_ERROR;
469
0
    }
470
469
  }
471
36.9k
  sp->RasterBits = (unsigned char *)NULL;
472
36.9k
  sp->ExtensionBlockCount = 0;
473
36.9k
  sp->ExtensionBlocks = (ExtensionBlock *)NULL;
474
475
36.9k
  GifFile->ImageCount++;
476
477
36.9k
  return GIF_OK;
478
36.9k
}
479
480
/******************************************************************************
481
 Get one full scanned line (Line) of length LineLen from GIF file.
482
******************************************************************************/
483
676k
int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) {
484
676k
  GifByteType *Dummy;
485
676k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
486
487
676k
  if (!IS_READABLE(Private)) {
488
    /* This file was NOT open for reading: */
489
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
490
0
    return GIF_ERROR;
491
0
  }
492
493
676k
  if (!LineLen) {
494
0
    LineLen = GifFile->Image.Width;
495
0
  }
496
497
676k
  if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
498
0
    GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
499
0
    return GIF_ERROR;
500
0
  }
501
502
676k
  if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
503
676k
    if (Private->PixelCount == 0) {
504
      /* We probably won't be called any more, so let's clean
505
       * up everything before we return: need to flush out all
506
       * the rest of image until an empty block (size 0)
507
       * detected. We use GetCodeNext.
508
       */
509
37.0k
      do {
510
37.0k
        if (DGifGetCodeNext(GifFile, &Dummy) ==
511
37.0k
            GIF_ERROR) {
512
15
          return GIF_ERROR;
513
15
        }
514
37.0k
      } while (Dummy != NULL);
515
36.5k
    }
516
676k
    return GIF_OK;
517
676k
  } else {
518
322
    return GIF_ERROR;
519
322
  }
520
676k
}
521
522
/******************************************************************************
523
 Put one pixel (Pixel) into GIF file.
524
******************************************************************************/
525
0
int DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel) {
526
0
  GifByteType *Dummy;
527
0
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
528
529
0
  if (!IS_READABLE(Private)) {
530
    /* This file was NOT open for reading: */
531
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
532
0
    return GIF_ERROR;
533
0
  }
534
0
  if (--Private->PixelCount > 0xffff0000UL) {
535
0
    GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
536
0
    return GIF_ERROR;
537
0
  }
538
539
0
  if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
540
0
    if (Private->PixelCount == 0) {
541
      /* We probably won't be called any more, so let's clean
542
       * up everything before we return: need to flush out all
543
       * the rest of image until an empty block (size 0)
544
       * detected. We use GetCodeNext.
545
       */
546
0
      do {
547
0
        if (DGifGetCodeNext(GifFile, &Dummy) ==
548
0
            GIF_ERROR) {
549
0
          return GIF_ERROR;
550
0
        }
551
0
      } while (Dummy != NULL);
552
0
    }
553
0
    return GIF_OK;
554
0
  } else {
555
0
    return GIF_ERROR;
556
0
  }
557
0
}
558
559
/******************************************************************************
560
 Get an extension block (see GIF manual) from GIF file. This routine only
561
 returns the first data block, and DGifGetExtensionNext should be called
562
 after this one until NULL extension is returned.
563
 The Extension should NOT be freed by the user (not dynamically allocated).
564
 Note it is assumed the Extension description header has been read.
565
******************************************************************************/
566
int DGifGetExtension(GifFileType *GifFile, int *ExtCode,
567
3.45k
                     GifByteType **Extension) {
568
3.45k
  GifByteType Buf;
569
3.45k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
570
571
  // fprintf(stderr, "### -> DGifGetExtension:\n");
572
3.45k
  if (!IS_READABLE(Private)) {
573
    /* This file was NOT open for reading: */
574
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
575
0
    return GIF_ERROR;
576
0
  }
577
578
  /* coverity[check_return] */
579
3.45k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
580
0
    GifFile->Error = D_GIF_ERR_READ_FAILED;
581
0
    return GIF_ERROR;
582
0
  }
583
3.45k
  *ExtCode = Buf;
584
  // fprintf(stderr, "### <- DGifGetExtension: %02x, about to call
585
  // next\n", Buf);
586
587
3.45k
  return DGifGetExtensionNext(GifFile, Extension);
588
3.45k
}
589
590
/******************************************************************************
591
 Get a following extension block (see GIF manual) from GIF file. This
592
 routine should be called until NULL Extension is returned.
593
 The Extension should NOT be freed by the user (not dynamically allocated).
594
******************************************************************************/
595
37.8k
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **Extension) {
596
37.8k
  GifByteType Buf;
597
37.8k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
598
599
  // fprintf(stderr, "### -> DGifGetExtensionNext\n");
600
37.8k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
601
6
    GifFile->Error = D_GIF_ERR_READ_FAILED;
602
6
    return GIF_ERROR;
603
6
  }
604
  // fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf);
605
606
37.8k
  if (Buf > 0) {
607
33.3k
    *Extension = Private->Buf; /* Use private unused buffer. */
608
33.3k
    (*Extension)[0] =
609
33.3k
        Buf; /* Pascal strings notation (pos. 0 is len.). */
610
             /* coverity[tainted_data,check_return] */
611
33.3k
    if (InternalRead(GifFile, &((*Extension)[1]), Buf) != Buf) {
612
110
      GifFile->Error = D_GIF_ERR_READ_FAILED;
613
110
      return GIF_ERROR;
614
110
    }
615
33.3k
  } else {
616
4.47k
    *Extension = NULL;
617
4.47k
  }
618
  // fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension);
619
620
37.7k
  return GIF_OK;
621
37.8k
}
622
623
/******************************************************************************
624
 Extract a Graphics Control Block from raw extension data
625
******************************************************************************/
626
627
int DGifExtensionToGCB(const size_t GifExtensionLength,
628
                       const GifByteType *GifExtension,
629
604
                       GraphicsControlBlock *GCB) {
630
604
  if (GifExtensionLength != 4) {
631
203
    return GIF_ERROR;
632
203
  }
633
634
401
  GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
635
401
  GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
636
401
  GCB->DelayTime =
637
401
      UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
638
401
  if (GifExtension[0] & 0x01) {
639
198
    GCB->TransparentColor = (int)GifExtension[3];
640
203
  } else {
641
203
    GCB->TransparentColor = NO_TRANSPARENT_COLOR;
642
203
  }
643
644
401
  return GIF_OK;
645
604
}
646
647
/******************************************************************************
648
 Extract the Graphics Control Block for a saved image, if it exists.
649
******************************************************************************/
650
651
int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex,
652
34.1k
                            GraphicsControlBlock *GCB) {
653
34.1k
  int i;
654
655
34.1k
  if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) {
656
0
    return GIF_ERROR;
657
0
  }
658
659
34.1k
  GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
660
34.1k
  GCB->UserInputFlag = false;
661
34.1k
  GCB->DelayTime = 0;
662
34.1k
  GCB->TransparentColor = NO_TRANSPARENT_COLOR;
663
664
55.2k
  for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount;
665
34.1k
       i++) {
666
21.6k
    ExtensionBlock *ep =
667
21.6k
        &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
668
21.6k
    if (ep->Function == GRAPHICS_EXT_FUNC_CODE) {
669
604
      return DGifExtensionToGCB(ep->ByteCount, ep->Bytes,
670
604
                                GCB);
671
604
    }
672
21.6k
  }
673
674
33.5k
  return GIF_ERROR;
675
34.1k
}
676
677
/******************************************************************************
678
 This routine should be called last, to close the GIF file.
679
******************************************************************************/
680
942
int DGifCloseFile(GifFileType *GifFile, int *ErrorCode) {
681
942
  GifFilePrivateType *Private;
682
683
942
  if (GifFile == NULL || GifFile->Private == NULL) {
684
0
    return GIF_ERROR;
685
0
  }
686
687
942
  if (GifFile->Image.ColorMap) {
688
27
    GifFreeMapObject(GifFile->Image.ColorMap);
689
27
    GifFile->Image.ColorMap = NULL;
690
27
  }
691
692
942
  if (GifFile->SColorMap) {
693
29
    GifFreeMapObject(GifFile->SColorMap);
694
29
    GifFile->SColorMap = NULL;
695
29
  }
696
697
942
  if (GifFile->SavedImages) {
698
569
    GifFreeSavedImages(GifFile);
699
569
    GifFile->SavedImages = NULL;
700
569
  }
701
702
942
  GifFreeExtensions(&GifFile->ExtensionBlockCount,
703
942
                    &GifFile->ExtensionBlocks);
704
705
942
  Private = (GifFilePrivateType *)GifFile->Private;
706
707
942
  if (!IS_READABLE(Private)) {
708
    /* This file was NOT open for reading: */
709
0
    if (ErrorCode != NULL) {
710
0
      *ErrorCode = D_GIF_ERR_NOT_READABLE;
711
0
    }
712
0
    free((char *)GifFile->Private);
713
0
    free(GifFile);
714
0
    return GIF_ERROR;
715
0
  }
716
717
942
  if (Private->File && (fclose(Private->File) != 0)) {
718
0
    if (ErrorCode != NULL) {
719
0
      *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
720
0
    }
721
0
    free((char *)GifFile->Private);
722
0
    free(GifFile);
723
0
    return GIF_ERROR;
724
0
  }
725
726
942
  free((char *)GifFile->Private);
727
942
  free(GifFile);
728
942
  if (ErrorCode != NULL) {
729
942
    *ErrorCode = D_GIF_SUCCEEDED;
730
942
  }
731
942
  return GIF_OK;
732
942
}
733
734
/******************************************************************************
735
 Get 2 bytes (word) from the given file:
736
******************************************************************************/
737
150k
static int DGifGetWord(GifFileType *GifFile, GifWord *Word) {
738
150k
  unsigned char c[2];
739
740
  /* coverity[check_return] */
741
150k
  if (InternalRead(GifFile, c, 2) != 2) {
742
12
    GifFile->Error = D_GIF_ERR_READ_FAILED;
743
12
    return GIF_ERROR;
744
12
  }
745
746
150k
  *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
747
150k
  return GIF_OK;
748
150k
}
749
750
/******************************************************************************
751
 Get the image code in compressed form.  This routine can be called if the
752
 information needed to be piped out as is. Obviously this is much faster
753
 than decoding and encoding again. This routine should be followed by calls
754
 to DGifGetCodeNext, until NULL block is returned.
755
 The block should NOT be freed by the user (not dynamically allocated).
756
******************************************************************************/
757
0
int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock) {
758
0
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
759
760
0
  if (!IS_READABLE(Private)) {
761
    /* This file was NOT open for reading: */
762
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
763
0
    return GIF_ERROR;
764
0
  }
765
766
0
  *CodeSize = Private->BitsPerPixel;
767
768
0
  return DGifGetCodeNext(GifFile, CodeBlock);
769
0
}
770
771
/******************************************************************************
772
 Continue to get the image code in compressed form. This routine should be
773
 called until NULL block is returned.
774
 The block should NOT be freed by the user (not dynamically allocated).
775
******************************************************************************/
776
37.0k
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock) {
777
37.0k
  GifByteType Buf;
778
37.0k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
779
780
  /* coverity[tainted_data_argument] */
781
  /* coverity[check_return] */
782
37.0k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
783
2
    GifFile->Error = D_GIF_ERR_READ_FAILED;
784
2
    return GIF_ERROR;
785
2
  }
786
787
  /* coverity[lower_bounds] */
788
37.0k
  if (Buf > 0) {
789
552
    *CodeBlock = Private->Buf; /* Use private unused buffer. */
790
552
    (*CodeBlock)[0] =
791
552
        Buf; /* Pascal strings notation (pos. 0 is len.). */
792
             /* coverity[tainted_data] */
793
552
    if (InternalRead(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
794
13
      GifFile->Error = D_GIF_ERR_READ_FAILED;
795
13
      return GIF_ERROR;
796
13
    }
797
36.5k
  } else {
798
36.5k
    *CodeBlock = NULL;
799
36.5k
    Private->Buf[0] = 0; /* Make sure the buffer is empty! */
800
36.5k
    Private->PixelCount =
801
36.5k
        0; /* And local info. indicate image read. */
802
36.5k
  }
803
804
37.0k
  return GIF_OK;
805
37.0k
}
806
807
/******************************************************************************
808
 Setup the LZ decompression for this image:
809
******************************************************************************/
810
37.0k
static int DGifSetupDecompress(GifFileType *GifFile) {
811
37.0k
  int i, BitsPerPixel;
812
37.0k
  GifByteType CodeSize;
813
37.0k
  GifPrefixType *Prefix;
814
37.0k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
815
816
  /* coverity[check_return] */
817
37.0k
  if (InternalRead(GifFile, &CodeSize, 1) <
818
37.0k
      1) { /* Read Code size from file. */
819
9
    GifFile->Error = D_GIF_ERR_READ_FAILED;
820
9
    return GIF_ERROR; /* Failed to read Code size. */
821
9
  }
822
37.0k
  BitsPerPixel = CodeSize;
823
824
  /* this can only happen on a severely malformed GIF */
825
37.0k
  if (BitsPerPixel > 8) {
826
43
    GifFile->Error =
827
43
        D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
828
43
    return GIF_ERROR;          /* Failed to read Code size. */
829
43
  }
830
831
36.9k
  Private->Buf[0] = 0; /* Input Buffer empty. */
832
36.9k
  Private->BitsPerPixel = BitsPerPixel;
833
36.9k
  Private->ClearCode = (1 << BitsPerPixel);
834
36.9k
  Private->EOFCode = Private->ClearCode + 1;
835
36.9k
  Private->RunningCode = Private->EOFCode + 1;
836
36.9k
  Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
837
36.9k
  Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
838
36.9k
  Private->StackPtr = 0; /* No pixels on the pixel stack. */
839
36.9k
  Private->LastCode = NO_SUCH_CODE;
840
36.9k
  Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
841
36.9k
  Private->CrntShiftDWord = 0;
842
843
36.9k
  Prefix = Private->Prefix;
844
151M
  for (i = 0; i <= LZ_MAX_CODE; i++) {
845
151M
    Prefix[i] = NO_SUCH_CODE;
846
151M
  }
847
848
36.9k
  return GIF_OK;
849
37.0k
}
850
851
/******************************************************************************
852
 The LZ decompression routine:
853
 This version decompress the given GIF file into Line of length LineLen.
854
 This routine can be called few times (one per scan line, for example), in
855
 order the complete the whole image.
856
******************************************************************************/
857
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
858
676k
                              int LineLen) {
859
676k
  int i = 0;
860
676k
  int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
861
676k
  GifByteType *Stack, *Suffix;
862
676k
  GifPrefixType *Prefix;
863
676k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
864
865
676k
  StackPtr = Private->StackPtr;
866
676k
  Prefix = Private->Prefix;
867
676k
  Suffix = Private->Suffix;
868
676k
  Stack = Private->Stack;
869
676k
  EOFCode = Private->EOFCode;
870
676k
  ClearCode = Private->ClearCode;
871
676k
  LastCode = Private->LastCode;
872
873
676k
  if (StackPtr > LZ_MAX_CODE) {
874
0
    return GIF_ERROR;
875
0
  }
876
877
676k
  if (StackPtr != 0) {
878
    /* Let pop the stack off before continueing to read the GIF
879
     * file: */
880
858k
    while (StackPtr != 0 && i < LineLen) {
881
445k
      Line[i++] = Stack[--StackPtr];
882
445k
    }
883
412k
  }
884
885
1.33M
  while (i < LineLen) { /* Decode LineLen items. */
886
658k
    if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) {
887
231
      return GIF_ERROR;
888
231
    }
889
890
658k
    if (CrntCode == EOFCode) {
891
      /* Note however that usually we will not be here as we
892
       * will stop decoding as soon as we got all the pixel,
893
       * or EOF code will not be read at all, and
894
       * DGifGetLine/Pixel clean everything.  */
895
20
      GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
896
20
      return GIF_ERROR;
897
658k
    } else if (CrntCode == ClearCode) {
898
      /* We need to start over again: */
899
574M
      for (j = 0; j <= LZ_MAX_CODE; j++) {
900
573M
        Prefix[j] = NO_SUCH_CODE;
901
573M
      }
902
140k
      Private->RunningCode = Private->EOFCode + 1;
903
140k
      Private->RunningBits = Private->BitsPerPixel + 1;
904
140k
      Private->MaxCode1 = 1 << Private->RunningBits;
905
140k
      LastCode = Private->LastCode = NO_SUCH_CODE;
906
518k
    } else {
907
      /* Its regular code - if in pixel range simply add it to
908
       * output stream, otherwise trace to codes linked list
909
       * until the prefix is in pixel range: */
910
518k
      if (CrntCode < ClearCode) {
911
        /* This is simple - its pixel scalar, so add it
912
         * to output: */
913
207k
        Line[i++] = CrntCode;
914
310k
      } else {
915
        /* Its a code to needed to be traced: trace the
916
         * linked list until the prefix is a pixel,
917
         * while pushing the suffix pixels on our stack.
918
         * If we done, pop the stack in reverse (thats
919
         * what stack is good for!) order to output.  */
920
310k
        if (Prefix[CrntCode] == NO_SUCH_CODE) {
921
101k
          CrntPrefix = LastCode;
922
923
          /* Only allowed if CrntCode is exactly
924
           * the running code: In that case
925
           * CrntCode = XXXCode, CrntCode or the
926
           * prefix code is last code and the
927
           * suffix char is exactly the prefix of
928
           * last code! */
929
101k
          if (CrntCode ==
930
101k
              Private->RunningCode - 2) {
931
35.0k
            Suffix[Private->RunningCode -
932
35.0k
                   2] = Stack[StackPtr++] =
933
35.0k
                DGifGetPrefixChar(
934
35.0k
                    Prefix, LastCode,
935
35.0k
                    ClearCode);
936
66.3k
          } else {
937
66.3k
            Suffix[Private->RunningCode -
938
66.3k
                   2] = Stack[StackPtr++] =
939
66.3k
                DGifGetPrefixChar(
940
66.3k
                    Prefix, CrntCode,
941
66.3k
                    ClearCode);
942
66.3k
          }
943
209k
        } else {
944
209k
          CrntPrefix = CrntCode;
945
209k
        }
946
947
        /* Now (if image is O.K.) we should not get a
948
         * NO_SUCH_CODE during the trace. As we might
949
         * loop forever, in case of defective image, we
950
         * use StackPtr as loop counter and stop before
951
         * overflowing Stack[]. */
952
1.10M
        while (StackPtr < LZ_MAX_CODE &&
953
1.10M
               CrntPrefix > ClearCode &&
954
1.10M
               CrntPrefix <= LZ_MAX_CODE) {
955
795k
          Stack[StackPtr++] = Suffix[CrntPrefix];
956
795k
          CrntPrefix = Prefix[CrntPrefix];
957
795k
        }
958
310k
        if (StackPtr >= LZ_MAX_CODE ||
959
310k
            CrntPrefix > LZ_MAX_CODE) {
960
71
          GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
961
71
          return GIF_ERROR;
962
71
        }
963
        /* Push the last character on stack: */
964
310k
        Stack[StackPtr++] = CrntPrefix;
965
966
        /* Now lets pop all the stack into output: */
967
1.05M
        while (StackPtr != 0 && i < LineLen) {
968
748k
          Line[i++] = Stack[--StackPtr];
969
748k
        }
970
310k
      }
971
518k
      if (LastCode != NO_SUCH_CODE &&
972
518k
          Private->RunningCode - 2 < (LZ_MAX_CODE + 1) &&
973
518k
          Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
974
444k
        Prefix[Private->RunningCode - 2] = LastCode;
975
976
444k
        if (CrntCode == Private->RunningCode - 2) {
977
          /* Only allowed if CrntCode is exactly
978
           * the running code: In that case
979
           * CrntCode = XXXCode, CrntCode or the
980
           * prefix code is last code and the
981
           * suffix char is exactly the prefix of
982
           * last code! */
983
35.0k
          Suffix[Private->RunningCode - 2] =
984
35.0k
              DGifGetPrefixChar(Prefix, LastCode,
985
35.0k
                                ClearCode);
986
409k
        } else {
987
409k
          Suffix[Private->RunningCode - 2] =
988
409k
              DGifGetPrefixChar(Prefix, CrntCode,
989
409k
                                ClearCode);
990
409k
        }
991
444k
      }
992
518k
      LastCode = CrntCode;
993
518k
    }
994
658k
  }
995
996
676k
  Private->LastCode = LastCode;
997
676k
  Private->StackPtr = StackPtr;
998
999
676k
  return GIF_OK;
1000
676k
}
1001
1002
/******************************************************************************
1003
 Routine to trace the Prefixes linked list until we get a prefix which is
1004
 not code, but a pixel value (less than ClearCode). Returns that pixel value.
1005
 If image is defective, we might loop here forever, so we limit the loops to
1006
 the maximum possible if image O.k. - LZ_MAX_CODE times.
1007
******************************************************************************/
1008
static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code,
1009
546k
                             int ClearCode) {
1010
546k
  int i = 0;
1011
1012
1.39M
  while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
1013
981k
    if (Code > LZ_MAX_CODE) {
1014
132k
      return NO_SUCH_CODE;
1015
132k
    }
1016
848k
    Code = Prefix[Code];
1017
848k
  }
1018
413k
  return Code;
1019
546k
}
1020
1021
/******************************************************************************
1022
 Interface for accessing the LZ codes directly. Set Code to the real code
1023
 (12bits), or to -1 if EOF code is returned.
1024
******************************************************************************/
1025
0
int DGifGetLZCodes(GifFileType *GifFile, int *Code) {
1026
0
  GifByteType *CodeBlock;
1027
0
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
1028
1029
0
  if (!IS_READABLE(Private)) {
1030
    /* This file was NOT open for reading: */
1031
0
    GifFile->Error = D_GIF_ERR_NOT_READABLE;
1032
0
    return GIF_ERROR;
1033
0
  }
1034
1035
0
  if (DGifDecompressInput(GifFile, Code) == GIF_ERROR) {
1036
0
    return GIF_ERROR;
1037
0
  }
1038
1039
0
  if (*Code == Private->EOFCode) {
1040
    /* Skip rest of codes (hopefully only NULL terminating block):
1041
     */
1042
0
    do {
1043
0
      if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
1044
0
        return GIF_ERROR;
1045
0
      }
1046
0
    } while (CodeBlock != NULL);
1047
1048
0
    *Code = -1;
1049
0
  } else if (*Code == Private->ClearCode) {
1050
    /* We need to start over again: */
1051
0
    Private->RunningCode = Private->EOFCode + 1;
1052
0
    Private->RunningBits = Private->BitsPerPixel + 1;
1053
0
    Private->MaxCode1 = 1 << Private->RunningBits;
1054
0
  }
1055
1056
0
  return GIF_OK;
1057
0
}
1058
1059
/******************************************************************************
1060
 The LZ decompression input routine:
1061
 This routine is responsable for the decompression of the bit stream from
1062
 8 bits (bytes) packets, into the real codes.
1063
 Returns GIF_OK if read successfully.
1064
******************************************************************************/
1065
658k
static int DGifDecompressInput(GifFileType *GifFile, int *Code) {
1066
658k
  static const unsigned short CodeMasks[] = {
1067
658k
      0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f,
1068
658k
      0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff};
1069
1070
658k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
1071
1072
658k
  GifByteType NextByte;
1073
1074
  /* The image can't contain more than LZ_BITS per code. */
1075
658k
  if (Private->RunningBits > LZ_BITS) {
1076
0
    GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1077
0
    return GIF_ERROR;
1078
0
  }
1079
1080
1.19M
  while (Private->CrntShiftState < Private->RunningBits) {
1081
    /* Needs to get more bytes from input stream for next code: */
1082
534k
    if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) ==
1083
534k
        GIF_ERROR) {
1084
231
      return GIF_ERROR;
1085
231
    }
1086
534k
    Private->CrntShiftDWord |= ((unsigned long)NextByte)
1087
534k
                               << Private->CrntShiftState;
1088
534k
    Private->CrntShiftState += 8;
1089
534k
  }
1090
658k
  *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
1091
1092
658k
  Private->CrntShiftDWord >>= Private->RunningBits;
1093
658k
  Private->CrntShiftState -= Private->RunningBits;
1094
1095
  /* If code cannot fit into RunningBits bits, must raise its size. Note
1096
   * however that codes above 4095 are used for special signaling.
1097
   * If we're using LZ_BITS bits already and we're at the max code, just
1098
   * keep using the table as it is, don't increment Private->RunningCode.
1099
   */
1100
658k
  if (Private->RunningCode < LZ_MAX_CODE + 2 &&
1101
658k
      ++Private->RunningCode > Private->MaxCode1 &&
1102
658k
      Private->RunningBits < LZ_BITS) {
1103
213k
    Private->MaxCode1 <<= 1;
1104
213k
    Private->RunningBits++;
1105
213k
  }
1106
658k
  return GIF_OK;
1107
658k
}
1108
1109
/******************************************************************************
1110
 This routines read one GIF data block at a time and buffers it internally
1111
 so that the decompression routine could access it.
1112
 The routine returns the next byte from its internal buffer (or read next
1113
 block in if buffer empty) and returns GIF_OK if succesful.
1114
******************************************************************************/
1115
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
1116
534k
                             GifByteType *NextByte) {
1117
534k
  if (Buf[0] == 0) {
1118
    /* Needs to read the next buffer - this one is empty: */
1119
    /* coverity[check_return] */
1120
43.5k
    if (InternalRead(GifFile, Buf, 1) != 1) {
1121
71
      GifFile->Error = D_GIF_ERR_READ_FAILED;
1122
71
      return GIF_ERROR;
1123
71
    }
1124
    /* There shouldn't be any empty data blocks here as the LZW spec
1125
     * says the LZW termination code should come first.  Therefore
1126
     * we shouldn't be inside this routine at that point.
1127
     */
1128
43.5k
    if (Buf[0] == 0) {
1129
65
      GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1130
65
      return GIF_ERROR;
1131
65
    }
1132
43.4k
    if (InternalRead(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1133
95
      GifFile->Error = D_GIF_ERR_READ_FAILED;
1134
95
      return GIF_ERROR;
1135
95
    }
1136
43.3k
    *NextByte = Buf[1];
1137
43.3k
    Buf[1] = 2; /* We use now the second place as last char read! */
1138
43.3k
    Buf[0]--;
1139
491k
  } else {
1140
491k
    *NextByte = Buf[Buf[1]++];
1141
491k
    Buf[0]--;
1142
491k
  }
1143
1144
534k
  return GIF_OK;
1145
534k
}
1146
1147
/******************************************************************************
1148
 This routine is called in case of error during parsing image. We need to
1149
 decrease image counter and reallocate memory for saved images. Not decreasing
1150
 ImageCount may lead to null pointer dereference, because the last element in
1151
 SavedImages may point to the spoilt image and null pointer buffers.
1152
*******************************************************************************/
1153
421
void DGifDecreaseImageCounter(GifFileType *GifFile) {
1154
421
  GifFile->ImageCount--;
1155
421
  if (GifFile->SavedImages[GifFile->ImageCount].RasterBits != NULL) {
1156
337
    free(GifFile->SavedImages[GifFile->ImageCount].RasterBits);
1157
337
  }
1158
1159
  // Realloc array according to the new image counter.
1160
421
  SavedImage *correct_saved_images = (SavedImage *)reallocarray(
1161
421
      GifFile->SavedImages, GifFile->ImageCount, sizeof(SavedImage));
1162
421
  if (correct_saved_images != NULL) {
1163
30
    GifFile->SavedImages = correct_saved_images;
1164
30
  }
1165
421
}
1166
1167
/******************************************************************************
1168
 This routine reads an entire GIF into core, hanging all its state info off
1169
 the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
1170
 first to initialize I/O.  Its inverse is EGifSpew().
1171
*******************************************************************************/
1172
942
int DGifSlurp(GifFileType *GifFile) {
1173
942
  size_t ImageSize;
1174
942
  GifRecordType RecordType;
1175
942
  SavedImage *sp;
1176
942
  GifByteType *ExtData;
1177
942
  int ExtFunction;
1178
1179
942
  GifFile->ExtensionBlocks = NULL;
1180
942
  GifFile->ExtensionBlockCount = 0;
1181
1182
40.8k
  do {
1183
40.8k
    if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
1184
115
      return (GIF_ERROR);
1185
115
    }
1186
1187
40.7k
    switch (RecordType) {
1188
37.0k
    case IMAGE_DESC_RECORD_TYPE:
1189
37.0k
      if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
1190
89
        return (GIF_ERROR);
1191
89
      }
1192
1193
36.9k
      sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1194
      /* Allocate memory for the image */
1195
36.9k
      if (sp->ImageDesc.Width <= 0 ||
1196
36.9k
          sp->ImageDesc.Height <= 0 ||
1197
36.9k
          sp->ImageDesc.Width >
1198
36.8k
              (INT_MAX / sp->ImageDesc.Height)) {
1199
84
        DGifDecreaseImageCounter(GifFile);
1200
84
        return GIF_ERROR;
1201
84
      }
1202
36.8k
      ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1203
1204
36.8k
      if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1205
0
        DGifDecreaseImageCounter(GifFile);
1206
0
        return GIF_ERROR;
1207
0
      }
1208
36.8k
      sp->RasterBits = (unsigned char *)reallocarray(
1209
36.8k
          NULL, ImageSize, sizeof(GifPixelType));
1210
1211
36.8k
      if (sp->RasterBits == NULL) {
1212
0
        DGifDecreaseImageCounter(GifFile);
1213
0
        return GIF_ERROR;
1214
0
      }
1215
1216
36.8k
      if (sp->ImageDesc.Interlace) {
1217
35.0k
        int i, j;
1218
        /*
1219
         * The way an interlaced image should be read -
1220
         * offsets and jumps...
1221
         */
1222
35.0k
        static const int InterlacedOffset[] = {0, 4, 2,
1223
35.0k
                                               1};
1224
35.0k
        static const int InterlacedJumps[] = {8, 8, 4,
1225
35.0k
                                              2};
1226
        /* Need to perform 4 passes on the image */
1227
174k
        for (i = 0; i < 4; i++) {
1228
139k
          for (j = InterlacedOffset[i];
1229
814k
               j < sp->ImageDesc.Height;
1230
674k
               j += InterlacedJumps[i]) {
1231
674k
            if (DGifGetLine(
1232
674k
                    GifFile,
1233
674k
                    sp->RasterBits +
1234
674k
                        j * sp->ImageDesc
1235
674k
                                .Width,
1236
674k
                    sp->ImageDesc.Width) ==
1237
674k
                GIF_ERROR) {
1238
151
              DGifDecreaseImageCounter(
1239
151
                  GifFile);
1240
151
              return GIF_ERROR;
1241
151
            }
1242
674k
          }
1243
139k
        }
1244
35.0k
      } else {
1245
1.78k
        if (DGifGetLine(GifFile, sp->RasterBits,
1246
1.78k
                        ImageSize) == GIF_ERROR) {
1247
186
          DGifDecreaseImageCounter(GifFile);
1248
186
          return GIF_ERROR;
1249
186
        }
1250
1.78k
      }
1251
1252
36.5k
      if (GifFile->ExtensionBlocks) {
1253
1.02k
        sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1254
1.02k
        sp->ExtensionBlockCount =
1255
1.02k
            GifFile->ExtensionBlockCount;
1256
1257
1.02k
        GifFile->ExtensionBlocks = NULL;
1258
1.02k
        GifFile->ExtensionBlockCount = 0;
1259
1.02k
      }
1260
36.5k
      break;
1261
1262
3.45k
    case EXTENSION_RECORD_TYPE:
1263
3.45k
      if (DGifGetExtension(GifFile, &ExtFunction, &ExtData) ==
1264
3.45k
          GIF_ERROR) {
1265
11
        return (GIF_ERROR);
1266
11
      }
1267
      /* Create an extension block with our data */
1268
3.44k
      if (ExtData != NULL) {
1269
2.31k
        if (GifAddExtensionBlock(
1270
2.31k
                &GifFile->ExtensionBlockCount,
1271
2.31k
                &GifFile->ExtensionBlocks, ExtFunction,
1272
2.31k
                ExtData[0], &ExtData[1]) == GIF_ERROR) {
1273
0
          return (GIF_ERROR);
1274
0
        }
1275
2.31k
      }
1276
34.3k
      for (;;) {
1277
34.3k
        if (DGifGetExtensionNext(GifFile, &ExtData) ==
1278
34.3k
            GIF_ERROR) {
1279
105
          return (GIF_ERROR);
1280
105
        }
1281
34.2k
        if (ExtData == NULL) {
1282
3.34k
          break;
1283
3.34k
        }
1284
        /* Continue the extension block */
1285
30.9k
        if (GifAddExtensionBlock(
1286
30.9k
                &GifFile->ExtensionBlockCount,
1287
30.9k
                &GifFile->ExtensionBlocks,
1288
30.9k
                CONTINUE_EXT_FUNC_CODE, ExtData[0],
1289
30.9k
                &ExtData[1]) == GIF_ERROR) {
1290
0
          return (GIF_ERROR);
1291
0
        }
1292
30.9k
      }
1293
3.34k
      break;
1294
1295
3.34k
    case TERMINATE_RECORD_TYPE:
1296
201
      break;
1297
1298
0
    default: /* Should be trapped by DGifGetRecordType */
1299
0
      break;
1300
40.7k
    }
1301
40.7k
  } while (RecordType != TERMINATE_RECORD_TYPE);
1302
1303
  /* Sanity check for corrupted file */
1304
201
  if (GifFile->ImageCount == 0) {
1305
84
    GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
1306
84
    return (GIF_ERROR);
1307
84
  }
1308
1309
117
  return (GIF_OK);
1310
201
}
1311
1312
/* end */