FIBITMAP * DLL_CALLCONV FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) { if (bitmap) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); // only lock if the page wasn't locked before... for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) { if (i->second == page) { return NULL; } } // open the bitmap header->io->seek_proc(header->handle, 0, SEEK_SET); void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE); // load the bitmap data if (data != NULL) { FIBITMAP *dib = (header->node->m_plugin->load_proc != NULL) ? header->node->m_plugin->load_proc(header->io, header->handle, page, header->load_flags, data) : NULL; // close the file FreeImage_Close(header->node, header->io, header->handle, data); // if there was still another bitmap open, get rid of it if (dib) { header->locked_pages[dib] = page; return dib; } return NULL; } } return NULL; }
int DLL_CALLCONV FreeImage_InternalGetPageCount(FIMULTIBITMAP *bitmap) { if (bitmap) { if (((MULTIBITMAPHEADER *)bitmap->data)->handle) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); header->io->seek_proc(header->handle, 0, SEEK_SET); void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE); int page_count = (header->node->m_plugin->pagecount_proc != NULL) ? header->node->m_plugin->pagecount_proc(header->io, header->handle, data) : 1; FreeImage_Close(header->node, header->io, header->handle, data); return page_count; } } return 0; }
BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) { if (bitmap) { BOOL success = TRUE; if (bitmap->data) { MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); if (header->changed) { // open a temp file char spool_name[256]; ReplaceExtension(spool_name, header->m_filename, "fispool"); // open the spool file and the source file FILE *f = fopen(spool_name, "w+b"); void *data = FreeImage_Open(header->node, header->io, (fi_handle)f, FALSE); void *data_read = NULL; if (header->handle) { 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 temp file 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++) { FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read); success = header->node->m_plugin->save_proc(header->io, dib, (fi_handle)f, 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 = header->node->m_plugin->save_proc(header->io, dib, (fi_handle)f, count, flags, data); count++; // unload the dib FreeImage_Unload(dib); break; } } } else { break; } } // close the files FreeImage_Close(header->node, header->io, (fi_handle)f, data); fclose(f); if (header->handle) { FreeImage_Close(header->node, header->io, header->handle, data_read); fclose((FILE *)header->handle); } if (success) { remove(header->m_filename); rename(spool_name, header->m_filename); } else { remove(spool_name); } } else { if (header->handle && header->m_filename) { fclose((FILE *)header->handle); } } // clear the blocks list for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) delete *i; // flush and dispose the cache if (header->m_cachefile) { header->m_cachefile->close(); delete header->m_cachefile; } // delete the last open bitmaps while (!header->locked_pages.empty()) { FreeImage_Unload(header->locked_pages.begin()->first); header->locked_pages.erase(header->locked_pages.begin()->first); } // get rid of the IO structure delete header->io; // delete the filename if(header->m_filename) delete[] header->m_filename; // delete the FIMULTIBITMAPHEADER delete header; } delete bitmap; return success; } return FALSE; }
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; }