⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dgif_lib.c

📁 支持各种栅格图像和矢量图像读取的库
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -