Coverage Report

Created: 2025-09-04 06:28

/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
331k
#define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
31
32
/* avoid extra function call in case we use fread (TVT) */
33
1.03M
static int InternalRead(GifFileType *gif, GifByteType *buf, int len) {
34
  // fprintf(stderr, "### Read: %d\n", len);
35
1.03M
  return (((GifFilePrivateType *)gif->Private)->Read
36
1.03M
              ? ((GifFilePrivateType *)gif->Private)->Read(gif, buf, len)
37
1.03M
              : fread(buf, 1, len,
38
0
                      ((GifFilePrivateType *)gif->Private)->File));
39
1.03M
}
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
1.93k
GifFileType *DGifOpen(void *userData, InputFunc readFunc, int *Error) {
168
1.93k
  char Buf[GIF_STAMP_LEN + 1];
169
1.93k
  GifFileType *GifFile;
170
1.93k
  GifFilePrivateType *Private;
171
172
1.93k
  GifFile = (GifFileType *)malloc(sizeof(GifFileType));
173
1.93k
  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
1.93k
  memset(GifFile, '\0', sizeof(GifFileType));
181
182
  /* Belt and suspenders, in case the null pointer isn't zero */
183
1.93k
  GifFile->SavedImages = NULL;
184
1.93k
  GifFile->SColorMap = NULL;
185
186
1.93k
  Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
187
1.93k
  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
1.93k
  /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType));
195
196
1.93k
  GifFile->Private = (void *)Private;
197
1.93k
  Private->FileHandle = 0;
198
1.93k
  Private->File = NULL;
199
1.93k
  Private->FileState = FILE_STATE_READ;
200
201
1.93k
  Private->Read = readFunc;     /* TVT */
202
1.93k
  GifFile->UserData = userData; /* TVT */
203
204
  /* Lets see if this is a GIF file: */
205
  /* coverity[check_return] */
206
1.93k
  if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) !=
207
1.93k
      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
1.92k
  Buf[GIF_STAMP_LEN] = '\0';
218
1.92k
  if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
219
35
    if (Error != NULL) {
220
35
      *Error = D_GIF_ERR_NOT_GIF_FILE;
221
35
    }
222
35
    free((char *)Private);
223
35
    free((char *)GifFile);
224
35
    return NULL;
225
35
  }
226
227
1.89k
  if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
228
49
    free((char *)Private);
229
49
    free((char *)GifFile);
230
49
    if (Error != NULL) {
231
49
      *Error = D_GIF_ERR_NO_SCRN_DSCR;
232
49
    }
233
49
    return NULL;
234
49
  }
235
236
1.84k
  GifFile->Error = 0;
237
238
  /* What version of GIF? */
239
1.84k
  Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9');
240
241
1.84k
  return GifFile;
242
1.89k
}
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.89k
int DGifGetScreenDesc(GifFileType *GifFile) {
249
1.89k
  int BitsPerPixel;
250
1.89k
  bool SortFlag;
251
1.89k
  GifByteType Buf[3];
252
1.89k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
253
254
1.89k
  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.89k
  if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
262
1.89k
      DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) {
263
4
    return GIF_ERROR;
264
4
  }
265
266
1.88k
  if (InternalRead(GifFile, Buf, 3) != 3) {
267
7
    GifFile->Error = D_GIF_ERR_READ_FAILED;
268
7
    GifFreeMapObject(GifFile->SColorMap);
269
7
    GifFile->SColorMap = NULL;
270
7
    return GIF_ERROR;
271
7
  }
272
1.88k
  GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
273
1.88k
  SortFlag = (Buf[0] & 0x08) != 0;
274
1.88k
  BitsPerPixel = (Buf[0] & 0x07) + 1;
275
1.88k
  GifFile->SBackGroundColor = Buf[1];
276
1.88k
  GifFile->AspectByte = Buf[2];
277
1.88k
  if (Buf[0] & 0x80) { /* Do we have global color map? */
278
135
    int i;
279
280
135
    GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
281
135
    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
135
    GifFile->SColorMap->SortFlag = SortFlag;
288
1.60k
    for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
289
      /* coverity[check_return] */
290
1.51k
      if (InternalRead(GifFile, Buf, 3) != 3) {
291
38
        GifFreeMapObject(GifFile->SColorMap);
292
38
        GifFile->SColorMap = NULL;
293
38
        GifFile->Error = D_GIF_ERR_READ_FAILED;
294
38
        return GIF_ERROR;
295
38
      }
296
1.47k
      GifFile->SColorMap->Colors[i].Red = Buf[0];
297
1.47k
      GifFile->SColorMap->Colors[i].Green = Buf[1];
298
1.47k
      GifFile->SColorMap->Colors[i].Blue = Buf[2];
299
1.47k
    }
300
1.74k
  } else {
301
1.74k
    GifFile->SColorMap = NULL;
302
1.74k
  }
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.84k
  return GIF_OK;
310
1.88k
}
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
92.4k
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type) {
326
92.4k
  GifByteType Buf;
327
92.4k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
328
329
92.4k
  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
92.4k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
337
83
    GifFile->Error = D_GIF_ERR_READ_FAILED;
338
83
    return GIF_ERROR;
339
83
  }
340
341
  // fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf);
342
92.3k
  switch (Buf) {
343
81.2k
  case DESCRIPTOR_INTRODUCER:
344
81.2k
    *Type = IMAGE_DESC_RECORD_TYPE;
345
81.2k
    break;
346
10.7k
  case EXTENSION_INTRODUCER:
347
10.7k
    *Type = EXTENSION_RECORD_TYPE;
348
10.7k
    break;
349
308
  case TERMINATOR_INTRODUCER:
350
308
    *Type = TERMINATE_RECORD_TYPE;
351
308
    break;
352
128
  default:
353
128
    *Type = UNDEFINED_RECORD_TYPE;
354
128
    GifFile->Error = D_GIF_ERR_WRONG_RECORD;
355
128
    return GIF_ERROR;
356
92.3k
  }
357
358
92.2k
  return GIF_OK;
359
92.3k
}
360
361
81.2k
int DGifGetImageHeader(GifFileType *GifFile) {
362
81.2k
  unsigned int BitsPerPixel;
363
81.2k
  GifByteType Buf[3];
364
81.2k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
365
366
81.2k
  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
81.2k
  if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
373
81.2k
      DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
374
81.2k
      DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
375
81.2k
      DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) {
376
45
    return GIF_ERROR;
377
45
  }
378
81.1k
  if (InternalRead(GifFile, Buf, 1) != 1) {
379
9
    GifFile->Error = D_GIF_ERR_READ_FAILED;
380
9
    GifFreeMapObject(GifFile->Image.ColorMap);
381
9
    GifFile->Image.ColorMap = NULL;
382
9
    return GIF_ERROR;
383
9
  }
384
81.1k
  BitsPerPixel = (Buf[0] & 0x07) + 1;
385
81.1k
  GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
386
387
  /* Setup the colormap */
388
81.1k
  if (GifFile->Image.ColorMap) {
389
1.30k
    GifFreeMapObject(GifFile->Image.ColorMap);
390
1.30k
    GifFile->Image.ColorMap = NULL;
391
1.30k
  }
392
  /* Does this image have local color map? */
393
81.1k
  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
6.09k
    for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
405
      /* coverity[check_return] */
406
4.73k
      if (InternalRead(GifFile, Buf, 3) != 3) {
407
61
        GifFreeMapObject(GifFile->Image.ColorMap);
408
61
        GifFile->Error = D_GIF_ERR_READ_FAILED;
409
61
        GifFile->Image.ColorMap = NULL;
410
61
        return GIF_ERROR;
411
61
      }
412
4.67k
      GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
413
4.67k
      GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
414
4.67k
      GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
415
4.67k
    }
416
1.42k
  }
417
418
81.1k
  Private->PixelCount =
419
81.1k
      (long)GifFile->Image.Width * (long)GifFile->Image.Height;
420
421
  /* Reset decompress algorithm parameters. */
422
81.1k
  return DGifSetupDecompress(GifFile);
