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

📄 plugingif.cpp

📁 一款最完整的工业组态软源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ==========================================================
// 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 + -