?? plugingif.cpp
字號:
// ==========================================================
// GIF Loader
//
// Design and implementation by
// - Rui Godinho Lopes <ruiglopes@yahoo.com>
// - Detlev Vendt (detlev.vendt@brillit.de)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================
#define GIF_PLUGIN_SAVE_SUPPORT // enable write support only with UNISYS license ....
extern "C" {
#include "../LibGIF/gif_lib.h"
}
#include "FreeImage.h"
#include "Utilities.h"
// interlace pattern constants for loading/saving interlaced gif files
static const int InterlacedOffset[]= { 0, 4, 2, 1 }; // The way Interlaced image should
static const int InterlacedJumps[]= { 8, 8, 4, 2 }; // be read - offsets and jumps...
#ifdef WIN32
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif
struct TGIFGraphicControlExtensionBlock
{
BYTE nFlags;
WORD nDelay;
BYTE nTransparentColorIndex;
};
#ifdef WIN32
#pragma pack(pop)
#else
#pragma pack(4)
#endif
// data structure created at GifPlugin_Open and destroyed at GifPlugin_Close
struct TGifPluginData {
FreeImageIO *m_pIO;
fi_handle m_Handle;
GifFileType *m_pGifFileType;
int m_nTransparentColorIndex;
#ifdef GIF_PLUGIN_SAVE_SUPPORT
BOOL m_bRead;
#endif
};
// adapter function for use by the gif-lib input logic
int InputFuncAdapt(GifFileType *pGifFileType, GifByteType *pBuf, int nBytesToRead) {
return ((TGifPluginData *)pGifFileType->UserData)->m_pIO->read_proc(
pBuf, 1, nBytesToRead, ((TGifPluginData *)pGifFileType->UserData)->m_Handle);
}
// adapter function for use by the gif-lib output logic
#ifdef GIF_PLUGIN_SAVE_SUPPORT
int OutputFuncAdapt(GifFileType *pGifFileType, const GifByteType *pBuf, int nBytesToWrite) {
return ((TGifPluginData *)pGifFileType->UserData)->m_pIO->write_proc(
(unsigned char *)pBuf, 1, nBytesToWrite, ((TGifPluginData *)pGifFileType->UserData)->m_Handle);
}
#endif
// ==========================================================
// Plugin Interface
// ==========================================================
static int gs_format_id;
// ==========================================================
// Plugin Implementation
// ==========================================================
static const char * DLL_CALLCONV
GifPlugin_Format() {
return "GIF";
}
static const char * DLL_CALLCONV
GifPlugin_MimeType() {
return "image/gif";
}
static const char * DLL_CALLCONV
GifPlugin_Description() {
return "Graphics Interchange Format";
}
static const char * DLL_CALLCONV
GifPlugin_Extension() {
return "gif";
}
static const char * DLL_CALLCONV
GifPlugin_RegExpr() {
return "^GIF";
}
static BOOL DLL_CALLCONV
GifPlugin_SupportsExportDepth(int depth) {
#ifdef GIF_PLUGIN_SAVE_SUPPORT
return (depth == 8);
#else
return FALSE;
#endif
}
static BOOL DLL_CALLCONV
GifPlugin_SupportsExportType(FREE_IMAGE_TYPE type) {
return (type == FIT_BITMAP) ? TRUE : FALSE;
}
static BOOL DLL_CALLCONV
GifPlugin_Validate(FreeImageIO *io, fi_handle handle) {
char buf[GIF_STAMP_LEN];
int nBytesReaded = io->read_proc(buf, 1, GIF_STAMP_LEN, handle);
//NOTE: The actual gif file version is not checked, this because
//the GIF file structure is designed not to change significantly...
BOOL bResult = (nBytesReaded != GIF_STAMP_LEN ? FALSE : !strncmp(GIF_STAMP, buf, GIF_VERSION_POS));
io->seek_proc(handle, -nBytesReaded, SEEK_CUR);
return bResult;
}
// this plugin open function
static void *DLL_CALLCONV
GifPlugin_Open(FreeImageIO *io, fi_handle handle, BOOL read) {
TGifPluginData *pData= new TGifPluginData;
if (!pData)
return NULL;
pData->m_Handle = handle;
pData->m_pIO = io;
pData->m_nTransparentColorIndex = -1; // set to no transparent color
#ifdef GIF_PLUGIN_SAVE_SUPPORT
pData->m_bRead = read;
#endif
if (read)
{
pData->m_pGifFileType = ::DGifOpen(pData, InputFuncAdapt);
}
else
{
#ifdef GIF_PLUGIN_SAVE_SUPPORT
pData->m_pGifFileType = ::EGifOpen(pData, OutputFuncAdapt);
#else
pData->m_pGifFileType = NULL;
#endif
}
if (!pData->m_pGifFileType)
{
delete pData;
return NULL;
}
return pData;
}
// this plugin close function
static void DLL_CALLCONV
GifPlugin_Close(FreeImageIO *io, fi_handle handle, void *data) {
TGifPluginData *pData = (TGifPluginData *)data;
if (!pData)
return;
#ifdef GIF_PLUGIN_SAVE_SUPPORT
if (pData->m_bRead)
::DGifCloseFile(pData->m_pGifFileType);
else
::EGifCloseFile(pData->m_pGifFileType);
#else
::DGifCloseFile(pData->m_pGifFileType);
#endif
delete pData;
}
// this plugin load function
static FIBITMAP * DLL_CALLCONV
GifPlugin_Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
TGifPluginData *pData = (TGifPluginData *)data;
if (!pData)
return NULL;
FIBITMAP *pBitmap= NULL; // the freeimage bitmap. NOTE: This is needed here because of the exception logic (if we throw an exeception we will free the bitmap in the catch block).
GifFileType *pGifFile = pData->m_pGifFileType;
GifRecordType RecordType;
try {
do {
if (::DGifGetRecordType(pGifFile, &RecordType) == GIF_ERROR)
throw "io error or invalid gif format";
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
{
/*if (8 != pGifFile->SColorResolution)
throw "only 8 bit color resolution gif are supported";*/
if (::DGifGetImageDesc(pGifFile) == GIF_ERROR)
throw "io error or invalid gif format";
//
// Read the image line by line
// NOTE: The global size of the image is given by,
// GifFile->SWidth and GifFile->SHeight
//
// The following sizes/positions are for the current frame only!
//
int nImagePosX = pGifFile->Image.Left;
int nImagePosY = pGifFile->Image.Top;
int nImageWidth = pGifFile->Image.Width;
int nImageHeight = pGifFile->Image.Height;
if (nImagePosX < 0 ||
nImagePosX > pGifFile->SWidth ||
nImagePosX + nImageWidth > pGifFile->SWidth ||
nImagePosY < 0 ||
nImagePosY > pGifFile->SHeight ||
nImagePosY + nImageHeight > pGifFile->SHeight)
throw "invalid gif dimensions";
//
// 1. Allocate a freeimage bitmap
//
pBitmap = FreeImage_Allocate(pGifFile->SWidth, pGifFile->SHeight, 8);
if (!pBitmap)
throw "DIB allocation failed";
// Set's the transparent color of the gif
if (pData->m_nTransparentColorIndex >= 0)
{
BYTE TransparencyTable[256];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -