int main(int argc, char **argv) { int i, ErrorCode; GifFileType *GifFileIn, *GifFileOut = (GifFileType *)NULL; if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (DGifSlurp(GifFileIn) == GIF_ERROR) { PrintGifError(GifFileIn->Error); exit(EXIT_FAILURE); } if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* * Your operations on in-core structures go here. * This code just copies the header and each image from the incoming file. */ GifFileOut->SWidth = GifFileIn->SWidth; GifFileOut->SHeight = GifFileIn->SHeight; GifFileOut->SColorResolution = GifFileIn->SColorResolution; GifFileOut->SBackGroundColor = GifFileIn->SBackGroundColor; GifFileOut->SColorMap = GifMakeMapObject( GifFileIn->SColorMap->ColorCount, GifFileIn->SColorMap->Colors); for (i = 0; i < GifFileIn->ImageCount; i++) (void) GifMakeSavedImage(GifFileOut, &GifFileIn->SavedImages[i]); /* * Note: don't do DGifCloseFile early, as this will * deallocate all the memory containing the GIF data! * * Further note: EGifSpew() doesn't try to validity-check any of this * data; it's *your* responsibility to keep your changes consistent. * Caveat hacker! */ if (EGifSpew(GifFileOut) == GIF_ERROR) PrintGifError(GifFileOut->Error); if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) PrintGifError(ErrorCode); if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) PrintGifError(ErrorCode); return 0; }
bool CMakeGifDoc::addImagesToGif() { const PixRectArray &prArray = getQuantizedPrArray(); if(prArray.size() == 0) { return false; } if(!hasGifFile()) { const CSize size = prArray.getMaxSize(); m_gif = allocateGifFile(size.cx, size.cy); } const SavedImageArray images(prArray, m_imageSettings.m_colorCount); for(size_t i = 0; i < images.size(); i++) { GifMakeSavedImage(m_gif, images[i]); } const SavedImage *image0 = images[0]; const ColorMapObject *colorMap = image0->ImageDesc.ColorMap; m_gif->SColorMap = GifMakeMapObject(colorMap->ColorCount, colorMap->Colors); updateTimestamp(); return true; }
static void saveGif(ByteOutputStream &out, GifFileType *gf) { int error; GifFileType *gifOut = NULL; try { gifOut = EGifOpen(&out, writeGifStreamFunction, &error); if(gifOut == NULL) { THROWGIFERROR(error); } gifOut->SWidth = gf->SWidth; gifOut->SHeight = gf->SHeight; gifOut->SColorResolution = gf->SColorResolution; gifOut->SBackGroundColor = gf->SBackGroundColor; gifOut->SColorMap = GifMakeMapObject(gf->SColorMap->ColorCount ,gf->SColorMap->Colors); for(int i = 0; i < gf->ImageCount; i++) { GifMakeSavedImage(gifOut, &gf->SavedImages[i]); } if(gifOut->ImageCount > 0) { SavedImage *image0 = gifOut->SavedImages; addNetscapeBlock(image0); } EGifSetGifVersion(gifOut, true); if(EGifSpew(gifOut) != GIF_OK) { THROWGIFERROR(gifOut->Error); } } catch(Exception e) { if(gifOut != NULL) { EGifCloseFile(gifOut, &error); } throw e; } catch(...) { if(gifOut != NULL) { EGifCloseFile(gifOut, &error); } throw; } }
void EncodeToGifBufferWorker::Execute () { GifByteType * redBuff = (GifByteType *) _pixbuf, * greenBuff = (GifByteType *) _pixbuf + _width * _height, * blueBuff = (GifByteType *) _pixbuf + 2 * _width * _height, * alphaBuff = (GifByteType *) _pixbuf + 3 * _width * _height, * gifimgbuf = (GifByteType *) malloc(_width * _height * sizeof(GifByteType)); // the indexed image ColorMapObject *cmap; SavedImage * simg; if (NULL == gifimgbuf){ SetErrorMessage("Out of memory"); return; } cmap = GifMakeMapObject(_cmapSize, NULL); if (NULL == cmap){ free(gifimgbuf); SetErrorMessage("Out of memory"); return; } if (GIF_ERROR == GifQuantizeBuffer( _width, _height, &_colors, redBuff, greenBuff, blueBuff, gifimgbuf, cmap->Colors )){ free(gifimgbuf); GifFreeMapObject(cmap); SetErrorMessage("Unable to quantize image"); return; } int errcode; gifWriteCbData buffinf = {NULL, 0}; GifFileType * gif; gif = EGifOpen((void *) &buffinf, gifWriteCB, &errcode); if (NULL == gif){ free(gifimgbuf); GifFreeMapObject(cmap); SetErrorMessage(GifErrorString(errcode)); return; } gif->SWidth = _width; gif->SHeight = _height; gif->SColorResolution = _cmapSize; simg = GifMakeSavedImage(gif, NULL); if (NULL == simg){ free(gifimgbuf); EGifCloseFile(gif, &errcode); // will also free cmap SetErrorMessage("Out of memory"); return; } simg->ImageDesc.Left = 0; simg->ImageDesc.Top = 0; simg->ImageDesc.Width = _width; simg->ImageDesc.Height = _height; simg->ImageDesc.Interlace = _interlaced; simg->ImageDesc.ColorMap = cmap; simg->RasterBits = gifimgbuf; // for some reason giflib sometimes creates an invalid file if the global // color table is not set as well gif->SColorMap = cmap; if (_trans){ ExtensionBlock ext; // 1. assign transparent color index in color table GraphicsControlBlock gcb = {0, false, 0, _colors++}; // 2. replace transparent pixels above threshold with this color remapTransparentPixels(gifimgbuf, alphaBuff, _width, _height, gcb.TransparentColor, _threshold); // 3. create a control block size_t extlen = EGifGCBToExtension(&gcb, (GifByteType *) &ext); if (GIF_ERROR == GifAddExtensionBlock( &(simg->ExtensionBlockCount), &(simg->ExtensionBlocks), GRAPHICS_EXT_FUNC_CODE, extlen, (unsigned char *) &ext) ) { EGifCloseFile(gif, &errcode); SetErrorMessage("Out of memory"); return; } } if (GIF_ERROR == EGifSpew(gif)){ EGifCloseFile(gif, &errcode); SetErrorMessage(GifErrorString(gif->Error)); return; } _gifbuf = (char *) buffinf.buff; _gifbufsize = buffinf.buffsize; return; }