Coverage Report

Created: 2026-09-25 06:53

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