summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormio <[email protected]>2024-09-21 12:10:59 +1000
committermio <[email protected]>2024-09-22 18:12:55 +1000
commitcb2ce97afa2f18427c1b4b3857fd56f69ce83d97 (patch)
tree8338c6b7851606dec64428ec9d0e2a558ba95b2c
parent5c1b76e6bf8e72bc04fe819b5e8bc2cd83241cf1 (diff)
downloadtdelibs-cb2ce97afa2f18427c1b4b3857fd56f69ce83d97.tar.gz
tdelibs-cb2ce97afa2f18427c1b4b3857fd56f69ce83d97.zip
Improve JasPer 3/4 support
Versions prior to 3 registered an atexit hander which performed resource cleanup with 'jas_cleanup', this was removed in version 3 meaning we were leaking resources. The 'jas_init' and 'jas_cleanup' functions were deprecated in version 3, so we use the newer jas_init_library/jas_init_thread functions. The max memory that JasPer can use has been limited to (at most) 512 MB. Without this change, JasPer will use whatever JAS_DEFAULT_MAX_MEM_USAGE is configured to, which is 1 GB by default. Signed-off-by: mio <[email protected]>
-rw-r--r--kimgio/jp2.cpp91
1 files changed, 84 insertions, 7 deletions
diff --git a/kimgio/jp2.cpp b/kimgio/jp2.cpp
index ff64f9263..7cd6879b1 100644
--- a/kimgio/jp2.cpp
+++ b/kimgio/jp2.cpp
@@ -15,6 +15,7 @@
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
+#include <kdebug.h>
#include <tdetempfile.h>
#include <tqcolor.h>
#include <tqcstring.h>
@@ -57,7 +58,7 @@ read_image( const TQImageIO* io )
tempf = new KTempFile();
if( tempf->status() != 0 ) {
delete tempf;
- return 0;
+ return nullptr;
} // if
tempf->setAutoDelete( true );
TQFile* out = tempf->file();
@@ -76,7 +77,7 @@ read_image( const TQImageIO* io )
} // else
if( !in ) {
delete tempf;
- return 0;
+ return nullptr;
} // if
jas_image_t* image = jas_image_decode( in, -1, 0 );
@@ -148,16 +149,77 @@ render_view( gs_t& gs, TQImage& qti )
return true;
} // render_view
+static bool initializeJasper()
+{
+#if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
+ jas_conf_clear();
+
+ // Limit JasPer memory usage to at most 512 MB
+ size_t memoryLimit = (512 * 1024) * 1024;
+ size_t jasperTotalMemory = jas_get_total_mem_size();
+ if (!jasperTotalMemory)
+ {
+ jasperTotalMemory = JAS_DEFAULT_MAX_MEM_USAGE;
+ }
+ memoryLimit = memoryLimit < jasperTotalMemory ? memoryLimit : jasperTotalMemory;
+ jas_conf_set_max_mem_usage(memoryLimit);
+
+ if (jas_init_library())
+ {
+ return false;
+ }
+
+ if (jas_init_thread())
+ {
+ jas_cleanup_library();
+ return false;
+ }
+
+#else
+ if (jas_init())
+ {
+ return false;
+ }
+#endif // defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
+
+ return true;
+}
+
+static void cleanupJasper()
+{
+#if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
+ jas_cleanup_thread();
+ jas_cleanup_library();
+#endif
+}
+
+
TDE_EXPORT void
kimgio_jp2_read( TQImageIO* io )
{
- if( jas_init() ) return;
+ if (!initializeJasper())
+ {
+ kdError(399) << "Failed to initialize JasPer library" << endl;
+ return;
+ }
gs_t gs;
- if( !(gs.image = read_image( io )) ) return;
+ gs.image = read_image(io);
- if( !convert_colorspace( gs ) ) return;
+ if (!gs.image)
+ {
+ kdError(399) << "Failed to read JP2 image from IO." << endl;
+ cleanupJasper();
+ return;
+ }
+
+ if (!convert_colorspace(gs))
+ {
+ kdError(399) << "Could not convert JP2 colorspace." << endl;
+ cleanupJasper();
+ return;
+ }
TQImage image;
render_view( gs, image );
@@ -165,6 +227,8 @@ kimgio_jp2_read( TQImageIO* io )
if( gs.image ) jas_image_destroy( gs.image );
if( gs.altimage ) jas_image_destroy( gs.altimage );
+ cleanupJasper();
+
io->setImage( image );
io->setStatus( 0 );
} // kimgio_jp2_read
@@ -236,7 +300,11 @@ write_components( jas_image_t* ji, const TQImage& qi )
TDE_EXPORT void
kimgio_jp2_write( TQImageIO* io )
{
- if( jas_init() ) return;
+ if (!initializeJasper())
+ {
+ kdError(399) << "Failed to initialize JasPer library." << endl;
+ return;
+ }
// open the stream. we write directly to the file if possible, to a
// temporary file otherwise.
@@ -255,12 +323,19 @@ kimgio_jp2_write( TQImageIO* io )
// by here, a jas_stream_t is open
- if( !stream ) return;
+ if (!stream)
+ {
+ kdError(399)
+ << "Failed to create a stream to write JP2 image" << endl;
+ cleanupJasper();
+ return;
+ }
jas_image_t* ji = create_image( io->image() );
if( !ji ) {
delete ktempf;
jas_stream_close( stream );
+ cleanupJasper();
return;
} // if
@@ -268,6 +343,7 @@ kimgio_jp2_write( TQImageIO* io )
delete ktempf;
jas_stream_close( stream );
jas_image_destroy( ji );
+ cleanupJasper();
return;
} // if
@@ -292,6 +368,7 @@ kimgio_jp2_write( TQImageIO* io )
jas_image_destroy( ji );
jas_stream_close( stream );
+ cleanupJasper();
if( i != 0 ) { delete ktempf; return; }