static void SaveGif(const char* FileName, GifByteType *OutputBuffer, ColorMapObject *OutputColorMap, int ExpColorMapSize, int Width, int Height) { int i; GifFileType *GifFile; GifByteType *Ptr = OutputBuffer; if ((GifFile = EGifOpenFileName(FileName,0)) == NULL) QuitGifError(GifFile); if (EGifPutScreenDesc(GifFile, Width, Height, ExpColorMapSize, 0, OutputColorMap) == GIF_ERROR || EGifPutImageDesc(GifFile, 0, 0, Width, Height, FALSE, NULL) == GIF_ERROR) QuitGifError(GifFile); printf("Image '%s' at (%d, %d) [%dx%d]\n", FileName, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); for (i = 0; i < Height; i++) { if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR) QuitGifError(GifFile); Ptr += Width; } if (EGifCloseFile(GifFile) == GIF_ERROR) QuitGifError(GifFile); }
void save_image (image* img, char* file, image_format fmt) { if (fmt == imgIRMID) { FILE* fp; fp = fopen (file, "w"); fwrite (img, img->size, 1, fp); fclose (fp); } else if (fmt == imgGIF) { GifFileType* GifFileOut = (GifFileType *)NULL; GifFileOut = EGifOpenFileName (file, 0); GifColorType* color_map = new GifColorType[0x100 * 3]; for (uint n = 0; n < 0x100 ; ++n) { color_map[n].Red = n; color_map[n].Green = n; color_map[n].Blue = n; } ColorMapObject* map_object = MakeMapObject (0x100, color_map); GifRowType pixels = (GifRowType) new GifPixelType[img->xy]; for (uint n = 0; n < img->xy; ++n) pixels[n] = (GifPixelType)data(img)[n]; EGifPutScreenDesc (GifFileOut, img->dimx, img->dimy, 0x100, 0x100, map_object); EGifPutImageDesc (GifFileOut, 0, 0, img->dimx, img->dimy, 0, map_object); EGifPutLine (GifFileOut, pixels, img->xy); EGifCloseFile (GifFileOut); } }
void init_gifs(char *fileName, int sizex, int sizey) { if(gifFileIn==NULL) { gifFileIn = DGifOpenFileName("kaavyhdi.gif"); if(gifFileIn==NULL) {failExit;} printf("%i,%i: %i\n", gifFileIn->SWidth, gifFileIn->SHeight, gifFileIn->SColorResolution); if(DGifSlurp(gifFileIn) == GIF_ERROR) failExit; printf("slurp done\n"); } gifFileOut = EGifOpenFileName(fileName, FALSE); if(gifFileOut==NULL) failExit; printf("making output...\n"); if(EGifPutScreenDesc(gifFileOut, sizex, sizey, gifFileIn->SColorResolution, gifFileIn->SBackGroundColor, MakeMapObject(gifFileIn->SColorMap->ColorCount, gifFileIn->SColorMap->Colors)) == GIF_ERROR) failExit; if(EGifPutImageDesc(gifFileOut, 0, 0, sizex, sizey, FALSE, NULL) == GIF_ERROR) failExit; }
int GifTranscoder::transcode(const char* pathIn, const char* pathOut) { int error; double t0; GifFileType* gifIn; GifFileType* gifOut; // Automatically closes the GIF files when this method returns GifFilesCloser closer; gifIn = DGifOpenFileName(pathIn, &error); if (gifIn) { closer.setGifIn(gifIn); LOGD("Opened input GIF: %s", pathIn); } else { LOGE("Could not open input GIF: %s, error = %d", pathIn, error); return GIF_ERROR; } gifOut = EGifOpenFileName(pathOut, false, &error); if (gifOut) { closer.setGifOut(gifOut); LOGD("Opened output GIF: %s", pathOut); } else { LOGE("Could not open output GIF: %s, error = %d", pathOut, error); return GIF_ERROR; } t0 = now(); if (resizeBoxFilter(gifIn, gifOut)) { LOGD("Resized GIF in %.2f ms", now() - t0); } else { LOGE("Could not resize GIF"); return GIF_ERROR; } return GIF_OK; }
int main(int argc, char **argv) { FILE *input_file; float arg,size,rx,ry,rz; float f,fmin=1e10,fmax=-1e10; uint16_t i; uint64_t count; int xi,yi,zi,xo,yo,zo,nx,ny,nz,dx,dy,dz,x0,y0,z0,h; int **image; char format,type,comment[256]; GifFileType *GIFfile; ColorMapObject *GIFcmap; GifPixelType *GIFline; // // command line args // if (!((argc == 6) || (argc == 7) || (argc == 8) || (argc == 9) || (argc == 10) || (argc == 13) || (argc == 16) || (argc == 19))) { printf("command line: vol_gif in.vol out.gif nx ny nz [format [type [arg [size [dx dy dz [x0 y0 z0 [rx ry rz]]]]]]]\n"); printf(" in.vol = input volume file\n"); printf(" out.gif = output GIF file\n"); printf(" nx,ny,nz = x,y,z input voxel number\n"); printf(" format = 'f' for float 32, 'i' for uint16_t (default 'f')\n"); printf(" type = 's' for section, 'h' for height (default 's')\n"); printf(" arg = gamma for 's', threshold for 'h' (default 1)\n"); printf(" size = mm per voxel (default 1)\n"); printf(" dx,dy,dz = x,y,z output voxel number (default all)\n"); printf(" x0,y0,z0 = x,y,z output voxel origin (default 0)\n"); printf(" to be implemented: rx,ry,rz = view rotation angles (degrees; default 0)\n"); exit(-1); } format = 'f'; type = 's'; arg = 1; size = 1.0; rx = ry = rz = 0; sscanf(argv[3],"%d",&nx); sscanf(argv[4],"%d",&ny); sscanf(argv[5],"%d",&nz); dx = nx; dy = ny; dz = nz; x0 = y0 = z0 = 0; if (argc >= 7) { sscanf(argv[6],"%c",&format); if (!((format == 'f') || (format == 'i'))) { printf("vol_gif: oops -- format must be 'f' or 'i'\n"); exit(-1); } } if (argc >= 8) { sscanf(argv[7],"%c",&type); if (!((type == 's') || (type == 'h'))) { printf("vol_gif: oops -- type must be 's' or 'h'\n"); exit(-1); } } if (argc >= 9) { sscanf(argv[8],"%f",&arg); } if (argc >= 10) { sscanf(argv[9],"%f",&size); } if (argc >= 13) { sscanf(argv[10],"%d",&x0); sscanf(argv[11],"%d",&y0); sscanf(argv[12],"%d",&z0); } if (argc >= 16) { sscanf(argv[13],"%d",&dx); sscanf(argv[14],"%d",&dy); sscanf(argv[15],"%d",&dz); } if (argc >= 19) { sscanf(argv[16],"%f",&rx); sscanf(argv[17],"%f",&ry); sscanf(argv[18],"%f",&rz); } // // check and find limits // input_file = fopen(argv[1],"rb"); if (input_file == NULL) { printf("vol_gif: oops -- can not open %s\n",argv[1]); exit(-1); } if (((x0 + dx) > nx) || ((y0 + dy) > ny) || ((z0 + dz) > nz)) { printf("vol_gif: oops -- region too large\n"); exit(-1); } printf("read %s\n",argv[1]); if (format == 'f') { count = 0; while (fread(&f,sizeof(f),1,input_file) != 0) { if (f > fmax) fmax = f; if (f < fmin) fmin = f; count += 1; } } else if (format == 'i') { count = 0; while (fread(&i,sizeof(i),1,input_file) != 0) { if (i > fmax) fmax = i; if (i < fmin) fmin = i; count += 1; } } printf(" %" PRIu64 " points, min %f, max %f\n",count,fmin,fmax); printf(" nx ny nz: %d %d %d\n",nx,ny,nz); rewind(input_file); // // set up color map // #if GIFLIB_MAJOR >= 5 GIFcmap = GifMakeMapObject(256, NULL); #else GIFcmap = MakeMapObject(256, NULL); #endif for (i = 0; i < 256; i++) { GIFcmap->Colors[i].Red = i; GIFcmap->Colors[i].Green = i; GIFcmap->Colors[i].Blue = i; } // // open GIF file // printf("write %s\n",argv[2]); EGifPutScreenDesc(GIFfile,dx,dy,8,0,GIFcmap); unsigned char loop_count[] = {1,0,0}; #if GIFLIB_MAJOR >= 5 GIFfile = EGifOpenFileName(argv[2], 0, NULL); EGifPutExtension(GIFfile, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0"); EGifPutExtension(GIFfile, APPLICATION_EXT_FUNC_CODE, 3, loop_count); #else GIFfile = EGifOpenFileName(argv[2], 0); EGifPutExtensionFirst(GIFfile, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0"); EGifPutExtensionLast(GIFfile, APPLICATION_EXT_FUNC_CODE, 3, loop_count); #endif unsigned char delay_count[5] = { 0, // no transparency 0, // delay time 0, // delay time 0 // transparent index not used }; // // allocate image // image = malloc(dy*sizeof(int *)); for (yo = 0; yo < dy; ++yo) { image[yo] = malloc(dx*sizeof(int)); for (xo = 0; xo < dx; ++xo) image[yo][xo] = 0; } GIFline = malloc(dx*sizeof(GifPixelType)); // // scan file // xi = yi = zi = 0; for (zo = 0; zo < dz; ++zo) { printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b layer = %d",zo); EGifPutExtension(GIFfile,GRAPHICS_EXT_FUNC_CODE,4,delay_count); EGifPutImageDesc(GIFfile,0,0,dx,dy,0,NULL); // // read layer // for (yo = 0; yo < dy; ++yo) { for (xo = 0; xo < dx; ++xo) { if (format == 'f') { read_voxel_f(input_file,&f,xo+x0,yo+y0,zo+z0,&xi,&yi,&zi,nx,ny,nz); if (type == 'h') { h = 255*zo/(nz-1.0); if ((h > image[yo][xo]) && (f > arg)) image[yo][xo] = h; GIFline[xo] = image[yo][xo]*(nz-1.0)/zo; } else if (type == 's') { GIFline[xo] = 255*pow((f-fmin)/(fmax-fmin),arg); } } else if (format == 'i') { read_voxel_i(input_file,&i,xo+x0,yo+y0,zo+z0,&xi,&yi,&zi,nx,ny,nz); if (type == 'h') { h = 255*zo/(nz-1.0); if ((h > image[yo][xo]) && (i > arg)) image[yo][xo] = h; GIFline[xo] = image[yo][xo]*(nz-1.0)/zo; } else if (type == 's') { GIFline[xo] = 255*pow((i-fmin)/(fmax-fmin),arg); } } } EGifPutLine(GIFfile,GIFline,dx); } } printf("\n"); // // put mm per pixel in comment // sprintf(comment,"mm per pixel: %f;",size); EGifPutComment(GIFfile,comment); // // exit // fclose(input_file); EGifCloseFile(GIFfile); exit(0); }
bool toGif(QImage& img, QString& path) { int errcode; if(QFile(path).exists()) // Remove old file QFile::remove(path); GifFileType* t = EGifOpenFileName(path.toLocal8Bit().data(),true, &errcode); if(!t){ EGifCloseFile(t, &errcode); QTextStream(stdout) << "Can't open\n"; return false; } EGifSetGifVersion(t, true); GifColorType* colorArr = new GifColorType[256]; ColorMapObject* cmo = GifMakeMapObject(256, colorArr); bool unfinished = false; QImage tarQImg(img.width(), img.height(), QImage::Format_Indexed8); QVector<QRgb> table; for(int y = 0; y < img.height(); y++){ for(int x = 0; x < img.width(); x++){ if(table.size() >= 256){ unfinished = true; break; } QRgb pix; if(!table.contains(pix = img.pixel(x,y))){ table.push_back(pix); tarQImg.setColor(tarQImg.colorCount(), pix); } tarQImg.setPixel(x,y,table.indexOf(pix)); } if(table.size() >= 256){ unfinished = true; break; } } if(unfinished){ EGifCloseFile(t, &errcode); QTextStream(stdout) << "Unfinished\n"; return false; } for(int l = tarQImg.colorCount(); l < 256; l++){ tarQImg.setColor(l,0); } if(tarQImg.colorTable().size() != 256){ EGifCloseFile(t, &errcode); QTextStream(stdout) << "A lot of colors\n"; return false; } QVector<QRgb> clTab = tarQImg.colorTable(); for(int i = 0; i < 255; i++){ QRgb rgb = clTab[i]; colorArr[i].Red = qRed(rgb); colorArr[i].Green = qGreen(rgb); colorArr[i].Blue = qBlue(rgb); } cmo->Colors = colorArr; errcode = EGifPutScreenDesc(t, img.width(), img.height(), 256, 0, cmo); if(errcode != GIF_OK){ EGifCloseFile(t, &errcode); QTextStream(stdout) << "EGifPutScreenDesc error 1\n"; return false; } errcode = EGifPutImageDesc(t, 0, 0, img.width(), img.height(), false, 0); if(errcode != GIF_OK){ EGifCloseFile(t, &errcode); QTextStream(stdout) << "EGifPutImageDesc error 2\n"; return false; } //gen byte array GifByteType* byteArr = tarQImg.bits(); for(int h = 0; h < tarQImg.height(); h++){ errcode = EGifPutLine(t, byteArr, tarQImg.width()); if(errcode != GIF_OK){ EGifCloseFile(t, &errcode); QTextStream(stdout) << "EGifPutLine error 3\n"; return false; } byteArr += tarQImg.width(); byteArr += ((tarQImg.width() % 4)!=0 ? 4 - (tarQImg.width() % 4) : 0); } if(errcode != GIF_OK){ QTextStream(stdout) << "GIF error 4\n"; return false; } EGifCloseFile(t, &errcode); return true; }
bool Graphics::toGif(QImage &img, QString &path) { int errcode; if(QFile(path).exists()) // Remove old file QFile::remove(path); GifFileType *t = EGifOpenFileName(path.toStdString().c_str(), true, &errcode); if(!t) { EGifCloseFile(t, &errcode); std::cout << "Can't open\n"; return false; } EGifSetGifVersion(t, true); std::vector<GifColorType>colorArr; colorArr.resize(256); ColorMapObject *cmo = GifMakeMapObject(256, colorArr.data()); bool unfinished = false; QImage tarQImg(img.width(), img.height(), QImage::Format_Indexed8); QVector<QRgb> table; for(int y = 0; y < img.height(); y++) { for(int x = 0; x < img.width(); x++) { if(table.size() >= 256) { unfinished = true; break; } QRgb pix; if(!table.contains(pix = img.pixel(x, y))) { table.push_back(pix); tarQImg.setColor(tarQImg.colorCount(), pix); } tarQImg.setPixel(x, y, static_cast<uint>(table.indexOf(pix))); } if(table.size() >= 256) { unfinished = true; break; } } if(unfinished) { GifFreeMapObject(cmo); EGifCloseFile(t, &errcode); std::cout << "Unfinished\n"; return false; } for(int l = tarQImg.colorCount(); l < 256; l++) tarQImg.setColor(l, 0); if(tarQImg.colorTable().size() != 256) { GifFreeMapObject(cmo); EGifCloseFile(t, &errcode); std::cout << "A lot of colors\n"; return false; } std::vector<QRgb> clTab = tarQImg.colorTable().toStdVector(); for(size_t i = 0; i < 255; i++) { QRgb rgb = clTab[i]; colorArr[i].Red = static_cast<unsigned char>(qRed(rgb)); colorArr[i].Green = static_cast<unsigned char>(qGreen(rgb)); colorArr[i].Blue = static_cast<unsigned char>(qBlue(rgb)); } cmo->Colors = colorArr.data(); errcode = EGifPutScreenDesc(t, img.width(), img.height(), 256, 0, cmo); if(errcode != GIF_OK) { GifFreeMapObject(cmo); EGifCloseFile(t, &errcode); std::cout << "EGifPutScreenDesc error 1\n"; return false; } errcode = EGifPutImageDesc(t, 0, 0, img.width(), img.height(), false, 0); if(errcode != GIF_OK) { GifFreeMapObject(cmo); EGifCloseFile(t, &errcode); std::cout << "EGifPutImageDesc error 2\n"; return false; } //gen byte array GifByteType *byteArr = tarQImg.bits(); for(int h = 0; h < tarQImg.height(); h++) { errcode = EGifPutLine(t, byteArr, tarQImg.width()); if(errcode != GIF_OK) { GifFreeMapObject(cmo); EGifCloseFile(t, &errcode); std::cout << "EGifPutLine error 3\n"; return false; } byteArr += tarQImg.width(); byteArr += ((tarQImg.width() % 4) != 0 ? 4 - (tarQImg.width() % 4) : 0); } GifFreeMapObject(cmo); EGifCloseFile(t, &errcode); return true; }
/****************************************************************************** * Perform the disassembly operation - take one input files into few output. * ******************************************************************************/ static int DoDisassemblyNum(const char *InFileName, char *OutFileName, int FileNum) { int ExtCode, CodeSize, FileEmpty; GifRecordType RecordType; char CrntFileName[80], *p; GifByteType *Extension, *CodeBlock; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; int ErrorCode; /* If name has type postfix, strip it out, and make sure name is less */ /* or equal to 6 chars, so we will have 2 chars in name for numbers. */ //strupr(OutFileName); /* Make sure all is upper case */ #if 0 printf("OutFileName : %s\n", OutFileName); if ((p = strrchr(OutFileName, '.')) != NULL && strlen(p) <= 4) p[0] = 0; if ((p = strrchr(OutFileName, '/')) != NULL || (p = strrchr(OutFileName, '\\')) != NULL || (p = strrchr(OutFileName, ':')) != NULL) { if (strlen(p) > 7) p[7] = 0; /* p includes the '/', '\\', ':' char */ } else { /* Only name is given for current directory: */ //if (strlen(OutFileName) > 6) OutFileName[6] = 0; } printf("OutFileName : %s\n", OutFileName); #endif /* Open input file: */ if (InFileName != NULL) { if ((GifFileIn = DGifOpenFileName(InFileName, &ErrorCode)) == NULL) return QuitGifError(GifFileIn, GifFileOut); } else { /* Use the stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) return QuitGifError(GifFileIn, GifFileOut); } /* Scan the content of GIF file and dump image(s) to seperate file(s): */ //sprintf(CrntFileName, "%s_%02d.gif", OutFileName, FileNum); sprintf(CrntFileName, "%s", OutFileName); if ((GifFileOut = EGifOpenFileName(CrntFileName, TRUE, &ErrorCode)) == NULL) return QuitGifError(GifFileIn, GifFileOut); FileEmpty = TRUE; /* And dump out its exactly same screen information: */ if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: FileEmpty = FALSE; if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); /* Put same image descriptor to out file: */ if (EGifPutImageDesc(GifFileOut, GifFileIn->Image.Left, GifFileIn->Image.Top, GifFileIn->Image.Width, GifFileIn->Image.Height, GifFileIn->Image.Interlace, GifFileIn->Image.ColorMap) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); /* Now read image itself in decoded form as we dont */ /* really care what is there, and this is much faster. */ if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); while (CodeBlock != NULL) if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); break; case EXTENSION_RECORD_TYPE: FileEmpty = FALSE; /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], Extension) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); /* No support to more than one extension blocks, discard */ while (Extension != NULL) if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType */ break; } } while (RecordType != IMAGE_DESC_RECORD_TYPE && RecordType != TERMINATE_RECORD_TYPE); if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); if (FileEmpty) { /* Might happen on last file - delete it if so: */ unlink(CrntFileName); } if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) return QuitGifError(GifFileIn, GifFileOut); }
bool ParupaintPanvasInputOutput::exportGIF(ParupaintPanvas * panvas, const QString & filename, QString & errorStr) { Q_ASSERT(panvas); if(filename.isEmpty()) return (errorStr = "Enter a filename to save to.").isEmpty(); #ifndef PARUPAINT_NOGIF int error = 0; GifFileType * gif = EGifOpenFileName(filename.toStdString().c_str(), false, &error); foreach(const QImage & image, panvas->mergedImageFrames(true)){ error = 0; bool alpha = false; QImage toWrite = convertToIndexed8(image, &alpha); QVector<QRgb> colorTable = toWrite.colorTable(); ColorMapObject cmap; int numColors = 1 << BitSize(toWrite.colorCount()); numColors = 256; cmap.ColorCount = numColors; cmap.BitsPerPixel = 8; /// @todo based on numColors (or not? we did ask for Format_Indexed8, so the data is always 8-bit, right?) GifColorType* colorValues = (GifColorType*)malloc(cmap.ColorCount * sizeof(GifColorType)); cmap.Colors = colorValues; int c = 0; for(; c < toWrite.colorCount(); ++c) { //qDebug("color %d has %02X%02X%02X", c, qRed(colorTable[c]), qGreen(colorTable[c]), qBlue(colorTable[c])); colorValues[c].Red = qRed(colorTable[c]); colorValues[c].Green = qGreen(colorTable[c]); colorValues[c].Blue = qBlue(colorTable[c]); } // In case we had an actual number of colors that's not a power of 2, // fill the rest with something (black perhaps). for (; c < numColors; ++c) { colorValues[c].Red = 0; colorValues[c].Green = 0; colorValues[c].Blue = 0; } /// @todo how to specify which version, or decide based on features in use // Because of this call, libgif is not re-entrant EGifSetGifVersion(gif, true); if ((error = EGifPutScreenDesc(gif, toWrite.width(), toWrite.height(), numColors, 0, &cmap)) == GIF_ERROR) qCritical("EGifPutScreenDesc returned error %d", error); int fps = (100.0/panvas->frameRate()); char flags = 1 << 3; if(alpha) flags |= 1; char graphics_ext[] = { flags, (char)(fps % 256), (char)(fps / 256), (char)(alpha ? 0x00 : 0xff) }; EGifPutExtension(gif, GRAPHICS_EXT_FUNC_CODE, 4, graphics_ext); if ((error = EGifPutImageDesc(gif, 0, 0, toWrite.width(), toWrite.height(), 0, &cmap)) == GIF_ERROR) qCritical("EGifPutImageDesc returned error %d", error); int lc = toWrite.height(); int llen = toWrite.bytesPerLine(); for (int l = 0; l < lc; ++l) { uchar* line = toWrite.scanLine(l); if ((error = EGifPutLine(gif, (GifPixelType*)line, llen)) == GIF_ERROR) { qCritical("EGifPutLine returned error %d", error); } } if(true){ // loop forever unsigned char loopblock[3] = {1, 0, 0}; EGifPutExtensionLeader(gif, APPLICATION_EXT_FUNC_CODE); EGifPutExtensionBlock(gif, 11, "NETSCAPE2.0"); EGifPutExtensionBlock(gif, 3, loopblock); EGifPutExtensionTrailer(gif); } } EGifCloseFile(gif, &error); return true; #endif return (errorStr = "GIF export not available.").isEmpty(); }
int write_gif(const char *filename, int width, int height, char *rgb) { int i; int colormap_size = 256; GifByteType *red, *green, *blue, *buffer, *ptr; GifFileType *outfile; ColorMapObject *colormap; red = malloc(width * height * sizeof(GifByteType)); green = malloc(width * height * sizeof(GifByteType)); blue = malloc(width * height * sizeof(GifByteType)); buffer = malloc(width * height * sizeof(GifByteType)); if (red == NULL || green == NULL || blue == NULL || buffer == NULL) { fprintf(stderr, "Can't allocate memory for GIF file.\n"); return(0); } colormap = MakeMapObject(colormap_size, NULL); for (i = 0; i < width * height; i++) { red[i] = (GifByteType) rgb[3*i ]; green[i] = (GifByteType) rgb[3*i+1]; blue[i] = (GifByteType) rgb[3*i+2]; } if (QuantizeBuffer(width, height, &colormap_size, red, green, blue, buffer, colormap->Colors) == GIF_ERROR) { PrintGifError(); return(0); } free(red); free(green); free(blue); outfile = EGifOpenFileName((char *) filename, FALSE); if (outfile == NULL) { PrintGifError(); return(0); } if (EGifPutScreenDesc(outfile, width, height, colormap_size, 0, colormap) == GIF_ERROR) { PrintGifError(); return(0); } if (EGifPutImageDesc(outfile, 0, 0, width, height, FALSE, NULL) == GIF_ERROR) { PrintGifError(); return(0); } ptr = buffer; for (i = 0; i < height; i++) { if (EGifPutLine(outfile, ptr, width) == GIF_ERROR) { PrintGifError(); return(0); } ptr += width; } EGifSpew(outfile); if (EGifCloseFile(outfile) == GIF_ERROR) PrintGifError(); free(buffer); return(1); }
static int ImageToGif(UCHAR **Image,int ImageWidth,int ImageHeight, char *GifFileName,int Paleta,int Laplas) { int NumLevels=255,i; /* Konwersja ekranu wirtualnego do postaci */ GifColorType *ColorMap; /* obrazu w formacie GIF */ GifFileType *GifFile; /* Oparte na bibliotece giflib */ if(prn==ON) fprintf(stdout,"<<< TWORZENIE OBRAZU W FORMACIE GIF'A : %s >>>\n",GifFileName); if((GifFile=EGifOpenFileName(GifFileName,0))==NULL) { QuitGifError(GifFile); return -1; } if((ColorMap=(GifColorType *)malloc(NumLevels*sizeof(GifColorType)))==NULL) { fprintf(stderr,"Failed to allocate memory required, aborted.\n"); QuitGifError(GifFile); return -1; } if(prn==ON) fprintf(stdout,"<<< GENERACJA PALETY BARW (%s) >>>\n", ((Paleta==COLOR) ? "TERM" : ( (Paleta==INVERT_GRAY) ? "INVERT GARY" : "GRAY") ) ); MakePalette(ColorMap,Paleta,Laplas); if(EGifPutScreenDesc(GifFile,ImageWidth,ImageHeight,8,0, 8,ColorMap)==GIF_ERROR) { QuitGifError(GifFile); free((void *)ColorMap); return -1; } if(EGifPutImageDesc(GifFile,0,0,ImageWidth,ImageHeight, FALSE,8,NULL)==GIF_ERROR) { QuitGifError(GifFile); free((void *)ColorMap); return -1; } if(prn==ON) fprintf(stdout,"<<< KODOWANIE OBRAZU >>>\n"); for(i=0 ; i<ImageHeight ; i++) if(EGifPutLine(GifFile,Image[i],ImageWidth)==GIF_ERROR) { QuitGifError(GifFile); free((void *)ColorMap); return -1; } if(EGifCloseFile(GifFile)==GIF_ERROR) { QuitGifError(GifFile); free((void *)ColorMap); return -1; } free((void *)ColorMap); return 0; }
void AnimatedGifEncoder::new_frame(unsigned char *data, int delay) { if (!gif_file) { if (write_func != NULL) { int nError; gif_file = EGifOpen(write_user_data, write_func, &nError); if (!gif_file) throw "EGifOpen in AnimatedGifEncoder::new_frame failed"; } else if (file_name.empty()) { // memory writer int nError; gif_file = EGifOpen(&gif, gif_writer, &nError); if (!gif_file) throw "EGifOpen in AnimatedGifEncoder::new_frame failed"; } else { int nError; gif_file = EGifOpenFileName(file_name.c_str(), FALSE, &nError); if (!gif_file) throw "EGifOpenFileName in AnimatedGifEncoder::new_frame failed"; } output_color_map = GifMakeMapObject(color_map_size, ext_web_safe_palette); if (!output_color_map) throw "MakeMapObject in AnimatedGifEncoder::new_frame failed"; gif_buf = (GifByteType *)malloc(sizeof(GifByteType)*width*height); if (!gif_buf) throw "malloc in AnimatedGifEncoder::new_frame failed"; } RGBator rgb(data, width, height, buf_type); if (web_safe_quantize(width, height, rgb.red, rgb.green, rgb.blue, gif_buf) == GIF_ERROR) throw "web_safe_quantize in AnimatedGifEncoder::new_frame failed"; /* if (QuantizeBuffer(width, height, &color_map_size, rgb.red, rgb.green, rgb.blue, gif_buf, output_color_map->Colors) == GIF_ERROR) { throw "QuantizeBuffer in AnimatedGifEncoder::new_frame failed"; } */ if (!headers_set) { if (EGifPutScreenDesc(gif_file, width, height, color_map_size, 0, output_color_map) == GIF_ERROR) { throw "EGifPutScreenDesc in AnimatedGifEncoder::new_frame failed"; } char netscape_extension[] = "NETSCAPE2.0"; EGifPutExtension(gif_file, APPLICATION_EXT_FUNC_CODE, 11, netscape_extension); char animation_extension[] = { 1, 1, 0 }; // repeat one time EGifPutExtension(gif_file, APPLICATION_EXT_FUNC_CODE, 3, animation_extension); headers_set = true; } char frame_flags = 1 << 2; char transp_color_idx = 0; if (transparency_color.color_present) { int i = find_color_index(output_color_map, color_map_size, transparency_color); if (i>=0) { frame_flags |= 1; transp_color_idx = i; } } char extension[] = { frame_flags, delay%256, delay/256, transp_color_idx }; EGifPutExtension(gif_file, GRAPHICS_EXT_FUNC_CODE, 4, extension); if (EGifPutImageDesc(gif_file, 0, 0, width, height, FALSE, NULL) == GIF_ERROR) { throw "EGifPutImageDesc in AnimatedGifEncoder::new_frame failed"; } GifByteType *gif_bufp = gif_buf; for (int i = 0; i < height; i++) { if (EGifPutLine(gif_file, gif_bufp, width) == GIF_ERROR) { throw "EGifPutLine in AnimatedGifEncoder::new_frame failed"; } gif_bufp += width; } }