1
0

dgif_lib.c 41 KB

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