423
81.1k
}
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
81.2k
int DGifGetImageDesc(GifFileType *GifFile) {
430
81.2k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
431
81.2k
  SavedImage *sp;
432
433
81.2k
  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
81.2k
  if (DGifGetImageHeader(GifFile) == GIF_ERROR) {
440
199
    return GIF_ERROR;
441
199
  }
442
443
81.0k
  if (GifFile->SavedImages) {
444
79.7k
    SavedImage *new_saved_images = (SavedImage *)reallocarray(
445
79.7k
        GifFile->SavedImages, (GifFile->ImageCount + 1),
446
79.7k
        sizeof(SavedImage));
447
79.7k
    if (new_saved_images == NULL) {
448
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
449
0
      return GIF_ERROR;
450
0
    }
451
79.7k
    GifFile->SavedImages = new_saved_images;
452
79.7k
  } else {
453
1.30k
    if ((GifFile->SavedImages =
454
1.30k
             (SavedImage *)malloc(sizeof(SavedImage))) == NULL) {
455
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
456
0
      return GIF_ERROR;
457
0
    }
458
1.30k
  }
459
460
81.0k
  sp = &GifFile->SavedImages[GifFile->ImageCount];
461
81.0k
  memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
462
81.0k
  if (GifFile->Image.ColorMap != NULL) {
463
1.34k
    sp->ImageDesc.ColorMap =
464
1.34k
        GifMakeMapObject(GifFile->Image.ColorMap->ColorCount,
465
1.34k
                         GifFile->Image.ColorMap->Colors);
466
1.34k
    if (sp->ImageDesc.ColorMap == NULL) {
467
0
      GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
468
0
      return GIF_ERROR;
469
0
    }
470
1.34k
  }
471
81.0k
  sp->RasterBits = (unsigned char *)NULL;
472
81.0k
  sp->ExtensionBlockCount = 0;
473
81.0k
  sp->ExtensionBlocks = (ExtensionBlock *)NULL;
474
475
81.0k
  GifFile->ImageCount++;
476
477
81.0k
  return GIF_OK;
478
81.0k
}
479
480
/******************************************************************************
481
 Get one full scanned line (Line) of length LineLen from GIF file.
482
******************************************************************************/
483
732k
int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) {
484
732k
  GifByteType *Dummy;
485
732k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
486
487
732k
  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
732k
  if (!LineLen) {
494
0
    LineLen = GifFile->Image.Width;
495
0
  }
496
497
732k
  if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
498
0
    GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
499
0
    return GIF_ERROR;
500
0
  }
501
502
732k
  if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
503
731k
    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
84.5k
      do {
510
84.5k
        if (DGifGetCodeNext(GifFile, &Dummy) ==
511
84.5k
            GIF_ERROR) {
512
43
          return GIF_ERROR;
513
43
        }
514
84.5k
      } while (Dummy != NULL);
515
80.1k
    }
516
731k
    return GIF_OK;
517
731k
  } else {
518
768
    return GIF_ERROR;
519
768
  }
520
732k
}
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
10.7k
                     GifByteType **Extension) {
568
10.7k
  GifByteType Buf;
569
10.7k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
570
571
  // fprintf(stderr, "### -> DGifGetExtension:\n");
572
10.7k
  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
10.7k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
580
7
    GifFile->Error = D_GIF_ERR_READ_FAILED;
581
7
    return GIF_ERROR;
582
7
  }
583
10.7k
  *ExtCode = Buf;
584
  // fprintf(stderr, "### <- DGifGetExtension: %02x, about to call
585
  // next\n", Buf);
586
587
10.7k
  return DGifGetExtensionNext(GifFile, Extension);
588
10.7k
}
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
83.3k
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **Extension) {
596
83.3k
  GifByteType Buf;
597
83.3k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
598
599
  // fprintf(stderr, "### -> DGifGetExtensionNext\n");
600
83.3k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
601
59
    GifFile->Error = D_GIF_ERR_READ_FAILED;
602
59
    return GIF_ERROR;
603
59
  }
604
  // fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf);
605
606
83.3k
  if (Buf > 0) {
607
70.5k
    *Extension = Private->Buf; /* Use private unused buffer. */
608
70.5k
    (*Extension)[0] =
609
70.5k
        Buf; /* Pascal strings notation (pos. 0 is len.). */
610
             /* coverity[tainted_data,check_return] */
611
70.5k
    if (InternalRead(GifFile, &((*Extension)[1]), Buf) != Buf) {
612
146
      GifFile->Error = D_GIF_ERR_READ_FAILED;
613
146
      return GIF_ERROR;
614
146
    }
615
70.5k
  } else {
616
12.8k
    *Extension = NULL;
617
12.8k
  }
618
  // fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension);
619
620
83.1k
  return GIF_OK;
621
83.3k
}
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
3.72k
                       GraphicsControlBlock *GCB) {
630
3.72k
  if (GifExtensionLength != 4) {
631
670
    return GIF_ERROR;
632
670
  }
633
634
3.05k
  GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
635
3.05k
  GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
636
3.05k
  GCB->DelayTime =
637
3.05k
      UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
638
3.05k
  if (GifExtension[0] & 0x01) {
639
833
    GCB->TransparentColor = (int)GifExtension[3];
640
2.21k
  } else {
641
2.21k
    GCB->TransparentColor = NO_TRANSPARENT_COLOR;
642
2.21k
  }
643
644
3.05k
  return GIF_OK;
645
3.72k
}
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
70.6k
                            GraphicsControlBlock *GCB) {
653
70.6k
  int i;
654
655
70.6k
  if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) {
656
0
    return GIF_ERROR;
657
0
  }
658
659
70.6k
  GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
660
70.6k
  GCB->UserInputFlag = false;
661
70.6k
  GCB->DelayTime = 0;
662
70.6k
  GCB->TransparentColor = NO_TRANSPARENT_COLOR;
663
664
105k
  for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount;
665
70.6k
       i++) {
666
38.2k
    ExtensionBlock *ep =
667
38.2k
        &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
668
38.2k
    if (ep->Function == GRAPHICS_EXT_FUNC_CODE) {
669
3.72k
      return DGifExtensionToGCB(ep->ByteCount, ep->Bytes,
670
3.72k
                                GCB);
671
3.72k
    }
672
38.2k
  }
673
674
66.9k
  return GIF_ERROR;
675
70.6k
}
676
677
/******************************************************************************
678
 This routine should be called last, to close the GIF file.
679
******************************************************************************/
680
1.84k
int DGifCloseFile(GifFileType *GifFile, int *ErrorCode) {
681
1.84k
  GifFilePrivateType *Private;
682
683
1.84k
  if (GifFile == NULL || GifFile->Private == NULL) {
684
0
    return GIF_ERROR;
685
0
  }
686
687
1.84k
  if (GifFile->Image.ColorMap) {
688
53
    GifFreeMapObject(GifFile->Image.ColorMap);
689
53
    GifFile->Image.ColorMap = NULL;
690
53
  }
691
692
1.84k
  if (GifFile->SColorMap) {
693
97
    GifFreeMapObject(GifFile->SColorMap);
694
97
    GifFile->SColorMap = NULL;
695
97
  }
696
697
1.84k
  if (GifFile->SavedImages) {
698
1.30k
    GifFreeSavedImages(GifFile);
699
1.30k
    GifFile->SavedImages = NULL;
700
1.30k
  }
701
702
1.84k
  GifFreeExtensions(&GifFile->ExtensionBlockCount,
703
1.84k
                    &GifFile->ExtensionBlocks);
704
705
1.84k
  Private = (GifFilePrivateType *)GifFile->Private;
706
707
1.84k
  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
1.84k
  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
1.84k
  free((char *)GifFile->Private);
727
1.84k
  free(GifFile);
728
1.84k
  if (ErrorCode != NULL) {
729
1.84k
    *ErrorCode = D_GIF_SUCCEEDED;
730
1.84k
  }
731
1.84k
  return GIF_OK;
732
1.84k
}
733
734
/******************************************************************************
735
 Get 2 bytes (word) from the given file:
736
******************************************************************************/
737
328k
static int DGifGetWord(GifFileType *GifFile, GifWord *Word) {
738
328k
  unsigned char c[2];
739
740
  /* coverity[check_return] */
741
328k
  if (InternalRead(GifFile, c, 2) != 2) {
742
49
    GifFile->Error = D_GIF_ERR_READ_FAILED;
743
49
    return GIF_ERROR;
744
49
  }
745
746
328k
  *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
747
328k
  return GIF_OK;
748
328k
}
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
84.5k
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock) {
777
84.5k
  GifByteType Buf;
778
84.5k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
779
780
  /* coverity[tainted_data_argument] */
781
  /* coverity[check_return] */
782
84.5k
  if (InternalRead(GifFile, &Buf, 1) != 1) {
783
16
    GifFile->Error = D_GIF_ERR_READ_FAILED;
784
16
    return GIF_ERROR;
785
16
  }
786
787
  /* coverity[lower_bounds] */
788
84.5k
  if (Buf > 0) {
789
4.45k
    *CodeBlock = Private->Buf; /* Use private unused buffer. */
790
4.45k
    (*CodeBlock)[0] =
791
4.45k
        Buf; /* Pascal strings notation (pos. 0 is len.). */
792
             /* coverity[tainted_data] */
793
4.45k
    if (InternalRead(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
794
27
      GifFile->Error = D_GIF_ERR_READ_FAILED;
795
27
      return GIF_ERROR;
796
27
    }
797
80.1k
  } else {
798
80.1k
    *CodeBlock = NULL;
799
80.1k
    Private->Buf[0] = 0; /* Make sure the buffer is empty! */
800
80.1k
    Private->PixelCount =
801
80.1k
        0; /* And local info. indicate image read. */
802
80.1k
  }
803
804
84.5k
  return GIF_OK;
805
84.5k
}
806
807
/******************************************************************************
808
 Setup the LZ decompression for this image:
809
******************************************************************************/
810
81.1k
static int DGifSetupDecompress(GifFileType *GifFile) {
811
81.1k
  int i, BitsPerPixel;
812
81.1k
  GifByteType CodeSize;
813
81.1k
  GifPrefixType *Prefix;
814
81.1k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
815
816
  /* coverity[check_return] */
817
81.1k
  if (InternalRead(GifFile, &CodeSize, 1) <
818
81.1k
      1) { /* Read Code size from file. */
819
32
    GifFile->Error = D_GIF_ERR_READ_FAILED;
820
32
    return GIF_ERROR; /* Failed to read Code size. */
821
32
  }
822
81.0k
  BitsPerPixel = CodeSize;
823
824
  /* this can only happen on a severely malformed GIF */
825
81.0k
  if (BitsPerPixel > 8) {
826
52
    GifFile->Error =
827
52
        D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
828
52
    return GIF_ERROR;          /* Failed to read Code size. */
829
52
  }
830
831
81.0k
  Private->Buf[0] = 0; /* Input Buffer empty. */
832
81.0k
  Private->BitsPerPixel = BitsPerPixel;
833
81.0k
  Private->ClearCode = (1 << BitsPerPixel);
834
81.0k
  Private->EOFCode = Private->ClearCode + 1;
835
81.0k
  Private->RunningCode = Private->EOFCode + 1;
836
81.0k
  Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
837
81.0k
  Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
838
81.0k
  Private->StackPtr = 0; /* No pixels on the pixel stack. */
839
81.0k
  Private->LastCode = NO_SUCH_CODE;
840
81.0k
  Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
841
81.0k
  Private->CrntShiftDWord = 0;
842
843
81.0k
  Prefix = Private->Prefix;
844
331M
  for (i = 0; i <= LZ_MAX_CODE; i++) {
845
331M
    Prefix[i] = NO_SUCH_CODE;
846
331M
  }
847
848
81.0k
  return GIF_OK;
849
81.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
732k
                              int LineLen) {
859
732k
  int i = 0;
860
732k
  int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
861
732k
  GifByteType *Stack, *Suffix;
862
732k
  GifPrefixType *Prefix;
863
732k
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
864
865
732k
  StackPtr = Private->StackPtr;
866
732k
  Prefix = Private->Prefix;
867
732k
  Suffix = Private->Suffix;
868
732k
  Stack = Private->Stack;
869
732k
  EOFCode = Private->EOFCode;
870
732k
  ClearCode = Private->ClearCode;
871
732k
  LastCode = Private->LastCode;
872
873
732k
  if (StackPtr > LZ_MAX_CODE) {
874
0
    return GIF_ERROR;
875
0
  }
876
877
732k
  if (StackPtr != 0) {
878
    /* Let pop the stack off before continueing to read the GIF
879
     * file: */
880
946k
    while (StackPtr != 0 && i < LineLen) {
881
526k
      Line[i++] = Stack[--StackPtr];
882
526k
    }
883
420k
  }
884
885
2.04M
  while (i < LineLen) { /* Decode LineLen items. */
886
1.31M
    if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) {
887
583
      return GIF_ERROR;
888
583
    }
889
890
1.31M
    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
29
      GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
896
29
      return GIF_ERROR;
897
1.31M
    } else if (CrntCode == ClearCode) {
898
      /* We need to start over again: */
899
876M
      for (j = 0; j <= LZ_MAX_CODE; j++) {
900
875M
        Prefix[j] = NO_SUCH_CODE;
901
875M
      }
902
213k
      Private->RunningCode = Private->EOFCode + 1;
903
213k
      Private->RunningBits = Private->BitsPerPixel + 1;
904
213k
      Private->MaxCode1 = 1 << Private->RunningBits;
905
213k
      LastCode = Private->LastCode = NO_SUCH_CODE;
906
1.09M
    } 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
1.09M
      if (CrntCode < ClearCode) {
911
        /* This is simple - its pixel scalar, so add it
912
         * to output: */
913
489k
        Line[i++] = CrntCode;
914
608k
      } 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
608k
        if (Prefix[CrntCode] == NO_SUCH_CODE) {
921
213k
          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
213k
          if (CrntCode ==
930
213k
              Private->RunningCode - 2) {
931
66.8k
            Suffix[Private->RunningCode -
932
66.8k
                   2] = Stack[StackPtr++] =
933
66.8k
                DGifGetPrefixChar(
934
66.8k
                    Prefix, LastCode,
935
66.8k
                    ClearCode);
936
146k
          } else {
937
146k
            Suffix[Private->RunningCode -
938
146k
                   2] = Stack[StackPtr++] =
939
146k
                DGifGetPrefixChar(
940
146k
                    Prefix, CrntCode,
941
146k
                    ClearCode);
942
146k
          }
943
395k
        } else {
944
395k
          CrntPrefix = CrntCode;
945
395k
        }
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
2.65M
        while (StackPtr < LZ_MAX_CODE &&
953
2.65M
               CrntPrefix > ClearCode &&
954
2.65M
               CrntPrefix <= LZ_MAX_CODE) {
955
2.04M
          Stack[StackPtr++] = Suffix[CrntPrefix];
956
2.04M
          CrntPrefix = Prefix[CrntPrefix];
957
2.04M
        }
958
608k
        if (StackPtr >= LZ_MAX_CODE ||
959
608k
            CrntPrefix > LZ_MAX_CODE) {
960
156
          GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
961
156
          return GIF_ERROR;
962
156
        }
963
        /* Push the last character on stack: */
964
608k
        Stack[StackPtr++] = CrntPrefix;
965
966
        /* Now lets pop all the stack into output: */
967
2.91M
        while (StackPtr != 0 && i < LineLen) {
968
2.30M
          Line[i++] = Stack[--StackPtr];
969
2.30M
        }
970
608k
      }
971
1.09M
      if (LastCode != NO_SUCH_CODE &&
972
1.09M
          Private->RunningCode - 2 < (LZ_MAX_CODE + 1) &&
973
1.09M
          Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
974
934k
        Prefix[Private->RunningCode - 2] = LastCode;
975
976
934k
        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
66.8k
          Suffix[Private->RunningCode - 2] =
984
66.8k
              DGifGetPrefixChar(Prefix, LastCode,
985
66.8k
                                ClearCode);
986
867k
        } else {
987
867k
          Suffix[Private->RunningCode - 2] =
988
867k
              DGifGetPrefixChar(Prefix, CrntCode,
989
867k
                                ClearCode);
990
867k
        }
991
934k
      }
992
1.09M
      LastCode = CrntCode;
993
1.09M
    }
994
1.31M
  }
995
996
731k
  Private->LastCode = LastCode;
997
731k
  Private->StackPtr = StackPtr;
998
999
731k
  return GIF_OK;
1000
732k
}
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
1.14M
                             int ClearCode) {
1010
1.14M
  int i = 0;
1011
1012
3.59M
  while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
1013
2.73M
    if (Code > LZ_MAX_CODE) {
1014
292k
      return NO_SUCH_CODE;
1015
292k
    }
1016
2.44M
    Code = Prefix[Code];
1017
2.44M
  }
1018
855k
  return Code;
1019
1.14M
}
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
1.31M
static int DGifDecompressInput(GifFileType *GifFile, int *Code) {
1066
1.31M
  static const unsigned short CodeMasks[] = {
1067
1.31M
      0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f,
1068
1.31M
      0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff};
1069
1070
1.31M
  GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
1071
1072
1.31M
  GifByteType NextByte;
1073
1074
  /* The image can't contain more than LZ_BITS per code. */
1075
1.31M
  if (Private->RunningBits > LZ_BITS) {
1076
0
    GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1077
0
    return GIF_ERROR;
1078
0
  }
1079
1080
2.55M
  while (Private->CrntShiftState < Private->RunningBits) {
1081
    /* Needs to get more bytes from input stream for next code: */
1082
1.24M
    if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) ==
1083
1.24M
        GIF_ERROR) {
1084
583
      return GIF_ERROR;
1085
583
    }
1086
1.24M
    Private->CrntShiftDWord |= ((unsigned long)NextByte)
1087
1.24M
                               << Private->CrntShiftState;
