By default, only the main thread is used. If opj_codec_set_threads() is not used,
but the OPJ_NUM_THREADS environment variable is set, its value will be
used to initialize the number of threads. The value can be either an integer
number, or "ALL_CPUS". If OPJ_NUM_THREADS is set and this function is called,
this function will override the behaviour of the environment variable.
}
}
+OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads)
+{
+ if( opj_has_thread_support() )
+ {
+ opj_thread_pool_destroy(j2k->m_tp);
+ j2k->m_tp = opj_thread_pool_create((int)num_threads);
+ if( j2k->m_tp == 0 )
+ {
+ j2k->m_tp = opj_thread_pool_create(0);
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
+ }
+ return OPJ_FALSE;
+}
+
+static int opj_j2k_get_default_thread_count()
+{
+ const char* num_threads = getenv("OPJ_NUM_THREADS");
+ if( num_threads == NULL || !opj_has_thread_support() )
+ return 0;
+ if( strcmp(num_threads, "ALL_CPUS") == 0 )
+ return opj_get_num_cpus();
+ return atoi(num_threads);
+}
+
/* ----------------------------------------------------------------------- */
/* J2K encoder interface */
/* ----------------------------------------------------------------------- */
return NULL;
}
+ l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count());
+ if( !l_j2k->m_tp )
+ {
+ l_j2k->m_tp = opj_thread_pool_create(0);
+ }
+ if( !l_j2k->m_tp )
+ {
+ opj_j2k_destroy(l_j2k);
+ return NULL;
+ }
+
return l_j2k;
}
return OPJ_FALSE;
}
- if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp)) ) {
+ if ( !opj_tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp), p_j2k->m_tp) ) {
opj_tcd_destroy(p_j2k->m_tcd);
p_j2k->m_tcd = 00;
opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n");
opj_image_destroy(p_j2k->m_output_image);
p_j2k->m_output_image = NULL;
+ opj_thread_pool_destroy(p_j2k->m_tp);
+ p_j2k->m_tp = NULL;
+
opj_free(p_j2k);
}
return 00;
}
+ l_j2k->m_tp = opj_thread_pool_create(opj_j2k_get_default_thread_count());
+ if( !l_j2k->m_tp )
+ {
+ l_j2k->m_tp = opj_thread_pool_create(0);
+ }
+ if( !l_j2k->m_tp )
+ {
+ opj_j2k_destroy(l_j2k);
+ return NULL;
+ }
+
return l_j2k;
}
return OPJ_FALSE;
}
- if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp)) {
+ if (!opj_tcd_init(p_j2k->m_tcd,p_j2k->m_private_image,&p_j2k->m_cp, p_j2k->m_tp)) {
opj_tcd_destroy(p_j2k->m_tcd);
p_j2k->m_tcd = 00;
return OPJ_FALSE;
/** the current tile coder/decoder **/
struct opj_tcd * m_tcd;
+
+ /** Number of threads to use */
+ int m_num_threads;
+
+ /** Thread pool */
+ opj_thread_pool_t* m_tp;
}
opj_j2k_t;
*/
void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
+OPJ_BOOL opj_j2k_set_threads(opj_j2k_t *j2k, OPJ_UINT32 num_threads);
+
/**
* Creates a J2K compression structure
*
jp2->ignore_pclr_cmap_cdef = parameters->flags & OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
}
+OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads)
+{
+ return opj_j2k_set_threads(jp2->j2k, num_threads);
+}
+
/* ----------------------------------------------------------------------- */
/* JP2 encoder interface */
/* ----------------------------------------------------------------------- */
*/
void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters);
+OPJ_BOOL opj_jp2_set_threads(opj_jp2_t *jp2, OPJ_UINT32 num_threads);
+
/**
* Decode an image from a JPEG-2000 file stream
* @param jp2 JP2 decompressor handle
OPJ_UINT32 res_factor,
struct opj_event_mgr * p_manager)) opj_j2k_set_decoded_resolution_factor;
+ l_codec->opj_set_threads =
+ (OPJ_BOOL (*) ( void * p_codec, OPJ_UINT32 num_threads )) opj_j2k_set_threads;
+
l_codec->m_codec = opj_j2k_create_decompress();
if (! l_codec->m_codec) {
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager)) opj_jp2_set_decoded_resolution_factor;
+ l_codec->opj_set_threads =
+ (OPJ_BOOL (*) ( void * p_codec, OPJ_UINT32 num_threads )) opj_jp2_set_threads;
+
l_codec->m_codec = opj_jp2_create(OPJ_TRUE);
if (! l_codec->m_codec) {
}
}
+
+OPJ_API OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
+ int num_threads)
+{
+ if (p_codec ) {
+ opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+ return l_codec->opj_set_threads(l_codec->m_codec, num_threads);
+ }
+ return OPJ_FALSE;
+}
+
OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
opj_dparameters_t *parameters
)
OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_codec,
opj_dparameters_t *parameters );
+/**
+ * Allocates worker threads for the compressor/decompressor.
+ *
+ * By default, only the main thread is used. If this function is not used,
+ * but the OPJ_NUM_THREADS environment variable is set, its value will be
+ * used to initialize the number of threads. The value can be either an integer
+ * number, or "ALL_CPUS". If OPJ_NUM_THREADS is set and this function is called,
+ * this function will override the behaviour of the environment variable.
+ *
+ * Note: currently only has effect on the decompressor.
+ *
+ * @param p_codec decompressor handler
+ * @param num_threads number of threads.
+ *
+ * @return OPJ_TRUE if the decoder is correctly set
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_codec_set_threads(opj_codec_t *p_codec,
+ int num_threads);
+
/**
* Decodes an image header.
*
OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec,
OPJ_UINT32 res_factor,
opj_event_mgr_t * p_manager);
+
} m_decompression;
/**
void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream);
opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec);
opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec);
+
+ /** Set number of threads */
+ OPJ_BOOL (*opj_set_threads) ( void * p_codec, OPJ_UINT32 num_threads );
}
opj_codec_private_t;
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
opj_image_t * p_image,
- opj_cp_t * p_cp )
+ opj_cp_t * p_cp,
+ opj_thread_pool_t* p_tp )
{
p_tcd->image = p_image;
p_tcd->cp = p_cp;
p_tcd->tcd_image->tiles->numcomps = p_image->numcomps;
p_tcd->tp_pos = p_cp->m_specific_param.m_enc.m_tp_pos;
+ p_tcd->thread_pool = p_tp;
return OPJ_TRUE;
}
OPJ_UINT32 tcd_tileno;
/** tell if the tcd is a decoder. */
OPJ_UINT32 m_is_decoder : 1;
+ /** Thread pool */
+ opj_thread_pool_t* thread_pool;
} opj_tcd_t;
/** @name Exported functions */
* @param p_tcd TCD handle.
* @param p_image raw image.
* @param p_cp coding parameters.
+ * @param p_tp thread pool
*
* @return true if the encoding values could be set (false otherwise).
*/
OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd,
opj_image_t * p_image,
- opj_cp_t * p_cp );
+ opj_cp_t * p_cp,
+ opj_thread_pool_t* p_tp);
/**
* Allocates memory for decoding a specific tile.