opj_jp2_read_header(): move setting icc_profile here instead in opj_jp2_decode()... 1463/head
authorEven Rouault <even.rouault@spatialys.com>
Sun, 26 Mar 2023 12:03:59 +0000 (14:03 +0200)
committerEven Rouault <even.rouault@spatialys.com>
Sun, 26 Mar 2023 12:03:59 +0000 (14:03 +0200)
src/lib/openjp2/jp2.c
tests/unit/CMakeLists.txt
tests/unit/testjp2.c [new file with mode: 0644]

index 25f379af8f1c695a2ef72f9c2f58dc6a4372a059..6015190e1f5b9ef47639d74b96f5f6ce70ce1886 100644 (file)
@@ -1623,12 +1623,6 @@ static OPJ_BOOL opj_jp2_apply_color_postprocessing(opj_jp2_t *jp2,
         if (jp2->color.jp2_cdef) {
             opj_jp2_apply_cdef(p_image, &(jp2->color), p_manager);
         }
-
-        if (jp2->color.icc_profile_buf) {
-            p_image->icc_profile_buf = jp2->color.icc_profile_buf;
-            p_image->icc_profile_len = jp2->color.icc_profile_len;
-            jp2->color.icc_profile_buf = NULL;
-        }
     }
 
     return OPJ_TRUE;
@@ -2890,6 +2884,12 @@ OPJ_BOOL opj_jp2_read_header(opj_stream_private_t *p_stream,
         } else {
             (*p_image)->color_space = OPJ_CLRSPC_UNKNOWN;
         }
+
+        if (jp2->color.icc_profile_buf) {
+            (*p_image)->icc_profile_buf = jp2->color.icc_profile_buf;
+            (*p_image)->icc_profile_len = jp2->color.icc_profile_len;
+            jp2->color.icc_profile_buf = NULL;
+        }
     }
     return ret;
 }
index 772b1a30fdc49d6ede3d4782e4a7394e50dcedf9..652643e614bf8be8458498f034d88f54d754de45 100644 (file)
@@ -15,3 +15,7 @@ foreach(ut ${unit_test})
   target_link_libraries(${ut} openjp2)
   add_test(NAME ${ut} COMMAND ${ut})
 endforeach()
+
+add_executable(testjp2 testjp2.c)
+target_link_libraries(testjp2 openjp2)
+add_test(NAME testjp2 COMMAND testjp2 ${OPJ_DATA_ROOT})
diff --git a/tests/unit/testjp2.c b/tests/unit/testjp2.c
new file mode 100644 (file)
index 0000000..0e7a85b
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2023, Even Rouault
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+
+#include "openjpeg.h"
+
+static void test_colorspace(const char* pszDirectory)
+{
+    char szFile[2048];
+    opj_image_t* image = NULL;
+    opj_stream_t *l_stream = NULL;              /* Stream */
+    opj_codec_t* l_codec = NULL;                /* Handle to a decompressor */
+    opj_dparameters_t parameters;               /* decompression parameters */
+
+    snprintf(szFile, sizeof(szFile), "%s/input/conformance/file1.jp2",
+             pszDirectory);
+    l_stream = opj_stream_create_default_file_stream(szFile, 1);
+    if (!l_stream) {
+        fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n",
+                szFile);
+        exit(1);
+    }
+    l_codec = opj_create_decompress(OPJ_CODEC_JP2);
+
+    /* Setup the decoder */
+    opj_set_default_decoder_parameters(&parameters);
+    if (!opj_setup_decoder(l_codec, &parameters)) {
+        fprintf(stderr, "ERROR -> opj_decompress: failed to setup the decoder\n");
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
+        exit(1);
+    }
+
+    /* Read the main header of the codestream and if necessary the JP2 boxes*/
+    if (! opj_read_header(l_stream, l_codec, &image)) {
+        fprintf(stderr, "ERROR -> opj_decompress: failed to read the header\n");
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
+        opj_image_destroy(image);
+        exit(1);
+    }
+
+    /* Check that color_space is set after opj_read_header() */
+    if (image->color_space != OPJ_CLRSPC_SRGB) {
+        fprintf(stderr, "ERROR -> image->color_space (=%d) != OPJ_CLRSPC_SRGB\n",
+                image->color_space);
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
+        opj_image_destroy(image);
+        exit(1);
+    }
+
+    opj_destroy_codec(l_codec);
+    opj_stream_destroy(l_stream);
+    opj_image_destroy(image);
+}
+
+static void test_iccprofile(const char* pszDirectory)
+{
+    char szFile[2048];
+    opj_image_t* image = NULL;
+    opj_stream_t *l_stream = NULL;              /* Stream */
+    opj_codec_t* l_codec = NULL;                /* Handle to a decompressor */
+    opj_dparameters_t parameters;               /* decompression parameters */
+
+    snprintf(szFile, sizeof(szFile), "%s/input/nonregression/relax.jp2",
+             pszDirectory);
+    l_stream = opj_stream_create_default_file_stream(szFile, 1);
+    if (!l_stream) {
+        fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n",
+                szFile);
+        exit(1);
+    }
+    l_codec = opj_create_decompress(OPJ_CODEC_JP2);
+
+    /* Setup the decoder */
+    opj_set_default_decoder_parameters(&parameters);
+    if (!opj_setup_decoder(l_codec, &parameters)) {
+        fprintf(stderr, "ERROR -> opj_decompress: failed to setup the decoder\n");
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
+        exit(1);
+    }
+
+    /* Read the main header of the codestream and if necessary the JP2 boxes*/
+    if (! opj_read_header(l_stream, l_codec, &image)) {
+        fprintf(stderr, "ERROR -> opj_decompress: failed to read the header\n");
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
+        opj_image_destroy(image);
+        exit(1);
+    }
+
+    /* Check that icc_profile_len is set after opj_read_header() */
+    if (image->icc_profile_len != 278) {
+        fprintf(stderr, "ERROR -> image->icc_profile_len (=%d) != 278\n",
+                image->icc_profile_len);
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
+        opj_image_destroy(image);
+        exit(1);
+    }
+
+    opj_destroy_codec(l_codec);
+    opj_stream_destroy(l_stream);
+    opj_image_destroy(image);
+}
+
+int main(int argc, char* argv[])
+{
+    if (argc != 2) {
+        fprintf(stderr, "usage: testjp2 /path/to/opj_data_root\n");
+        exit(1);
+    }
+
+    test_colorspace(argv[1]);
+    test_iccprofile(argv[1]);
+
+    return 0;
+}