1088
1.24M
    Private->CrntShiftState += 8;
1089
1.24M
  }
1090
1.31M
  *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
1091
1092
1.31M
  Private->CrntShiftDWord >>= Private->RunningBits;
1093
1.31M
  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
1.31M
  if (Private->RunningCode < LZ_MAX_CODE + 2 &&
1101
1.31M
      ++Private->RunningCode > Private->MaxCode1 &&
1102
1.31M
      Private->RunningBits < LZ_BITS) {
1103
375k
    Private->MaxCode1 <<= 1;
1104
375k
    Private->RunningBits++;
1105
375k
  }
1106
1.31M
  return GIF_OK;
1107
1.31M
}
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
1.24M
                             GifByteType *NextByte) {
1117
1.24M
  if (Buf[0] == 0) {
1118
    /* Needs to read the next buffer - this one is empty: */
1119
    /* coverity[check_return] */
1120
91.7k
    if (InternalRead(GifFile, Buf, 1) != 1) {
1121
391
      GifFile->Error = D_GIF_ERR_READ_FAILED;
1122
391
      return GIF_ERROR;
1123
391
    }
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
91.3k
    if (Buf[0] == 0) {
1129
68
      GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1130
68
      return GIF_ERROR;
1131
68
    }
1132
91.3k
    if (InternalRead(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1133
124
      GifFile->Error = D_GIF_ERR_READ_FAILED;
1134
124
      return GIF_ERROR;
1135
124
    }
1136
91.1k
    *NextByte = Buf[1];
1137
91.1k
    Buf[1] = 2; /* We use now the second place as last char read! */
1138
91.1k
    Buf[0]--;
1139
1.15M
  } else {
1140
1.15M
    *NextByte = Buf[Buf[1]++];
1141
1.15M
    Buf[0]--;
1142
1.15M
  }
1143
1144
1.24M
  return GIF_OK;
1145
1.24M
}
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
914
void DGifDecreaseImageCounter(GifFileType *GifFile) {
1154
914
  GifFile->ImageCount--;
1155
914
  if (GifFile->SavedImages[GifFile->ImageCount].RasterBits != NULL) {
1156
811
    free(GifFile->SavedImages[GifFile->ImageCount].RasterBits);
1157
811
  }
1158
1159
  // Realloc array according to the new image counter.
1160
914
  SavedImage *correct_saved_images = (SavedImage *)reallocarray(
1161
914
      GifFile->SavedImages, GifFile->ImageCount, sizeof(SavedImage));
1162
914
  if (correct_saved_images != NULL) {
1163
75
    GifFile->SavedImages = correct_saved_images;
1164
75
  }
1165
914
}
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
1.84k
int DGifSlurp(GifFileType *GifFile) {
1173
1.84k
  size_t ImageSize;
1174
1.84k
  GifRecordType RecordType;
1175
1.84k
  SavedImage *sp;
1176
1.84k
  GifByteType *ExtData;
1177
1.84k
  int ExtFunction;
1178
1179
1.84k
  GifFile->ExtensionBlocks = NULL;
1180
1.84k
  GifFile->ExtensionBlockCount = 0;
1181
1182
92.4k
  do {
1183
92.4k
    if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
1184
211
      return (GIF_ERROR);
1185
211
    }
1186
1187
92.2k
    switch (RecordType) {
1188
81.2k
    case IMAGE_DESC_RECORD_TYPE:
1189
81.2k
      if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
1190
199
        return (GIF_ERROR);
1191
199
      }
1192
1193
81.0k
      sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1194
      /* Allocate memory for the image */
1195
81.0k
      if (sp->ImageDesc.Width <= 0 ||
1196
81.0k
          sp->ImageDesc.Height <= 0 ||
1197
81.0k
          sp->ImageDesc.Width >
1198
80.9k
              (INT_MAX / sp->ImageDesc.Height)) {
1199
103
        DGifDecreaseImageCounter(GifFile);
1200
103
        return GIF_ERROR;
1201
103
      }
1202
80.9k
      ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1203
1204
80.9k
      if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1205
0
        DGifDecreaseImageCounter(GifFile);
1206
0
        return GIF_ERROR;
1207
0
      }
1208
80.9k
      sp->RasterBits = (unsigned char *)reallocarray(
1209
80.9k
          NULL, ImageSize, sizeof(GifPixelType));
1210
1211
80.9k
      if (sp->RasterBits == NULL) {
1212
0
        DGifDecreaseImageCounter(GifFile);
1213
0
        return GIF_ERROR;
1214
0
      }
1215
1216
80.9k
      if (sp->ImageDesc.Interlace) {
1217
75.9k
        int i, j;
1218
        /*
1219
         * The way an interlaced image should be read -
1220
         * offsets and jumps...
1221
         */
1222
75.9k
        static const int InterlacedOffset[] = {0, 4, 2,
1223
75.9k
                                               1};
1224
75.9k
        static const int InterlacedJumps[] = {8, 8, 4,
1225
75.9k
                                              2};
1226
        /* Need to perform 4 passes on the image */
1227
378k
        for (i = 0; i < 4; i++) {
1228
302k
          for (j = InterlacedOffset[i];
1229
1.02M
               j < sp->ImageDesc.Height;
1230
727k
               j += InterlacedJumps[i]) {
1231
727k
            if (DGifGetLine(
1232
727k
                    GifFile,
1233
727k
                    sp->RasterBits +
1234
727k
                        j * sp->ImageDesc
1235
727k
                                .Width,
1236
727k
                    sp->ImageDesc.Width) ==
1237
727k
                GIF_ERROR) {
1238
392
              DGifDecreaseImageCounter(
1239
392
                  GifFile);
1240
392
              return GIF_ERROR;
1241
392
            }
1242
727k
          }
1243
302k
        }
1244
75.9k
      } else {
1245
4.97k
        if (DGifGetLine(GifFile, sp->RasterBits,
1246
4.97k
                        ImageSize) == GIF_ERROR) {
1247
419
          DGifDecreaseImageCounter(GifFile);
1248
419
          return GIF_ERROR;
1249
419
        }
1250
4.97k
      }
1251
1252
80.1k
      if (GifFile->ExtensionBlocks) {
1253
6.12k
        sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1254
6.12k
        sp->ExtensionBlockCount =
1255
6.12k
            GifFile->ExtensionBlockCount;
1256
1257
6.12k
        GifFile->ExtensionBlocks = NULL;
1258
6.12k
        GifFile->ExtensionBlockCount = 0;
1259
6.12k
      }
1260
80.1k
      break;
1261
1262
10.7k
    case EXTENSION_RECORD_TYPE:
1263
10.7k
      if (DGifGetExtension(GifFile, &ExtFunction, &ExtData) ==
1264
10.7k
          GIF_ERROR) {
1265
42
        return (GIF_ERROR);
1266
42
      }
1267
      /* Create an extension block with our data */
1268
10.6k
      if (ExtData != NULL) {
1269
8.38k
        if (GifAddExtensionBlock(
1270
8.38k
                &GifFile->ExtensionBlockCount,
1271
8.38k
                &GifFile->ExtensionBlocks, ExtFunction,
1272
8.38k
                ExtData[0], &ExtData[1]) == GIF_ERROR) {
1273
0
          return (GIF_ERROR);
1274
0
        }
1275
8.38k
      }
1276
72.6k
      for (;;) {
1277
72.6k
        if (DGifGetExtensionNext(GifFile, &ExtData) ==
1278
72.6k
            GIF_ERROR) {
1279
170
          return (GIF_ERROR);
1280
170
        }
1281
72.4k
        if (ExtData == NULL) {
1282
10.5k
          break;
1283
10.5k
        }
1284
        /* Continue the extension block */
1285
61.9k
        if (GifAddExtensionBlock(
1286
61.9k
                &GifFile->ExtensionBlockCount,
1287
61.9k
                &GifFile->ExtensionBlocks,
1288
61.9k
                CONTINUE_EXT_FUNC_CODE, ExtData[0],
1289
61.9k
                &ExtData[1]) == GIF_ERROR) {
1290
0
          return (GIF_ERROR);
1291
0
        }
1292
61.9k
      }
1293
10.5k
      break;
1294
1295
10.5k
    case TERMINATE_RECORD_TYPE:
1296
308
      break;
1297
1298
0
    default: /* Should be trapped by DGifGetRecordType */
1299
0
      break;
1300
92.2k
    }
1301
92.2k
  } while (RecordType != TERMINATE_RECORD_TYPE);
1302
1303
  /* Sanity check for corrupted file */
1304
308
  if (GifFile->ImageCount == 0) {
1305
78
    GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
1306
78
    return (GIF_ERROR);
1307
78
  }
1308
1309
230
  return (GIF_OK);
1310
308
}
1311
1312
/* end */