summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/dimg/loaders/jp2kloader.cpp103
1 files changed, 89 insertions, 14 deletions
diff --git a/src/libs/dimg/loaders/jp2kloader.cpp b/src/libs/dimg/loaders/jp2kloader.cpp
index 66351c25..016a7196 100644
--- a/src/libs/dimg/loaders/jp2kloader.cpp
+++ b/src/libs/dimg/loaders/jp2kloader.cpp
@@ -58,6 +58,16 @@ extern "C"
#include "dimgloaderobserver.h"
#include "jp2kloader.h"
+static void cleanup_jasper()
+{
+#if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
+ jas_cleanup_thread();
+ jas_cleanup_library();
+#else
+ jas_cleanup();
+#endif
+}
+
namespace Digikam
{
@@ -69,7 +79,7 @@ JP2KLoader::JP2KLoader(DImg* image)
}
bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
-{
+{
readMetadata(filePath, DImg::JPEG);
FILE *file = fopen(TQFile::encodeName(filePath), "rb");
@@ -109,17 +119,45 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
jas_stream_t *jp2_stream = 0;
jas_matrix_t *pixels[4];
- int init = jas_init();
- if (init != 0)
+
+#if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
+ jas_conf_clear();
+
+ // Limit JasPer memory usage to 512 MB
+ size_t memoryLimit = (512 * 1024) * 1024;
+ size_t jasperTotalMemSize = jas_get_total_mem_size();
+ if (!jasperTotalMemSize)
+ {
+ jasperTotalMemSize = JAS_DEFAULT_MAX_MEM_USAGE;
+ }
+ memoryLimit = (memoryLimit < jasperTotalMemSize) ? memoryLimit : jasperTotalMemSize;
+ jas_conf_set_max_mem_usage(memoryLimit);
+
+ if (jas_init_library())
+ {
+ DDebug() << "Unable to init JPEG2000 decoder" << endl;
+ return false;
+ }
+
+ if (jas_init_thread())
+ {
+ DDebug() << "Unable to init JPEG2000 decoder" << endl;
+ jas_cleanup_library();
+ return false;
+ }
+#else
+ if (jas_init())
{
DDebug() << "Unable to init JPEG2000 decoder" << endl;
return false;
}
+#endif
jp2_stream = jas_stream_fopen(TQFile::encodeName(filePath), "rb");
if (jp2_stream == 0)
{
DDebug() << "Unable to open JPEG2000 stream" << endl;
+ cleanup_jasper();
return false;
}
@@ -127,6 +165,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
if (jp2_image == 0)
{
jas_stream_close(jp2_stream);
+ cleanup_jasper();
DDebug() << "Unable to decode JPEG2000 image" << endl;
return false;
}
@@ -150,6 +189,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
{
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error parsing JPEG2000 image : Missing Image Channel" << endl;
return false;
}
@@ -169,6 +209,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
if (components[0] < 0)
{
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error parsing JP2000 image : Missing Image Channel" << endl;
return false;
}
@@ -183,6 +224,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
{
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error parsing JP2000 image : Missing Image Channel" << endl;
return false;
}
@@ -199,6 +241,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
default:
{
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error parsing JP2000 image : Colorspace Model Is Not Supported" << endl;
return false;
}
@@ -221,6 +264,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
(jas_image_cmptsgnd(jp2_image, components[i]) != false))
{
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error parsing JPEG2000 image : Irregular Channel Geometry Not Supported" << endl;
return false;
}
@@ -242,6 +286,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
if (!pixels[i])
{
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error decoding JPEG2000 image data : Memory Allocation Failed" << endl;
return false;
}
@@ -271,7 +316,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return false;
}
@@ -295,7 +340,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return false;
}
}
@@ -402,7 +447,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return false;
}
@@ -452,7 +497,7 @@ bool JP2KLoader::load(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return true;
}
@@ -476,20 +521,48 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
jas_matrix_t *pixels[4];
jas_image_cmptparm_t component_info[4];
- int init = jas_init();
- if (init != 0)
+
+#if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
+ jas_conf_clear();
+
+ // Limit JasPer memory usage to 512 MB
+ size_t memoryLimit = (512 * 1024) * 1024;
+ size_t jasperTotalMemSize = jas_get_total_mem_size();
+ if (!jasperTotalMemSize)
+ {
+ jasperTotalMemSize = JAS_DEFAULT_MAX_MEM_USAGE;
+ }
+ memoryLimit = (memoryLimit < jasperTotalMemSize) ? memoryLimit : jasperTotalMemSize;
+ jas_conf_set_max_mem_usage(memoryLimit);
+
+ if (jas_init_library())
+ {
+ DDebug() << "Unable to init JPEG2000 decoder" << endl;
+ return false;
+ }
+
+ if (jas_init_thread())
+ {
+ DDebug() << "Unable to init JPEG2000 decoder" << endl;
+ jas_cleanup_library();
+ return false;
+ }
+#else
+ if (jas_init())
{
DDebug() << "Unable to init JPEG2000 decoder" << endl;
return false;
}
+#endif
jp2_stream = jas_stream_fopen(TQFile::encodeName(filePath), "wb");
if (jp2_stream == 0)
{
DDebug() << "Unable to open JPEG2000 stream" << endl;
+ cleanup_jasper();
return false;
}
-
+
number_components = imageHasAlpha() ? 4 : 3;
for (i = 0 ; i < (long)number_components ; i++)
@@ -508,6 +581,7 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
if (jp2_image == 0)
{
jas_stream_close(jp2_stream);
+ cleanup_jasper();
DDebug() << "Unable to create JPEG2000 image" << endl;
return false;
}
@@ -562,6 +636,7 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
jas_matrix_destroy(pixels[x]);
jas_image_destroy(jp2_image);
+ cleanup_jasper();
DDebug() << "Error encoding JPEG2000 image data : Memory Allocation Failed" << endl;
return false;
}
@@ -583,7 +658,7 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return false;
}
@@ -633,7 +708,7 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return false;
}
}
@@ -680,7 +755,7 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return false;
}
@@ -697,7 +772,7 @@ bool JP2KLoader::save(const TQString& filePath, DImgLoaderObserver *observer)
for (i = 0 ; i < (long)number_components ; i++)
jas_matrix_destroy(pixels[i]);
- jas_cleanup();
+ cleanup_jasper();
return true;
}