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

📄 plugingif.cpp

📁 一款最完整的工业组态软源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						memset(TransparencyTable, 0xff, pData->m_nTransparentColorIndex);
						TransparencyTable[pData->m_nTransparentColorIndex] = 0;

						FreeImage_SetTransparencyTable(pBitmap, 
							TransparencyTable, pData->m_nTransparentColorIndex+1);
					}

					// clear dib with GIF background color
					{
						//TODO: memset the all the bib at once and not line by line.
						for (int n = 0; n < pGifFile->SHeight; ++n)
						{
							BYTE *pScanLine = FreeImage_GetScanLine(pBitmap, n);
							memset(pScanLine, pGifFile->SBackGroundColor, pGifFile->SWidth);
						}
					}


					//
					// 2. copy the palette from gif to freeimage palette
					//

					// get the current image color map (the image map can be local to a frame or global to all the file)
					ColorMapObject *pImageColorMap = 
						pGifFile->Image.ColorMap? pGifFile->Image.ColorMap : pGifFile->SColorMap;

					if (pImageColorMap->ColorCount > 256)
						throw "invalid gif color count";

					GifColorType *pGifPalette = pImageColorMap->Colors;
					RGBQUAD *pPalette = FreeImage_GetPalette(pBitmap);

					for (int nColorIndex = 0; nColorIndex < pImageColorMap->ColorCount; ++nColorIndex)
					{
						pPalette->rgbRed   = pGifPalette->Red;
						pPalette->rgbGreen = pGifPalette->Green;
						pPalette->rgbBlue  = pGifPalette->Blue;

						++pGifPalette;
						++pPalette;
					}

					//
					// 3. copy gif scanlines to freeimage bitmap
					//

					if (pGifFile->Image.Interlace)
					{
						// Need to perform 4 passes on the image
						for (int nPass= 0; nPass < 4; ++nPass)
							for (int n = InterlacedOffset[nPass]; n < nImageHeight; n += InterlacedJumps[nPass])
							{
								//NOTE: The gif is an top-down image BUT freeimage dib are bottom-up
								BYTE *pScanLine = FreeImage_GetScanLine(pBitmap, nImageHeight-n-1+nImagePosY);

								if (::DGifGetLine(pGifFile, pScanLine, nImageWidth) == GIF_ERROR)
									throw "io error or invalid gif format";
							}
					}
					else
						for (int n = nImageHeight; n--; )
						{
							//NOTE: The gif is an top-down image BUT freeimage dib are bottom-up
							BYTE *pScanLine = FreeImage_GetScanLine(pBitmap, n+nImagePosY);

							if (::DGifGetLine(pGifFile, pScanLine+nImagePosX, nImageWidth) == GIF_ERROR)
								throw "io error or invalid gif format";
						}


					// free this image since we don't need it in the gif structure...
					// NOTE: If we don't free it and the gif as more than one image
					// that images all get appended to the SavedImages array.
					::FreeSavedImages(pGifFile);
					pGifFile->SavedImages = NULL;
					pGifFile->ImageCount  = 0;

					return pBitmap;
				}
				break;

				case EXTENSION_RECORD_TYPE:
				{
					int ExtCode;
					GifByteType *Extension;

					//
					// Skip any extension blocks in file
					//
					if (::DGifGetExtension(pGifFile, &ExtCode, &Extension) == GIF_ERROR)
						throw "io error or invalid gif format";

					if (ExtCode == GRAPHICS_EXT_FUNC_CODE	// is this a Graphic Control Extension block?
						&& Extension[0] >= 4)				// this block must have at least 4 bytes!
					{
						TGIFGraphicControlExtensionBlock *pExt = 
							(TGIFGraphicControlExtensionBlock *)&Extension[1];

						if (pExt->nFlags&0x01)  // this image has an transparent color?
							pData->m_nTransparentColorIndex = pExt->nTransparentColorIndex;

						//in pExt->nDelay is the delay time in 1/100 of a second that the next frame is expected to wait
						//unsigned nDelay= (Extension[2] | (Extension[3]<<8)) * 10; // nDelay converted to ms
					}

					while (Extension)
					{
						if (::DGifGetExtensionNext(pGifFile, &Extension) == GIF_ERROR)
							throw "io error or invalid gif format";
					}
				}
				break;
			} // switch

		} while (RecordType != TERMINATE_RECORD_TYPE);

	} catch (const char *pErrorMsg)	{
		FreeImage_OutputMessageProc(gs_format_id, pErrorMsg);
	}
	FreeImage_Unload(pBitmap);
	return NULL;
}

// this plugin save function
#ifdef GIF_PLUGIN_SAVE_SUPPORT
static BOOL DLL_CALLCONV 
GifPlugin_Save(FreeImageIO *io, FIBITMAP *pDib, fi_handle handle, int page, int flags, void *data) {

	TGifPluginData *pData = (TGifPluginData *)data;
	if (!pData)
		return FALSE;

	GifFileType *pGifFile = pData->m_pGifFileType;
	ColorMapObject *pGifColorMap = NULL;

	try {
		if (FreeImage_GetBPP(pDib) != 8)
			throw "Only 8 bit images are supported";

		//
		// if we have an transparency table make sure that the transparent
		// color is with 0 (full transparent alpha) value.
		// NOTE: This plugin sets the gif transparent color index to the
		// last transparency index of the freeimage dib.
		//
		int nTransparentColorIndex = FreeImage_GetTransparencyCount(pDib)-1;
		if (nTransparentColorIndex >= 0 && FreeImage_GetTransparencyTable(pDib)[nTransparentColorIndex])
			throw "invalid transparent color in dib";

		//
		// copy color table from dib into gif color map
		//
		if (!(pGifColorMap = ::MakeMapObject(256, NULL)))
			throw "No memory";

		RGBQUAD *pPalette = FreeImage_GetPalette(pDib);
		GifColorType *pGifPalette = pGifColorMap->Colors;

		for (int nColorIndex = 0; nColorIndex < 256; ++nColorIndex)
		{
			pGifPalette->Red   = pPalette->rgbRed;
			pGifPalette->Green = pPalette->rgbGreen;
			pGifPalette->Blue  = pPalette->rgbBlue;

			++pGifPalette;
			++pPalette;
		}

		//
		// write gif screen description
		//
		if (::EGifPutScreenDesc(pGifFile, 
				FreeImage_GetWidth(pDib), FreeImage_GetHeight(pDib), 8, 0, NULL) == GIF_ERROR)
			throw "io error";

		//
		// write transparent color information if the dib has one
		//
		if (nTransparentColorIndex >= 0)
		{
			TGIFGraphicControlExtensionBlock Extension = { 0x01, 0, nTransparentColorIndex };
			if (::EGifPutExtension(pGifFile, GRAPHICS_EXT_FUNC_CODE, 4, &Extension) == GIF_ERROR)
				throw "io error";
		}

		//
		// write image data
		//
		int nImageWidth  = pGifFile->SWidth;
		int nImageHeight = pGifFile->SHeight;

		//TODO: retreive the interlace option value from flags argument
		if (::EGifPutImageDesc(pGifFile, 0, 0, 
				nImageWidth, nImageHeight, FALSE, pGifColorMap) == GIF_ERROR)
			throw "io error";

		::FreeMapObject(pGifColorMap);
		pGifColorMap = NULL; //NOTE: need to place NULL here because the exception handling code frees it!

		for (int n= nImageHeight; n--; )
		{
			//NOTE: The gif is an top-down image BUT freeimage dib are bottom-up
			BYTE *pScanLine = FreeImage_GetScanLine(pDib, n);

			if (::EGifPutLine(pGifFile, pScanLine, nImageWidth) == GIF_ERROR)
				throw "io error";
		}
		return TRUE;

	} catch (const char *pErrorMsg)	{
		FreeImage_OutputMessageProc(gs_format_id, pErrorMsg);
	}

	if (pGifColorMap)
		::FreeMapObject(pGifColorMap);

	return FALSE;
}
#endif //#ifdef GIF_PLUGIN_SAVE_SUPPORT

// ==========================================================
//   Init
// ==========================================================

void DLL_CALLCONV 
InitGIF(Plugin *plugin, int format_id) {
	gs_format_id = format_id;

	plugin->format_proc = GifPlugin_Format;
	plugin->description_proc = GifPlugin_Description;
	plugin->extension_proc = GifPlugin_Extension;
	plugin->regexpr_proc = GifPlugin_RegExpr;
	plugin->open_proc = GifPlugin_Open;
	plugin->load_proc = GifPlugin_Load;

#ifdef GIF_PLUGIN_SAVE_SUPPORT
	plugin->save_proc = GifPlugin_Save;
#else
	plugin->save_proc = NULL;
#endif // #ifdef GIF_PLUGIN_SAVE_SUPPORT

	plugin->close_proc = GifPlugin_Close;
	plugin->validate_proc = GifPlugin_Validate;

	plugin->pagecount_proc = NULL;
	plugin->pagecapability_proc = NULL;
	plugin->mime_proc = GifPlugin_MimeType;
	plugin->supports_export_bpp_proc = GifPlugin_SupportsExportDepth;
	plugin->supports_export_type_proc = GifPlugin_SupportsExportType;
	plugin->supports_icc_profiles_proc = NULL;

#ifdef GIF_PLUGIN_SAVE_SUPPORT
	//NOTE: Since this plugin can make transparent gif
	//we will produce gif89a version gif's
	::EGifSetGifVersion("89a");
#endif // #ifdef GIF_PLUGIN_SAVE_SUPPORT

}

⌨️ 快捷键说明

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