summaryrefslogtreecommitdiff
path: root/libs/freeimage/src/FreeImage
diff options
context:
space:
mode:
Diffstat (limited to 'libs/freeimage/src/FreeImage')
-rw-r--r--libs/freeimage/src/FreeImage/BitmapAccess.cpp31
-rw-r--r--libs/freeimage/src/FreeImage/CacheFile.cpp27
-rw-r--r--libs/freeimage/src/FreeImage/Conversion.cpp18
-rw-r--r--libs/freeimage/src/FreeImage/Conversion32.cpp6
-rw-r--r--libs/freeimage/src/FreeImage/GetType.cpp82
-rw-r--r--libs/freeimage/src/FreeImage/MemoryIO.cpp16
-rw-r--r--libs/freeimage/src/FreeImage/MultiPage.cpp519
-rw-r--r--libs/freeimage/src/FreeImage/Plugin.cpp2
-rw-r--r--libs/freeimage/src/FreeImage/PluginBMP.cpp112
-rw-r--r--libs/freeimage/src/FreeImage/PluginGIF.cpp47
-rw-r--r--libs/freeimage/src/FreeImage/PluginJPEG.cpp55
-rw-r--r--libs/freeimage/src/FreeImage/PluginPNG.cpp36
12 files changed, 523 insertions, 428 deletions
diff --git a/libs/freeimage/src/FreeImage/BitmapAccess.cpp b/libs/freeimage/src/FreeImage/BitmapAccess.cpp
index c3be7a1742..e77344e1e1 100644
--- a/libs/freeimage/src/FreeImage/BitmapAccess.cpp
+++ b/libs/freeimage/src/FreeImage/BitmapAccess.cpp
@@ -1,4 +1,4 @@
-// ==========================================================
+// ==========================================================
// FreeImage implementation
//
// Design and implementation by
@@ -537,6 +537,7 @@ FreeImage_Clone(FIBITMAP *dib) {
unsigned height = FreeImage_GetHeight(dib);
unsigned bpp = FreeImage_GetBPP(dib);
+ // if the FIBITMAP is a wrapper to a user provided pixel buffer, get a pointer to this buffer
const BYTE *ext_bits = ((FREEIMAGEHEADER *)dib->data)->external_bits;
// check for pixel availability ...
@@ -558,7 +559,7 @@ FreeImage_Clone(FIBITMAP *dib) {
METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;
- // calculate the size of the src image
+ // calculate the size of the dst image
// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
// palette is aligned on a 16 bytes boundary
// pixels are aligned on a 16 bytes boundary
@@ -579,6 +580,10 @@ FreeImage_Clone(FIBITMAP *dib) {
// reset thumbnail link for new_dib
((FREEIMAGEHEADER *)new_dib->data)->thumbnail = NULL;
+ // reset external wrapped buffer link for new_dib
+ ((FREEIMAGEHEADER *)new_dib->data)->external_bits = NULL;
+ ((FREEIMAGEHEADER *)new_dib->data)->external_pitch = 0;
+
// copy possible ICC profile
FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
dst_iccProfile->flags = src_iccProfile->flags;
@@ -697,12 +702,14 @@ FreeImage_GetColorType(FIBITMAP *dib) {
return FIC_MINISBLACK;
}
break;
+
case FIT_RGB16:
case FIT_RGBF:
return FIC_RGB;
+
case FIT_RGBA16:
case FIT_RGBAF:
- return FIC_RGBALPHA;
+ return (((FreeImage_GetICCProfile(dib)->flags) & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) ? FIC_CMYK : FIC_RGBALPHA;
}
return FIC_MINISBLACK;
@@ -767,7 +774,7 @@ FreeImage_GetColorType(FIBITMAP *dib) {
case 32:
{
- if (FreeImage_GetICCProfile(dib)->flags & FIICC_COLOR_IS_CMYK) {
+ if (((FreeImage_GetICCProfile(dib)->flags) & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) {
return FIC_CMYK;
}
@@ -944,7 +951,7 @@ FreeImage_IsTransparent(FIBITMAP *dib) {
break;
case FIT_RGBA16:
case FIT_RGBAF:
- return TRUE;
+ return (((FreeImage_GetICCProfile(dib)->flags) & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) ? FALSE : TRUE;
default:
break;
}
@@ -1085,6 +1092,9 @@ FreeImage_DestroyICCProfile(FIBITMAP *dib) {
profile->data = NULL;
profile->size = 0;
}
+
+ // destroy also Exif-Main ICC profile
+ FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);
}
// ----------------------------------------------------------
@@ -1194,12 +1204,12 @@ FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag
FIMETADATA *handle = (FIMETADATA *)malloc(sizeof(FIMETADATA));
if(handle) {
// calculate the size of a METADATAHEADER
- int header_size = sizeof(METADATAHEADER);
+ const size_t header_size = sizeof(METADATAHEADER);
- handle->data = (BYTE *)malloc(header_size * sizeof(BYTE));
+ handle->data = (BYTE *)malloc(header_size);
if(handle->data) {
- memset(handle->data, 0, header_size * sizeof(BYTE));
+ memset(handle->data, 0, header_size);
// write out the METADATAHEADER
METADATAHEADER *mdh = (METADATAHEADER *)handle->data;
@@ -1334,6 +1344,11 @@ FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key,
if(key != NULL) {
+ if ((tag == NULL) && !tagmap) {
+ // remove a tag from an unknown tagmap, nothing to do
+ return TRUE;
+ }
+
if(!tagmap) {
// this model, doesn't exist: create it
tagmap = new(std::nothrow) TAGMAP();
diff --git a/libs/freeimage/src/FreeImage/CacheFile.cpp b/libs/freeimage/src/FreeImage/CacheFile.cpp
index 086393bf03..e98906d39e 100644
--- a/libs/freeimage/src/FreeImage/CacheFile.cpp
+++ b/libs/freeimage/src/FreeImage/CacheFile.cpp
@@ -4,6 +4,7 @@
// Design and implementation by
// - Floris van den Berg (flvdberg@wxs.nl)
// - checkered (checkered@users.sourceforge.net)
+// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
//
// This file is part of FreeImage 3
//
@@ -28,25 +29,31 @@
// ----------------------------------------------------------
-CacheFile::CacheFile(const std::string filename, BOOL keep_in_memory) :
+CacheFile::CacheFile() :
m_file(NULL),
-m_filename(filename),
m_free_pages(),
m_page_cache_mem(),
m_page_cache_disk(),
m_page_map(),
m_page_count(0),
m_current_block(NULL),
-m_keep_in_memory(keep_in_memory) {
+m_keep_in_memory(TRUE) {
}
CacheFile::~CacheFile() {
+ close();
}
BOOL
-CacheFile::open() {
+CacheFile::open(const std::string& filename, BOOL keep_in_memory) {
+
+ assert(!m_file);
+
+ m_filename = filename;
+ m_keep_in_memory = keep_in_memory;
+
if ((!m_filename.empty()) && (!m_keep_in_memory)) {
- m_file = fopen(m_filename.c_str(), "w+b");
+ m_file = fopen(m_filename.c_str(), "w+b");
return (m_file != NULL);
}
@@ -72,11 +79,10 @@ CacheFile::close() {
if (m_file) {
// close the file
-
fclose(m_file);
-
+ m_file = NULL;
+
// delete the file
-
remove(m_filename.c_str());
}
}
@@ -164,10 +170,8 @@ BOOL
CacheFile::unlockBlock(int nr) {
if (m_current_block) {
m_current_block = NULL;
-
return TRUE;
}
-
return FALSE;
}
@@ -178,8 +182,9 @@ CacheFile::deleteBlock(int nr) {
// remove block from cache
- if (it != m_page_map.end())
+ if (it != m_page_map.end()) {
m_page_map.erase(nr);
+ }
// add block to free page list
diff --git a/libs/freeimage/src/FreeImage/Conversion.cpp b/libs/freeimage/src/FreeImage/Conversion.cpp
index 9ef49f393b..f8d8ce4512 100644
--- a/libs/freeimage/src/FreeImage/Conversion.cpp
+++ b/libs/freeimage/src/FreeImage/Conversion.cpp
@@ -28,8 +28,17 @@
// ----------------------------------------------------------
#define CONVERT(from, to) case to : FreeImage_ConvertLine##from##To##to(bits, scanline, FreeImage_GetWidth(dib)); break;
+
#define CONVERTWITHPALETTE(from, to) case to : FreeImage_ConvertLine##from##To##to(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); break;
+#define CONVERTTO32WITHPALETTE(from) case 32 : \
+ if (bIsTransparent) { \
+ FreeImage_ConvertLine##from##To32MapTransparency(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib)); \
+ } else { \
+ FreeImage_ConvertLine##from##To32(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); \
+ } \
+ break;
+
#define CONVERTTO16(from) \
case 16 : \
if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) { \
@@ -491,14 +500,15 @@ FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, u
}
}
} else if (FreeImage_GetBPP(dib) != bpp) {
+ BOOL bIsTransparent = FreeImage_IsTransparent(dib);
switch(FreeImage_GetBPP(dib)) {
case 1 :
switch(bpp) {
CONVERT(1, 8)
CONVERTTO16WITHPALETTE(1)
CONVERTWITHPALETTE(1, 24)
- CONVERTWITHPALETTE(1, 32)
- }
+ CONVERTTO32WITHPALETTE(1)
+ }
break;
@@ -507,7 +517,7 @@ FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, u
CONVERT(4, 8)
CONVERTTO16WITHPALETTE(4)
CONVERTWITHPALETTE(4, 24)
- CONVERTWITHPALETTE(4, 32)
+ CONVERTTO32WITHPALETTE(4)
}
break;
@@ -516,7 +526,7 @@ FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, u
switch(bpp) {
CONVERTTO16WITHPALETTE(8)
CONVERTWITHPALETTE(8, 24)
- CONVERTWITHPALETTE(8, 32)
+ CONVERTTO32WITHPALETTE(8)
}
break;
diff --git a/libs/freeimage/src/FreeImage/Conversion32.cpp b/libs/freeimage/src/FreeImage/Conversion32.cpp
index f5eb0c2103..17dbe7e7b8 100644
--- a/libs/freeimage/src/FreeImage/Conversion32.cpp
+++ b/libs/freeimage/src/FreeImage/Conversion32.cpp
@@ -131,7 +131,7 @@ FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
// ----------------------------------------------------------
-inline void
+void DLL_CALLCONV
FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
for (int cols = 0; cols < width_in_pixels; cols++) {
int index = (source[cols>>3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
@@ -144,7 +144,7 @@ FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_
}
}
-inline void
+void DLL_CALLCONV
FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
BOOL low_nibble = FALSE;
int x = 0;
@@ -170,7 +170,7 @@ FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_
}
}
-inline void
+void DLL_CALLCONV
FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
for (int cols = 0; cols < width_in_pixels; cols++) {
target[FI_RGBA_BLUE] = palette[source[cols]].rgbBlue;
diff --git a/libs/freeimage/src/FreeImage/GetType.cpp b/libs/freeimage/src/FreeImage/GetType.cpp
index b2991a0e49..625b81246a 100644
--- a/libs/freeimage/src/FreeImage/GetType.cpp
+++ b/libs/freeimage/src/FreeImage/GetType.cpp
@@ -1,8 +1,9 @@
-// ==========================================================
-// GetType
+// ==========================================================
+// GetType / Validate
//
// Design and implementation by
// - Floris van den Berg (flvdberg@wxs.nl)
+// - Hervé Drolon (drolon@infonie.fr)
//
// This file is part of FreeImage 3
//
@@ -25,7 +26,9 @@
#include "../stdafx.h"
-// ----------------------------------------------------------
+// =====================================================================
+// Generic stream file type access
+// =====================================================================
FREE_IMAGE_FORMAT DLL_CALLCONV
FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size) {
@@ -34,7 +37,7 @@ FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size) {
for (int i = 0; i < fif_count; ++i) {
FREE_IMAGE_FORMAT fif = (FREE_IMAGE_FORMAT)i;
- if (FreeImage_Validate(fif, io, handle)) {
+ if (FreeImage_ValidateFIF(fif, io, handle)) {
/*if(fif == FIF_TIFF) {
// many camera raw files use a TIFF signature ...
// ... try to revalidate against FIF_RAW (even if it breaks the code genericity)
@@ -50,6 +53,10 @@ FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size) {
return FIF_UNKNOWN;
}
+// =====================================================================
+// File stream file type access
+// =====================================================================
+
FREE_IMAGE_FORMAT DLL_CALLCONV
FreeImage_GetFileType(const char *filename, int size) {
FreeImageIO io;
@@ -86,3 +93,70 @@ FreeImage_GetFileTypeU(const wchar_t *filename, int size) {
return FIF_UNKNOWN;
}
+// =====================================================================
+// Memory stream file type access
+// =====================================================================
+
+FREE_IMAGE_FORMAT DLL_CALLCONV
+FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size) {
+ FreeImageIO io;
+ SetMemoryIO(&io);
+
+ if (stream != NULL) {
+ return FreeImage_GetFileTypeFromHandle(&io, (fi_handle)stream, size);
+ }
+
+ return FIF_UNKNOWN;
+}
+
+// --------------------------------------------------------------------------
+
+BOOL DLL_CALLCONV
+FreeImage_ValidateFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle) {
+ return FreeImage_ValidateFIF(fif, io, handle);
+}
+
+BOOL DLL_CALLCONV
+FreeImage_Validate(FREE_IMAGE_FORMAT fif, const char *filename) {
+ FreeImageIO io;
+ SetDefaultIO(&io);
+
+ FILE *handle = fopen(filename, "rb");
+
+ if (handle != NULL) {
+ BOOL bIsValidFIF = FreeImage_ValidateFromHandle(fif, &io, (fi_handle)handle);
+ fclose(handle);
+ return bIsValidFIF;
+ }
+
+ return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_ValidateU(FREE_IMAGE_FORMAT fif, const wchar_t *filename) {
+#ifdef _WIN32
+ FreeImageIO io;
+ SetDefaultIO(&io);
+ FILE *handle = _wfopen(filename, L"rb");
+
+ if (handle != NULL) {
+ BOOL bIsValidFIF = FreeImage_ValidateFromHandle(fif, &io, (fi_handle)handle);
+ fclose(handle);
+ return bIsValidFIF;
+ }
+#endif
+ return FALSE;
+}
+
+BOOL DLL_CALLCONV
+FreeImage_ValidateFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream) {
+ FreeImageIO io;
+ SetMemoryIO(&io);
+
+ if (stream != NULL) {
+ BOOL bIsValidFIF = FreeImage_ValidateFromHandle(fif, &io, (fi_handle)stream);
+ return bIsValidFIF;
+ }
+
+ return FALSE;
+}
diff --git a/libs/freeimage/src/FreeImage/MemoryIO.cpp b/libs/freeimage/src/FreeImage/MemoryIO.cpp
index c04612373a..cda97e1e71 100644
--- a/libs/freeimage/src/FreeImage/MemoryIO.cpp
+++ b/libs/freeimage/src/FreeImage/MemoryIO.cpp
@@ -126,22 +126,6 @@ FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes) {
}
// =====================================================================
-// Memory stream file type access
-// =====================================================================
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- if (stream != NULL) {
- return FreeImage_GetFileTypeFromHandle(&io, (fi_handle)stream, size);
- }
-
- return FIF_UNKNOWN;
-}
-
-// =====================================================================
// Seeking in Memory stream
// =====================================================================
diff --git a/libs/freeimage/src/FreeImage/MultiPage.cpp b/libs/freeimage/src/FreeImage/MultiPage.cpp
index 0d49f46633..5788d241fd 100644
--- a/libs/freeimage/src/FreeImage/MultiPage.cpp
+++ b/libs/freeimage/src/FreeImage/MultiPage.cpp
@@ -10,6 +10,7 @@
// - Vadim Alexandrov (vadimalexandrov@users.sourceforge.net
// - Martin Dyring-Andersen (mda@spamfighter.com)
// - Volodymyr Goncharov (volodymyr.goncharov@gmail.com)
+// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
//
// This file is part of FreeImage 3
//
@@ -32,58 +33,89 @@
#include "../stdafx.h"
+namespace {
+
// ----------------------------------------------------------
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) {
- }
+class PageBlock {
+
+ union {
+ struct {
+ int m_start;
+ int m_end;
+ };
+ struct {
+ int m_reference;
+ int m_size;
+ };
+ };
+
+public:
+ BlockType m_type;
+
+ PageBlock(BlockType type = BLOCK_CONTINUEUS, int val1 = -1, int val2 = -1) : m_type(type)
+ {
+ if(m_type == BLOCK_CONTINUEUS)
+ {
+ m_start = val1;
+ m_end = val2;
+ }
+ else
+ {
+ m_reference = val1;
+ m_size = val2;
+ }
+ }
+
+ bool isValid() const { return !(m_type == BLOCK_CONTINUEUS && m_start == -1 && m_end == -1); }
+ /*explicit*/ operator bool() const { return isValid(); }
+
+ int getStart() const { assert(isValid() && m_type == BLOCK_CONTINUEUS); return m_start; }
+ int getEnd() const { assert(isValid() && m_type == BLOCK_CONTINUEUS); return m_end; }
+
+ bool isSinglePage() const { assert(isValid()); return m_type == BLOCK_CONTINUEUS ? (m_start == m_end) : true; }
+ int getPageCount() const { assert(isValid()); return m_type == BLOCK_CONTINUEUS ? (m_end - m_start + 1) : 1;}
+
+ int getReference() const { assert(isValid() && m_type == BLOCK_REFERENCE); return m_reference; }
+ int getSize() const { assert(isValid() && m_type == BLOCK_REFERENCE); return m_size; }
};
// ----------------------------------------------------------
-typedef std::list<BlockTypeS *> BlockList;
-typedef std::list<BlockTypeS *>::iterator BlockListIterator;
+typedef std::list<PageBlock> BlockList;
+typedef BlockList::iterator BlockListIterator;
// ----------------------------------------------------------
-FI_STRUCT (MULTIBITMAPHEADER) {
+struct MULTIBITMAPHEADER {
+
+ MULTIBITMAPHEADER()
+ : node(NULL)
+ , fif(FIF_UNKNOWN)
+ , handle(NULL)
+ , changed(FALSE)
+ , page_count(0)
+ , read_only(TRUE)
+ , cache_fif(fif)
+ , load_flags(0)
+ {
+ SetDefaultIO(&io);
+ }
+
PluginNode *node;
FREE_IMAGE_FORMAT fif;
- FreeImageIO *io;
+ FreeImageIO io;
fi_handle handle;
- CacheFile *m_cachefile;
+ CacheFile m_cachefile;
std::map<FIBITMAP *, int> locked_pages;
BOOL changed;
int page_count;
BlockList m_blocks;
- char *m_filename;
+ std::string m_filename;
BOOL read_only;
FREE_IMAGE_FORMAT cache_fif;
int load_flags;
@@ -107,6 +139,9 @@ ReplaceExtension(std::string& dst_filename, const std::string& src_filename, con
}
}
+} //< ns
+
+
// =====================================================================
// Internal Multipage functions
// =====================================================================
@@ -127,77 +162,55 @@ FreeImage_FindBlock(FIMULTIBITMAP *bitmap, int 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;
+
+ count += i->getPageCount();
- 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)
+ 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;
- }
+ // * if the block is single page, just return it
+ // * if the block is a span of pages, split it in 3 new blocks
+ // and return the middle block, which is now a single page
+
+ if ((i != header->m_blocks.end()) && (count > position)) {
+
+ if (i->isSinglePage()) {
+ return i;
+ }
+
+ const int item = i->getStart() + (position - prev_count);
+
+ // left part
+
+ if (item != i->getStart()) {
+ header->m_blocks.insert(i, PageBlock(BLOCK_CONTINUEUS, i->getStart(), item - 1));
+ }
+
+ // middle part
+
+ BlockListIterator block_target = header->m_blocks.insert(i, PageBlock(BLOCK_CONTINUEUS, item, item));
+
+ // right part
+
+ if (item != i->getEnd()) {
+ header->m_blocks.insert(i, PageBlock(BLOCK_CONTINUEUS, item + 1, i->getEnd()));
}
+
+ // remove the old block that was just splitted
+
+ header->m_blocks.erase(i);
+
+ // return the splitted block
+
+ return block_target;
}
+
// we should never go here ...
assert(false);
return header->m_blocks.end();
@@ -208,19 +221,19 @@ 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);
-
+
+ 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;
}
@@ -247,10 +260,6 @@ FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL crea
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) {
@@ -260,15 +269,12 @@ FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL crea
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->m_filename = filename;
+ // io is default
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;
@@ -283,7 +289,7 @@ FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL crea
// allocate a continueus block to describe the bitmap
if (!create_new) {
- header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
+ header->m_blocks.push_back(PageBlock(BLOCK_CONTINUEUS, 0, header->page_count - 1));
}
// set up the cache
@@ -291,13 +297,8 @@ FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL crea
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 {
+
+ if (!header->m_cachefile.open(cache_name, keep_cache_in_memory)) {
// an error occured ...
fclose(handle);
return NULL;
@@ -306,15 +307,15 @@ FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL crea
// 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)
+ if (handle) {
fclose(handle);
+ }
return NULL;
}
@@ -350,15 +351,11 @@ FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_h
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->io = *io;
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;
@@ -371,18 +368,11 @@ FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_h
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->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();
}
@@ -418,8 +408,8 @@ FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap,
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);
+ 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
@@ -428,15 +418,13 @@ FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap,
for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); i++) {
if (success) {
- switch((*i)->m_type) {
+ switch(i->m_type) {
case BLOCK_CONTINUEUS:
{
- BlockContinueus *block = (BlockContinueus *)(*i);
-
- for (int j = block->m_start; j <= block->m_end; j++) {
-
+ for (int j = i->getStart(); j <= i->getEnd(); j++) {
+
// load the original source data
- FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read);
+ 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);
@@ -450,17 +438,15 @@ FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap,
case BLOCK_REFERENCE:
{
- BlockReference *ref = (BlockReference *)(*i);
-
// read the compressed data
- BYTE *compressed_data = (BYTE*)malloc(ref->m_size * sizeof(BYTE));
+ BYTE *compressed_data = (BYTE*)malloc(i->getSize() * sizeof(BYTE));
- header->m_cachefile->readFile((BYTE *)compressed_data, ref->m_reference, ref->m_size);
+ header->m_cachefile.readFile((BYTE *)compressed_data, i->getReference(), i->getSize());
// uncompress the data
- FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, ref->m_size);
+ FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, i->getSize());
FIBITMAP *dib = FreeImage_LoadFromMemory(header->cache_fif, hmem, 0);
FreeImage_CloseMemory(hmem);
@@ -486,7 +472,7 @@ FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap,
// close the files
- FreeImage_Close(header->node, header->io, header->handle, data_read);
+ FreeImage_Close(header->node, &header->io, header->handle, data_read);
FreeImage_Close(node, io, handle, data);
@@ -507,7 +493,7 @@ FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
// saves changes only of images loaded directly from a file
- if (header->changed && header->m_filename) {
+ if (header->changed && !header->m_filename.empty()) {
try {
// open a temp file
@@ -524,7 +510,7 @@ FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
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);
+ success = FreeImage_SaveMultiBitmapToHandle(header->fif, bitmap, &header->io, (fi_handle)f, flags);
// close the files
@@ -540,10 +526,10 @@ FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
// applies changes to the destination file
if (success) {
- remove(header->m_filename);
- success = (rename(spool_name.c_str(), header->m_filename) == 0) ? TRUE:FALSE;
+ remove(header->m_filename.c_str());
+ success = (rename(spool_name.c_str(), header->m_filename.c_str()) == 0) ? TRUE:FALSE;
if(!success) {
- FreeImage_OutputMessageProc(header->fif, "Failed to rename %s to %s", spool_name.c_str(), header->m_filename);
+ FreeImage_OutputMessageProc(header->fif, "Failed to rename %s to %s", spool_name.c_str(), header->m_filename.c_str());
}
} else {
remove(spool_name.c_str());
@@ -553,24 +539,11 @@ FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
}
} else {
- if (header->handle && header->m_filename) {
+ if (header->handle && !header->m_filename.empty()) {
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()) {
@@ -579,16 +552,6 @@ FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
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;
@@ -611,15 +574,7 @@ FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) {
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;
- }
+ header->page_count += i->getPageCount();
}
}
@@ -629,10 +584,13 @@ FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) {
return 0;
}
-static BlockReference*
+static PageBlock
FreeImage_SavePageToBlock(MULTIBITMAPHEADER *header, FIBITMAP *data) {
- if (header->read_only || !header->locked_pages.empty())
- return NULL;
+ PageBlock res;
+
+ if (header->read_only || !header->locked_pages.empty()) {
+ return res;
+ }
DWORD compressed_size = 0;
BYTE *compressed_data = NULL;
@@ -641,66 +599,69 @@ FreeImage_SavePageToBlock(MULTIBITMAPHEADER *header, FIBITMAP *data) {
// open a memory handle
FIMEMORY *hmem = FreeImage_OpenMemory();
- if(hmem==NULL) return NULL;
+ if(hmem==NULL) {
+ return res;
+ }
// save the file to memory
if(!FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0)) {
FreeImage_CloseMemory(hmem);
- return NULL;
+ return res;
}
// get the buffer from the memory stream
if(!FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size)) {
FreeImage_CloseMemory(hmem);
- return NULL;
+ return res;
}
-
+
// write the compressed data to the cache
- int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
+ 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);
+
+ res = PageBlock(BLOCK_REFERENCE, ref, compressed_size);
+
+ return res;
}
void DLL_CALLCONV
FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) {
- if (!bitmap || !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;
+
+ if(const PageBlock block = FreeImage_SavePageToBlock(header, data)) {
+ // add the block
+ header->m_blocks.push_back(block);
+ header->changed = TRUE;
+ header->page_count = -1;
+ }
}
void DLL_CALLCONV
FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) {
- if (!bitmap || !data)
+ if (!bitmap || !data) {
return;
-
- if (page >= FreeImage_GetPageCount(bitmap))
+ }
+ 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);
+
+ if(const PageBlock block = FreeImage_SavePageToBlock(header, data)) {
+ // add a block
+ if (page > 0) {
+ BlockListIterator block_source = FreeImage_FindBlock(bitmap, page);
+ header->m_blocks.insert(block_source, block);
+ } else {
+ header->m_blocks.push_front(block);
+ }
+
+ header->changed = TRUE;
+ header->page_count = -1;
}
-
- header->changed = TRUE;
- header->page_count = -1;
}
void DLL_CALLCONV
@@ -711,21 +672,19 @@ FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) {
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) {
+ 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_cachefile.deleteFile(i->getReference());
header->m_blocks.erase(i);
break;
}
-
+
header->changed = TRUE;
header->page_count = -1;
}
@@ -734,7 +693,6 @@ FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) {
}
}
-
FIBITMAP * DLL_CALLCONV
FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) {
if (bitmap) {
@@ -749,19 +707,19 @@ FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) {
}
// open the bitmap
-
- header->io->seek_proc(header->handle, 0, SEEK_SET);
-
- void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
-
+
+ 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;
+ 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);
+
+ FreeImage_Close(header->node, &header->io, header->handle, data);
// if there was still another bitmap open, get rid of it
@@ -787,7 +745,7 @@ FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) {
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;
@@ -808,35 +766,15 @@ FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) {
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;
- }
+
+ if (i->m_type == BLOCK_REFERENCE) {
+ header->m_cachefile.deleteFile(i->getReference());
}
-
+
+ int iPage = header->m_cachefile.writeFile(compressed_data, compressed_size);
+
+ *i = PageBlock(BLOCK_REFERENCE, iPage, compressed_size);
+
// get rid of the compressed data
FreeImage_CloseMemory(hmem);
@@ -863,9 +801,9 @@ FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source) {
header->m_blocks.insert(block_target, *block_source);
header->m_blocks.erase(block_source);
-
+
header->changed = TRUE;
-
+
return TRUE;
}
}
@@ -889,8 +827,9 @@ FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count) {
c++;
- if (c == *count)
+ if (c == *count) {
break;
+ }
}
}
@@ -916,10 +855,6 @@ FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int
PluginNode *node = list->FindNodeFromFIF(fif);
if (node) {
- FreeImageIO *io = new(std::nothrow) FreeImageIO;
-
- if (io) {
- SetMemoryIO(io);
FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP;
@@ -927,14 +862,11 @@ FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int
MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER;
if (header) {
- header->m_filename = NULL;
header->node = node;
header->fif = fif;
- header->io = io;
+ SetMemoryIO(&header->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;
@@ -947,26 +879,17 @@ FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int
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;
- }
- }
+ 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;
}
-
- delete io;
- }
+
}
}
diff --git a/libs/freeimage/src/FreeImage/Plugin.cpp b/libs/freeimage/src/FreeImage/Plugin.cpp
index 048237a540..0e5452c929 100644
--- a/libs/freeimage/src/FreeImage/Plugin.cpp
+++ b/libs/freeimage/src/FreeImage/Plugin.cpp
@@ -791,7 +791,7 @@ FreeImage_GetFIFFromFilenameU(const wchar_t *filename) {
}
BOOL DLL_CALLCONV
-FreeImage_Validate(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle) {
+FreeImage_ValidateFIF(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle) {
if (s_plugins != NULL) {
BOOL validated = FALSE;
diff --git a/libs/freeimage/src/FreeImage/PluginBMP.cpp b/libs/freeimage/src/FreeImage/PluginBMP.cpp
index 713a9140f7..ceae053893 100644
--- a/libs/freeimage/src/FreeImage/PluginBMP.cpp
+++ b/libs/freeimage/src/FreeImage/PluginBMP.cpp
@@ -1,4 +1,4 @@
-// ==========================================================
+// ==========================================================
// BMP Loader and Writer
//
// Design and implementation by
@@ -7,6 +7,7 @@
// - Martin Weber (martweb@gmx.net)
// - Hervé Drolon (drolon@infonie.fr)
// - Michal Novotny (michal@etc.cz)
+// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
//
// This file is part of FreeImage 3
//
@@ -579,8 +580,13 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
DWORD bitfields[4];
io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
- } else
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ } else {
+ if( bit_count == 32 ) {
+ dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ } else {
+ dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ }
+ }
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
@@ -782,7 +788,11 @@ LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_
case 24 :
case 32 :
{
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ if( bit_count == 32 ) {
+ dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ } else {
+ dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ }
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
@@ -925,7 +935,11 @@ LoadOS21XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_
case 24 :
case 32 :
{
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ if( bit_count == 32 ) {
+ dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ } else {
+ dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ }
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
@@ -1249,16 +1263,24 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
if ((dib != NULL) && (handle != NULL)) {
// write the file header
+ const unsigned dst_width = FreeImage_GetWidth(dib);
+ const unsigned dst_height = FreeImage_GetHeight(dib);
+
+ // note that the dib may have been created using FreeImage_CreateView
+ // we need to recalculate the dst pitch here
+ const unsigned dst_bpp = FreeImage_GetBPP(dib);
+ const unsigned dst_pitch = CalculatePitch(CalculateLine(dst_width, dst_bpp));
+
BITMAPFILEHEADER bitmapfileheader;
bitmapfileheader.bfType = 0x4D42;
bitmapfileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD);
- bitmapfileheader.bfSize = bitmapfileheader.bfOffBits + FreeImage_GetHeight(dib) * FreeImage_GetPitch(dib);
+ bitmapfileheader.bfSize = bitmapfileheader.bfOffBits + dst_height * dst_pitch;
bitmapfileheader.bfReserved1 = 0;
bitmapfileheader.bfReserved2 = 0;
// take care of the bit fields data of any
- bool bit_fields = (FreeImage_GetBPP(dib) == 16);
+ bool bit_fields = (dst_bpp == 16) ? true : false;
if (bit_fields) {
bitmapfileheader.bfSize += 3 * sizeof(DWORD);
@@ -1268,28 +1290,33 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
#ifdef FREEIMAGE_BIGENDIAN
SwapFileHeader(&bitmapfileheader);
#endif
- if (io->write_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1)
- return FALSE;
+ if (io->write_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1) {
+ return FALSE;
+ }
// update the bitmap info header
BITMAPINFOHEADER bih;
memcpy(&bih, FreeImage_GetInfoHeader(dib), sizeof(BITMAPINFOHEADER));
- if (bit_fields)
+ if (bit_fields) {
bih.biCompression = BI_BITFIELDS;
- else if ((bih.biBitCount == 8) && (flags & BMP_SAVE_RLE))
+ }
+ else if ((bih.biBitCount == 8) && ((flags & BMP_SAVE_RLE) == BMP_SAVE_RLE)) {
bih.biCompression = BI_RLE8;
- else
+ }
+ else {
bih.biCompression = BI_RGB;
+ }
// write the bitmap info header
#ifdef FREEIMAGE_BIGENDIAN
SwapInfoHeader(&bih);
#endif
- if (io->write_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1)
+ if (io->write_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) {
return FALSE;
+ }
// write the bit fields when we are dealing with a 16 bit BMP
@@ -1298,18 +1325,21 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
d = FreeImage_GetRedMask(dib);
- if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
+ if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1) {
return FALSE;
+ }
d = FreeImage_GetGreenMask(dib);
- if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
+ if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1) {
return FALSE;
+ }
d = FreeImage_GetBlueMask(dib);
- if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
+ if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1) {
return FALSE;
+ }
}
// write the palette
@@ -1322,18 +1352,18 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
bgra.g = pal[i].rgbGreen;
bgra.r = pal[i].rgbRed;
bgra.a = pal[i].rgbReserved;
- if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
+ if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1) {
return FALSE;
+ }
}
}
// write the bitmap data... if RLE compression is enable, use it
- unsigned bpp = FreeImage_GetBPP(dib);
- if ((bpp == 8) && (flags & BMP_SAVE_RLE)) {
- BYTE *buffer = (BYTE*)malloc(FreeImage_GetPitch(dib) * 2 * sizeof(BYTE));
+ if ((dst_bpp == 8) && ((flags & BMP_SAVE_RLE) == BMP_SAVE_RLE)) {
+ BYTE *buffer = (BYTE*)malloc(dst_pitch * 2 * sizeof(BYTE));
- for (DWORD i = 0; i < FreeImage_GetHeight(dib); ++i) {
+ for (unsigned i = 0; i < dst_height; ++i) {
int size = RLEEncodeLine(buffer, FreeImage_GetScanLine(dib, i), FreeImage_GetLine(dib));
if (io->write_proc(buffer, size, 1, handle) != 1) {
@@ -1353,16 +1383,17 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
free(buffer);
#ifdef FREEIMAGE_BIGENDIAN
} else if (bpp == 16) {
- int padding = FreeImage_GetPitch(dib) - FreeImage_GetWidth(dib) * sizeof(WORD);
+ int padding = dst_pitch - dst_width * sizeof(WORD);
WORD pad = 0;
WORD pixel;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
+ for(unsigned y = 0; y < dst_height; y++) {
BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
+ for(unsigned x = 0; x < dst_width; x++) {
pixel = ((WORD *)line)[x];
SwapShort(&pixel);
- if (io->write_proc(&pixel, sizeof(WORD), 1, handle) != 1)
+ if (io->write_proc(&pixel, sizeof(WORD), 1, handle) != 1) {
return FALSE;
+ }
}
if(padding != 0) {
if(io->write_proc(&pad, padding, 1, handle) != 1) {
@@ -1373,18 +1404,19 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
#endif
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
} else if (bpp == 24) {
- int padding = FreeImage_GetPitch(dib) - FreeImage_GetWidth(dib) * sizeof(FILE_BGR);
+ int padding = dst_pitch - dst_width * sizeof(FILE_BGR);
DWORD pad = 0;
FILE_BGR bgr;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
+ for(unsigned y = 0; y < dst_height; y++) {
BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
+ for(unsigned x = 0; x < dst_width; x++) {
RGBTRIPLE *triple = ((RGBTRIPLE *)line)+x;
bgr.b = triple->rgbtBlue;
bgr.g = triple->rgbtGreen;
bgr.r = triple->rgbtRed;
- if (io->write_proc(&bgr, sizeof(FILE_BGR), 1, handle) != 1)
+ if (io->write_proc(&bgr, sizeof(FILE_BGR), 1, handle) != 1) {
return FALSE;
+ }
}
if(padding != 0) {
if(io->write_proc(&pad, padding, 1, handle) != 1) {
@@ -1394,24 +1426,36 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
}
} else if (bpp == 32) {
FILE_BGRA bgra;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
+ for(unsigned y = 0; y < dst_height; y++) {
BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
+ for(unsigned x = 0; x < dst_width; x++) {
RGBQUAD *quad = ((RGBQUAD *)line)+x;
bgra.b = quad->rgbBlue;
bgra.g = quad->rgbGreen;
bgra.r = quad->rgbRed;
bgra.a = quad->rgbReserved;
- if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
+ if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1) {
return FALSE;
+ }
}
}
#endif
- } else if (io->write_proc(FreeImage_GetBits(dib), FreeImage_GetHeight(dib) * FreeImage_GetPitch(dib), 1, handle) != 1) {
- return FALSE;
+ }
+ else if (FreeImage_GetPitch(dib) == dst_pitch) {
+ return (io->write_proc(FreeImage_GetBits(dib), dst_height * dst_pitch, 1, handle) != 1) ? FALSE : TRUE;
+ }
+ else {
+ for (unsigned y = 0; y < dst_height; y++) {
+ BYTE *line = (BYTE*)FreeImage_GetScanLine(dib, y);
+
+ if (io->write_proc(line, dst_pitch, 1, handle) != 1) {
+ return FALSE;
+ }
+ }
}
return TRUE;
+
} else {
return FALSE;
}
diff --git a/libs/freeimage/src/FreeImage/PluginGIF.cpp b/libs/freeimage/src/FreeImage/PluginGIF.cpp
index 1a7a84041b..8fe0422b31 100644
--- a/libs/freeimage/src/FreeImage/PluginGIF.cpp
+++ b/libs/freeimage/src/FreeImage/PluginGIF.cpp
@@ -3,9 +3,13 @@
//
// Design and implementation by
// - Ryan Rubley <ryan@lostreality.org>
-// - Raphaлl Gaquer <raphael.gaquer@alcer.com>
+// - Raphaël Gaquer <raphael.gaquer@alcer.com>
// - Aaron Shumate <aaron@shumate.us>
//
+// References
+// http://www.w3.org/Graphics/GIF/spec-gif87.txt
+// http://www.w3.org/Graphics/GIF/spec-gif89a.txt
+//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
@@ -41,6 +45,7 @@
// Constant/Typedef declarations
// ==========================================================
+
struct GIFinfo {
BOOL read;
//only really used when reading
@@ -488,23 +493,20 @@ MimeType() {
return "image/gif";
}
-static BOOL DLL_CALLCONV
+static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
- char buf[6];
- if( io->read_proc(buf, 6, 1, handle) < 1 ) {
- return FALSE;
- }
+ BYTE GIF89a[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }; // ASCII code for "GIF89a"
+ BYTE GIF87a[] = { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }; // ASCII code for "GIF87a"
+ BYTE signature[6] = { 0, 0, 0, 0, 0, 0 };
- BOOL bResult = FALSE;
- if( !strncmp(buf, "GIF", 3) ) {
- if( buf[3] >= '0' && buf[3] <= '9' && buf[4] >= '0' && buf[4] <= '9' && buf[5] >= 'a' && buf[5] <= 'z' ) {
- bResult = TRUE;
- }
- }
+ io->read_proc(signature, 1, 6, handle);
- io->seek_proc(handle, -6, SEEK_CUR);
+ if (memcmp(GIF89a, signature, 6) == 0)
+ return TRUE;
+ if (memcmp(GIF87a, signature, 6) == 0)
+ return TRUE;
- return bResult;
+ return FALSE;
}
static BOOL DLL_CALLCONV
@@ -528,18 +530,15 @@ Open(FreeImageIO *io, fi_handle handle, BOOL read) {
return NULL;
}
- // 25/02/2008 MDA: Not safe to memset GIFinfo structure with VS 2008 (safe iterators),
- // perform initialization in constructor instead.
- // memset(info, 0, sizeof(GIFinfo));
-
+ // set Read/Write mode
info->read = read;
+
if( read ) {
try {
- //Header
+ // read Header (6 bytes)
if( !Validate(io, handle) ) {
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
- io->seek_proc(handle, 6, SEEK_CUR);
//Logical Screen Descriptor
io->seek_proc(handle, 4, SEEK_CUR);
@@ -1013,19 +1012,19 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
}
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "Loop", ANIMTAG_LOOP, FIDT_LONG, 1, 4, &loop);
- // Comment Extension
- for (idx = 0; idx < info->comment_extension_offsets.size(); idx++) {
+ //Comment Extension
+ for( idx = 0; idx < info->comment_extension_offsets.size(); idx++ ) {
io->seek_proc(handle, (long)info->comment_extension_offsets[idx], SEEK_SET);
std::string comment;
char buf[255];
io->read_proc(&b, 1, 1, handle);
- while (b) {
+ while( b ) {
io->read_proc(buf, b, 1, handle);
comment.append(buf, b);
io->read_proc(&b, 1, 1, handle);
}
comment.append(1, '\0');
- sprintf(buf, "Comment%d", (int)idx);
+ sprintf(buf, "Comment%zd", idx);
DWORD comment_size = (DWORD)comment.size();
FreeImage_SetMetadataEx(FIMD_COMMENTS, dib, buf, 1, FIDT_ASCII, comment_size, comment_size, comment.c_str());
}
diff --git a/libs/freeimage/src/FreeImage/PluginJPEG.cpp b/libs/freeimage/src/FreeImage/PluginJPEG.cpp
index 49e653d9e0..4dbd5d26a6 100644
--- a/libs/freeimage/src/FreeImage/PluginJPEG.cpp
+++ b/libs/freeimage/src/FreeImage/PluginJPEG.cpp
@@ -1,4 +1,4 @@
-// ==========================================================
+// ==========================================================
// JPEG Loader and writer
// Based on code developed by The Independent JPEG Group
//
@@ -1126,8 +1126,9 @@ Validate(FreeImageIO *io, fi_handle handle) {
static BOOL DLL_CALLCONV
SupportsExportDepth(int depth) {
return (
- (depth == 8) ||
- (depth == 24)
+ (depth == 8) ||
+ (depth == 24) ||
+ (depth == 32) // only if 32-bit CMYK
);
}
@@ -1315,6 +1316,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
dst += 3;
}
}
+
+ // if original image is CMYK but is converted to RGB, remove ICC profile from Exif-TIFF metadata
+ FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, "InterColorProfile", NULL);
+
} else if((cinfo.out_color_space == JCS_CMYK) && ((flags & JPEG_CMYK) == JPEG_CMYK)) {
// convert from LibJPEG CMYK to standard CMYK
@@ -1400,12 +1405,12 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
try {
// Check dib format
- const char *sError = "only 24-bit highcolor or 8-bit greyscale/palette bitmaps can be saved as JPEG";
+ const char *sError = "only 24-bit RGB, 8-bit greyscale/palette or 32-bit CMYK bitmaps can be saved as JPEG";
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
WORD bpp = (WORD)FreeImage_GetBPP(dib);
- if ((bpp != 24) && (bpp != 8)) {
+ if ((bpp != 24) && (bpp != 8) && !(bpp == 32 && (color_type == FIC_CMYK))) {
throw sError;
}
@@ -1454,7 +1459,10 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
cinfo.in_color_space = JCS_GRAYSCALE;
cinfo.input_components = 1;
break;
-
+ case FIC_CMYK:
+ cinfo.in_color_space = JCS_CMYK;
+ cinfo.input_components = 4;
+ break;
default :
cinfo.in_color_space = JCS_RGB;
cinfo.input_components = 3;
@@ -1481,14 +1489,14 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
// thumbnail support (JFIF 1.02 extension markers)
if(FreeImage_GetThumbnail(dib) != NULL) {
- cinfo.write_JFIF_header = 1; //<### force it, though when color is CMYK it will be incorrect
+ cinfo.write_JFIF_header = static_cast<boolean>(1); //<### force it, though when color is CMYK it will be incorrect
cinfo.JFIF_minor_version = 2;
}
// baseline JPEG support
- if ((flags & JPEG_BASELINE) == JPEG_BASELINE) {
- cinfo.write_JFIF_header = 0; // No marker for non-JFIF colorspaces
- cinfo.write_Adobe_marker = 0; // write no Adobe marker by default
+ if ((flags & JPEG_BASELINE) == JPEG_BASELINE) {
+ cinfo.write_JFIF_header = static_cast<boolean>(0); // No marker for non-JFIF colorspaces
+ cinfo.write_Adobe_marker = static_cast<boolean>(0); // write no Adobe marker by default
}
// set subsampling options if required
@@ -1598,6 +1606,33 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
}
free(target);
}
+ else if(color_type == FIC_CMYK) {
+ unsigned pitch = FreeImage_GetPitch(dib);
+ BYTE *target = (BYTE*)malloc(pitch * sizeof(BYTE));
+ if (target == NULL) {
+ throw FI_MSG_ERROR_MEMORY;
+ }
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ // get a copy of the scanline
+ memcpy(target, FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1), pitch);
+
+ BYTE *target_p = target;
+ for(unsigned x = 0; x < cinfo.image_width; x++) {
+ // CMYK pixels are inverted
+ target_p[0] = ~target_p[0]; // C
+ target_p[1] = ~target_p[1]; // M
+ target_p[2] = ~target_p[2]; // Y
+ target_p[3] = ~target_p[3]; // K
+
+ target_p += 4;
+ }
+
+ // write the scanline
+ jpeg_write_scanlines(&cinfo, &target, 1);
+ }
+ free(target);
+ }
else if(color_type == FIC_MINISBLACK) {
// 8-bit standard greyscale images
while (cinfo.next_scanline < cinfo.image_height) {
diff --git a/libs/freeimage/src/FreeImage/PluginPNG.cpp b/libs/freeimage/src/FreeImage/PluginPNG.cpp
index 0753192140..c64f12d465 100644
--- a/libs/freeimage/src/FreeImage/PluginPNG.cpp
+++ b/libs/freeimage/src/FreeImage/PluginPNG.cpp
@@ -1,9 +1,9 @@
-// ==========================================================
+// ==========================================================
// PNG Loader and Writer
//
// Design and implementation by
// - Floris van den Berg (flvdberg@wxs.nl)
-// - Herve Drolon (drolon@infonie.fr)
+// - Hervé Drolon (drolon@infonie.fr)
// - Detlev Vendt (detlev.vendt@brillit.de)
// - Aaron Shumate (trek@startreker.com)
// - Tanner Helland (tannerhelland@users.sf.net)
@@ -50,6 +50,12 @@ typedef struct {
} fi_ioStructure, *pfi_ioStructure;
// ==========================================================
+// Plugin Interface
+// ==========================================================
+
+static int s_format_id;
+
+// ==========================================================
// libpng interface
// ==========================================================
@@ -76,8 +82,8 @@ _FlushProc(png_structp png_ptr) {
static void
error_handler(png_structp png_ptr, const char *error) {
- (png_structp)png_ptr;
- throw error;
+ FreeImage_OutputMessageProc(s_format_id, error);
+ png_longjmp(png_ptr, 1);
}
// in FreeImage warnings disabled
@@ -234,12 +240,6 @@ WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
}
// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
// Plugin Implementation
// ==========================================================
@@ -548,11 +548,13 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
// init the IO
- png_set_read_fn(png_ptr, &fio, _ReadProc);
+ png_set_read_fn(png_ptr, &fio, _ReadProc);
+
+ // PNG errors will be redirected here
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return NULL;
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ // assume error_handler was called before by the PNG library
+ throw((const char*)NULL);
}
// because we have already read the signature...
@@ -789,7 +791,9 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
if (dib) {
FreeImage_Unload(dib);
}
- FreeImage_OutputMessageProc(s_format_id, text);
+ if (NULL != text) {
+ FreeImage_OutputMessageProc(s_format_id, text);
+ }
return NULL;
}
@@ -990,6 +994,8 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void
FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
if (iccProfile->size && iccProfile->data) {
+ // skip ICC profile check
+ png_set_option(png_ptr, PNG_SKIP_sRGB_CHECK_PROFILE, 1);
png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_const_bytep)iccProfile->data, iccProfile->size);
}