Add opj_codec_set_threads() in public API and propagate resulting thread pool to...
[openjpeg.git] / src / lib / openjp2 / j2k.c
index 9eaa155ed91d818dc8f9637148c7cfb836fae026..68b2f82e540408623217c942e953d1f3b1320d09 100644 (file)
@@ -5944,6 +5944,32 @@ 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)
+{
+        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                                                       */
 /* ----------------------------------------------------------------------- */
@@ -5981,6 +6007,17 @@ opj_j2k_t* opj_j2k_create_compress(void)
                 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;
 }
 
@@ -7486,7 +7523,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd (       opj_j2k_t * p_j2
                 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");
@@ -7567,6 +7604,9 @@ void opj_j2k_destroy (opj_j2k_t *p_j2k)
         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);
 }
 
@@ -8658,6 +8698,17 @@ opj_j2k_t* opj_j2k_create_decompress(void)
                 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;
 }
 
@@ -10934,7 +10985,7 @@ static OPJ_BOOL opj_j2k_create_tcd(     opj_j2k_t *p_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;