?? plugingif.cpp
字號:
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 + -