📄 dgif_lib.c
字号:
GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); /* Get the image local color map: */ for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) { if (READ(GifFile,Buf, 3) != 3) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } GifFile->Image.ColorMap->Colors[i].Red = Buf[0]; GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; } } if (GifFile->SavedImages) { if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount + 1))) == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } else { if ((GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage))) == NULL) { _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } sp = &GifFile->SavedImages[GifFile->ImageCount]; memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc)); if (GifFile->Image.ColorMap != NULL) { sp->ImageDesc.ColorMap = MakeMapObject( GifFile->Image.ColorMap->ColorCount, GifFile->Image.ColorMap->Colors ); } sp->RasterBits = (char *)NULL; sp->ExtensionBlockCount = 0; sp->ExtensionBlocks = (ExtensionBlock *)NULL; GifFile->ImageCount++; Private->PixelCount = (long) GifFile->Image.Width * (long) GifFile->Image.Height; DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ return GIF_OK;}/******************************************************************************* Get one full scanned line (Line) of length LineLen from GIF file. *******************************************************************************/int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen){ GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (!LineLen) LineLen = GifFile->Image.Width;#if defined(__MSDOS__) || defined(__GNUC__) if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {#else if ((Private->PixelCount -= LineLen) > 0xffff0000) {#endif /* __MSDOS__ */ _GifError = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { if (Private->PixelCount == 0) { /* We probably would not be called any more, so lets clean */ /* everything before we return: need to flush out all rest of */ /* image until empty block (size 0) detected. We use GetCodeNext.*/ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) return GIF_ERROR; while (Dummy != NULL); } return GIF_OK; } else return GIF_ERROR;}/******************************************************************************* Put one pixel (Pixel) into GIF file. *******************************************************************************/int DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel){ GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; }#if defined(__MSDOS__) || defined(__GNUC__) if (--Private->PixelCount > 0xffff0000UL)#else if (--Private->PixelCount > 0xffff0000)#endif /* __MSDOS__ */ { _GifError = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { if (Private->PixelCount == 0) { /* We probably would not be called any more, so lets clean */ /* everything before we return: need to flush out all rest of */ /* image until empty block (size 0) detected. We use GetCodeNext.*/ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) return GIF_ERROR; while (Dummy != NULL); } return GIF_OK; } else return GIF_ERROR;}/******************************************************************************* Get an extension block (see GIF manual) from gif file. This routine only ** returns the first data block, and DGifGetExtensionNext shouldbe called ** after this one until NULL extension is returned. ** The Extension should NOT be freed by the user (not dynamically allocated).** Note it is assumed the Extension desc. header ('!') has been read. *******************************************************************************/int DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension){ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (READ(GifFile,&Buf, 1) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *ExtCode = Buf; return DGifGetExtensionNext(GifFile, Extension);}/******************************************************************************* Get a following extension block (see GIF manual) from gif file. This ** routine sould be called until NULL Extension is returned. ** The Extension should NOT be freed by the user (not dynamically allocated).*******************************************************************************/int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **Extension){ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (READ(GifFile,&Buf, 1) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } if (Buf > 0) { *Extension = Private->Buf; /* Use private unused buffer. */ (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ if (READ(GifFile,&((*Extension)[1]), Buf) != Buf) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else *Extension = NULL; return GIF_OK;}/******************************************************************************* This routine should be called last, to close the GIF file. *******************************************************************************/int DGifCloseFile(GifFileType *GifFile){ GifFilePrivateType *Private; FILE *File; if (GifFile == NULL) return GIF_ERROR; Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } File = Private->File; if (GifFile->Image.ColorMap) FreeMapObject(GifFile->Image.ColorMap); if (GifFile->SColorMap) FreeMapObject(GifFile->SColorMap); if (Private) free((char *) Private); if (GifFile->SavedImages) FreeSavedImages(GifFile); free(GifFile); if ( File && (fclose(File) != 0)) { _GifError = D_GIF_ERR_CLOSE_FAILED; return GIF_ERROR; } return GIF_OK;}/******************************************************************************* Get 2 bytes (word) from the given file: *******************************************************************************/static int DGifGetWord(GifFileType *GifFile, int *Word){ unsigned char c[2]; if (READ(GifFile,c, 2) != 2) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *Word = (((unsigned int) c[1]) << 8) + c[0]; return GIF_OK;}/******************************************************************************* Get the image code in compressed form. his routine can be called if the ** information needed to be piped out as is. Obviously this is much faster ** than decoding and encoding again. This routine should be followed by calls ** to DGifGetCodeNext, until NULL block is returned. ** The block should NOT be freed by the user (not dynamically allocated). *******************************************************************************/int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock){ GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ _GifError = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } *CodeSize = Private->BitsPerPixel; return DGifGetCodeNext(GifFile, CodeBlock);}/******************************************************************************* Continue to get the image code in compressed form. This routine should be ** called until NULL block is returned. ** The block should NOT be freed by the user (not dynamically allocated). *******************************************************************************/int DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock){ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (READ(GifFile,&Buf, 1) != 1) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } if (Buf > 0) { *CodeBlock = Private->Buf; /* Use private unused buffer. */ (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ if (READ(GifFile,&((*CodeBlock)[1]), Buf) != Buf) { _GifError = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else { *CodeBlock = NULL; Private->Buf[0] = 0; /* Make sure the buffer is empty! */ Private->PixelCount = 0; /* And local info. indicate image read. */ } return GIF_OK;}/******************************************************************************* Setup the LZ decompression for this image: *******************************************************************************/static int DGifSetupDecompress(GifFileType *GifFile){ int i, BitsPerPixel; GifByteType CodeSize; unsigned int *Prefix; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; READ(GifFile,&CodeSize, 1); /* Read Code size from file. */ BitsPerPixel = CodeSize; Private->Buf[0] = 0; /* Input Buffer empty. */ Private->BitsPerPixel = BitsPerPixel; Private->ClearCode = (1 << BitsPerPixel); Private->EOFCode = Private->ClearCode + 1; Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ Private->StackPtr = 0; /* No pixels on the pixel stack. */ Private->LastCode = NO_SUCH_CODE; Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ Private->CrntShiftDWord = 0; Prefix = Private->Prefix; for (i = 0; i <= LZ_MAX_CODE; i++) Prefix[i] = NO_SUCH_CODE; return GIF_OK;}/******************************************************************************* The LZ decompression routine: ** This version decompress the given gif file into Line of length LineLen. ** This routine can be called few times (one per scan line, for example), in ** order the complete the whole image. *******************************************************************************/static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen){ int i = 0, j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; GifByteType *Stack, *Suffix;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -