📄 egif_lib.c
字号:
/* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } GifFile->Image.Left = Left; GifFile->Image.Top = Top; GifFile->Image.Width = Width; GifFile->Image.Height = Height; GifFile->Image.Interlace = Interlace; if (ColorMap) { GifFile->Image.ColorMap = MakeMapObject(ColorMap->ColorCount, ColorMap->Colors); if (GifFile->Image.ColorMap == NULL) { _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } else { GifFile->Image.ColorMap = NULL; } /* Put the image descriptor into the file: */ Buf[0] = ','; /* Image seperator character. */#ifndef DEBUG_NO_PREFIX WRITE(GifFile, Buf, 1);#endif /* DEBUG_NO_PREFIX */ EGifPutWord(Left, GifFile); EGifPutWord(Top, GifFile); EGifPutWord(Width, GifFile); EGifPutWord(Height, GifFile); Buf[0] = (ColorMap ? 0x80 : 0x00) | (Interlace ? 0x40 : 0x00) | (ColorMap ? ColorMap->BitsPerPixel - 1 : 0);#ifndef DEBUG_NO_PREFIX WRITE(GifFile, Buf, 1);#endif /* DEBUG_NO_PREFIX */ /* If we have Global color map - dump it also: */#ifndef DEBUG_NO_PREFIX if (ColorMap != NULL) for (i = 0; i < ColorMap->ColorCount; i++) { /* Put the ColorMap out also: */ Buf[0] = ColorMap->Colors[i].Red; Buf[1] = ColorMap->Colors[i].Green; Buf[2] = ColorMap->Colors[i].Blue; if (WRITE(GifFile, Buf, 3) != 3) { _GifError = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } }#endif /* DEBUG_NO_PREFIX */ if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL) { _GifError = E_GIF_ERR_NO_COLOR_MAP; return GIF_ERROR; } /* Mark this file as has screen descriptor: */ Private->FileState |= FILE_STATE_IMAGE; Private->PixelCount = (long)Width *(long)Height; EGifSetupCompress(GifFile); /* Reset compress algorithm parameters. */ return GIF_OK;}/****************************************************************************** * Put one full scanned line (Line) of length LineLen into GIF file. *****************************************************************************/intEGifPutLine(GifFileType * GifFile, GifPixelType * Line, int LineLen) { int i; GifPixelType Mask; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (!LineLen) LineLen = GifFile->Image.Width; if (Private->PixelCount < (unsigned)LineLen) { _GifError = E_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } Private->PixelCount -= LineLen; /* Make sure the codes are not out of bit range, as we might generate * wrong code (because of overflow when we combine them) in this case: */ Mask = CodeMask[Private->BitsPerPixel]; for (i = 0; i < LineLen; i++) Line[i] &= Mask; return EGifCompressLine(GifFile, Line, LineLen);}/****************************************************************************** * Put one pixel (Pixel) into GIF file. *****************************************************************************/intEGifPutPixel(GifFileType * GifFile, GifPixelType Pixel) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (Private->PixelCount == 0) { _GifError = E_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } --Private->PixelCount; /* Make sure the code is not out of bit range, as we might generate * wrong code (because of overflow when we combine them) in this case: */ Pixel &= CodeMask[Private->BitsPerPixel]; return EGifCompressLine(GifFile, &Pixel, 1);}/****************************************************************************** * Put a comment into GIF file using the GIF89 comment extension block. *****************************************************************************/intEGifPutComment(GifFileType * GifFile, const char *Comment) { unsigned int length = strlen(Comment); char *buf; length = strlen(Comment); if (length <= 255) { return EGifPutExtension(GifFile, COMMENT_EXT_FUNC_CODE, length, Comment); } else { buf = (char *)Comment; if (EGifPutExtensionFirst(GifFile, COMMENT_EXT_FUNC_CODE, 255, buf) == GIF_ERROR) { return GIF_ERROR; } length -= 255; buf = buf + 255; /* Break the comment into 255 byte sub blocks */ while (length > 255) { if (EGifPutExtensionNext(GifFile, 0, 255, buf) == GIF_ERROR) { return GIF_ERROR; } buf = buf + 255; length -= 255; } /* Output any partial block and the clear code. */ if (length > 0) { if (EGifPutExtensionLast(GifFile, 0, length, buf) == GIF_ERROR) { return GIF_ERROR; } } else { if (EGifPutExtensionLast(GifFile, 0, 0, NULL) == GIF_ERROR) { return GIF_ERROR; } } } return GIF_OK;}/****************************************************************************** * Put a first extension block (see GIF manual) into gif file. Here more * extensions can be dumped using EGifPutExtensionNext until * EGifPutExtensionLast is invoked. *****************************************************************************/intEGifPutExtensionFirst(GifFileType * GifFile, int ExtCode, int ExtLen, const VoidPtr Extension) { GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (ExtCode == 0) { WRITE(GifFile, (GifByteType *)&ExtLen, 1); } else { Buf[0] = '!'; Buf[1] = ExtCode; Buf[2] = ExtLen; WRITE(GifFile, Buf, 3); } WRITE(GifFile, Extension, ExtLen); return GIF_OK;}/****************************************************************************** * Put a middle extension block (see GIF manual) into gif file. *****************************************************************************/intEGifPutExtensionNext(GifFileType * GifFile, int ExtCode, int ExtLen, const VoidPtr Extension) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } Buf = ExtLen; WRITE(GifFile, &Buf, 1); WRITE(GifFile, Extension, ExtLen); return GIF_OK;}/****************************************************************************** * Put a last extension block (see GIF manual) into gif file. *****************************************************************************/intEGifPutExtensionLast(GifFileType * GifFile, int ExtCode, int ExtLen, const VoidPtr Extension) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } /* If we are given an extension sub-block output it now. */ if (ExtLen > 0) { Buf = ExtLen; WRITE(GifFile, &Buf, 1); WRITE(GifFile, Extension, ExtLen); } /* Write the block terminator */ Buf = 0; WRITE(GifFile, &Buf, 1); return GIF_OK;}/****************************************************************************** * Put an extension block (see GIF manual) into gif file. * Warning: This function is only useful for Extension blocks that have at * most one subblock. Extensions with more than one subblock need to use the * EGifPutExtension{First,Next,Last} functions instead. *****************************************************************************/intEGifPutExtension(GifFileType * GifFile, int ExtCode, int ExtLen, const VoidPtr Extension) { GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (ExtCode == 0) WRITE(GifFile, (GifByteType *)&ExtLen, 1); else { Buf[0] = '!'; /* Extension Introducer 0x21 */ Buf[1] = ExtCode; /* Extension Label */ Buf[2] = ExtLen; /* Extension length */ WRITE(GifFile, Buf, 3); } WRITE(GifFile, Extension, ExtLen); Buf[0] = 0; WRITE(GifFile, Buf, 1); return GIF_OK;}/****************************************************************************** * Put the image code in compressed form. This 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 EGifPutCodeNext, until NULL block is given. * The block should NOT be freed by the user (not dynamically allocated). *****************************************************************************/intEGifPutCode(GifFileType * GifFile, int CodeSize, const GifByteType * CodeBlock) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ _GifError = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } /* No need to dump code size as Compression set up does any for us: */ /* * Buf = CodeSize; * if (WRITE(GifFile, &Buf, 1) != 1) { * _GifError = E_GIF_ERR_WRITE_FAILED; * return GIF_ERROR; * } */ return EGifPutCodeNext(GifFile, CodeBlock);}/****************************************************************************** * Continue to put the image code in compressed form. This routine should be * called with blocks of code as read via DGifGetCode/DGifGetCodeNext. If * given buffer pointer is NULL, empty block is written to mark end of code. *****************************************************************************/intEGifPutCodeNext(GifFileType * GifFile, const GifByteType * CodeBlock) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (CodeBlock != NULL) { if (WRITE(GifFile, CodeBlock, CodeBlock[0] + 1) != (unsigned)(CodeBlock[0] + 1)) { _GifError = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } else { Buf = 0; if (WRITE(GifFile, &Buf, 1) != 1) { _GifError = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } Private->PixelCount = 0; /* And local info. indicate image read. */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -