FIMULTIBITMAP * DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) { // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if (node) { FreeImageIO *io = new FreeImageIO; if (io) { SetMemoryIO(io); FIMULTIBITMAP *bitmap = new FIMULTIBITMAP; if (bitmap) { MULTIBITMAPHEADER *header = new MULTIBITMAPHEADER; header->m_filename = NULL; header->node = node; header->fif = fif; header->io = io; header->handle = (fi_handle)stream; header->changed = FALSE; header->read_only = TRUE; header->m_cachefile = NULL; header->cache_fif = fif; header->load_flags = flags; if (header) { // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure bitmap->data = header; // cache the page count header->page_count = FreeImage_InternalGetPageCount(bitmap); // allocate a continueus block to describe the bitmap header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1)); // set up the cache return bitmap; } return NULL; } } delete io; } } return NULL; }
FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) { try { BOOL read_only = FALSE; // modifications (if any) will be stored into the memory cache if (io && handle) { // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if (node) { std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP); std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER); std::auto_ptr<FreeImageIO> tmp_io (new FreeImageIO (*io)); header->io = tmp_io.get(); header->m_filename = NULL; header->node = node; header->fif = fif; header->handle = handle; header->changed = FALSE; header->read_only = read_only; header->m_cachefile = NULL; header->cache_fif = fif; header->load_flags = flags; // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure bitmap->data = header.get(); // cache the page count header->page_count = FreeImage_InternalGetPageCount(bitmap.get()); // allocate a continueus block to describe the bitmap header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1)); if (!read_only) { // set up the cache std::auto_ptr<CacheFile> cache_file (new CacheFile("", TRUE)); if (cache_file->open()) { header->m_cachefile = cache_file.release(); } } tmp_io.release(); header.release(); return bitmap.release(); } } } } catch (std::bad_alloc &) { /** @todo report error */ } return NULL; }
FIMULTIBITMAP * DLL_CALLCONV FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) { BOOL read_only = FALSE; // modifications (if any) will be stored into the memory cache // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if (node) { FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP; if (bitmap) { MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER; if (header) { header->node = node; header->fif = fif; SetMemoryIO(&header->io); header->handle = (fi_handle)stream; header->read_only = read_only; header->cache_fif = fif; header->load_flags = flags; // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure bitmap->data = header; // cache the page count header->page_count = FreeImage_InternalGetPageCount(bitmap); // allocate a continueus block to describe the bitmap header->m_blocks.push_back(PageBlock(BLOCK_CONTINUEUS, 0, header->page_count - 1)); // no need to open cache - it is in-memory by default return bitmap; } delete bitmap; } } } return NULL; }
FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) { try { BOOL read_only = FALSE; // modifications (if any) will be stored into the memory cache if (io && handle) { // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if (node) { std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP); std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER); header->io = *io; header->node = node; header->fif = fif; header->handle = handle; header->read_only = read_only; header->cache_fif = fif; header->load_flags = flags; // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure bitmap->data = header.get(); // cache the page count header->page_count = FreeImage_InternalGetPageCount(bitmap.get()); // allocate a continueus block to describe the bitmap header->m_blocks.push_back(PageBlock(BLOCK_CONTINUEUS, 0, header->page_count - 1)); // no need to open cache - it is in-memory by default header.release(); return bitmap.release(); } } } } catch (std::bad_alloc &) { /** @todo report error */ } return NULL; }
FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) { // sanity check on the parameters if (create_new) read_only = FALSE; // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if (node) { FreeImageIO *io = new FreeImageIO; if (io) { SetDefaultIO(io); BOOL cont = TRUE; FILE *handle = NULL; if (!create_new) { handle = fopen(filename, "rb"); if (handle == NULL) { cont = FALSE; } } if (cont) { FIMULTIBITMAP *bitmap = new FIMULTIBITMAP; if (bitmap) { MULTIBITMAPHEADER *header = new MULTIBITMAPHEADER; header->m_filename = new char[strlen(filename) + 1]; strcpy(header->m_filename, filename); header->node = node; header->fif = fif; header->io = io; header->handle = handle; header->changed = FALSE; header->read_only = read_only; header->m_cachefile = NULL; header->cache_fif = fif; header->load_flags = flags; if (header) { // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure bitmap->data = header; // cache the page count header->page_count = FreeImage_InternalGetPageCount(bitmap); // allocate a continueus block to describe the bitmap if (!create_new) header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1)); // set up the cache if (!read_only) { char cache_name[256]; ReplaceExtension(cache_name, filename, "ficache"); CacheFile *cache_file = new CacheFile(cache_name, keep_cache_in_memory); if (cache_file->open()) { header->m_cachefile = cache_file; // return the multibitmap return bitmap; } delete cache_file; delete header; } return bitmap; } return NULL; } } } delete io; } } return NULL; }
BOOL DLL_CALLCONV FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags) { if(!bitmap || !bitmap->data || !io || !handle) { return FALSE; } BOOL success = TRUE; // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if(node) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); // dst data void *data = FreeImage_Open(node, io, handle, FALSE); // src data void *data_read = NULL; if(header->handle) { // open src header->io->seek_proc(header->handle, 0, SEEK_SET); data_read = FreeImage_Open(header->node, header->io, header->handle, TRUE); } // write all the pages to the file using handle and io int count = 0; for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); i++) { if (success) { switch((*i)->m_type) { case BLOCK_CONTINUEUS: { BlockContinueus *block = (BlockContinueus *)(*i); for (int j = block->m_start; j <= block->m_end; j++) { // load the original source data FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read); // save the data success = node->m_plugin->save_proc(io, dib, handle, count, flags, data); count++; FreeImage_Unload(dib); } break; } case BLOCK_REFERENCE: { BlockReference *ref = (BlockReference *)(*i); // read the compressed data BYTE *compressed_data = (BYTE*)malloc(ref->m_size * sizeof(BYTE)); header->m_cachefile->readFile((BYTE *)compressed_data, ref->m_reference, ref->m_size); // uncompress the data FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, ref->m_size); FIBITMAP *dib = FreeImage_LoadFromMemory(header->cache_fif, hmem, 0); FreeImage_CloseMemory(hmem); // get rid of the buffer free(compressed_data); // save the data success = node->m_plugin->save_proc(io, dib, handle, count, flags, data); count++; // unload the dib FreeImage_Unload(dib); break; } } } else { break; } } // close the files FreeImage_Close(header->node, header->io, header->handle, data_read); FreeImage_Close(node, io, handle, data); return success; } } return FALSE; }
FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) { FILE *handle = NULL; try { // sanity check on the parameters if (create_new) { read_only = FALSE; } // retrieve the plugin list to find the node belonging to this plugin PluginList *list = FreeImage_GetPluginList(); if (list) { PluginNode *node = list->FindNodeFromFIF(fif); if (node) { std::auto_ptr<FreeImageIO> io (new FreeImageIO); SetDefaultIO(io.get()); if (!create_new) { handle = fopen(filename, "rb"); if (handle == NULL) { return NULL; } } std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP); std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER); header->m_filename = new char[strlen(filename) + 1]; strcpy(header->m_filename, filename); header->node = node; header->fif = fif; header->io = io.get (); header->handle = handle; header->changed = FALSE; header->read_only = read_only; header->m_cachefile = NULL; header->cache_fif = fif; header->load_flags = flags; // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure bitmap->data = header.get(); // cache the page count header->page_count = FreeImage_InternalGetPageCount(bitmap.get()); // allocate a continueus block to describe the bitmap if (!create_new) { header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1)); } // set up the cache if (!read_only) { std::string cache_name; ReplaceExtension(cache_name, filename, "ficache"); std::auto_ptr<CacheFile> cache_file (new CacheFile(cache_name, keep_cache_in_memory)); if (cache_file->open()) { // we can use release() as std::bad_alloc won't be thrown from here on header->m_cachefile = cache_file.release(); } else { // an error occured ... fclose(handle); return NULL; } } // return the multibitmap // std::bad_alloc won't be thrown from here on header.release(); // now owned by bitmap io.release(); // now owned by bitmap return bitmap.release(); // now owned by caller } } } catch (std::bad_alloc &) { /** @todo report error */ } if (handle) fclose(handle); return NULL; }