Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/MultiPage.cpp view on Meta::CPAN
// 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_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:
{
src/Source/FreeImage/MultiPage.cpp view on Meta::CPAN
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
( run in 0.740 second using v1.01-cache-2.11-cpan-5735350b133 )