void DLL_CALLCONV FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) { if (bitmap) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); if ((!header->read_only) && (header->locked_pages.empty())) { if (FreeImage_GetPageCount(bitmap) > 1) { BlockListIterator i = FreeImage_FindBlock(bitmap, page); if (i != header->m_blocks.end()) { switch((*i)->m_type) { case BLOCK_CONTINUEUS : header->m_blocks.erase(i); break; case BLOCK_REFERENCE : header->m_cachefile->deleteFile(((BlockReference *)(*i))->m_reference); header->m_blocks.erase(i); break; } header->changed = TRUE; header->page_count = -1; } } } } }
void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) { if (!bitmap || !data) return; if (page >= FreeImage_GetPageCount(bitmap)) return; MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); BlockReference *block = FreeImage_SavePageToBlock(header, data); if(block==NULL) return; // add a block if (page > 0) { BlockListIterator block_source = FreeImage_FindBlock(bitmap, page); header->m_blocks.insert(block_source, (BlockTypeS *)block); } else { header->m_blocks.push_front((BlockTypeS *)block); } header->changed = TRUE; header->page_count = -1; }
void FreeImageGifData::add24bitBGRDataPage(int width, int height, BYTE* pData) { FIBITMAP* newBitmap = FreeImage_Allocate(width, height, 24, 0x0000FF, 0x00FF00, 0xFF0000); BYTE* bitmapData = FreeImage_GetBits(newBitmap); memcpy(bitmapData, pData, width * height * 3); //Set metadata FIBITMAP* convBitmap = FreeImage_ColorQuantizeEx(newBitmap, FIQ_WUQUANT, 256); FITAG* delayTag = FreeImage_CreateTag(); FreeImage_SetMetadata(FIMD_ANIMATION, convBitmap, NULL, NULL); LONG delayVal = 20; if (delayTag) { FreeImage_SetTagKey(delayTag, "FrameTime"); FreeImage_SetTagType(delayTag, FIDT_LONG); FreeImage_SetTagCount(delayTag, 1); FreeImage_SetTagLength(delayTag, 4); FreeImage_SetTagValue(delayTag, &delayVal); FreeImage_SetMetadata(FIMD_ANIMATION, convBitmap, FreeImage_GetTagKey(delayTag), delayTag); FreeImage_DeleteTag(delayTag); } FreeImage_AppendPage(m_gifHandle, convBitmap); int pCount = FreeImage_GetPageCount(m_gifHandle); FreeImage_Unload(newBitmap); FreeImage_Unload(convBitmap); }
void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) { if ((bitmap) && (data)) { if (page < FreeImage_GetPageCount(bitmap)) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); if ((!header->read_only) && (header->locked_pages.empty())) { DWORD compressed_size = 0; BYTE *compressed_data = NULL; // compress the bitmap data // open a memory handle FIMEMORY *hmem = FreeImage_OpenMemory(); // save the file to memory FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0); // get the buffer from the memory stream FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size); // write the compressed data to the cache int ref = header->m_cachefile->writeFile(compressed_data, compressed_size); // add a block if (page > 0) { BlockListIterator block_source = FreeImage_FindBlock(bitmap, page); BlockReference *block = new BlockReference(ref, compressed_size); header->m_blocks.insert(block_source, (BlockTypeS *)block); } else { BlockReference *block = new BlockReference(ref, compressed_size); header->m_blocks.push_front((BlockTypeS *)block); } // get rid of the compressed buffer FreeImage_CloseMemory(hmem); header->changed = TRUE; header->page_count = -1; } } } }
// return a bool if succesful? bool ofxGifDecoder::decode(string fileName) { reset(); int width, height, bpp; fileName = ofToDataPath(fileName); bool bDecoded = false; FIMULTIBITMAP* multiBmp = NULL; FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; fif = FreeImage_GetFileType(fileName.c_str(), 0); if(fif != FIF_GIF) { ofLog(OF_LOG_WARNING, "ofxGifDecoder::decode. this is not a gif file. not processing"); return bDecoded; } multiBmp = FreeImage_OpenMultiBitmap(fif, fileName.c_str(), false, false,true, GIF_LOAD256); if (multiBmp){ // num frames int nPages = FreeImage_GetPageCount(multiBmp); // here we process the first frame for (int i = 0; i < nPages; i++) { FIBITMAP * dib = FreeImage_LockPage(multiBmp, i); if(dib) { if (i == 0) { createGifFile(dib, nPages); bDecoded = true; // we have at least 1 frame } processFrame(dib, i); FreeImage_UnlockPage(multiBmp, dib, false); } else { ofLog(OF_LOG_WARNING, "ofxGifDecoder::decode. problem locking page"); } } FreeImage_CloseMultiBitmap(multiBmp, 0); }else { ofLog(OF_LOG_WARNING, "ofxGifDecoder::decode. there was an error processing."); } return bDecoded; }
BOOL DLL_CALLCONV FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source) { if (bitmap) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); if ((!header->read_only) && (header->locked_pages.empty())) { if ((target != source) && ((target >= 0) && (target < FreeImage_GetPageCount(bitmap))) && ((source >= 0) && (source < FreeImage_GetPageCount(bitmap)))) { BlockListIterator block_source = FreeImage_FindBlock(bitmap, target); BlockListIterator block_target = FreeImage_FindBlock(bitmap, source); header->m_blocks.insert(block_target, *block_source); header->m_blocks.erase(block_source); header->changed = TRUE; return TRUE; } } } return FALSE; }
void DLL_CALLCONV FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) { if (!bitmap || !data) { return; } if (page >= FreeImage_GetPageCount(bitmap)) { return; } MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); if(const PageBlock block = FreeImage_SavePageToBlock(header, data)) { // add a block if (page > 0) { BlockListIterator block_source = FreeImage_FindBlock(bitmap, page); header->m_blocks.insert(block_source, block); } else { header->m_blocks.push_front(block); } header->changed = TRUE; header->page_count = -1; } }
bool CloneMultiPage(FREE_IMAGE_FORMAT fif, char *input, char *output, int output_flag) { BOOL bMemoryCache = TRUE; // Open src file (read-only, use memory cache) FIMULTIBITMAP *src = FreeImage_OpenMultiBitmap(fif, input, FALSE, TRUE, bMemoryCache); if(src) { // Open dst file (creation, use memory cache) FIMULTIBITMAP *dst = FreeImage_OpenMultiBitmap(fif, output, TRUE, FALSE, bMemoryCache); // Get src page count int count = FreeImage_GetPageCount(src); // Clone src to dst for(int page = 0; page < count; page++) { // Load the bitmap at position 'page' FIBITMAP *dib = FreeImage_LockPage(src, page); if(dib) { // add a new bitmap to dst FreeImage_AppendPage(dst, dib); // Unload the bitmap (do not apply any change to src) FreeImage_UnlockPage(src, dib, FALSE); } } // Close src FreeImage_CloseMultiBitmap(src, 0); // Save and close dst FreeImage_CloseMultiBitmap(dst, output_flag); return true; } return false; }
static void *bg_new_img(void *data) { /* so we can poll for it */ block_usr1_signal(); struct imv_loader *ldr = data; char path[PATH_MAX] = "-"; pthread_mutex_lock(&ldr->lock); int from_stdin = !strncmp(path, ldr->path, 2); if(!from_stdin) { (void)snprintf(path, PATH_MAX, "%s", ldr->path); } pthread_mutex_unlock(&ldr->lock); FREE_IMAGE_FORMAT fmt; if (from_stdin) { pthread_mutex_lock(&ldr->lock); ldr->fi_buffer = FreeImage_OpenMemory(ldr->buffer, ldr->buffer_size); fmt = FreeImage_GetFileTypeFromMemory(ldr->fi_buffer, 0); pthread_mutex_unlock(&ldr->lock); } else { fmt = FreeImage_GetFileType(path, 0); } if(fmt == FIF_UNKNOWN) { if (from_stdin) { pthread_mutex_lock(&ldr->lock); FreeImage_CloseMemory(ldr->fi_buffer); pthread_mutex_unlock(&ldr->lock); } error_occurred(ldr); return NULL; } int num_frames = 1; FIMULTIBITMAP *mbmp = NULL; FIBITMAP *bmp = NULL; int width, height; int raw_frame_time = 100; /* default to 100 */ if(fmt == FIF_GIF) { if(from_stdin) { pthread_mutex_lock(&ldr->lock); mbmp = FreeImage_LoadMultiBitmapFromMemory(FIF_GIF, ldr->fi_buffer, GIF_LOAD256); pthread_mutex_unlock(&ldr->lock); } else { mbmp = FreeImage_OpenMultiBitmap(FIF_GIF, path, /* don't create file */ 0, /* read only */ 1, /* keep in memory */ 1, /* flags */ GIF_LOAD256); } if(!mbmp) { error_occurred(ldr); return NULL; } num_frames = FreeImage_GetPageCount(mbmp); FIBITMAP *frame = FreeImage_LockPage(mbmp, 0); width = FreeImage_GetWidth(frame); height = FreeImage_GetHeight(frame); bmp = FreeImage_ConvertTo32Bits(frame); /* get duration of first frame */ FITAG *tag = NULL; FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag); if(FreeImage_GetTagValue(tag)) { raw_frame_time = *(int*)FreeImage_GetTagValue(tag); } FreeImage_UnlockPage(mbmp, frame, 0); } else { /* Future TODO: If we load image line-by-line we could stop loading large * ones before wasting much more time/memory on them. */ int flags = (fmt == FIF_JPEG) ? JPEG_EXIFROTATE : 0; FIBITMAP *image; if(from_stdin) { pthread_mutex_lock(&ldr->lock); image = FreeImage_LoadFromMemory(fmt, ldr->fi_buffer, flags); pthread_mutex_unlock(&ldr->lock); } else { image = FreeImage_Load(fmt, path, flags); } if(!image) { error_occurred(ldr); pthread_mutex_lock(&ldr->lock); FreeImage_CloseMemory(ldr->fi_buffer); ldr->fi_buffer = NULL; pthread_mutex_unlock(&ldr->lock); return NULL; } /* Check for cancellation before we convert pixel format */ if(is_thread_cancelled()) { FreeImage_Unload(image); return NULL; } width = FreeImage_GetWidth(bmp); height = FreeImage_GetHeight(bmp); bmp = FreeImage_ConvertTo32Bits(image); FreeImage_Unload(image); } /* now update the loader */ pthread_mutex_lock(&ldr->lock); /* check for cancellation before finishing */ if(is_thread_cancelled()) { if(mbmp) { FreeImage_CloseMultiBitmap(mbmp, 0); } if(bmp) { FreeImage_Unload(bmp); } pthread_mutex_unlock(&ldr->lock); return NULL; } if(ldr->mbmp) { FreeImage_CloseMultiBitmap(ldr->mbmp, 0); } if(ldr->bmp) { FreeImage_Unload(ldr->bmp); } ldr->mbmp = mbmp; ldr->bmp = bmp; if(ldr->out_bmp) { FreeImage_Unload(ldr->out_bmp); } ldr->out_bmp = FreeImage_Clone(bmp); ldr->out_is_new_image = 1; ldr->width = width; ldr->height = height; ldr->cur_frame = 0; ldr->next_frame = 1; ldr->num_frames = num_frames; ldr->frame_time = (double)raw_frame_time * 0.0001; pthread_mutex_unlock(&ldr->lock); return NULL; }
unsigned int FreeImageStack::slices() const { return FreeImage_GetPageCount(pImageStack_); }
void task_glow_precalc() { FIMULTIBITMAP* anim = inputanim; float thresh=0.5; float gain=2.0; float blur=1.5; int frameskip=1; sscanf(args[1].c_str(), "%f", &thresh); sscanf(args[2].c_str(), "%f", &gain); sscanf(args[3].c_str(), "%f", &blur); sscanf(args[4].c_str(), "%i", &frameskip); int frameCount = FreeImage_GetPageCount(anim); vector<double> fb; for (int frame=0; frame<frameCount/frameskip; frame++) { FIBITMAP* fiBitmap = FreeImage_LockPage(anim, frame*frameskip); FIBITMAP* grayBitmap = FreeImage_ConvertToGreyscale(fiBitmap); FreeImage_UnlockPage(anim, fiBitmap, FALSE); int width = FreeImage_GetWidth(grayBitmap); int height = FreeImage_GetHeight(grayBitmap); // put into an array of doubles (phew) fb.resize(width*height); for (int y=0; y<height; y++) { BYTE* src = FreeImage_GetScanLine(grayBitmap, y); double* dst = &fb[y*width]; for (int x=0; x<width; x++) { *dst++ = *src++ * (1.0/255); } } // threshold for (int i=0; i<(int)fb.size(); i++) { double& v = fb[i]; v = (v-thresh)*gain; if (v<0) v=0; } // blur Blur(fb, width, height, blur); // put it back into greyBitmap for (int y=0; y<height; y++) { BYTE* dst = FreeImage_GetScanLine(grayBitmap, y); double* src = &fb[y*width]; for (int x=0; x<width; x++) { double v = *src++ * 256; if (v<0) v=0; if (v>255) v=255; *dst++ = int(v); } } // downsample it to glowgrid FIBITMAP* smallBitmap = FreeImage_Rescale(grayBitmap, GLOWGRID_W, GLOWGRID_H, FILTER_BSPLINE); // print result (should use 4bpp not 8?) for (int y=0; y<GLOWGRID_H; y++) { BYTE* src = FreeImage_GetScanLine(smallBitmap, y); for (int x=0; x<GLOWGRID_W; x++) { putchar( *src++ ); } } } }
/* * Render a particular frame to a canvas (not gif specific). */ bool CAnimation::renderFileFrame(CCanvas *cnv, unsigned int frame) { extern STRING g_projectPath; cnv->ClearScreen(TRANSP_COLOR); // Wrap around. frame %= m_data.frameCount; if (m_data.filename.empty()) return false; const STRING file = resolve(g_projectPath + MISC_PATH + m_data.filename); FIMULTIBITMAP *mbmp = FreeImage_OpenMultiBitmap( FreeImage_GetFileType(getAsciiString(file).c_str(), 16), getAsciiString(file).c_str(), FALSE, TRUE, TRUE ); if (!mbmp) return false; CCanvas cnvImg; cnvImg.CreateBlank(NULL, m_data.pxWidth, m_data.pxHeight, TRUE); const int pageCount = FreeImage_GetPageCount(mbmp); if (frame < pageCount) { CONST HDC hdc = cnvImg.OpenDC(); FIBITMAP *bmp = FreeImage_LockPage(mbmp, frame); SetDIBitsToDevice( hdc, 0, 0, m_data.pxWidth, m_data.pxHeight, 0, 0, 0, FreeImage_GetHeight(bmp), FreeImage_GetBits(bmp), FreeImage_GetInfo(bmp), DIB_RGB_COLORS ); /* No need to stretch gif. StretchDIBits( hdc, 0, 0, m_data.pxWidth, m_data.pxHeight, 0, 0, FreeImage_GetWidth(bmp), FreeImage_GetHeight(bmp), FreeImage_GetBits(bmp), FreeImage_GetInfo(bmp), DIB_RGB_COLORS, SRCCOPY );*/ FreeImage_UnlockPage(mbmp, bmp, FALSE); cnvImg.CloseDC(hdc); } FreeImage_CloseMultiBitmap(mbmp, 0); // Apply ambient level. extern AMBIENT_LEVEL g_ambientLevel; if (g_ambientLevel.color) { CCanvas cnvAl; cnvAl.CreateBlank(NULL, m_data.pxWidth, m_data.pxHeight, TRUE); cnvAl.ClearScreen(g_ambientLevel.color); cnvAl.BltAdditivePart(cnvImg.GetDXSurface(), 0, 0, 0, 0, m_data.pxWidth, m_data.pxHeight, g_ambientLevel.sgn, -1, m_data.transpColors[frame]); } cnvImg.BltTransparent(cnv, 0, 0, m_data.transpColors[frame]); return true; }
int fipMultiPage::getPageCount() const { return _mpage ? FreeImage_GetPageCount(_mpage) : 0; }