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

📄 egif_lib.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 3 页
字号:
    return GIF_OK;}/****************************************************************************** * This routine should be called last, to close GIF file. *****************************************************************************/intEGifCloseFile(GifFileType * GifFile) {    GifByteType Buf;    GifFilePrivateType *Private;    FILE *File;    if (GifFile == NULL)        return GIF_ERROR;    Private = (GifFilePrivateType *) GifFile->Private;    if (!IS_WRITEABLE(Private)) {        /* This file was NOT open for writing: */        _GifError = E_GIF_ERR_NOT_WRITEABLE;        return GIF_ERROR;    }    File = Private->File;    Buf = ';';    WRITE(GifFile, &Buf, 1);    if (GifFile->Image.ColorMap) {        FreeMapObject(GifFile->Image.ColorMap);        GifFile->Image.ColorMap = NULL;    }    if (GifFile->SColorMap) {        FreeMapObject(GifFile->SColorMap);        GifFile->SColorMap = NULL;    }    if (Private) {        free((char *)Private);    }    free(GifFile);    if (File && fclose(File) != 0) {        _GifError = E_GIF_ERR_CLOSE_FAILED;        return GIF_ERROR;    }    return GIF_OK;}/****************************************************************************** * Put 2 bytes (word) into the given file: *****************************************************************************/static intEGifPutWord(int Word,            GifFileType * GifFile) {    unsigned char c[2];    c[0] = Word & 0xff;    c[1] = (Word >> 8) & 0xff;#ifndef DEBUG_NO_PREFIX    if (WRITE(GifFile, c, 2) == 2)        return GIF_OK;    else        return GIF_ERROR;#else    return GIF_OK;#endif /* DEBUG_NO_PREFIX */}/****************************************************************************** * Setup the LZ compression for this image: *****************************************************************************/static intEGifSetupCompress(GifFileType * GifFile) {    int BitsPerPixel;    GifByteType Buf;    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;    /* Test and see what color map to use, and from it # bits per pixel: */    if (GifFile->Image.ColorMap)        BitsPerPixel = GifFile->Image.ColorMap->BitsPerPixel;    else if (GifFile->SColorMap)        BitsPerPixel = GifFile->SColorMap->BitsPerPixel;    else {        _GifError = E_GIF_ERR_NO_COLOR_MAP;        return GIF_ERROR;    }    Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel);    WRITE(GifFile, &Buf, 1);    /* Write the Code size to file. */    Private->Buf[0] = 0;    /* Nothing was output yet. */    Private->BitsPerPixel = BitsPerPixel;    Private->ClearCode = (1 << BitsPerPixel);    Private->EOFCode = Private->ClearCode + 1;    Private->RunningCode = 0;    Private->RunningBits = BitsPerPixel + 1;    /* Number of bits per code. */    Private->MaxCode1 = 1 << Private->RunningBits;    /* Max. code + 1. */    Private->CrntCode = FIRST_CODE;    /* Signal that this is first one! */    Private->CrntShiftState = 0;    /* No information in CrntShiftDWord. */    Private->CrntShiftDWord = 0;    /* Send Clear to make sure the encoder is initialized. */    if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) {        _GifError = E_GIF_ERR_DISK_IS_FULL;        return GIF_ERROR;    }    return GIF_OK;}/****************************************************************************** * The LZ compression routine: * This version compresses the given buffer Line of length LineLen. * This routine can be called a few times (one per scan line, for example), in * order to complete the whole image.******************************************************************************/static intEGifCompressLine(GifFileType * GifFile,                 GifPixelType * Line,                 int LineLen) {    int i = 0, CrntCode;    GifPixelType Pixel;    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;    if (Private->CrntCode == FIRST_CODE)    /* Its first time! */        CrntCode = Line[i++];    else        CrntCode = Private->CrntCode;    /* Get last code in compression. */    while (i < LineLen) {    /* Decode LineLen items. */        Pixel = Line[i++];    /* Get next pixel from stream. */        if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) {            _GifError = E_GIF_ERR_DISK_IS_FULL;            return GIF_ERROR;        }        Private->RunningCode++;        CrntCode = Pixel;        if (Private->RunningCode >= (1 << (Private->BitsPerPixel)) - 2) {            if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) {                _GifError = E_GIF_ERR_DISK_IS_FULL;                return GIF_ERROR;            }            Private->RunningCode = 0;        }    }    /* Preserve the current state of the compression algorithm: */    Private->CrntCode = CrntCode;    if (Private->PixelCount == 0) {        /* We are done - output last Code and flush output buffers: */        if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) {            _GifError = E_GIF_ERR_DISK_IS_FULL;            return GIF_ERROR;        }        if (EGifCompressOutput(GifFile, Private->EOFCode) == GIF_ERROR) {            _GifError = E_GIF_ERR_DISK_IS_FULL;            return GIF_ERROR;        }        if (EGifCompressOutput(GifFile, FLUSH_OUTPUT) == GIF_ERROR) {            _GifError = E_GIF_ERR_DISK_IS_FULL;            return GIF_ERROR;        }    }    return GIF_OK;}/****************************************************************************** * The LZ compression output routine: * This routine is responsible for the compression of the bit stream into * 8 bits (bytes) packets. * Returns GIF_OK if written succesfully. *****************************************************************************/static intEGifCompressOutput(GifFileType * GifFile,                   int Code) {    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;    int retval = GIF_OK;    if (Code == FLUSH_OUTPUT) {        while (Private->CrntShiftState > 0) {            /* Get Rid of what is left in DWord, and flush it. */            if (EGifBufferedOutput(GifFile, Private->Buf,                                 Private->CrntShiftDWord & 0xff) == GIF_ERROR)                retval = GIF_ERROR;            Private->CrntShiftDWord >>= 8;            Private->CrntShiftState -= 8;        }        Private->CrntShiftState = 0;    /* For next time. */        if (EGifBufferedOutput(GifFile, Private->Buf,                               FLUSH_OUTPUT) == GIF_ERROR)            retval = GIF_ERROR;    } else {        Private->CrntShiftDWord |= ((long)Code) << Private->CrntShiftState;        Private->CrntShiftState += Private->RunningBits;        while (Private->CrntShiftState >= 8) {            /* Dump out full bytes: */            if (EGifBufferedOutput(GifFile, Private->Buf,                                 Private->CrntShiftDWord & 0xff) == GIF_ERROR)                retval = GIF_ERROR;            Private->CrntShiftDWord >>= 8;            Private->CrntShiftState -= 8;        }    }    return retval;}/****************************************************************************** * This routines buffers the given characters until 255 characters are ready * to be output. If Code is equal to -1 the buffer is flushed (EOF). * The buffer is Dumped with first byte as its size, as GIF format requires. * Returns GIF_OK if written succesfully. *****************************************************************************/static intEGifBufferedOutput(GifFileType * GifFile,                   GifByteType * Buf,                   int c) {    if (c == FLUSH_OUTPUT) {        /* Flush everything out. */        if (Buf[0] != 0            && WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) {            _GifError = E_GIF_ERR_WRITE_FAILED;            return GIF_ERROR;        }        /* Mark end of compressed data, by an empty block (see GIF doc): */        Buf[0] = 0;        if (WRITE(GifFile, Buf, 1) != 1) {            _GifError = E_GIF_ERR_WRITE_FAILED;            return GIF_ERROR;        }    } else {        if (Buf[0] == 255) {            /* Dump out this buffer - it is full: */            if (WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) {                _GifError = E_GIF_ERR_WRITE_FAILED;                return GIF_ERROR;            }            Buf[0] = 0;        }        Buf[++Buf[0]] = c;    }    return GIF_OK;}/****************************************************************************** * This routine writes to disk an in-core representation of a GIF previously * created by DGifSlurp(). *****************************************************************************/intEGifSpew(GifFileType * GifFileOut) {    int i, j, gif89 = FALSE;    int bOff;   /* Block Offset for adding sub blocks in Extensions */    char SavedStamp[GIF_STAMP_LEN + 1];    for (i = 0; i < GifFileOut->ImageCount; i++) {        for (j = 0; j < GifFileOut->SavedImages[i].ExtensionBlockCount; j++) {            int function =               GifFileOut->SavedImages[i].ExtensionBlocks[j].Function;            if (function == COMMENT_EXT_FUNC_CODE                || function == GRAPHICS_EXT_FUNC_CODE                || function == PLAINTEXT_EXT_FUNC_CODE                || function == APPLICATION_EXT_FUNC_CODE)                gif89 = TRUE;        }    }    strncpy(SavedStamp, GifVersionPrefix, GIF_STAMP_LEN);    if (gif89) {        strncpy(GifVersionPrefix, GIF89_STAMP, GIF_STAMP_LEN);    } else {        strncpy(GifVersionPrefix, GIF87_STAMP, GIF_STAMP_LEN);    }    if (EGifPutScreenDesc(GifFileOut,                          GifFileOut->SWidth,                          GifFileOut->SHeight,                          GifFileOut->SColorResolution,                          GifFileOut->SBackGroundColor,                          GifFileOut->SColorMap) == GIF_ERROR) {        strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN);        return (GIF_ERROR);    }    strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN);    for (i = 0; i < GifFileOut->ImageCount; i++) {        SavedImage *sp = &GifFileOut->SavedImages[i];        int SavedHeight = sp->ImageDesc.Height;        int SavedWidth = sp->ImageDesc.Width;        ExtensionBlock *ep;        /* this allows us to delete images by nuking their rasters */        if (sp->RasterBits == NULL)            continue;        if (sp->ExtensionBlocks) {            for (j = 0; j < sp->ExtensionBlockCount; j++) {                ep = &sp->ExtensionBlocks[j];                if (j == sp->ExtensionBlockCount - 1 || (ep+1)->Function != 0) {                    /*** FIXME: Must check whether outputting                     * <ExtLen><Extension> is ever valid or if we should just                     * drop anything with a 0 for the Function.  (And whether                     * we should drop here or in EGifPutExtension)                     */                    if (EGifPutExtension(GifFileOut,                                         (ep->Function != 0) ? ep->Function : '\0',                                         ep->ByteCount,                                         ep->Bytes) == GIF_ERROR) {                        return (GIF_ERROR);                    }                } else {                    EGifPutExtensionFirst(GifFileOut, ep->Function, ep->ByteCount, ep->Bytes);                    for (bOff = j+1; bOff < sp->ExtensionBlockCount; bOff++) {                        ep = &sp->ExtensionBlocks[bOff];                        if (ep->Function != 0) {                            break;                        }                        EGifPutExtensionNext(GifFileOut, 0,                                ep->ByteCount, ep->Bytes);                    }                    EGifPutExtensionLast(GifFileOut, 0, 0, NULL);                    j = bOff-1;                }            }        }        if (EGifPutImageDesc(GifFileOut,                             sp->ImageDesc.Left,                             sp->ImageDesc.Top,                             SavedWidth,                             SavedHeight,                             sp->ImageDesc.Interlace,                             sp->ImageDesc.ColorMap) == GIF_ERROR)            return (GIF_ERROR);        for (j = 0; j < SavedHeight; j++) {            if (EGifPutLine(GifFileOut,                            sp->RasterBits + j * SavedWidth,                            SavedWidth) == GIF_ERROR)                return (GIF_ERROR);        }    }    if (EGifCloseFile(GifFileOut) == GIF_ERROR)        return (GIF_ERROR);    return (GIF_OK);}

⌨️ 快捷键说明

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