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 <stigma@disroot.org>
pull/306/head
mio 2 months ago
parent 5c1b76e6bf
commit cb2ce97afa

@ -15,6 +15,7 @@
#ifdef HAVE_STDINT_H #ifdef HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
#endif #endif
#include <kdebug.h>
#include <tdetempfile.h> #include <tdetempfile.h>
#include <tqcolor.h> #include <tqcolor.h>
#include <tqcstring.h> #include <tqcstring.h>
@ -57,7 +58,7 @@ read_image( const TQImageIO* io )
tempf = new KTempFile(); tempf = new KTempFile();
if( tempf->status() != 0 ) { if( tempf->status() != 0 ) {
delete tempf; delete tempf;
return 0; return nullptr;
} // if } // if
tempf->setAutoDelete( true ); tempf->setAutoDelete( true );
TQFile* out = tempf->file(); TQFile* out = tempf->file();
@ -76,7 +77,7 @@ read_image( const TQImageIO* io )
} // else } // else
if( !in ) { if( !in ) {
delete tempf; delete tempf;
return 0; return nullptr;
} // if } // if
jas_image_t* image = jas_image_decode( in, -1, 0 ); jas_image_t* image = jas_image_decode( in, -1, 0 );
@ -148,16 +149,77 @@ render_view( gs_t& gs, TQImage& qti )
return true; return true;
} // render_view } // 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 TDE_EXPORT void
kimgio_jp2_read( TQImageIO* io ) kimgio_jp2_read( TQImageIO* io )
{ {
if( jas_init() ) return; if (!initializeJasper())
{
kdError(399) << "Failed to initialize JasPer library" << endl;
return;
}
gs_t gs; 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; TQImage image;
render_view( gs, image ); render_view( gs, image );
@ -165,6 +227,8 @@ kimgio_jp2_read( TQImageIO* io )
if( gs.image ) jas_image_destroy( gs.image ); if( gs.image ) jas_image_destroy( gs.image );
if( gs.altimage ) jas_image_destroy( gs.altimage ); if( gs.altimage ) jas_image_destroy( gs.altimage );
cleanupJasper();
io->setImage( image ); io->setImage( image );
io->setStatus( 0 ); io->setStatus( 0 );
} // kimgio_jp2_read } // kimgio_jp2_read
@ -236,7 +300,11 @@ write_components( jas_image_t* ji, const TQImage& qi )
TDE_EXPORT void TDE_EXPORT void
kimgio_jp2_write( TQImageIO* io ) 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 // open the stream. we write directly to the file if possible, to a
// temporary file otherwise. // temporary file otherwise.
@ -255,12 +323,19 @@ kimgio_jp2_write( TQImageIO* io )
// by here, a jas_stream_t is open // 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() ); jas_image_t* ji = create_image( io->image() );
if( !ji ) { if( !ji ) {
delete ktempf; delete ktempf;
jas_stream_close( stream ); jas_stream_close( stream );
cleanupJasper();
return; return;
} // if } // if
@ -268,6 +343,7 @@ kimgio_jp2_write( TQImageIO* io )
delete ktempf; delete ktempf;
jas_stream_close( stream ); jas_stream_close( stream );
jas_image_destroy( ji ); jas_image_destroy( ji );
cleanupJasper();
return; return;
} // if } // if
@ -292,6 +368,7 @@ kimgio_jp2_write( TQImageIO* io )
jas_image_destroy( ji ); jas_image_destroy( ji );
jas_stream_close( stream ); jas_stream_close( stream );
cleanupJasper();
if( i != 0 ) { delete ktempf; return; } if( i != 0 ) { delete ktempf; return; }

Loading…
Cancel
Save