/* * Open the gif file */ static GifFileType* open_gif(SkStream* stream) { #if GIFLIB_MAJOR < 5 return DGifOpen(stream, read_bytes_callback); #else return DGifOpen(stream, read_bytes_callback, nullptr); #endif }
GifFileType* GIFAbstractDataset::myDGifOpen( void *userPtr, InputFunc readFunc ) { #if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 int nErrorCode; return DGifOpen( userPtr, readFunc, &nErrorCode ); #else return DGifOpen( userPtr, readFunc ); #endif }
static void * open_load( PImgCodec instance, PImgLoadFileInstance fi) { LoadRec * l = malloc( sizeof( LoadRec)); HV * profile = fi-> fileProperties; if ( !l) return nil; memset( l, 0, sizeof( LoadRec)); GIF_CALL 0; if ( !( l-> gft = DGifOpen( fi-> req, my_gif_read GIF_ERROR_ARG))) { free( l); return nil; } fi-> stop = true; l-> passed = -1; l-> transparent = -1; if ( fi-> loadExtras) { pset_i( screenWidth, l-> gft-> SWidth); pset_i( screenHeight, l-> gft-> SHeight); pset_i( screenColorResolution, l-> gft-> SColorResolution); pset_i( screenBackGroundColor, l-> gft-> SBackGroundColor); pset_sv_noinc( screenPalette, make_palette_sv( l-> gft-> SColorMap)); } return l; }
/*! * \brief pixReadMemGif() * * \param[in] cdata const; gif-encoded * \param[in] size bytes data * \return pix, or NULL on error * * <pre> * Notes: * (1) For libgif version >= 5.1, this uses the DGifOpen() buffer * interface. No temp files are required. * (2) For libgif version < 5.1, it was necessary to write the compressed * data to file and read it back, and we couldn't use the GNU * runtime extension fmemopen() because libgif doesn't have a file * stream interface. * </pre> */ PIX * pixReadMemGif(const l_uint8 *cdata, size_t size) { GifFileType *gif; GifReadBuffer buffer; PROCNAME("pixReadMemGif"); /* 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 NULL; #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 NULL; #endif /* 5.1.2 */ if (!cdata) return (PIX *)ERROR_PTR("cdata not defined", procName, NULL); buffer.cdata = cdata; buffer.size = size; buffer.pos = 0; if ((gif = DGifOpen((void*)&buffer, gifReadFunc, NULL)) == NULL) return (PIX *)ERROR_PTR("could not open gif stream from memory", procName, NULL); return gifToPix(gif); }
ImageSet* process_gif(const char *buf, size_t len) { int error; GifFileType* gif = DGifOpen((char*)buf, &gif_readfunc, &error); if (error != GIF_OK) { printf("GIF reading error %d: %s\n", error, GifErrorString(error)); return NULL; } printf("gif read, now converting\n", error); ImageSet* imgset = (ImageSet*)malloc(sizeof(ImageSet)); imgset->width = gif->SWidth; imgset->height = gif->SHeight; ColorMapObject* gif_colormap = gif->SColorMap; if (gif_colormap != NULL) { gif_colormap->ColorCount; imgset->palette = (Color*)calloc(256, sizeof(Color)); int shift = 8 - gif_colormap->BitsPerPixel; if (shift < 1 || shift > 7) { fprintf(stderr, "Error opening gif: invalid palette BPP %d\n", gif_colormap->BitsPerPixel); } for (int i=0; i < 256; i++) { if (i <= gif_colormap->ColorCount) { imgset->palette[i].r = gif_colormap->Colors[i].Red >> shift; imgset->palette[i].g = gif_colormap->Colors[i].Green >> shift; imgset->palette[i].b = gif_colormap->Colors[i].Blue >> shift; } else { //gset->palette[i] = Color{0,0,0}; } } } else {
Image* readGifFile ( int infile ) { Image *img = 0; #if defined(INCLUDE_GIF) /* * we don't use DGifOpenFile because file io might be intercepted * (because of threading) */ FileSource fileSrc; GifFileType *gf; fileSrc.fd = infile; if ( !(gf = DGifOpen( &fileSrc, readGifFileSource)) ) return 0; img = readGif( gf); DGifCloseFile( gf); #endif return img; }
SWFDBLBitmapData newSWFDBLBitmapData_fromGifInput(SWFInput input) { GifFileType *file; SWFDBLBitmapData ret; struct dbl_data gifdata; #if GIFLIB_MAJOR >= 5 if((file = DGifOpen(input, (InputFunc) gifReadFunc, NULL)) == NULL) #else if((file = DGifOpen(input, (InputFunc) gifReadFunc)) == NULL) #endif return NULL; if(!readGif(file, &gifdata)) return NULL; ret = newSWFDBLBitmapData_fromData(&gifdata); // ret->input = NULL; return ret; }
SkGIFMovie::SkGIFMovie(SkStream* stream) { #if GIFLIB_MAJOR < 5 fGIF = DGifOpen( stream, Decode ); #else fGIF = DGifOpen( stream, Decode, NULL ); #endif if (NULL == fGIF) return; if (DGifSlurp(fGIF) != GIF_OK) { DGifCloseFile(fGIF); fGIF = NULL; } fCurrIndex = -1; fLastDrawIndex = -1; }
static GifFileType *DGifOpenMem(const unsigned char *img, int imgSize) { GifMemoryType *gifMemoryType = (GifMemoryType *) gif_malloc(sizeof(GifMemoryType)); memset((void *) gifMemoryType, 0, sizeof(GifMemoryType)); gifMemoryType->imgData = (void *) img; gifMemoryType->imgSize = imgSize; return DGifOpen(gifMemoryType, DGifOpenFromMemoryCallback); }
static int read_gif_info(const ps_byte* data, size_t len, psx_image_header* header) { #if GIFLIB_MAJOR >= 5 int errorcode = 0; #endif struct gif_image_ctx* ctx = (struct gif_image_ctx*)calloc(1, sizeof(struct gif_image_ctx)); if (!ctx) { return -1; // out of memory. } ctx->buf = (uint8_t*)data; ctx->len = (uint32_t)len; ctx->pos = 0; #if GIFLIB_MAJOR >= 5 if ((ctx->gif = DGifOpen((void*)ctx, read_gif_from_memory, &errorcode)) == NULL) { free(ctx); return -1; } #else if ((ctx->gif = DGifOpen((void*)ctx, read_gif_from_memory)) == NULL) { free(ctx); return -1; } #endif if (GIF_OK != DGifSlurp(ctx->gif)) { GIF_CLOSE_DFILE(ctx->gif); free(ctx); return -1; } header->priv = ctx; header->width = ctx->gif->SWidth; header->height = ctx->gif->SHeight; header->pitch = ctx->gif->SWidth * 4; header->depth = 32; header->bpp = 4; header->format = 0; header->alpha = 1; header->frames = ctx->gif->ImageCount; return 0; }
SWFDBLBitmapData newSWFDBLBitmapData_fromGifInput(SWFInput input) { GifFileType *file; SWFDBLBitmapData ret; struct dbl_data gifdata; if((file = DGifOpen(input, (InputFunc) gifReadFunc)) == NULL) return NULL; if(!readGif(file, &gifdata)) return NULL; ret = newSWFDBLBitmapData_fromData(&gifdata); /* ret->input = NULL; */ return ret; }
bool compress_custom(void* input_data, InputFunc input_func, void* output_data, OutputFunc output_func, int sample_size) { GifFileType* input_gif = NULL; GifFileType* output_gif = NULL; int result = GIF_ERROR; // Check sample if (sample_size <= 0) { return false; } input_gif = DGifOpen(input_data, input_func, &error_code); if (input_gif == NULL) { LOGE(EMSG("Can't open input gif")); return false; } DGifSlurp(input_gif); if (input_gif->ImageCount == 0) { LOGE(EMSG("Gif frame count is 0")); DGifCloseFile(input_gif, &error_code); return false; } // Save gif output_gif = EGifOpen(output_data, output_func, &error_code); if (output_gif == NULL) { LOGE(EMSG("Can't open output gif")); DGifCloseFile(input_gif, &error_code); return false; } if (do_compress(input_gif, output_gif, sample_size)) { result = EGifSpew(output_gif); } // Free GifFreeExtensions(&output_gif->ExtensionBlockCount, &output_gif->ExtensionBlocks); if (output_gif->SavedImages) { GifFreeSavedImages(output_gif); output_gif->SavedImages = NULL; } // Close gif DGifCloseFile(input_gif, &error_code); return result == GIF_OK; }
SkGIFMovie::SkGIFMovie(SkStream* stream) { fGIF = DGifOpen( stream, Decode ); if (NULL == fGIF) return; if (DGifSlurp(fGIF) != GIF_OK) { DGifCloseFile(fGIF); fGIF = NULL; } fCurrIndex = -1; fLastDrawIndex = -1; }
int image_gif_read_header(image *im) { #ifdef GIFLIB_API_50 im->gif = DGifOpen(im, image_gif_read_buf, NULL); #else im->gif = DGifOpen(im, image_gif_read_buf); #endif if (im->gif == NULL) { #ifdef GIFLIB_API_41 PrintGifError(); #endif warn("Image::Scale unable to open GIF file (%s)\n", SvPVX(im->path)); image_gif_finish(im); return 0; } im->width = im->gif->SWidth; im->height = im->gif->SHeight; return 1; }
static GifFileType *loadGif(ByteInputStream &in) { int error; GifFileType *gf = DGifOpen(&in, readGifStreamFunction, &error); if(gf == NULL) { THROWGIFERROR(error); } try { if(DGifSlurp(gf) != GIF_OK) { THROWGIFERROR(gf->Error); } return gf; } catch(...) { DGifCloseFile(gf, &error); throw; } }
static HRESULT WINAPI GifDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, WICDecodeOptions cacheOptions) { GifDecoder *This = (GifDecoder*)iface; LARGE_INTEGER seek; int ret; TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); EnterCriticalSection(&This->lock); if (This->initialized || This->gif) { WARN("already initialized\n"); LeaveCriticalSection(&This->lock); return WINCODEC_ERR_WRONGSTATE; } /* seek to start of stream */ seek.QuadPart = 0; IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); /* read all data from the stream */ This->gif = DGifOpen((void*)pIStream, _gif_inputfunc); if (!This->gif) { LeaveCriticalSection(&This->lock); return E_FAIL; } ret = DGifSlurp(This->gif); if (ret == GIF_ERROR) { LeaveCriticalSection(&This->lock); return E_FAIL; } /* make sure we don't use the stream after this method returns */ This->gif->UserData = NULL; This->initialized = TRUE; LeaveCriticalSection(&This->lock); return S_OK; }
void AnimatedImage::load(CWnd *parent, ByteInputStream &in) { int error; GifFileType *gifFile = DGifOpen(&in, readGifStreamFunction, &error); if(gifFile == NULL) { THROWGIFERROR(error); } try { if(DGifSlurp(gifFile) != GIF_OK) { THROWGIFERROR(gifFile->Error); } createFromGifFile(parent, gifFile); DGifCloseFile(gifFile, &error); } catch(...) { DGifCloseFile(gifFile, &error); throw; } }
bool MCGIFImageLoader::LoadHeader(uint32_t &r_width, uint32_t &r_height, uint32_t &r_xhot, uint32_t &r_yhot, MCStringRef &r_name, uint32_t &r_frame_count, MCImageMetadata &r_metadata) { bool t_success; t_success = true; if (t_success) t_success = nil != (m_gif = DGifOpen(GetStream(), gif_readFunc, &m_error)); if (t_success) { r_width = m_gif->SWidth; r_height = m_gif->SHeight; r_xhot = r_yhot = 0; r_name = MCValueRetain(kMCEmptyString); r_frame_count = m_gif->ImageCount; } return t_success; }
JNIEXPORT jlong JNICALL Java_com_ly_widget_GifDrawable_loadGifAsset(JNIEnv * env, jobject obj, jobject assetManager, jstring filepath, jarray size) { int error; AAssetManager *mgr = AAssetManager_fromJava(env, assetManager); const char *native_file_path = (*env)->GetStringUTFChars(env, filepath, 0); AAsset* asset = AAssetManager_open(mgr, native_file_path, AASSET_MODE_UNKNOWN); off_t start, length; fd = AAsset_openFileDescriptor(asset, &start, &length); bytesLeft = length; lseek(fd, start, SEEK_SET); if (fd < 0) { return 0; } GifFileType* gif = DGifOpen(NULL,&readFunc,&error); error = DGifSlurp(gif); (*env)->ReleaseStringUTFChars(env, filepath, native_file_path); AAsset_close(asset); return loadGif(env, gif, size); }
bool GIFMovie::init(FILE* file) { if(file == NULL) { return false; } int error = 0; fGIF = DGifOpen(file,&DecodeCallBackProc,&error); if (NULL == fGIF || DGifSlurp(fGIF) != GIF_OK) { GifUtils::closeFile(file); DGifCloseFile(fGIF); fGIF = NULL; return false; } GifUtils::closeFile(file); return true; }
/*! * \brief pixReadMemGif() * * \param[in] data const; gif-encoded * \param[in] size of data * \return pix, or NULL on error * * <pre> * Notes: * * For Giflib version >= 5.1, this uses the DGifOpen() buffer * interface. No temp files are required. * * For Giflib version < 5.1: * (1) Write the gif compressed data to file and read it back. * Note: we can't use the GNU runtime extension fmemopen() * because libgif doesn't have a file stream interface. * (2) This should be relatively safe from a sophisticated attack, * because we use mkstemp (or its Windows equivalent) to generate * a filename and link the file. It would be nice to go further * and do this: * l_int32 fd = mkstemp(template); * FILE *fp = fdopen(fd, "w+b"); * fwrite(data, 1, size, fp); * rewind(fp); * Pix *pix = pixReadStreamGif(fp); * but this can't be done with gif files becuase of the way * that libgif handles the file descriptors: fp is in a * bad state after writing. * </pre> */ PIX * pixReadMemGif(const l_uint8 *cdata, size_t size) { #if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5 GifFileType *gif; GifReadBuffer buffer; #else char *fname; PIX *pix; #endif /* 5.1 and beyond */ PROCNAME("pixReadMemGif"); if (!cdata) return (PIX *)ERROR_PTR("cdata not defined", procName, NULL); #if (GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1) || GIFLIB_MAJOR > 5 buffer.cdata = cdata; buffer.size = size; buffer.pos = 0; if ((gif = DGifOpen((void*)&buffer, gifReadFunc, NULL)) == NULL) return (PIX *)ERROR_PTR("could not open gif stream from memory", procName, NULL); return gifToPix(gif); #else L_INFO("using a temp file; not reading from memory\n", procName); /* Write to a temp file */ fname = l_makeTempFilename(NULL); l_binaryWrite(fname, "w", (l_uint8 *)cdata, size); /* Read back from the file */ pix = pixRead(fname); lept_rmfile(fname); LEPT_FREE(fname); if (!pix) L_ERROR("pix not read\n", procName); return pix; #endif /* 5.1 and beyond */ }
Image* readGifData ( unsigned char* buf, long len ) { Image *img = 0; #if defined(INCLUDE_GIF) BufferSource bufSrc; GifFileType *gf; bufSrc.buf = bufSrc.p = buf; bufSrc.remain = len; if ( !(gf = DGifOpen( &bufSrc, readGifBuffer)) ) return 0; img = readGif( gf); DGifCloseFile( gf); #endif /* INCLUDE_GIF */ return img; }
int openStream(GifFileType* gifFileType,JNIEnv * env,jobject stream) { jclass streamCls = (jclass)env->NewGlobalRef(env->GetObjectClass(stream)); jmethodID mid = env->GetMethodID(streamCls, "mark", "(I)V"); jmethodID readMID = env->GetMethodID(streamCls, "read", "([BII)I"); jmethodID resetMID = env->GetMethodID(streamCls, "reset", "()V"); if (mid == 0 || readMID == 0 || resetMID == 0) { env->DeleteGlobalRef(streamCls); return (jint) NULL; } StreamContainer* container = (StreamContainer*)malloc(sizeof(StreamContainer)); if (container == NULL) { return (jint) NULL; } container->readMID = readMID; container->resetMID = resetMID; container->stream = env->NewGlobalRef(stream); container->streamCls = streamCls; container->buffer = NULL; container->env = env; int Error = 0; gifType = DGifOpen(container, &streamReadFun); if(gifType == NULL){ return GIF_ERROR; }else{ } if(DGifSlurp(gifType) == GIF_ERROR){ return GIF_ERROR; } return GIF_OK; }
void * gifconv_gif2lossless(unsigned char *gif_data, unsigned long gif_data_len, int *tag_no, int *format, unsigned short *width, unsigned short *height, void **colormap, int *colormap_count) { GifFileType *GifFile = NULL; ColorMapObject *ColorMap = NULL; my_gif_buffer gif_buff; int bpp; gif_uint_32 gif_width = 0, gif_height = 0; gif_bytep gif_image_data_ref = NULL; gif_uint_32 x, y; void *image_data = NULL; int palette_num = 0; int trans_index = -1; SavedImage Image; int i, j; unsigned char *indices_data; gif_buff.data = gif_data; gif_buff.data_len = gif_data_len; gif_buff.data_offset = 0; #if GIFLIB_MAJOR >= 5 GifFile = DGifOpen(& gif_buff, gif_data_read_func, NULL); #else GifFile = DGifOpen(& gif_buff, gif_data_read_func); #endif if (GifFile == NULL) { fprintf(stderr, "gifconv_gif2lossless: can't open GIFFile\n"); return NULL; } if (DGifSlurp(GifFile) == GIF_ERROR) { fprintf(stderr, "gifconv_gif2lossless: DGifSlurp failed\n"); #if GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1 || GIFLIB_MAJOR > 5 DGifCloseFile(GifFile, NULL); #else DGifCloseFile(GifFile); #endif return NULL; } Image = GifFile->SavedImages[0]; ColorMap = GifFile->SColorMap; if (ColorMap == NULL) { ColorMap = Image.ImageDesc.ColorMap; } gif_width = GifFile->SWidth; gif_height = GifFile->SHeight; bpp = ColorMap->BitsPerPixel; if (bpp > 8) { fprintf(stderr, "gifconv_gif2lossless: bpp=%d not implemented. accept only bpp <= 8\n", bpp); #if GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1 || GIFLIB_MAJOR > 5 DGifCloseFile(GifFile, NULL); #else DGifCloseFile(GifFile); #endif return NULL; } palette_num = ColorMap->ColorCount; trans_index = getTransparentIndex(Image); *width = (unsigned short) gif_width; *height = (unsigned short) gif_height; *format = 3; if (trans_index != -1) { *tag_no = 36; // DefineBitsLossless2 } else { *tag_no = 20; // DefineBitsLossless } /* * image copy */ *colormap_count = palette_num; if (trans_index == -1) { // Lossless swf_rgb_t *result_colormap = malloc(sizeof(swf_rgb_t) * palette_num); for (i=0 ; i < palette_num ; i++) { result_colormap[i].red = ColorMap->Colors[i].Red; result_colormap[i].green = ColorMap->Colors[i].Green; result_colormap[i].blue = ColorMap->Colors[i].Blue; } *colormap = result_colormap; } else { // Lossless2 swf_rgba_t *result_colormap = malloc(sizeof(swf_rgba_t) * palette_num); for (i=0 ; i < palette_num ; i++) { if (i == trans_index) { result_colormap[i].red = 0x0; result_colormap[i].green = 0x0; result_colormap[i].blue = 0x0; result_colormap[i].alpha = 0x0; } else { result_colormap[i].red = ColorMap->Colors[i].Red; result_colormap[i].green = ColorMap->Colors[i].Green; result_colormap[i].blue = ColorMap->Colors[i].Blue; result_colormap[i].alpha = 0xff; } } *colormap = result_colormap; } indices_data = malloc(((gif_width+ 3) & -4) * gif_height); gif_image_data_ref = Image.RasterBits; i = 0; j = 0; for (y=0 ; y < gif_height ; y++) { for (x=0 ; x < gif_width ; x++) { indices_data[i] = gif_image_data_ref[j]; i++; j++; } while (i % 4) { i++; } // 4byte alignment } image_data = indices_data; /* * destruct */ if (GifFile) { #if GIFLIB_MAJOR == 5 && GIFLIB_MINOR >= 1 || GIFLIB_MAJOR > 5 DGifCloseFile(GifFile, NULL); #else DGifCloseFile(GifFile); #endif } return image_data; }
/* * Open the gif file */ static GifFileType* open_gif(SkStream* stream) { return DGifOpen(stream, read_bytes_callback, nullptr); }
bool CxImageGIF::Decode(CxFile *fp) { if (fp == NULL) return false; GifFileType *GifFile = NULL; GifRecordType RecordType; GifByteType *Extension; GifColorType *ColorMap; int i, j, Count, Row, Col, Width, Height, ExtCode, ColorMapSize; static int InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ try { GifFile = DGifOpen(fp, readCxFile); if (!Create(GifFile->SWidth,GifFile->SHeight,8,CXIMAGE_FORMAT_GIF)) throw "Can't allocate memory"; do { DGifGetRecordType(GifFile, &RecordType); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: DGifGetImageDesc(GifFile); Row = GifFile->Image.Top; /* Image Position relative to Screen. */ Col = GifFile->Image.Left; Width = GifFile->Image.Width; Height = GifFile->Image.Height; if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth || GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) throw "Image is not confined to screen dimension, aborted.\n"; if (GifFile->Image.Interlace) { /* Need to perform 4 passes on the images: */ for (Count = i = 0; i < 4; i++) for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i]) DGifGetLine(GifFile, GetBits(GifFile->SHeight - j - 1) + Col, Width); } else { for (i = 0; i < Height; i++) DGifGetLine(GifFile,GetBits(GifFile->SHeight - Row++ - 1) + Col,Width); } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ DGifGetExtension(GifFile, &ExtCode, &Extension); while (Extension != NULL) DGifGetExtensionNext(GifFile, &Extension); break; default: break; } }while (RecordType != TERMINATE_RECORD_TYPE); ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap->Colors : GifFile->SColorMap->Colors); ColorMapSize = GifFile->Image.ColorMap ? GifFile->Image.ColorMap->ColorCount : GifFile->SColorMap->ColorCount; if(ColorMap && ColorMapSize) { RGBQUAD* ppal=GetPalette(); for (i=0; i < ColorMapSize; i++) { ppal[i].rgbRed = ColorMap[i].Red; ppal[i].rgbGreen = ColorMap[i].Green; ppal[i].rgbBlue = ColorMap[i].Blue; } head.biClrUsed = ColorMapSize; if(GifFile->SBackGroundColor) { info.nBkgndIndex = GifFile->SBackGroundColor; info.nBkgndColor.rgbRed = ColorMap[info.nBkgndIndex].Red; info.nBkgndColor.rgbGreen = ColorMap[info.nBkgndIndex].Green; info.nBkgndColor.rgbBlue = ColorMap[info.nBkgndIndex].Blue; } } DGifCloseFile(GifFile); GifFile = NULL; } catch (int errid) { strncpy(info.szLastError,GifGetErrorMessage(errid),255); if(GifFile != NULL) DGifCloseFile(GifFile); return false; } catch (char *message) { strncpy(info.szLastError,message,255); if(GifFile != NULL) DGifCloseFile(GifFile); return false; } return true; }
GifFileType* open_gif_read( FILE *in_stream ) { return DGifOpen(in_stream, fread_gif); }
CPLErr BIGGIFDataset::ReOpen() { /* -------------------------------------------------------------------- */ /* If the file is already open, close it so we can restart. */ /* -------------------------------------------------------------------- */ if( hGifFile != NULL ) DGifCloseFile( hGifFile ); /* -------------------------------------------------------------------- */ /* If we are actually reopening, then we assume that access to */ /* the image data is not strictly once through sequential, and */ /* we will try to create a working database in a temporary */ /* directory to hold the image as we read through it the second */ /* time. */ /* -------------------------------------------------------------------- */ if( hGifFile != NULL ) { GDALDriver *poGTiffDriver = (GDALDriver*) GDALGetDriverByName("GTiff"); if( poGTiffDriver != NULL ) { /* Create as a sparse file to avoid filling up the whole file */ /* while closing and then destroying this temporary dataset */ const char* apszOptions[] = { "COMPRESS=LZW", "SPARSE_OK=YES", NULL }; CPLString osTempFilename = CPLGenerateTempFilename("biggif"); osTempFilename += ".tif"; poWorkDS = poGTiffDriver->Create( osTempFilename, nRasterXSize, nRasterYSize, 1, GDT_Byte, const_cast<char**>(apszOptions)); } } /* -------------------------------------------------------------------- */ /* Open */ /* -------------------------------------------------------------------- */ VSIFSeekL( fp, 0, SEEK_SET ); nLastLineRead = -1; #if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5 int nError; hGifFile = DGifOpen( fp, VSIGIFReadFunc, &nError ); #else hGifFile = DGifOpen( fp, VSIGIFReadFunc ); #endif if( hGifFile == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "DGifOpen() failed. Perhaps the gif file is corrupt?\n" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Find the first image record. */ /* -------------------------------------------------------------------- */ GifRecordType RecordType = TERMINATE_RECORD_TYPE; while( DGifGetRecordType(hGifFile, &RecordType) != GIF_ERROR && RecordType != TERMINATE_RECORD_TYPE && RecordType != IMAGE_DESC_RECORD_TYPE ) { /* Skip extension records found before IMAGE_DESC_RECORD_TYPE */ if (RecordType == EXTENSION_RECORD_TYPE) { int nFunction; GifByteType *pExtData; if (DGifGetExtension(hGifFile, &nFunction, &pExtData) == GIF_ERROR) break; while (pExtData != NULL) { if (DGifGetExtensionNext(hGifFile, &pExtData) == GIF_ERROR) break; } } } if( RecordType != IMAGE_DESC_RECORD_TYPE ) { DGifCloseFile( hGifFile ); hGifFile = NULL; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find image description record in GIF file." ); return CE_Failure; } if (DGifGetImageDesc(hGifFile) == GIF_ERROR) { DGifCloseFile( hGifFile ); hGifFile = NULL; CPLError( CE_Failure, CPLE_OpenFailed, "Image description reading failed in GIF file." ); return CE_Failure; } return CE_None; }
/* * GIFの最初の1枚を読む */ static int load_gif_sub(RefImage *image, Value r, int info_only) { int err = 0; int rowbytes; GifFileType *gif = DGifOpen(&r, gif_read_callback, &err); if (gif == NULL) { fs->throw_errorf(mod_image, "ImageError", "Failed to read GIF image"); return FALSE; } if (gif->SWidth > MAX_IMAGE_SIZE || gif->SHeight > MAX_IMAGE_SIZE) { fs->throw_errorf(mod_image, "ImageError", "Image size too large (max:%d)", MAX_IMAGE_SIZE); DGifCloseFile(gif); return FALSE; } image->bands = BAND_P; image->width = gif->SWidth; image->height = gif->SHeight; rowbytes = image->width; image->pitch = rowbytes; if (!info_only) { const ColorMapObject *cmap; const SavedImage *si; if (DGifSlurp(gif) == GIF_ERROR || gif->ImageCount <= 0) { fs->throw_errorf(mod_image, "ImageError", "Failed to read GIF image"); return FALSE; } si = &gif->SavedImages[0]; // パレット読み込み if (si->ImageDesc.ColorMap != NULL) { cmap = si->ImageDesc.ColorMap; } else { cmap = gif->SColorMap; } if (cmap != NULL) { int i; int color_key; uint32_t *col = malloc(sizeof(uint32_t) * PALETTE_NUM); for (i = 0; i < PALETTE_NUM; i++) { col[i] = COLOR_A_MASK; } for (i = 0; i < cmap->ColorCount; i++) { const GifColorType *c = &cmap->Colors[i]; col[i] = (c->Red << COLOR_R_SHIFT) | (c->Green << COLOR_G_SHIFT) | (c->Blue << COLOR_B_SHIFT) | COLOR_A_MASK; } color_key = get_transparent_index(si); if (color_key >= 0) { col[color_key] &= ~COLOR_A_MASK; } image->palette = col; } else { // Illigal image->bands = BAND_L; } if (si->RasterBits != NULL) { int y; int size_alloc = rowbytes * image->height; const GifImageDesc *id = &si->ImageDesc; uint8_t *data; if (size_alloc > fs->max_alloc) { fs->throw_error_select(THROW_MAX_ALLOC_OVER__INT, fs->max_alloc); DGifCloseFile(gif); return FALSE; } if (id->Left < 0 || id->Left + id->Width > image->width || id->Top < 0 || id->Top + id->Height > image->height) { fs->throw_errorf(mod_image, "ImageError", "Invalid GIF format"); DGifCloseFile(gif); return FALSE; } data = malloc(size_alloc); memset(data, gif->SBackGroundColor, size_alloc); for (y = 0; y < id->Height; y++) { memcpy(data + rowbytes * (y + id->Top) + id->Left, si->RasterBits + id->Width * y, id->Width); } image->data = data; } } DGifCloseFile(gif); return TRUE; }
int FileGIF::read_frame(VFrame *output, VFrame *input) { data = input->get_data(); offset = 0; size = input->get_compressed_size(); GifFileType *gif_file; GifRowType *gif_buffer; gif_file = DGifOpen(this, input_func); if(gif_file == 0) { printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString()); return 1; } gif_buffer = (GifRowType*)malloc(sizeof(GifRowType) * gif_file->SHeight); int row_size = gif_file->SWidth * sizeof(GifPixelType); gif_buffer[0] = (GifRowType)malloc(row_size); for(int i = 0; i < gif_file->SWidth; i++) { gif_buffer[0][i] = gif_file->SBackGroundColor; } for(int i = 0; i < gif_file->SHeight; i++) { gif_buffer[i] = (GifRowType)malloc(row_size); memcpy(gif_buffer[i], gif_buffer[0], row_size); } GifRecordType record_type; do { if(DGifGetRecordType(gif_file, &record_type) == GIF_ERROR) { printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString()); break; } switch(record_type) { case IMAGE_DESC_RECORD_TYPE: { if(DGifGetImageDesc(gif_file) == GIF_ERROR) { printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString()); break; } int row = gif_file->Image.Top; int col = gif_file->Image.Left; int width = gif_file->Image.Width; int height = gif_file->Image.Height; if(gif_file->Image.Left + gif_file->Image.Width > gif_file->SWidth || gif_file->Image.Top + gif_file->Image.Height > gif_file->SHeight) { DGifCloseFile(gif_file); for(int k = 0; k < gif_file->SHeight; k++) { free(gif_buffer[k]); } free(gif_buffer); return 1; } if (gif_file->Image.Interlace) { static int InterlacedOffset[] = { 0, 4, 2, 1 }; static int InterlacedJumps[] = { 8, 8, 4, 2 }; /* Need to perform 4 passes on the images: */ for (int i = 0; i < 4; i++) { for (int j = row + InterlacedOffset[i]; j < row + height; j += InterlacedJumps[i]) { if (DGifGetLine(gif_file, &gif_buffer[j][col], width) == GIF_ERROR) { DGifCloseFile(gif_file); for(int k = 0; k < gif_file->SHeight; k++) { free(gif_buffer[k]); } free(gif_buffer); return 1; } } } } else { for (int i = 0; i < height; i++) { if (DGifGetLine(gif_file, &gif_buffer[row++][col], width) == GIF_ERROR) { DGifCloseFile(gif_file); for(int k = 0; k < gif_file->SHeight; k++) { free(gif_buffer[k]); } free(gif_buffer); return 1; } } } break; } } } while(record_type != TERMINATE_RECORD_TYPE); int background = gif_file->SBackGroundColor; ColorMapObject *color_map = (gif_file->Image.ColorMap ? gif_file->Image.ColorMap : gif_file->SColorMap); if(!color_map) { DGifCloseFile(gif_file); for(int k = 0; k < gif_file->SHeight; k++) { free(gif_buffer[k]); } free(gif_buffer); return 1; } int screen_width = gif_file->SWidth; int screen_height = gif_file->SHeight; for(int i = 0; i < screen_height; i++) { GifRowType gif_row = gif_buffer[i]; unsigned char *out_ptr = output->get_rows()[i]; for(int j = 0; j < screen_width; j++) { GifColorType *color_map_entry = &color_map->Colors[gif_row[j]]; *out_ptr++ = color_map_entry->Red; *out_ptr++ = color_map_entry->Green; *out_ptr++ = color_map_entry->Blue; } } for(int k = 0; k < gif_file->SHeight; k++) { free(gif_buffer[k]); } free(gif_buffer); DGifCloseFile(gif_file); return 0; }