Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImage/MultiPage.cpp  view on Meta::CPAN

		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_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();
						}

src/Source/FreeImage/MultiPage.cpp  view on Meta::CPAN


	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;

src/Source/FreeImage/MultiPage.cpp  view on Meta::CPAN

		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;
}



( run in 0.674 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )