diff options
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/MultiPage.cpp')
-rw-r--r-- | plugins/AdvaImg/src/FreeImage/MultiPage.cpp | 990 |
1 files changed, 0 insertions, 990 deletions
diff --git a/plugins/AdvaImg/src/FreeImage/MultiPage.cpp b/plugins/AdvaImg/src/FreeImage/MultiPage.cpp deleted file mode 100644 index 8c49d45396..0000000000 --- a/plugins/AdvaImg/src/FreeImage/MultiPage.cpp +++ /dev/null @@ -1,990 +0,0 @@ -// ========================================================== -// Multi-Page functions -// -// Design and implementation by -// - Floris van den Berg (flvdberg@wxs.nl) -// - Laurent Rocher (rocherl@club-internet.fr) -// - Steve Johnson (steve@parisgroup.net) -// - Petr Pytelka (pyta@lightcomp.com) -// - Hervé Drolon (drolon@infonie.fr) -// - Vadim Alexandrov (vadimalexandrov@users.sourceforge.net -// - Martin Dyring-Andersen (mda@spamfighter.com) -// - Volodymyr Goncharov (volodymyr.goncharov@gmail.com) -// -// This file is part of FreeImage 3 -// -// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES -// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE -// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED -// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT -// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY -// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL -// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER -// THIS DISCLAIMER. -// -// Use at your own risk! -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "CacheFile.h" -#include "FreeImageIO.h" -#include "Plugin.h" -#include "Utilities.h" -#include "FreeImage.h" - -// ---------------------------------------------------------- - -enum BlockType { BLOCK_CONTINUEUS, BLOCK_REFERENCE }; - -// ---------------------------------------------------------- - -struct BlockTypeS { - BlockType m_type; - - BlockTypeS(BlockType type) : m_type(type) { - } - virtual ~BlockTypeS() {} -}; - -struct BlockContinueus : public BlockTypeS { - int m_start; - int m_end; - - BlockContinueus(int s, int e) : BlockTypeS(BLOCK_CONTINUEUS), - m_start(s), - m_end(e) { - } -}; - -struct BlockReference : public BlockTypeS { - int m_reference; - int m_size; - - BlockReference(int r, int size) : BlockTypeS(BLOCK_REFERENCE), - m_reference(r), - m_size(size) { - } -}; - -// ---------------------------------------------------------- - -typedef std::list<BlockTypeS *> BlockList; -typedef std::list<BlockTypeS *>::iterator BlockListIterator; - -// ---------------------------------------------------------- - -FI_STRUCT (MULTIBITMAPHEADER) { - PluginNode *node; - FREE_IMAGE_FORMAT fif; - FreeImageIO *io; - fi_handle handle; - CacheFile *m_cachefile; - std::map<FIBITMAP *, int> locked_pages; - BOOL changed; - int page_count; - BlockList m_blocks; - char *m_filename; - BOOL read_only; - FREE_IMAGE_FORMAT cache_fif; - int load_flags; -}; - -// ===================================================================== -// Helper functions -// ===================================================================== - -inline void -ReplaceExtension(std::string& dst_filename, const std::string& src_filename, const std::string& dst_extension) { - size_t lastDot = src_filename.find_last_of('.'); - if (lastDot == std::string::npos) { - dst_filename = src_filename; - dst_filename += "."; - dst_filename += dst_extension; - } - else { - dst_filename = src_filename.substr(0, lastDot + 1); - dst_filename += dst_extension; - } -} - -// ===================================================================== -// Internal Multipage functions -// ===================================================================== - -inline MULTIBITMAPHEADER * -FreeImage_GetMultiBitmapHeader(FIMULTIBITMAP *bitmap) { - return (MULTIBITMAPHEADER *)bitmap->data; -} - -static BlockListIterator DLL_CALLCONV -FreeImage_FindBlock(FIMULTIBITMAP *bitmap, int position) { - assert(NULL != bitmap); - - MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); - - // step 1: find the block that matches the given position - - int prev_count = 0; - int count = 0; - BlockListIterator i; - BlockTypeS *current_block = NULL; - - for (i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) { - prev_count = count; - - switch((*i)->m_type) { - case BLOCK_CONTINUEUS : - count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1; - break; - - case BLOCK_REFERENCE : - count++; - break; - } - - current_block = *i; - - if (count > position) - break; - } - - // step 2: make sure we found the node. from here it gets a little complicated: - // * if the block is there, just return it - // * if the block is a series of blocks, split it in max 3 new blocks - // and return the splitted block - - if ((current_block) && (count > position)) { - switch(current_block->m_type) { - case BLOCK_REFERENCE : - return i; - - case BLOCK_CONTINUEUS : - { - BlockContinueus *block = (BlockContinueus *)current_block; - - if (block->m_start != block->m_end) { - int item = block->m_start + (position - prev_count); - - // left part - - if (item != block->m_start) { - BlockContinueus *block_a = new BlockContinueus(block->m_start, item - 1); - header->m_blocks.insert(i, (BlockTypeS *)block_a); - } - - // middle part - - BlockContinueus *block_b = new BlockContinueus(item, item); - BlockListIterator block_target = header->m_blocks.insert(i, (BlockTypeS *)block_b); - - // right part - - if (item != block->m_end) { - BlockContinueus *block_c = new BlockContinueus(item + 1, block->m_end); - header->m_blocks.insert(i, (BlockTypeS *)block_c); - } - - // remove the old block that was just splitted - - header->m_blocks.remove((BlockTypeS *)block); - delete block; - - // return the splitted block - - return block_target; - } - - return i; - } - } - } - // we should never go here ... - assert(false); - return header->m_blocks.end(); -} - -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; -} - -// ===================================================================== -// Multipage functions -// ===================================================================== - -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; -} - -FIMULTIBITMAP * DLL_CALLCONV -FreeImage_OpenMultiBitmapU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) { - - // convert to single character - no national chars in extensions - char *extension = (char *)malloc(wcslen(filename)+1); - unsigned int i=0; - for (; i < wcslen(filename); i++) // convert 16-bit to 8-bit - extension[i] = (char)(filename[i] & 0x00FF); - // set terminating 0 - extension[i]=0; - FIMULTIBITMAP *fRet = FreeImage_OpenMultiBitmap(fif, extension, create_new, read_only, keep_cache_in_memory, flags); - free(extension); - - return fRet; -} - -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; -} - -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; -} - - -BOOL DLL_CALLCONV -FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) { - if (bitmap) { - BOOL success = TRUE; - - if (bitmap->data) { - MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); - - // saves changes only of images loaded directly from a file - if (header->changed && header->m_filename) { - try { - // open a temp file - - std::string spool_name; - - ReplaceExtension(spool_name, header->m_filename, "fispool"); - - // open the spool file and the source file - - FILE *f = fopen(spool_name.c_str(), "w+b"); - - // saves changes - if (f == NULL) { - FreeImage_OutputMessageProc(header->fif, "Failed to open %s, %s", spool_name.c_str(), strerror(errno)); - success = FALSE; - } else { - success = FreeImage_SaveMultiBitmapToHandle(header->fif, bitmap, header->io, (fi_handle)f, flags); - - // close the files - - if (fclose(f) != 0) { - success = FALSE; - FreeImage_OutputMessageProc(header->fif, "Failed to close %s, %s", spool_name.c_str(), strerror(errno)); - } - } - if (header->handle) { - fclose((FILE *)header->handle); - } - - // applies changes to the destination file - - if (success) { - remove(header->m_filename); - success = (rename(spool_name.c_str(), header->m_filename) == 0) ? TRUE:FALSE; - if(!success) { - FreeImage_OutputMessageProc(header->fif, "Failed to rename %s to %s", spool_name.c_str(), header->m_filename); - } - } else { - remove(spool_name.c_str()); - } - } catch (std::bad_alloc &) { - success = FALSE; - } - - } 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; -} - -int DLL_CALLCONV -FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) { - if (bitmap) { - MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); - - if (header->page_count == -1) { - header->page_count = 0; - - for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) { - switch((*i)->m_type) { - case BLOCK_CONTINUEUS : - header->page_count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1; - break; - - case BLOCK_REFERENCE : - header->page_count++; - break; - } - } - } - - return header->page_count; - } - - return 0; -} - -static BlockReference* -FreeImage_SavePageToBlock(MULTIBITMAPHEADER *header, FIBITMAP *data) { - if (header->read_only || !header->locked_pages.empty()) - return NULL; - - DWORD compressed_size = 0; - BYTE *compressed_data = NULL; - - // compress the bitmap data - - // open a memory handle - FIMEMORY *hmem = FreeImage_OpenMemory(); - if(hmem==NULL) return NULL; - // save the file to memory - if(!FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0)) { - FreeImage_CloseMemory(hmem); - return NULL; - } - // get the buffer from the memory stream - if(!FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size)) { - FreeImage_CloseMemory(hmem); - return NULL; - } - - // write the compressed data to the cache - int ref = header->m_cachefile->writeFile(compressed_data, compressed_size); - // get rid of the compressed data - FreeImage_CloseMemory(hmem); - - return new(std::nothrow) BlockReference(ref, compressed_size); -} - -void DLL_CALLCONV -FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) { - if (!bitmap || !data) - return; - - MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); - - BlockReference *block = FreeImage_SavePageToBlock(header, data); - if(block==NULL) return; - - // add the block - header->m_blocks.push_back((BlockTypeS *)block); - 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 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 : - delete *i; - header->m_blocks.erase(i); - break; - - case BLOCK_REFERENCE : - header->m_cachefile->deleteFile(((BlockReference *)(*i))->m_reference); - delete *i; - header->m_blocks.erase(i); - break; - } - - header->changed = TRUE; - header->page_count = -1; - } - } - } - } -} - - -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; -} - -void DLL_CALLCONV -FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) { - if ((bitmap) && (page)) { - MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); - - // find out if the page we try to unlock is actually locked... - - if (header->locked_pages.find(page) != header->locked_pages.end()) { - // store the bitmap compressed in the cache for later writing - - if (changed && !header->read_only) { - header->changed = TRUE; - - // cut loose the block from the rest - - BlockListIterator i = FreeImage_FindBlock(bitmap, header->locked_pages[page]); - - // compress the data - - DWORD compressed_size = 0; - BYTE *compressed_data = NULL; - - // open a memory handle - FIMEMORY *hmem = FreeImage_OpenMemory(); - // save the page to memory - FreeImage_SaveToMemory(header->cache_fif, page, hmem, 0); - // get the buffer from the memory stream - FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size); - - // write the data to the cache - - switch ((*i)->m_type) { - case BLOCK_CONTINUEUS : - { - int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size); - - delete (*i); - - *i = (BlockTypeS *)new BlockReference(iPage, compressed_size); - - break; - } - - case BLOCK_REFERENCE : - { - BlockReference *reference = (BlockReference *)(*i); - - header->m_cachefile->deleteFile(reference->m_reference); - - delete (*i); - - int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size); - - *i = (BlockTypeS *)new BlockReference(iPage, compressed_size); - - break; - } - } - - // get rid of the compressed data - - FreeImage_CloseMemory(hmem); - } - - // reset the locked page so that another page can be locked - - FreeImage_Unload(page); - - header->locked_pages.erase(page); - } - } -} - -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; -} - -BOOL DLL_CALLCONV -FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count) { - if ((bitmap) && (count)) { - MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap); - - if ((pages == NULL) || (*count == 0)) { - *count = (int)header->locked_pages.size(); - } else { - int c = 0; - - for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) { - pages[c] = i->second; - - c++; - - if (c == *count) - break; - } - } - - return TRUE; - } - - return FALSE; -} - -// ===================================================================== -// Memory IO Multipage functions -// ===================================================================== - -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) { - FreeImageIO *io = new(std::nothrow) FreeImageIO; - - if (io) { - SetMemoryIO(io); - - FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP; - - if (bitmap) { - MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER; - - if (header) { - header->m_filename = NULL; - header->node = node; - header->fif = fif; - header->io = io; - header->handle = (fi_handle)stream; - 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; - - // 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)); - - if (!read_only) { - // set up the cache - CacheFile *cache_file = new(std::nothrow) CacheFile("", TRUE); - - if (cache_file && cache_file->open()) { - header->m_cachefile = cache_file; - } - } - - return bitmap; - } - - delete bitmap; - } - - delete io; - } - } - } - - return NULL; -} - -BOOL DLL_CALLCONV -FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags) { - if (stream && stream->data) { - FreeImageIO io; - SetMemoryIO(&io); - - return FreeImage_SaveMultiBitmapToHandle(fif, bitmap, &io, (fi_handle)stream, flags); - } - - return FALSE; -} |