static int gifdrv_close_memmap(void) { EGifCloseFile(gifdrv_memmap_fd); VICE_FreeMapObject(gif_colors); lib_free(gifdrv_memmap_ext_filename); return 0; }
/****************************************************************************** Close output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFile) { if (GifFile != NULL) { PrintGifError(GifFile->Error); EGifCloseFile(GifFile, NULL); } exit(EXIT_FAILURE); }
/*! * \brief pixWriteMemGif() * * \param[out] pdata data of gif compressed image * \param[out] psize size of returned data * \param[in] pix * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) See comments in pixReadMemGif() * (2) For Giflib version >= 5.1, this uses the EGifOpen() buffer * interface. No temp files are required. * </pre> */ l_int32 pixWriteMemGif(l_uint8 **pdata, size_t *psize, PIX *pix) { #if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5 int giferr; l_int32 result; GifFileType *gif; L_BBUFFER *buffer; #else char *fname; #endif /* 5.1 and beyond */ PROCNAME("pixWriteMemGif"); if (!pdata) return ERROR_INT("&data not defined", procName, 1 ); *pdata = NULL; if (!psize) return ERROR_INT("&size not defined", procName, 1 ); *psize = 0; if (!pix) return ERROR_INT("&pix not defined", procName, 1 ); #if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5 if((buffer = bbufferCreate(NULL, 0)) == NULL) { return ERROR_INT("failed to create buffer", procName, 1); } if ((gif = EGifOpen((void*)buffer, gifWriteFunc, NULL)) == NULL) { bbufferDestroy(&buffer); return ERROR_INT("failed to create GIF image handle", procName, 1); } result = pixToGif(pix, gif); EGifCloseFile(gif, &giferr); if(result == 0) { *pdata = bbufferDestroyAndSaveData(&buffer, psize); } else { bbufferDestroy(&buffer); } return result; #else L_INFO("writing to a temp file, not directly to memory\n", procName); /* Write to a temp file */ fname = l_makeTempFilename(NULL); pixWrite(fname, pix, IFF_GIF); /* Read back into memory */ *pdata = l_binaryRead(fname, psize); lept_rmfile(fname); LEPT_FREE(fname); return 0; #endif }
/****************************************************************************** * Close both input and output file (if open), and exit. * ******************************************************************************/ static int QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut) { int ErrorCode; // PrintGifError(ErrorCode); if (GifFileIn != NULL) DGifCloseFile(GifFileIn, &ErrorCode); if (GifFileOut != NULL) EGifCloseFile(GifFileOut, &ErrorCode); //exit(1); return -1; }
/****************************************************************************** * Handle last GIF error. Try to close the file and free all allocated memory. * ******************************************************************************/ static int HandleGifError(GifFileType *GifFile) { int i = GifLastError(); if (EGifCloseFile(GifFile) == GIF_ERROR) { GifLastError(); } return i; }
INLINE void * gif_save(const Image *image, const ColorMapObject *color_map, Frame *frames, int count, int frame_size, int *size) { GifBuffer buf = {0,}; int estimated = count * (image->columns * image->rows); buf.alloc = estimated; buf.data = malloc(estimated); GifFileType *gif_file = EGifOpen(&buf, gif_buffer_write, NULL); if (!gif_file) { return NULL; } if (EGifPutScreenDesc(gif_file, image->columns, image->rows, NCOLORS, 0, color_map) == GIF_ERROR) { EGifCloseFile(gif_file, NULL); return NULL; } if (GIF_BEGIN_APP_EXTENSION(gif_file) == GIF_ERROR) { EGifCloseFile(gif_file, NULL); return NULL; } unsigned char meta[] = { 0x01, // data sub-block index (always 1) 0xFF, 0xFF // 65535 repetitions - unsigned }; if (GIF_END_APP_EXTENSION(gif_file, meta) == GIF_ERROR) { EGifCloseFile(gif_file, NULL); return NULL; } int ii; unsigned char *p = (unsigned char*)frames; for (ii = 0; ii < count; ii++, p += frame_size) { Frame *frame = (Frame*)p; // GCE unsigned char gce[] = { 0x08, // no transparency frame->duration % 256, // LSB of delay frame->duration / 256, // MSB of delay in millisecs 0x00, // no transparent color }; if (EGifPutExtension(gif_file, GRAPHICS_EXT_FUNC_CODE, sizeof(gce), gce) == GIF_ERROR) { EGifCloseFile(gif_file, NULL); return NULL; } if (EGifPutImageDesc(gif_file, 0, 0, frame->width, frame->height, 0, NULL) == GIF_ERROR) { EGifCloseFile(gif_file, NULL); return NULL; } int yy; GifPixelType *p = frame->data; for (yy = 0; yy < frame->height; yy++, p += frame->width) { if (EGifPutLine(gif_file, p, frame->width) == GIF_ERROR) { EGifCloseFile(gif_file, NULL); return NULL; } } } EGifCloseFile(gif_file, NULL); *size = buf.size; return buf.data; }
static int gifdrv_open(screenshot_t *screenshot, const char *filename) { unsigned int i; gfxoutputdrv_data_t *sdata; GifColorType ColorMap256[256]; #if GIFLIB_MAJOR >= 5 int ec; #endif if (screenshot->palette->num_entries > 256) { log_error(LOG_DEFAULT, "Max 256 colors supported."); return -1; } sdata = lib_malloc(sizeof(gfxoutputdrv_data_t)); screenshot->gfxoutputdrv_data = sdata; sdata->line = 0; sdata->ext_filename = util_add_extension_const(filename, gif_drv.default_extension); sdata->fd = VICE_EGifOpenFileName(sdata->ext_filename, 0, &ec); if (sdata->fd == NULL) { lib_free(sdata->ext_filename); lib_free(sdata); return -1; } sdata->data = lib_malloc(screenshot->width); gif_colors = VICE_MakeMapObject(screenshot->palette->num_entries, ColorMap256); for (i = 0; i < screenshot->palette->num_entries; i++) { gif_colors->Colors[i].Blue = screenshot->palette->entries[i].blue; gif_colors->Colors[i].Green = screenshot->palette->entries[i].green; gif_colors->Colors[i].Red = screenshot->palette->entries[i].red; } #if GIFLIB_MAJOR < 5 EGifSetGifVersion("87a"); #endif if (EGifPutScreenDesc(sdata->fd, screenshot->width, screenshot->height, 8, 0, gif_colors) == GIF_ERROR || EGifPutImageDesc(sdata->fd, 0, 0, screenshot->width, screenshot->height, 0, NULL) == GIF_ERROR) { EGifCloseFile(sdata->fd); VICE_FreeMapObject(gif_colors); lib_free(sdata->data); lib_free(sdata->ext_filename); lib_free(sdata); return -1; } return 0; }
GifFilesCloser::~GifFilesCloser() { if (mGifIn) { DGifCloseFile(mGifIn); mGifIn = NULL; } if (mGifOut) { EGifCloseFile(mGifOut); mGifOut = NULL; } }
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 AnimatedGifEncoder::end_encoding() { free(gif_buf); gif_buf = NULL; if (output_color_map) { GifFreeMapObject(output_color_map); output_color_map = NULL; } if (gif_file) { EGifCloseFile(gif_file); gif_file = NULL; } }
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; }
/*! * \brief pixWriteMemGif() * * \param[out] pdata data of gif compressed image * \param[out] psize size of returned data * \param[in] pix * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) See comments in pixReadMemGif() * </pre> */ l_int32 pixWriteMemGif(l_uint8 **pdata, size_t *psize, PIX *pix) { int giferr; l_int32 result; GifFileType *gif; L_BBUFFER *buffer; PROCNAME("pixWriteMemGif"); /* 5.1+ and not 5.1.2 */ #if (GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0)) L_ERROR("Require giflib-5.1 or later\n", procName); return 1; #endif /* < 5.1 */ #if GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 1 && GIFLIB_RELEASE == 2 /* 5.1.2 */ L_ERROR("Can't use giflib-5.1.2; suggest 5.1.3 or later\n", procName); return 1; #endif /* 5.1.2 */ if (!pdata) return ERROR_INT("&data not defined", procName, 1 ); *pdata = NULL; if (!psize) return ERROR_INT("&size not defined", procName, 1 ); *psize = 0; if (!pix) return ERROR_INT("&pix not defined", procName, 1 ); if ((buffer = bbufferCreate(NULL, 0)) == NULL) return ERROR_INT("failed to create buffer", procName, 1); if ((gif = EGifOpen((void*)buffer, gifWriteFunc, NULL)) == NULL) { bbufferDestroy(&buffer); return ERROR_INT("failed to create GIF image handle", procName, 1); } result = pixToGif(pix, gif); EGifCloseFile(gif, &giferr); if (result == 0) { *pdata = bbufferDestroyAndSaveData(&buffer, psize); } else { bbufferDestroy(&buffer); } return result; }
static int gifdrv_close(screenshot_t *screenshot) { gfxoutputdrv_data_t *sdata; sdata = screenshot->gfxoutputdrv_data; EGifCloseFile(sdata->fd); VICE_FreeMapObject(gif_colors); /* for some reason giflib will create a file with unexpected permissions. for this reason we alter them according to the current umask. */ archdep_fix_permissions(sdata->ext_filename); lib_free(sdata->data); lib_free(sdata->ext_filename); lib_free(sdata); return 0; }
/*! * \brief pixWriteStreamGif() * * \param[in] fp file stream * \param[in] pix 1, 2, 4, 8, 16 or 32 bpp * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) All output gif have colormaps. If the pix is 32 bpp rgb, * this quantizes the colors and writes out 8 bpp. * If the pix is 16 bpp grayscale, it converts to 8 bpp first. * (2) We can't write to memory using open_memstream() because * the gif functions write through a file descriptor, not a * file stream. * </pre> */ l_int32 pixWriteStreamGif(FILE *fp, PIX *pix) { l_int32 result; l_int32 fd; GifFileType *gif; #if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5 int giferr; #endif /* 5.1 and beyond */ PROCNAME("pixWriteStreamGif"); /* See version information at top of this file */ #if GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 1 && GIFLIB_RELEASE == 2 /* 5.1.2 */ return ERROR_INT("Can't use giflib-5.1.2; suggest 5.1.1 or earlier\n", procName, 1); #endif /* 5.1.2 */ if (!fp) return ERROR_INT("stream not open", procName, 1); if (!pix) return ERROR_INT("pix not defined", procName, 1); rewind(fp); if ((fd = fileno(fp)) < 0) return ERROR_INT("invalid file descriptor", procName, 1); #ifdef _WIN32 fd = _dup(fd); #endif /* _WIN32 */ /* Get the gif file handle */ if ((gif = EGifOpenFileHandle(fd, NULL)) == NULL) { return ERROR_INT("failed to create GIF image handle", procName, 1); } result = pixToGif(pix, gif); EGifCloseFile(gif, &giferr); return result; }
static int gifdrv_open_memmap(const char *filename, int x_size, int y_size, BYTE *palette) { unsigned int i; GifColorType ColorMap256[256]; #if GIFLIB_MAJOR >= 5 int ec; #endif gifdrv_memmap_ext_filename = util_add_extension_const(filename, gif_drv.default_extension); gifdrv_memmap_fd = VICE_EGifOpenFileName(gifdrv_memmap_ext_filename, 0, &ec); if (gifdrv_memmap_fd == NULL) { lib_free(gifdrv_memmap_ext_filename); return -1; } gif_colors = VICE_MakeMapObject(256, ColorMap256); for (i = 0; i < 256; i++) { gif_colors->Colors[i].Blue = palette[(i * 3) + 2]; gif_colors->Colors[i].Green = palette[(i * 3) + 1]; gif_colors->Colors[i].Red = palette[i * 3]; } #if GIFLIB_MAJOR < 5 EGifSetGifVersion("87a"); #endif if (EGifPutScreenDesc(gifdrv_memmap_fd, x_size, y_size, 8, 0, gif_colors) == GIF_ERROR || EGifPutImageDesc(gifdrv_memmap_fd, 0, 0, x_size, y_size, 0, NULL) == GIF_ERROR) { EGifCloseFile(gifdrv_memmap_fd); VICE_FreeMapObject(gif_colors); lib_free(gifdrv_memmap_ext_filename); return -1; } return 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; }
/****************************************************************************** * Close output file (if open), and exit. * ******************************************************************************/ static void QuitGifError(GifFileType *GifFile) { PrintGifError(); if (GifFile != NULL) EGifCloseFile(GifFile); exit(EXIT_FAILURE); }
/****************************************************************************** Main sequence ******************************************************************************/ int main(int argc, char **argv) { GifFileType *GifFileIn = NULL, *GifFileOut = NULL; GifRecordType RecordType; int CodeSize, ExtCode, ErrorCode; GifByteType *CodeBlock, *Extension; /* * Command-line processing goes here. */ /* Use stdin as input (note this also read screen descriptor in: */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Use the stdout as output: */ if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* And dump out its screen information: */ if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Scan the content of the input GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Put 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) QuitGifError(GifFileIn, GifFileOut); /* Now read image itself in decoded form as we dont really */ /* care what we have there, and this is much faster. */ if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } break; case EXTENSION_RECORD_TYPE: /* pass through extension records */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifPutExtensionBlock(GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); while (Extension != NULL) { if (DGifGetExtensionNext(GifFileIn, &Extension)==GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (Extension != NULL) if (EGifPutExtensionBlock(GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); if (GifFileIn != NULL) { EGifCloseFile(GifFileIn, NULL); } exit(EXIT_FAILURE); } if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); if (GifFileOut != NULL) { EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } return 0; }
/****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ int main(int argc, char **argv) { int i, iy, last_iy, l, t, w, h, Error, NumFiles, ExtCode, ImageNum = 0, SizeFlag = FALSE, ScaleFlag = FALSE, XScaleFlag = FALSE, YScaleFlag = FALSE, HelpFlag = FALSE; double Scale, y; GifRecordType RecordType; char s[80]; GifByteType *Extension; GifRowType LineIn, LineOut; char **FileName = NULL; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &SizeFlag, &XSize, &YSize, &ScaleFlag, &Scale, &XScaleFlag, &XScale, &YScaleFlag, &YScale, &HelpFlag, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) GAPrintErrMsg(Error); else if (NumFiles > 1) GIF_MESSAGE("Error in command line parsing - one GIF file please."); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { fprintf(stderr, VersionStr); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } /* If specific direction was set, set other direction to 1: */ if (!XScaleFlag && YScaleFlag) XScale = 1.0; if (!YScaleFlag && XScaleFlag) YScale = 1.0; /* If the specific direction was not set, but global one did use it: */ if (!XScaleFlag && ScaleFlag) XScale = Scale; if (!YScaleFlag && ScaleFlag) YScale = Scale; if (XScale > MAX_SCALE) { sprintf(s, "XScale too big, maximum scale selected instead (%f).", MAX_SCALE); GIF_MESSAGE(s); XScale = MAX_SCALE; } if (YScale > MAX_SCALE) { sprintf(s, "YScale too big, maximum scale selected instead (%f).", MAX_SCALE); GIF_MESSAGE(s); YScale = MAX_SCALE; } if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) QuitGifError(GifFileIn, GifFileOut); } else { /* Use the stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) QuitGifError(GifFileIn, GifFileOut); } BackGroundColor = GifFileIn->SBackGroundColor; /* If size was specified, it is used to derive the scale: */ if (SizeFlag) { XScale = XSize / ((double) GifFileIn->SWidth); YScale = YSize / ((double) GifFileIn->SHeight); } else { XSize = (int) (GifFileIn->SWidth * XScale + 0.5); YSize = (int) (GifFileIn->SHeight * YScale + 0.5); } /* As at this time we know the Screen size of the input gif file, and as */ /* all image(s) in file must be less/equal to it, we can allocate the */ /* scan lines for the input file, and output file. The number of lines */ /* to allocate for each is set by ScaleDown & XScale & YScale: */ LineOut = (GifRowType) malloc(XSize * sizeof(GifPixelType)); LineIn = (GifRowType) malloc(GifFileIn->SWidth * sizeof(GifPixelType)); /* Open stdout for the output file: */ if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) QuitGifError(GifFileIn, GifFileOut); /* And dump out its new scaled screen information: */ if (EGifPutScreenDesc(GifFileOut, XSize, YSize, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Put the image descriptor to out file: */ l = (int) (GifFileIn->Image.Left * XScale + 0.5); w = (int) (GifFileIn->Image.Width * XScale + 0.5); t = (int) (GifFileIn->Image.Top * YScale + 0.5); h = (int) (GifFileIn->Image.Height * YScale + 0.5); if (l < 0) l = 0; if (t < 0) t = 0; if (l + w > XSize) w = XSize - l; if (t + h > YSize) h = YSize - t; if (EGifPutImageDesc(GifFileOut, l, t, w, h, GifFileIn->Image.Interlace, GifFileIn->Image.ColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (GifFileIn->Image.Interlace) { GIF_EXIT("Cannt resize interlaced images - use GifInter first."); } else { GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, ++ImageNum, GifFileOut->Image.Left, GifFileOut->Image.Top, GifFileOut->Image.Width, GifFileOut->Image.Height); for (i = GifFileIn->Image.Height, y = 0.0, last_iy = -1; i-- > 0; y += YScale) { if (DGifGetLine(GifFileIn, LineIn, GifFileIn->Image.Width) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); iy = (int) y; if (last_iy < iy && last_iy < YSize) { ResizeLine(LineIn, LineOut, GifFileIn->Image.Width, GifFileOut->Image.Width); for (; last_iy < iy && last_iy < GifFileOut->Image.Height - 1; last_iy++) { GifQprintf("\b\b\b\b%-4d", last_iy + 1); if (EGifPutLine(GifFileOut, LineOut, GifFileOut->Image.Width) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } } } /* If scale is not dividable - dump last lines: */ while (++last_iy < GifFileOut->Image.Height) { GifQprintf("\b\b\b\b%-4d", last_iy); if (EGifPutLine(GifFileOut, LineOut, GifFileOut->Image.Width) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* No support to more than one extension blocks, so discard: */ while (Extension != NULL) { if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifCloseFile(GifFileOut) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); free(LineOut); free(LineIn); return 0; }
/****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, l, c, LevelStep, LogNumLevels, ErrorCode, Count = 0; bool Error, LevelsFlag = false, SizeFlag = false, HelpFlag = false; GifRowType Line; ColorMapObject *ColorMap; GifFileType *GifFile; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &LevelsFlag, &NumLevels, &SizeFlag, &ImageWidth, &ImageHeight, &HelpFlag)) != false) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } /* Make sure the number of levels is power of 2 (up to 32 levels.). */ for (i = 1; i < 6; i++) if (NumLevels == (1 << i)) break; if (i == 6) GIF_EXIT("#Lvls (-l option) is not power of 2 up to 32."); LogNumLevels = i + 3; /* Multiple by 8 (see below). */ LevelStep = 256 / NumLevels; /* Make sure the image dimension is a multiple of NumLevels horizontally */ /* and 7 (White, Red, Green, Blue and Yellow Cyan Magenta) vertically. */ ImageWidth = (ImageWidth / NumLevels) * NumLevels; ImageHeight = (ImageHeight / 7) * 7; /* Open stdout for the output file: */ if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Dump out screen description with given size and generated color map: */ /* The color map has 7 NumLevels colors for White, Red, Green and then */ /* The secondary colors Yellow Cyan and magenta. */ if ((ColorMap = GifMakeMapObject(8 * NumLevels, NULL)) == NULL) GIF_EXIT("Failed to allocate memory required, aborted."); for (i = 0; i < 8; i++) /* Set color map. */ for (j = 0; j < NumLevels; j++) { l = LevelStep * j; c = i * NumLevels + j; ColorMap->Colors[c].Red = (i == 0 || i == 1 || i == 4 || i == 6) * l; ColorMap->Colors[c].Green = (i == 0 || i == 2 || i == 4 || i == 5) * l; ColorMap->Colors[c].Blue = (i == 0 || i == 3 || i == 5 || i == 6) * l; } if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap) == GIF_ERROR) { PrintGifError(GifFile->Error); } /* Dump out the image descriptor: */ if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); /* Allocate one scan line to be used for all image. */ if ((Line = (GifRowType) malloc(sizeof(GifPixelType) * ImageWidth)) == NULL) GIF_EXIT("Failed to allocate memory required, aborted."); /* Dump the pixels: */ for (c = 0; c < 7; c++) { for (i = 0, l = 0; i < NumLevels; i++) for (j = 0; j < ImageWidth / NumLevels; j++) Line[l++] = i + NumLevels * c; for (i = 0; i < ImageHeight / 7; i++) { if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } GifQprintf("\b\b\b\b%-4d", Count++); } } if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } return 0; }
/****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ int main(int argc, char **argv) { int i, j, Error, NumFiles, ExtCode, Row, Col, Width, Height, DarkestColor = 0, ColorIntens = 10000, HelpFlag = FALSE; GifRecordType RecordType; GifByteType *Extension; char **FileName = NULL; GifRowType LineBuffer; ColorMapObject *ColorMap; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &HelpFlag, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) GAPrintErrMsg(Error); else if (NumFiles > 1) GIF_MESSAGE("Error in command line parsing - one GIF file please."); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { fprintf(stderr, VersionStr); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) QuitGifError(GifFileIn, GifFileOut); } else { /* Use the stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) QuitGifError(GifFileIn, GifFileOut); } /* Open stdout for the output file: */ if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) QuitGifError(GifFileIn, GifFileOut); /* Dump out exactly same screen information: */ if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if ((LineBuffer = (GifRowType) malloc(GifFileIn->SWidth)) == NULL) GIF_EXIT("Failed to allocate memory required, aborted."); /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (GifFileIn->Image.Interlace) GIF_EXIT("Cannt fix interlaced images."); Row = GifFileIn->Image.Top; /* Image Position relative to Screen. */ Col = GifFileIn->Image.Left; Width = GifFileIn->Image.Width; Height = GifFileIn->Image.Height; GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); /* Put the image descriptor to out file: */ if (EGifPutImageDesc(GifFileOut, Col, Row, Width, Height, FALSE, GifFileIn->Image.ColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Find the darkest color in color map to use as a filler. */ ColorMap = (GifFileIn->Image.ColorMap ? GifFileIn->Image.ColorMap : GifFileIn->SColorMap); for (i = 0; i < ColorMap->ColorCount; i++) { j = ((int) ColorMap->Colors[i].Red) * 30 + ((int) ColorMap->Colors[i].Green) * 59 + ((int) ColorMap->Colors[i].Blue) * 11; if (j < ColorIntens) { ColorIntens = j; DarkestColor = i; } } /* Load the image, and dump it. */ for (i = 0; i < Height; i++) { GifQprintf("\b\b\b\b%-4d", i); if (DGifGetLine(GifFileIn, LineBuffer, Width) == GIF_ERROR) break; if (EGifPutLine(GifFileOut, LineBuffer, Width) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } if (i < Height) { fprintf(stderr, "\nFollowing error occured (and ignored):"); PrintGifError(); /* Fill in with the darkest color in color map. */ for (j = 0; j < Width; j++) LineBuffer[j] = DarkestColor; for (; i < Height; i++) if (EGifPutLine(GifFileOut, LineBuffer, Width) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (Extension && EGifPutExtension(GifFileOut, ExtCode, Extension[0], Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* No support to more than one extension blocks, so discard: */ while (Extension != NULL) { if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifCloseFile(GifFileOut) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); return 0; }
/****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ void main(int argc, char **argv) { int Error, NumFiles, ExtCode; GifRecordType RecordType; GifByteType *Extension; char **FileName = NULL; GifRowType *ImageBuffer; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, &InterlacedFlag, &SequencialFlag, &HelpFlag, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) GAPrintErrMsg(Error); else if (NumFiles > 1) GIF_MESSAGE("Error in command line parsing - one GIF file please."); GAPrintHowTo(CtrlStr); exit(1); } if (HelpFlag) { fprintf(stderr, VersionStr); GAPrintHowTo(CtrlStr); exit(0); } if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) QuitGifError(GifFileIn, GifFileOut); } else { /* Use the stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) QuitGifError(GifFileIn, GifFileOut); } /* Open stdout for the output file: */ if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) QuitGifError(GifFileIn, GifFileOut); /* And dump out exactly same screen information: */ if (EGifPutScreenDesc(GifFileOut, GifFileIn -> SWidth, GifFileIn -> SHeight, GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Put the image descriptor to out file: */ if (EGifPutImageDesc(GifFileOut, GifFileIn -> ILeft, GifFileIn -> ITop, GifFileIn -> IWidth, GifFileIn -> IHeight, InterlacedFlag, GifFileIn -> IBitsPerPixel, GifFileIn -> IColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Load the image (either Interlaced or not), and dump it as */ /* defined in GifFileOut -> IInterlaced. */ if (LoadImage(GifFileIn, &ImageBuffer) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (DumpImage(GifFileOut, ImageBuffer) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* No support to more than one extension blocks, so discard: */ while (Extension != NULL) { if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (EGifCloseFile(GifFileOut) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); }
bool MCImageEncodeGIF(MCImageIndexedBitmap *p_indexed, IO_handle p_stream, uindex_t &r_bytes_written) { bool t_success = true; int32_t t_transparent = -1; uindex_t t_palette_size; uindex_t t_depth; t_depth = GifBitSize(p_indexed->palette_size); // GIF requires palette size to be 2^depth t_palette_size = 1 << t_depth; int t_err = 0; GifFileType *t_gif = nil; ColorMapObject *t_colormap = nil; MCGIFWriteContext t_context; t_context.stream = p_stream; t_context.byte_count = 0; t_success = nil != (t_gif = EGifOpen(&t_context, gif_writeFunc, &t_err)); if (t_success) t_success = nil != (t_colormap = GifMakeMapObject(t_palette_size, nil)); if (t_success) { for (uindex_t i = 0; i < p_indexed->palette_size; i++) { t_colormap->Colors[i].Red = p_indexed->palette[i].red; t_colormap->Colors[i].Green = p_indexed->palette[i].green; t_colormap->Colors[i].Blue = p_indexed->palette[i].blue; } for (uindex_t i = p_indexed->palette_size; i < t_palette_size; i++) { t_colormap->Colors[i].Red = t_colormap->Colors[i].Green = t_colormap->Colors[i].Blue = 0; } if (MCImageIndexedBitmapHasTransparency(p_indexed)) { t_transparent = p_indexed->transparent_index; t_colormap->Colors[t_transparent].Red = t_colormap->Colors[t_transparent].Green = t_colormap->Colors[t_transparent].Blue = 0xFF; } t_success = GIF_OK == EGifPutScreenDesc(t_gif, p_indexed->width, p_indexed->height, t_depth, 0, t_colormap); } if (t_success) { if (t_transparent != -1) { GraphicsControlBlock t_gcb; MCMemoryClear(&t_gcb, sizeof(t_gcb)); t_gcb.TransparentColor = t_transparent; GifByteType t_extension[4]; uindex_t t_extension_size; t_extension_size = EGifGCBToExtension(&t_gcb, t_extension); // Should always be 4 bytes MCAssert(t_extension_size == sizeof(t_extension)); t_success = GIF_OK == EGifPutExtension(t_gif, GRAPHICS_EXT_FUNC_CODE, sizeof(t_extension), t_extension); } } if (t_success) t_success = GIF_OK == EGifPutImageDesc(t_gif, 0, 0, p_indexed->width, p_indexed->height, false, nil); for (uindex_t y = 0; t_success && y < p_indexed->height; y++) t_success = GIF_OK == EGifPutLine(t_gif, (uint8_t*)p_indexed->data + y * p_indexed->stride, p_indexed->width); int t_error_code; if (GIF_ERROR == EGifCloseFile(t_gif, &t_error_code)) t_success = false; GifFreeMapObject(t_colormap); if (t_success) r_bytes_written = t_context.byte_count; return t_success; }
bool CxImageGIF::Encode(CxFile * fp) { if (EncodeSafeCheck(fp)) return false; GifFileType *GifFile = NULL; ColorMapObject *OutputColorMap = NULL; int i, ColorMapSize; if(head.biBitCount != 8) { if(head.biBitCount < 8)IncreaseBpp(8); else DecreaseBpp(8, true); } try { GifFile = EGifOpen(fp, writeCxFile); ColorMapSize = head.biClrUsed; OutputColorMap = MakeMapObject(ColorMapSize, NULL); RGBQUAD* pPal = GetPalette(); for(i=0; i<ColorMapSize; ++i) { OutputColorMap->Colors[i].Red = pPal[i].rgbRed; OutputColorMap->Colors[i].Green = pPal[i].rgbGreen; OutputColorMap->Colors[i].Blue = pPal[i].rgbBlue; } EGifPutScreenDesc(GifFile, head.biWidth, head.biHeight, OutputColorMap->ColorCount, info.nBkgndIndex== -1 ? 0 : info.nBkgndIndex, OutputColorMap); FreeMapObject(OutputColorMap); OutputColorMap = NULL; if(info.nBkgndIndex != -1) { unsigned char ExtStr[4] = { 1, 0, 0, info.nBkgndIndex }; EGifPutExtension(GifFile, GRAPHICS_EXT_FUNC_CODE, 4, ExtStr); } EGifPutImageDesc(GifFile, 0, 0, head.biWidth, head.biHeight, FALSE, NULL); for (i = 0; i < head.biHeight; i++) EGifPutLine(GifFile, GetBits(head.biHeight - i - 1), head.biWidth); EGifCloseFile(GifFile); GifFile = NULL; } catch (int errid) { strncpy(info.szLastError,GifGetErrorMessage(errid),255); if(OutputColorMap) { FreeMapObject(OutputColorMap); OutputColorMap = NULL; } if(GifFile) { EGifCloseFile(GifFile); GifFile = NULL; } return false; } catch (char *message) { strncpy(info.szLastError,message,255); if(OutputColorMap) { FreeMapObject(OutputColorMap); OutputColorMap = NULL; } if(GifFile) { EGifCloseFile(GifFile); GifFile = NULL; } return false; } 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); }
/****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ int main(int argc, char **argv) { int Error, NumFiles, ExtCode, CodeSize, ImageNum = 0, ImageNFlag = FALSE, ImageN, HelpFlag = FALSE, HasGIFOutput; GifRecordType RecordType; GifByteType *Extension, *CodeBlock; char **FileName = NULL, *ColorFileName, *TranslateFileName; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &SaveFlag, &TranslateFlag, &TranslateFileName, &LoadFlag, &ColorFileName, &GammaFlag, &Gamma, &ImageNFlag, &ImageN, &HelpFlag, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) GAPrintErrMsg(Error); else if (NumFiles > 1) GIF_MESSAGE("Error in command line parsing - one GIF file please."); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { fprintf(stderr, VersionStr); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (SaveFlag + LoadFlag + GammaFlag + TranslateFlag > 1) GIF_EXIT("Can not handle more than one of -s -l, -t, or -g at the same time."); if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) QuitGifError(GifFileIn, GifFileOut); } else { /* Use stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) QuitGifError(GifFileIn, GifFileOut); } if (SaveFlag) { /* We are dumping out the color map as text file to stdout: */ ColorFile = stdout; } else { if (TranslateFlag) { /* We are loading new color map from specified file: */ if ((TranslateFile = fopen(TranslateFileName, "rt")) == NULL) GIF_EXIT("Failed to open specified color translation file."); } if (LoadFlag) { /* We are loading new color map from specified file: */ if ((ColorFile = fopen(ColorFileName, "rt")) == NULL) GIF_EXIT("Failed to open specified color map file."); } } if ((HasGIFOutput = (LoadFlag || TranslateFlag || GammaFlag)) != 0) { /* Open stdout for GIF output file: */ if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) QuitGifError(GifFileIn, GifFileOut); } if (!ImageNFlag) { /* We are suppose to modify the screen color map, so do it: */ GifFileIn->SColorMap = ModifyColorMap(GifFileIn->SColorMap); if (!HasGIFOutput) { /* We can quit here, as we have the color map: */ if (GifFileIn != NULL) DGifCloseFile(GifFileIn); fclose(ColorFile); exit(EXIT_SUCCESS); } } /* And dump out its new possible repositioned screen information: */ if (HasGIFOutput) if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if ((++ImageNum == ImageN) && ImageNFlag) { /* We are suppose to modify this image color map, do it: */ GifFileIn->SColorMap =ModifyColorMap(GifFileIn->SColorMap); if (!HasGIFOutput) { /* We can quit here, as we have the color map: */ if (GifFileIn != NULL) DGifCloseFile(GifFileIn); fclose(ColorFile); exit(EXIT_SUCCESS); } } if (HasGIFOutput) if (EGifPutImageDesc(GifFileOut, GifFileIn->Image.Left, GifFileIn->Image.Top, GifFileIn->Image.Width, GifFileIn->Image.Height, GifFileIn->Image.Interlace, GifFileIn->Image.ColorMap) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (!TranslateFlag || (ImageNFlag && (ImageN != ImageNum))) { /* Now read image itself in decoded form as we don't */ /* really care what we have there, and this is much */ /* faster. */ if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (HasGIFOutput) if (EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (HasGIFOutput) if (EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } } else /* we need to mung pixels intices */ { int i; register GifPixelType *cp; GifPixelType *Line = (GifPixelType *) malloc(GifFileIn->Image.Width * sizeof(GifPixelType)); for (i = 0; i < GifFileIn->Image.Height; i++) { if (DGifGetLine(GifFileIn, Line,GifFileIn->Image.Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* translation step goes here */ for (cp = Line; cp < Line+GifFileIn->Image.Width; cp++) *cp = Translation[*cp]; if (EGifPutLine(GifFileOut, Line, GifFileIn->Image.Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } free((char *) Line); } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (HasGIFOutput) if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); /* No support to more than one extension blocks, so discard: */ while (Extension != NULL) { if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); if (HasGIFOutput) if (EGifCloseFile(GifFileOut) == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); return 0; }
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); }
/****************************************************************************** * Interpret the command line, prepar global data and call the Gif routines. * ******************************************************************************/ void main(int argc, char **argv) { int Error, NumFiles, ImageWidth, ImageHeight, Dummy, Red, Green, Blue, ColorMapSize, InFileHandle, ImageSizeFlag = FALSE, ColorMapFlag = FALSE, HelpFlag = FALSE; char **FileName = NULL, *ColorMapFile; GifColorType *ColorMap; FILE *InColorMapFile; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, &ImageSizeFlag, &ImageWidth, &ImageHeight, &ColorMapFlag, &ColorMapFile, &HelpFlag, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) GAPrintErrMsg(Error); else if (NumFiles > 1) GIF_MESSAGE("Error in command line parsing - one GIF file please."); GAPrintHowTo(CtrlStr); exit(1); } if (HelpFlag) { fprintf(stderr, VersionStr); GAPrintHowTo(CtrlStr); exit(0); } if (ColorMapFlag) { /* Read color map from given file: */ if ((InColorMapFile = fopen(ColorMapFile, "rt")) == NULL) { GIF_MESSAGE("Failed to open COLOR MAP file (not exists!?)."); exit(2); } if ((ColorMap = (GifColorType *) malloc(sizeof(GifColorType) * 255)) /* Biggest map. */ == NULL) { GIF_MESSAGE("Failed to allocate bitmap, aborted."); exit(3); } for (ColorMapSize = 0; ColorMapSize < 256 && !feof(InColorMapFile); ColorMapSize++) { fscanf(InColorMapFile, "%3d %3d %3d %3d\n", &Dummy, &Red, &Green, &Blue); ColorMap[ColorMapSize].Red = Red; ColorMap[ColorMapSize].Green = Green; ColorMap[ColorMapSize].Blue = Blue; } } else { ColorMap = EGAPallete; ColorMapSize = EGA_PALLETE_SIZE; } if (NumFiles == 1) { #ifdef __MSDOS__ if ((InFileHandle = open(*FileName, O_RDONLY | O_BINARY)) == -1) { #else if ((InFileHandle = open(*FileName, O_RDONLY)) == -1) { #endif /* __MSDOS__ */ GIF_MESSAGE("Failed to open RAW image file (not exists!?)."); exit(2); } dup2(InFileHandle, 0); /* Make stdin from this file. */ } else { #ifdef __MSDOS__ setmode(0, O_BINARY); /* Make sure it is in binary mode. */ #endif /* __MSDOS__ */ } #ifdef __MSDOS__ setvbuf(stdin, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); #endif /* __MSDOS__ */ /* Conver Raw image from stdin to Gif file in stdout: */ Raw2Gif(ImageWidth, ImageHeight, ColorMap, ColorMapSize); } /****************************************************************************** * Convert Raw image (One byte per pixel) into Gif file. Raw data is read from * * stdin, and Gif is dumped to stdout. ImagwWidth times ImageHeight bytes are * * read. Color map is dumped from ColorMap. * ******************************************************************************/ int Raw2Gif(int ImageWidth, int ImageHeight, GifColorType *ColorMap, int ColorMapSize) { static int BitsPerPixelArray[] = { 2, 4 ,8, 16, 32, 64, 128, 256 }; int i, j, BitsPerPixel; static GifPixelType *ScanLine; GifFileType *GifFile; for (BitsPerPixel = 0; BitsPerPixel < 8 && BitsPerPixelArray[BitsPerPixel] != ColorMapSize; BitsPerPixel++); if (++BitsPerPixel > 8) { GIF_MESSAGE("Number of color map is NOT power of 2 up to 256."); exit(3); } if ((ScanLine = (GifPixelType *) malloc(sizeof(GifPixelType) * ImageWidth)) == NULL) { GIF_MESSAGE("Failed to allocate scan line, aborted."); exit(3); } if ((GifFile = EGifOpenFileHandle(1)) == NULL) { /* Gif to stdout. */ free((char *) ScanLine); return HandleGifError(GifFile); } if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, BitsPerPixel, 0, BitsPerPixel, ColorMap) == GIF_ERROR) { free((char *) ScanLine); return HandleGifError(GifFile); } if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, FALSE, 1, NULL) == GIF_ERROR) { free((char *) ScanLine); return HandleGifError(GifFile); } /* Here it is - get one raw line from stdin, and dump to stdout Gif: */ GifQprintf("\n%s: Image 1 at (0, 0) [%dx%d]: ", PROGRAM_NAME, ImageWidth, ImageHeight); for (i = 0; i < ImageHeight; i++) { /* Note we assume here PixelSize == Byte, which is not necessarily */ /* so. If not - must read one byte at a time, and coerce to pixel. */ if (fread(ScanLine, 1, ImageWidth, stdin) != ImageWidth) { GIF_MESSAGE("RAW input file ended prematurely."); exit(3); } for (j = 0; j < ImageWidth; j++) if (ScanLine[j] >= ColorMapSize) GIF_MESSAGE("Warning: RAW data color > maximum color map entry."); if (EGifPutLine(GifFile, ScanLine, ImageWidth) == GIF_ERROR) { free((char *) ScanLine); return HandleGifError(GifFile); } GifQprintf("\b\b\b\b%-4d", i); } if (EGifCloseFile(GifFile) == GIF_ERROR) { free((char *) ScanLine); return HandleGifError(GifFile); } free((char *) ScanLine); return 0; } /****************************************************************************** * Handle last GIF error. Try to close the file and free all allocated memory. * ******************************************************************************/ static int HandleGifError(GifFileType *GifFile) { int i = GifLastError(); if (EGifCloseFile(GifFile) == GIF_ERROR) { GifLastError(); } return i; }
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; }
unsigned char * gifconv_lossless2gif(void *image_data, unsigned short width, unsigned short height, void *index_data, unsigned short index_data_count, int tag_no, int format, unsigned long *length) { GifFileType *GifFile = NULL; GifColorType *Colors = NULL; int ColorCount; my_gif_buffer gif_buff; gif_uint_32 gif_width = 0, gif_height = 0; int bpp; gif_bytep gif_image_data = NULL; gif_uint_32 x, y; gif_colorp gif_palette = NULL; // int trans_index = -1; int i; if (format != 3) { fprintf(stderr, "jpegconv_lossless2gif: format=%d not implemented yes.\n", format); return NULL; } bpp = 8; gif_width = width; gif_height = height; ColorCount = 256; Colors = calloc(sizeof(GifColorType), ColorCount); gif_buff.data = NULL; gif_buff.data_len = 0; gif_buff.data_offset = 0; #if GIFLIB_MAJOR >= 5 GifFile = EGifOpen(& gif_buff, gif_data_write_func, NULL); #else GifFile = EGifOpen(& gif_buff, gif_data_write_func); #endif if (GifFile == NULL) { fprintf(stderr, "gifconv_lossless2gif: can't open GIFFile\n"); return NULL; } GifFile->SWidth = gif_width; GifFile->SHeight = gif_height; GifFile->SColorResolution = bpp; gif_palette = (gif_colorp) malloc(sizeof(gif_color)*index_data_count); if (tag_no == 20) { swf_rgb_t *rgb_list = index_data; for (i=0 ; i < index_data_count ; i++) { Colors[i].Red = rgb_list[i].red; Colors[i].Green = rgb_list[i].green; Colors[i].Blue = rgb_list[i].blue; } } else { swf_rgba_t *rgba_list = index_data; for (i=0 ; i < index_data_count ; i++) { // if (rgba_list[i].alpha) Colors[i].Red = rgba_list[i].red; Colors[i].Green = rgba_list[i].green; Colors[i].Blue = rgba_list[i].blue; // gif_palette[i].alpha = ; } } GifFile->SBackGroundColor = 0; // XXX gif_image_data = (gif_bytep) calloc(sizeof(unsigned char), gif_width * gif_height); i = 0; for (y=0 ; y < gif_height ; y++) { for (x=0 ; x < gif_width ; x++) { unsigned char *data = image_data; gif_image_data[i] = data[x + y*((gif_width +3) & -4)]; i++; } } GifFile->SavedImages[0].RasterBits = gif_image_data; #if GIFLIB_MAJOR >= 5 GifFile->SColorMap = GifMakeMapObject(ColorCount, Colors); #else GifFile->SColorMap = MakeMapObject(ColorCount, Colors); #endif EGifSpew(GifFile); // XXX free(gif_image_data); if (GifFile) { #if GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1 || GIFLIB_MAJOR > 5 EGifCloseFile(GifFile, NULL); #else EGifCloseFile(GifFile); #endif } *length = gif_buff.data_offset; return gif_buff.data; }