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

📄 dgif_lib.c

📁 giflib-4.1.6.tar.gz,最新的GIF 解码库
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** *   "Gif-Lib" - Yet another gif library. * * Written by:  Gershon Elber            IBM PC Ver 1.1,    Aug. 1990 ****************************************************************************** * The kernel of the GIF Decoding process can be found here. ****************************************************************************** * History: * 16 Jun 89 - Version 1.0 by Gershon Elber. *  3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *****************************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__)#include <io.h>#include <alloc.h>#include <sys\stat.h>#else#include <sys/types.h>#include <sys/stat.h>#endif /* __MSDOS__ */#ifdef HAVE_IO_H#include <io.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif /* HAVE_FCNTL_H */#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#include <stdio.h>#include <string.h>#include "gif_lib.h"#include "gif_lib_private.h"#define COMMENT_EXT_FUNC_CODE 0xfe  /* Extension function code for                                       comment. *//* avoid extra function call in case we use fread (TVT) */#define READ(_gif,_buf,_len)                                     \  (((GifFilePrivateType*)_gif->Private)->Read ?                   \    ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \    fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))static int DGifGetWord(GifFileType *GifFile, GifWord *Word);static int DGifSetupDecompress(GifFileType *GifFile);static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,                              int LineLen);static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);static int DGifDecompressInput(GifFileType *GifFile, int *Code);static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,                             GifByteType *NextByte);#ifndef _GBA_NO_FILEIO/****************************************************************************** * Open a new gif file for read, given by its name. * Returns GifFileType pointer dynamically allocated which serves as the gif * info record. _GifError is cleared if succesfull. *****************************************************************************/GifFileType *DGifOpenFileName(const char *FileName) {    int FileHandle;    GifFileType *GifFile;    if ((FileHandle = open(FileName, O_RDONLY#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY)                           | O_BINARY#endif /* __MSDOS__ || _OPEN_BINARY */         )) == -1) {        _GifError = D_GIF_ERR_OPEN_FAILED;        return NULL;    }    GifFile = DGifOpenFileHandle(FileHandle);    return GifFile;}/****************************************************************************** * Update a new gif file, given its file handle. * Returns GifFileType pointer dynamically allocated which serves as the gif * info record. _GifError is cleared if succesfull. *****************************************************************************/GifFileType *DGifOpenFileHandle(int FileHandle) {    unsigned char Buf[GIF_STAMP_LEN + 1];    GifFileType *GifFile;    GifFilePrivateType *Private;    FILE *f;    GifFile = (GifFileType *)malloc(sizeof(GifFileType));    if (GifFile == NULL) {        _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;        close(FileHandle);        return NULL;    }    memset(GifFile, '\0', sizeof(GifFileType));    Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));    if (Private == NULL) {        _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;        close(FileHandle);        free((char *)GifFile);        return NULL;    }#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY)    setmode(FileHandle, O_BINARY);    /* Make sure it is in binary mode. */#endif /* __MSDOS__ */    f = fdopen(FileHandle, "rb");    /* Make it into a stream: */#if defined(__MSDOS__) || defined(WINDOWS32)    setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);    /* And inc. stream                                                          buffer. */#endif /* __MSDOS__ */    GifFile->Private = (VoidPtr)Private;    Private->FileHandle = FileHandle;    Private->File = f;    Private->FileState = FILE_STATE_READ;    Private->Read = 0;    /* don't use alternate input method (TVT) */    GifFile->UserData = 0;    /* TVT */    /* Lets see if this is a GIF file: */    if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {        _GifError = D_GIF_ERR_READ_FAILED;        fclose(f);        free((char *)Private);        free((char *)GifFile);        return NULL;    }    /* The GIF Version number is ignored at this time. Maybe we should do     * something more useful with it.  */    Buf[GIF_STAMP_LEN] = 0;    if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {        _GifError = D_GIF_ERR_NOT_GIF_FILE;        fclose(f);        free((char *)Private);        free((char *)GifFile);        return NULL;    }    if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {        fclose(f);        free((char *)Private);        free((char *)GifFile);        return NULL;    }    _GifError = 0;    return GifFile;}#endif /* _GBA_NO_FILEIO *//****************************************************************************** * GifFileType constructor with user supplied input function (TVT) *****************************************************************************/GifFileType *DGifOpen(void *userData,         InputFunc readFunc) {    unsigned char Buf[GIF_STAMP_LEN + 1];    GifFileType *GifFile;    GifFilePrivateType *Private;    GifFile = (GifFileType *)malloc(sizeof(GifFileType));    if (GifFile == NULL) {        _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;        return NULL;    }    memset(GifFile, '\0', sizeof(GifFileType));    Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));    if (!Private) {        _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;        free((char *)GifFile);        return NULL;    }    GifFile->Private = (VoidPtr)Private;    Private->FileHandle = 0;    Private->File = 0;    Private->FileState = FILE_STATE_READ;    Private->Read = readFunc;    /* TVT */    GifFile->UserData = userData;    /* TVT */    /* Lets see if this is a GIF file: */    if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {        _GifError = D_GIF_ERR_READ_FAILED;        free((char *)Private);        free((char *)GifFile);        return NULL;    }    /* The GIF Version number is ignored at this time. Maybe we should do     * something more useful with it. */    Buf[GIF_STAMP_LEN] = 0;    if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {        _GifError = D_GIF_ERR_NOT_GIF_FILE;        free((char *)Private);        free((char *)GifFile);        return NULL;    }    if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {        free((char *)Private);        free((char *)GifFile);        return NULL;    }    _GifError = 0;    return GifFile;}/****************************************************************************** * This routine should be called before any other DGif calls. Note that * this routine is called automatically from DGif file open routines. *****************************************************************************/intDGifGetScreenDesc(GifFileType * GifFile) {    int i, BitsPerPixel;    GifByteType Buf[3];    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;    }    /* Put the screen descriptor into the file: */    if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||        DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)        return GIF_ERROR;    if (READ(GifFile, Buf, 3) != 3) {        _GifError = D_GIF_ERR_READ_FAILED;        return GIF_ERROR;    }    GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;    BitsPerPixel = (Buf[0] & 0x07) + 1;    GifFile->SBackGroundColor = Buf[1];    if (Buf[0] & 0x80) {    /* Do we have global color map? */        GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);        if (GifFile->SColorMap == NULL) {            _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;            return GIF_ERROR;        }        /* Get the global color map: */        for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {            if (READ(GifFile, Buf, 3) != 3) {                FreeMapObject(GifFile->SColorMap);                GifFile->SColorMap = NULL;                _GifError = D_GIF_ERR_READ_FAILED;                return GIF_ERROR;            }            GifFile->SColorMap->Colors[i].Red = Buf[0];            GifFile->SColorMap->Colors[i].Green = Buf[1];            GifFile->SColorMap->Colors[i].Blue = Buf[2];        }    } else {        GifFile->SColorMap = NULL;    }    return GIF_OK;}/****************************************************************************** * This routine should be called before any attempt to read an image. *****************************************************************************/intDGifGetRecordType(GifFileType * GifFile,                  GifRecordType * Type) {    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;    }    switch (Buf) {      case ',':          *Type = IMAGE_DESC_RECORD_TYPE;          break;      case '!':          *Type = EXTENSION_RECORD_TYPE;          break;      case ';':          *Type = TERMINATE_RECORD_TYPE;          break;      default:          *Type = UNDEFINED_RECORD_TYPE;          _GifError = D_GIF_ERR_WRONG_RECORD;          return GIF_ERROR;    }    return GIF_OK;}/****************************************************************************** * This routine should be called before any attempt to read an image. * Note it is assumed the Image desc. header (',') has been read. *****************************************************************************/intDGifGetImageDesc(GifFileType * GifFile) {    int i, BitsPerPixel;    GifByteType Buf[3];    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;    SavedImage *sp;    if (!IS_READABLE(Private)) {        /* This file was NOT open for reading: */        _GifError = D_GIF_ERR_NOT_READABLE;        return GIF_ERROR;    }    if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||        DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||        DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||        DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)        return GIF_ERROR;    if (READ(GifFile, Buf, 1) != 1) {        _GifError = D_GIF_ERR_READ_FAILED;        return GIF_ERROR;    }    BitsPerPixel = (Buf[0] & 0x07) + 1;    GifFile->Image.Interlace = (Buf[0] & 0x40);    if (Buf[0] & 0x80) {    /* Does this image have local color map? */        /*** FIXME: Why do we check both of these in order to do this?          * Why do we have both Image and SavedImages? */        if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)            FreeMapObject(GifFile->Image.ColorMap);        GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);        if (GifFile->Image.ColorMap == NULL) {            _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;            return GIF_ERROR;        }        /* Get the image local color map: */        for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -