Merge pull request #1211 from sebras/master
authorEven Rouault <even.rouault@spatialys.com>
Wed, 20 May 2020 19:10:55 +0000 (21:10 +0200)
committerGitHub <noreply@github.com>
Wed, 20 May 2020 19:10:55 +0000 (21:10 +0200)
Add check to validate SGcod/SPcoc/SPcod parameter values.

44 files changed:
src/bin/common/color.c
src/bin/jp2/convert.c
src/bin/jp2/convertpng.c
src/bin/jp2/converttif.c
src/bin/jp2/opj_compress.c
src/bin/jp3d/convert.c
src/bin/jpip/opj_jpip_transcode.c
src/bin/jpwl/convert.c
src/bin/jpwl/opj_jpwl_compress.c
src/bin/jpwl/opj_jpwl_decompress.c
src/bin/mj2/mj2_to_metadata.c
src/bin/mj2/opj_mj2_compress.c
src/bin/mj2/opj_mj2_decompress.c
src/lib/openjp2/j2k.c
src/lib/openjp2/j2k.h
src/lib/openjp2/jp2.c
src/lib/openjp2/jp2.h
src/lib/openjp2/mct.c
src/lib/openjp2/openjpeg.c
src/lib/openjp2/openjpeg.h
src/lib/openjp2/opj_codec.h
src/lib/openjp2/opj_common.h
src/lib/openjp2/opj_intmath.h
src/lib/openjp2/pi.c
src/lib/openjp2/pi.h
src/lib/openjp2/t2.c
src/lib/openjp2/t2.h
src/lib/openjp2/tcd.c
src/lib/openjp2/tcd.h
src/lib/openjp3d/t2.c
src/lib/openjpip/auxtrans_manager.c
src/lib/openjpip/box_manager.c
src/lib/openjpip/index_manager.c
src/lib/openjpip/jp2k_decoder.c
src/lib/openjpip/openjpip.c
src/lib/openmj2/mj2.c
src/lib/openmj2/mj2_convert.c
tests/fuzzers/GNUmakefile
tests/fuzzers/build_google_oss_fuzzers.sh
tests/nonregression/CMakeLists.txt
tests/nonregression/checkmd5refs.cmake
tests/nonregression/md5refs.txt
tests/nonregression/test_suite.ctest.in
tools/travis-ci/abi-check.sh

index d3a2f38d7ef3c9bdc63d1c3bbd069f4000b10b4c..27f15f137f73ee7aa6c6ae4b531368157a86ba26 100644 (file)
@@ -488,6 +488,10 @@ void color_apply_icc_profile(opj_image_t *image)
     if (out_space == cmsSigRgbData) { /* enumCS 16 */
         unsigned int i, nr_comp = image->numcomps;
 
+        if (nr_comp < 3) { /* GRAY or GRAYA, not RGB or RGBA */
+            cmsCloseProfile(in_prof);
+            return;
+        }
         if (nr_comp > 4) {
             nr_comp = 4;
         }
@@ -529,6 +533,10 @@ void color_apply_icc_profile(opj_image_t *image)
         out_prof = cmsCreate_sRGBProfile();
         new_space = OPJ_CLRSPC_SRGB;
     } else if (out_space == cmsSigYCbCrData) { /* enumCS 18 */
+        if (image->numcomps < 3) {
+            cmsCloseProfile(in_prof);
+            return;
+        }
         in_type = TYPE_YCbCr_16;
         out_type = TYPE_RGB_16;
         out_prof = cmsCreate_sRGBProfile();
index e670cd82fbe710107f4ee46697bdb3b5a13e38bf..23f820c0d707ab356247c8f5f843867f5582bfb2 100644 (file)
@@ -2067,10 +2067,26 @@ int imagetopnm(opj_image_t * image, const char *outfile, int force_split)
         has_alpha = (ncomp == 4 || ncomp == 2);
 
         red = image->comps[0].data;
+        if (red == NULL) {
+            fprintf(stderr,
+                    "imagetopnm: planes[%d] == NULL.\n", 0);
+            fprintf(stderr, "\tAborting\n");
+            fclose(fdest);
+            return fails;
+        }
 
         if (triple) {
             green = image->comps[1].data;
             blue = image->comps[2].data;
+            for (i = 1; i <= 2; i++) {
+                if (image->comps[i].data == NULL) {
+                    fprintf(stderr,
+                            "imagetopnm: planes[%d] == NULL.\n", i);
+                    fprintf(stderr, "\tAborting\n");
+                    fclose(fdest);
+                    return fails;
+                }
+            }
         } else {
             green = blue = NULL;
         }
index 44d985f2333a65f40050af190ba1b1eedaca11a1..328c91bebc7090f72586fa976392bdfde9d59726 100644 (file)
@@ -297,6 +297,12 @@ int imagetopng(opj_image_t * image, const char *write_idf)
     memset(&sig_bit, 0, sizeof(sig_bit));
     prec = (int)image->comps[0].prec;
     planes[0] = image->comps[0].data;
+    if (planes[0] == NULL) {
+        fprintf(stderr,
+                "imagetopng: planes[%d] == NULL.\n", 0);
+        fprintf(stderr, "\tAborting\n");
+        return 1;
+    }
     nr_comp = (int)image->numcomps;
 
     if (nr_comp > 4) {
@@ -316,6 +322,12 @@ int imagetopng(opj_image_t * image, const char *write_idf)
             break;
         }
         planes[i] = image->comps[i].data;
+        if (planes[i] == NULL) {
+            fprintf(stderr,
+                    "imagetopng: planes[%d] == NULL.\n", i);
+            fprintf(stderr, "\tAborting\n");
+            return 1;
+        }
     }
     if (i != nr_comp) {
         fprintf(stderr,
index 6714d69c72996c3814058027391dbfc341e8f514..9d1037acb63dd67c5600d2f8a47d1fd560f24ec7 100644 (file)
@@ -616,6 +616,12 @@ int imagetotif(opj_image_t * image, const char *outfile)
             break;
         }
         planes[i] = image->comps[i].data;
+        if (planes[i] == NULL) {
+            fprintf(stderr,
+                    "imagetotif: planes[%d] == NULL.\n", i);
+            fprintf(stderr, "\tAborting\n");
+            return 1;
+        }
     }
     if (i != numcomps) {
         fprintf(stderr,
index 148bf951d748214fbfcf41010298e8095927f0f1..cbc30fba3d62abcd705c535a3f18f9fdb8a8e42f 100644 (file)
@@ -229,6 +229,8 @@ static void encode_help_display(void)
     fprintf(stdout, "    Write SOP marker before each packet.\n");
     fprintf(stdout, "-EPH\n");
     fprintf(stdout, "    Write EPH marker after each header packet.\n");
+    fprintf(stdout, "-PLT\n");
+    fprintf(stdout, "    Write PLT marker in tile-part header.\n");
     fprintf(stdout, "-M <key value>\n");
     fprintf(stdout, "    Mode switch.\n");
     fprintf(stdout, "    [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
@@ -287,6 +289,13 @@ static void encode_help_display(void)
     fprintf(stdout, "-cinema4K\n");
     fprintf(stdout, "    Digital Cinema 4K profile compliant codestream.\n");
     fprintf(stdout, "  Frames per second not required. Default value is 24fps.\n");
+    fprintf(stdout, "-IMF <PROFILE>[,mainlevel=X][,sublevel=Y][,framerate=FPS]\n");
+    fprintf(stdout, "    Interoperable Master Format compliant codestream.\n");
+    fprintf(stdout, "    <PROFILE>=2K, 4K, 8K, 2K_R, 4K_R or 8K_R.\n");
+    fprintf(stdout, "    X >= 0 and X <= 11.\n");
+    fprintf(stdout, "    Y >= 0 and Y <= 9.\n");
+    fprintf(stdout,
+            "    framerate > 0 may be specified to enhance checks and set maximum bit rate when Y > 0.\n");
     fprintf(stdout, "-jpip\n");
     fprintf(stdout, "    Write jpip codestream index box in JP2 output file.\n");
     fprintf(stdout, "    Currently supports only RPCL order.\n");
@@ -568,7 +577,9 @@ static char get_next_file(int imageno, dircnt_t *dirptr, img_fol_t *img_fol,
 static int parse_cmdline_encoder(int argc, char **argv,
                                  opj_cparameters_t *parameters,
                                  img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename,
-                                 size_t indexfilename_size)
+                                 size_t indexfilename_size,
+                                 int* pOutFramerate,
+                                 OPJ_BOOL* pOutPLT)
 {
     OPJ_UINT32 i, j;
     int totlen, c;
@@ -583,7 +594,9 @@ static int parse_cmdline_encoder(int argc, char **argv,
         {"POC", REQ_ARG, NULL, 'P'},
         {"ROI", REQ_ARG, NULL, 'R'},
         {"jpip", NO_ARG, NULL, 'J'},
-        {"mct", REQ_ARG, NULL, 'Y'}
+        {"mct", REQ_ARG, NULL, 'Y'},
+        {"IMF", REQ_ARG, NULL, 'Z'},
+        {"PLT", NO_ARG, NULL, 'A'}
     };
 
     /* parse the command line */
@@ -1129,6 +1142,98 @@ static int parse_cmdline_encoder(int argc, char **argv,
 
         /* ------------------------------------------------------ */
 
+        case 'Z': {         /* IMF profile*/
+            int mainlevel = 0;
+            int sublevel = 0;
+            int profile = 0;
+            int framerate = 0;
+            const char* msg =
+                "Wrong value for -IMF. Should be "
+                "<PROFILE>[,mainlevel=X][,sublevel=Y][,framerate=FPS] where <PROFILE> is one "
+                "of 2K/4K/8K/2K_R/4K_R/8K_R.\n";
+            char* comma;
+
+            comma = strstr(opj_optarg, ",mainlevel=");
+            if (comma && sscanf(comma + 1, "mainlevel=%d", &mainlevel) != 1) {
+                fprintf(stderr, "%s", msg);
+                return 1;
+            }
+
+            comma = strstr(opj_optarg, ",sublevel=");
+            if (comma && sscanf(comma + 1, "sublevel=%d", &sublevel) != 1) {
+                fprintf(stderr, "%s", msg);
+                return 1;
+            }
+
+            comma = strstr(opj_optarg, ",framerate=");
+            if (comma && sscanf(comma + 1, "framerate=%d", &framerate) != 1) {
+                fprintf(stderr, "%s", msg);
+                return 1;
+            }
+
+            comma = strchr(opj_optarg, ',');
+            if (comma != NULL) {
+                *comma = 0;
+            }
+
+            if (strcmp(opj_optarg, "2K") == 0) {
+                profile = OPJ_PROFILE_IMF_2K;
+            } else if (strcmp(opj_optarg, "4K") == 0) {
+                profile = OPJ_PROFILE_IMF_4K;
+            } else if (strcmp(opj_optarg, "8K") == 0) {
+                profile = OPJ_PROFILE_IMF_8K;
+            } else if (strcmp(opj_optarg, "2K_R") == 0) {
+                profile = OPJ_PROFILE_IMF_2K_R;
+            } else if (strcmp(opj_optarg, "4K_R") == 0) {
+                profile = OPJ_PROFILE_IMF_4K_R;
+            } else if (strcmp(opj_optarg, "8K_R") == 0) {
+                profile = OPJ_PROFILE_IMF_8K_R;
+            } else {
+                fprintf(stderr, "%s", msg);
+                return 1;
+            }
+
+            if (!(mainlevel >= 0 && mainlevel <= 15)) {
+                /* Voluntarily rough validation. More fine grained done in library */
+                fprintf(stderr, "Invalid mainlevel value.\n");
+                return 1;
+            }
+            if (!(sublevel >= 0 && sublevel <= 15)) {
+                /* Voluntarily rough validation. More fine grained done in library */
+                fprintf(stderr, "Invalid sublevel value.\n");
+                return 1;
+            }
+            parameters->rsiz = (OPJ_UINT16)(profile | (sublevel << 4) | mainlevel);
+
+            fprintf(stdout, "IMF profile activated\n"
+                    "Other options specified could be overridden\n");
+
+            if (pOutFramerate) {
+                *pOutFramerate = framerate;
+            }
+            if (framerate > 0 && sublevel > 0 && sublevel <= 9) {
+                const int limitMBitsSec[] = {
+                    0,
+                    OPJ_IMF_SUBLEVEL_1_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_2_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_3_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_4_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_5_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_6_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_7_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_8_MBITSSEC,
+                    OPJ_IMF_SUBLEVEL_9_MBITSSEC
+                };
+                parameters->max_cs_size = limitMBitsSec[sublevel] * (1000 * 1000 / 8) /
+                                          framerate;
+                fprintf(stdout, "Setting max codestream size to %d bytes.\n",
+                        parameters->max_cs_size);
+            }
+        }
+        break;
+
+        /* ------------------------------------------------------ */
+
         case 'Y': {         /* Shall we do an MCT ? 0:no_mct;1:rgb->ycc;2:custom mct (-m option required)*/
             int mct_mode = 0;
             sscanf(opj_optarg, "%d", &mct_mode);
@@ -1569,6 +1674,13 @@ static int parse_cmdline_encoder(int argc, char **argv,
         break;
         /* ------------------------------------------------------ */
 
+        case 'A': {         /* PLT markers */
+            *pOutPLT = OPJ_TRUE;
+        }
+        break;
+
+        /* ------------------------------------------------------ */
+
 
         default:
             fprintf(stderr, "[WARNING] An invalid option has been ignored\n");
@@ -1744,8 +1856,11 @@ int main(int argc, char **argv)
     OPJ_BOOL bSuccess;
     OPJ_BOOL bUseTiles = OPJ_FALSE; /* OPJ_TRUE */
     OPJ_UINT32 l_nb_tiles = 4;
+    int framerate = 0;
     OPJ_FLOAT64 t = opj_clock();
 
+    OPJ_BOOL PLT = OPJ_FALSE;
+
     /* set encoding parameters to default values */
     opj_set_default_encoder_parameters(&parameters);
 
@@ -1765,7 +1880,7 @@ int main(int argc, char **argv)
     parameters.tcp_mct = (char)
                          255; /* This will be set later according to the input image or the provided option */
     if (parse_cmdline_encoder(argc, argv, &parameters, &img_fol, &raw_cp,
-                              indexfilename, sizeof(indexfilename)) == 1) {
+                              indexfilename, sizeof(indexfilename), &framerate, &PLT) == 1) {
         ret = 1;
         goto fin;
     }
@@ -1940,6 +2055,41 @@ int main(int argc, char **argv)
             }
         }
 
+        if (OPJ_IS_IMF(parameters.rsiz) && framerate > 0) {
+            const int mainlevel = OPJ_GET_IMF_MAINLEVEL(parameters.rsiz);
+            if (mainlevel > 0 && mainlevel <= OPJ_IMF_MAINLEVEL_MAX) {
+                const int limitMSamplesSec[] = {
+                    0,
+                    OPJ_IMF_MAINLEVEL_1_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_2_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_3_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_4_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_5_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_6_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_7_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_8_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_9_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_10_MSAMPLESEC,
+                    OPJ_IMF_MAINLEVEL_11_MSAMPLESEC
+                };
+                OPJ_UINT32 avgcomponents = image->numcomps;
+                double msamplespersec;
+                if (image->numcomps == 3 &&
+                        image->comps[1].dx == 2 &&
+                        image->comps[1].dy == 2) {
+                    avgcomponents = 2;
+                }
+                msamplespersec = (double)image->x1 * image->y1 * avgcomponents * framerate /
+                                 1e6;
+                if (msamplespersec > limitMSamplesSec[mainlevel]) {
+                    fprintf(stderr,
+                            "Warning: MSamples/sec is %f, whereas limit is %d.\n",
+                            msamplespersec,
+                            limitMSamplesSec[mainlevel]);
+                }
+            }
+        }
+
         /* encode the destination image */
         /* ---------------------------- */
 
@@ -1980,6 +2130,17 @@ int main(int argc, char **argv)
             goto fin;
         }
 
+        if (PLT) {
+            const char* const options[] = { "PLT=YES", NULL };
+            if (!opj_encoder_set_extra_options(l_codec, options)) {
+                fprintf(stderr, "failed to encode image: opj_encoder_set_extra_options\n");
+                opj_destroy_codec(l_codec);
+                opj_image_destroy(image);
+                ret = 1;
+                goto fin;
+            }
+        }
+
         /* open a byte stream for writing and allocate memory for all tiles */
         l_stream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_FALSE);
         if (! l_stream) {
index acad8f82a84fc4f64d2beef67a4ddb9c8122ed29..4e4bea9ce7f057304d1bf40a9f4db5161587a1f4 100644 (file)
@@ -280,6 +280,7 @@ opj_volume_t* pgxtovolume(char *relpath, opj_cparameters_t *parameters)
     if (!sliceno) {
         fprintf(stdout,
                 "[ERROR] No slices with this pattern founded !! Please check input volume name\n");
+        closedir(dirp);
         return NULL;
     }
     /*if ( maxslice != sliceno) {
@@ -317,6 +318,7 @@ opj_volume_t* pgxtovolume(char *relpath, opj_cparameters_t *parameters)
         } else {
             fprintf(stdout, "[ERROR] Bad pgx header, please check input file\n");
             fclose(f);
+            closedir(dirp);
             return NULL;
         }
 
@@ -396,9 +398,7 @@ opj_volume_t* pgxtovolume(char *relpath, opj_cparameters_t *parameters)
         fclose(f);
     } /* for s --> sliceno*/
     comp->bpp = int_floorlog2(maxvalue) + 1;
-    if (sliceno != 1) {
-        closedir(dirp);
-    }
+    closedir(dirp);
     /*dump_volume(stdout, volume);*/
     return volume;
 }
@@ -581,6 +581,7 @@ opj_volume_t* bintovolume(char *filename, char *fileimg,
     f = fopen(filename, "rb");
     if (!f) {
         fprintf(stdout, "[ERROR] Failed to open %s for reading !!\n", filename);
+        opj_free(volume);
         return 0;
     }
 
@@ -918,7 +919,7 @@ opj_volume_t* imgtovolume(char *fileimg, opj_cparameters_t *parameters)
     f = fopen(filename, "rb");
     if (!f) {
         fprintf(stderr, "[ERROR] Failed to open %s for reading !!\n", filename);
-        fclose(f);
+        opj_free(volume);
         return 0;
     }
 
index 6cd2604d6fdc81177773fc47f6fa423bfb12a939..bedd5cf9ca1a1625a0eb1ba87318a79784c0de0e 100644 (file)
@@ -49,12 +49,14 @@ static int jpip_to_jp2(char *argv[])
     dec = init_jpipdecoder(OPJ_TRUE);
 
     if (!(fread_jpip(argv[1], dec))) {
+        destroy_jpipdecoder(&dec);
         return 1;
     }
 
     decode_jpip(dec);
 
     if (!(fwrite_jp2k(argv[2], dec))) {
+        destroy_jpipdecoder(&dec);
         return 1;
     }
 
@@ -83,12 +85,14 @@ static int jpip_to_j2k(char *argv[])
     dec = init_jpipdecoder(OPJ_FALSE);
 
     if (!(fread_jpip(argv[1], dec))) {
+        destroy_jpipdecoder(&dec);
         return 1;
     }
 
     decode_jpip(dec);
 
     if (!(fwrite_jp2k(argv[2], dec))) {
+        destroy_jpipdecoder(&dec);
         return 1;
     }
 
index 4f636c175fce408fa30b85cd32181195734e6a1c..b7fb5b5c6bce4fe38b7084be3d37b72ea0068f07 100644 (file)
@@ -465,6 +465,7 @@ int imagetotga(opj_image_t * image, const char *outfile)
                 || (image->comps[0].prec != image->comps[i + 1].prec)) {
             fprintf(stderr,
                     "Unable to create a tga file with such J2K image charateristics.");
+            fclose(fdest);
             return 1;
         }
     }
@@ -478,6 +479,7 @@ int imagetotga(opj_image_t * image, const char *outfile)
     /* Write TGA header  */
     bpp = write_alpha ? 32 : 24;
     if (!tga_writeheader(fdest, bpp, width, height, OPJ_TRUE)) {
+        fclose(fdest);
         return 1;
     }
 
@@ -510,6 +512,7 @@ int imagetotga(opj_image_t * image, const char *outfile)
             res = fwrite(&value, 1, 1, fdest);
             if (res < 1) {
                 fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
+                fclose(fdest);
                 return 1;
             }
 
@@ -517,6 +520,7 @@ int imagetotga(opj_image_t * image, const char *outfile)
             res = fwrite(&value, 1, 1, fdest);
             if (res < 1) {
                 fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
+                fclose(fdest);
                 return 1;
             }
 
@@ -524,6 +528,7 @@ int imagetotga(opj_image_t * image, const char *outfile)
             res = fwrite(&value, 1, 1, fdest);
             if (res < 1) {
                 fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
+                fclose(fdest);
                 return 1;
             }
 
@@ -533,12 +538,15 @@ int imagetotga(opj_image_t * image, const char *outfile)
                 res = fwrite(&value, 1, 1, fdest);
                 if (res < 1) {
                     fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
+                    fclose(fdest);
                     return 1;
                 }
             }
         }
     }
 
+    fclose(fdest);
+
     return 0;
 }
 
@@ -832,6 +840,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
         RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
 
         if (fread(RGB, sizeof(unsigned char), W * H, IN) != W * H) {
+            fclose(IN);
             free(table_R);
             free(table_G);
             free(table_B);
@@ -1488,7 +1497,7 @@ int imagetopgx(opj_image_t * image, const char *outfile)
         const size_t olen = strlen(outfile);
         const size_t dotpos = olen - 4;
         const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
-        if (outfile[dotpos] != '.') {
+        if (olen < 4 || outfile[dotpos] != '.') {
             /* `pgx` was recognized but there is no dot at expected position */
             fprintf(stderr, "ERROR -> Impossible happen.");
             return 1;
@@ -1505,6 +1514,7 @@ int imagetopgx(opj_image_t * image, const char *outfile)
         fdest = fopen(name, "wb");
         if (!fdest) {
             fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
+            free(name);
             return 1;
         }
         /* don't need name anymore */
index c17486a0b59182ac0a8b9bc3c3dacbe3adb65716..ccf0361500250046a2199b38f526e8f772ba21cc 100644 (file)
@@ -1681,8 +1681,15 @@ int main(int argc, char **argv)
         if (dirptr) {
             dirptr->filename_buf = (char*)malloc(num_images * OPJ_PATH_LEN * sizeof(
                     char)); /* Stores at max 10 image file names*/
-            dirptr->filename = (char**) malloc(num_images * sizeof(char*));
             if (!dirptr->filename_buf) {
+                free(parameters.cp_comment);
+                free(dirptr);
+                return 0;
+            }
+            dirptr->filename = (char**) malloc(num_images * sizeof(char*));
+            if (!dirptr->filename) {
+                free(parameters.cp_comment);
+                free(dirptr);
                 return 0;
             }
             for (i = 0; i < num_images; i++) {
@@ -1690,9 +1697,13 @@ int main(int argc, char **argv)
             }
         }
         if (load_images(dirptr, img_fol.imgdirpath) == 1) {
+            free(parameters.cp_comment);
+            free(dirptr);
             return 0;
         }
         if (num_images == 0) {
+            free(parameters.cp_comment);
+            free(dirptr);
             fprintf(stdout, "Folder is empty\n");
             return 0;
         }
@@ -1850,6 +1861,7 @@ int main(int argc, char **argv)
             if (res < (size_t)codestream_length) {  /* FIXME */
                 fprintf(stderr, "failed to write %d (%s)\n", codestream_length,
                         parameters.outfile);
+                fclose(f);
                 return 1;
             }
             fclose(f);
@@ -1914,6 +1926,7 @@ int main(int argc, char **argv)
             if (res < (size_t)codestream_length) {  /* FIXME */
                 fprintf(stderr, "failed to write %d (%s)\n", codestream_length,
                         parameters.outfile);
+                fclose(f);
                 return 1;
             }
             fclose(f);
index ffe84e54e4c4c3322325845e03a7900e0cdb7a37..a73be1c386b7a034908280ca0d3b4a64f1b11209 100644 (file)
@@ -597,11 +597,16 @@ int main(int argc, char **argv)
         if (dirptr) {
             dirptr->filename_buf = (char*)malloc(num_images * OPJ_PATH_LEN * sizeof(
                     char)); /* Stores at max 10 image file names*/
-            dirptr->filename = (char**) malloc(num_images * sizeof(char*));
-
             if (!dirptr->filename_buf) {
+                free(dirptr);
+                return 1;
+            }
+            dirptr->filename = (char**) malloc(num_images * sizeof(char*));
+            if (!dirptr->filename) {
+                free(dirptr);
                 return 1;
             }
+
             for (i = 0; i < num_images; i++) {
                 dirptr->filename[i] = dirptr->filename_buf + i * OPJ_PATH_LEN;
             }
index 44858c86a3e2d6c34e0bed5e0cfb20967f65a0cd..27f164d7c96de118c1aabac988f10954603467d1 100644 (file)
@@ -304,6 +304,7 @@ int main(int argc, char *argv[])
     xmlout = fopen(outfile, "w"); /* was: argv[2] */
     if (!xmlout) {
         fprintf(stderr, "Failed to open %s for writing.\n", outfile); /* was: argv[2] */
+        fclose(file);
         return 1;
     }
     // Leave it open
index c61b4c920a820ff6f521783352e501a0649cb8c2..8386ba0ef2e765bb7323d959425a2112487baf9c 100644 (file)
@@ -708,6 +708,7 @@ int main(int argc, char **argv)
         yuv_num_frames(&movie->tk[0], mj2_parameters.infile);
 
     if (movie->tk[0].num_samples == 0) {
+        fclose(mj2file);
         return 1;
     }
 
index 6b26d563664c1c3f759e2ff36d53e16aa1fbc764..6d1a96163a54cfc21d88c99f9461e143ff4db815 100644 (file)
@@ -99,8 +99,9 @@ int main(int argc, char *argv[])
 
     /* Checking output file */
     outfile = fopen(argv[2], "w");
-    if (!file) {
+    if (!outfile) {
         fprintf(stderr, "failed to open %s for writing\n", argv[2]);
+        fclose(file);
         return 1;
     }
     fclose(outfile);
@@ -169,6 +170,7 @@ int main(int argc, char *argv[])
             if ((frame_codestream = (unsigned char*)
                                     realloc(frame_codestream, max_codstrm_size)) == NULL) {
                 printf("Error reallocation memory\n");
+                free(frame_codestream);
                 return 1;
             };
         }
index 43be7677ea413d546c708adb2b66d62dba985ef9..c45b6742e97a5c0c119e36b9008f1ad80fceca90 100644 (file)
@@ -879,6 +879,8 @@ static OPJ_BOOL opj_j2k_read_sot(opj_j2k_t *p_j2k,
 /**
  * Writes the SOD marker (Start of data)
  *
+ * This also writes optional PLT markers (before SOD)
+ *
  * @param       p_j2k               J2K codec.
  * @param       p_tile_coder        FIXME DOC
  * @param       p_data              FIXME DOC
@@ -1284,6 +1286,13 @@ static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters,
 static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz,
         opj_event_mgr_t *p_manager);
 
+static void opj_j2k_set_imf_parameters(opj_cparameters_t *parameters,
+                                       opj_image_t *image, opj_event_mgr_t *p_manager);
+
+static OPJ_BOOL opj_j2k_is_imf_compliant(opj_cparameters_t *parameters,
+        opj_image_t *image,
+        opj_event_mgr_t *p_manager);
+
 /**
  * Checks for invalid number of tile-parts in SOT marker (TPsot==TNsot). See issue 254.
  *
@@ -3442,6 +3451,28 @@ static OPJ_UINT32 opj_j2k_get_specific_header_sizes(opj_j2k_t *p_j2k)
 
     l_nb_bytes += opj_j2k_get_max_poc_size(p_j2k);
 
+    if (p_j2k->m_specific_param.m_encoder.m_PLT) {
+        /* Reserve space for PLT markers */
+
+        OPJ_UINT32 i;
+        const opj_cp_t * l_cp = &(p_j2k->m_cp);
+        OPJ_UINT32 l_max_packet_count = 0;
+        for (i = 0; i < l_cp->th * l_cp->tw; ++i) {
+            l_max_packet_count = opj_uint_max(l_max_packet_count,
+                                              opj_get_encoding_packet_count(p_j2k->m_private_image, l_cp, i));
+        }
+        /* Minimum 6 bytes per PLT marker, and at a minimum (taking a pessimistic */
+        /* estimate of 4 bytes for a packet size), one can write */
+        /* (65536-6) / 4 = 16382 paquet sizes per PLT marker */
+        p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT =
+            6 * opj_uint_ceildiv(l_max_packet_count, 16382);
+        /* Maximum 5 bytes per packet to encode a full UINT32 */
+        p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT +=
+            l_nb_bytes += 5 * l_max_packet_count;
+        p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT += 1;
+        l_nb_bytes += p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT;
+    }
+
     /*** DEVELOPER CORNER, Add room for your headers ***/
 
     return l_nb_bytes;
@@ -4601,6 +4632,93 @@ static OPJ_BOOL opj_j2k_read_sot(opj_j2k_t *p_j2k,
     return OPJ_TRUE;
 }
 
+/**
+ * Write one or more PLT markers in the provided buffer
+ */
+static OPJ_BOOL opj_j2k_write_plt_in_memory(opj_j2k_t *p_j2k,
+        opj_tcd_marker_info_t* marker_info,
+        OPJ_BYTE * p_data,
+        OPJ_UINT32 * p_data_written,
+        opj_event_mgr_t * p_manager)
+{
+    OPJ_BYTE Zplt = 0;
+    OPJ_UINT16 Lplt;
+    OPJ_BYTE* p_data_start = p_data;
+    OPJ_BYTE* p_data_Lplt = p_data + 2;
+    OPJ_UINT32 i;
+
+    OPJ_UNUSED(p_j2k);
+
+    opj_write_bytes(p_data, J2K_MS_PLT, 2);
+    p_data += 2;
+
+    /* Reserve space for Lplt */
+    p_data += 2;
+
+    opj_write_bytes(p_data, Zplt, 1);
+    p_data += 1;
+
+    Lplt = 3;
+
+    for (i = 0; i < marker_info->packet_count; i++) {
+        OPJ_BYTE var_bytes[5];
+        OPJ_UINT8 var_bytes_size = 0;
+        OPJ_UINT32 packet_size = marker_info->p_packet_size[i];
+
+        /* Packet size written in variable-length way, starting with LSB */
+        var_bytes[var_bytes_size] = (OPJ_BYTE)(packet_size & 0x7f);
+        var_bytes_size ++;
+        packet_size >>= 7;
+        while (packet_size > 0) {
+            var_bytes[var_bytes_size] = (OPJ_BYTE)((packet_size & 0x7f) | 0x80);
+            var_bytes_size ++;
+            packet_size >>= 7;
+        }
+
+        /* Check if that can fit in the current PLT marker. If not, finish */
+        /* current one, and start a new one */
+        if (Lplt + var_bytes_size > 65535) {
+            if (Zplt == 255) {
+                opj_event_msg(p_manager, EVT_ERROR,
+                              "More than 255 PLT markers would be needed for current tile-part !\n");
+                return OPJ_FALSE;
+            }
+
+            /* Patch Lplt */
+            opj_write_bytes(p_data_Lplt, Lplt, 2);
+
+            /* Start new segment */
+            opj_write_bytes(p_data, J2K_MS_PLT, 2);
+            p_data += 2;
+
+            /* Reserve space for Lplt */
+            p_data_Lplt = p_data;
+            p_data += 2;
+
+            Zplt ++;
+            opj_write_bytes(p_data, Zplt, 1);
+            p_data += 1;
+
+            Lplt = 3;
+        }
+
+        Lplt = (OPJ_UINT16)(Lplt + var_bytes_size);
+
+        /* Serialize variable-length packet size, starting with MSB */
+        for (; var_bytes_size > 0; --var_bytes_size) {
+            opj_write_bytes(p_data, var_bytes[var_bytes_size - 1], 1);
+            p_data += 1;
+        }
+    }
+
+    *p_data_written = (OPJ_UINT32)(p_data - p_data_start);
+
+    /* Patch Lplt */
+    opj_write_bytes(p_data_Lplt, Lplt, 2);
+
+    return OPJ_TRUE;
+}
+
 static OPJ_BOOL opj_j2k_write_sod(opj_j2k_t *p_j2k,
                                   opj_tcd_t * p_tile_coder,
                                   OPJ_BYTE * p_data,
@@ -4612,6 +4730,7 @@ static OPJ_BOOL opj_j2k_write_sod(opj_j2k_t *p_j2k,
 {
     opj_codestream_info_t *l_cstr_info = 00;
     OPJ_UINT32 l_remaining_data;
+    opj_tcd_marker_info_t* marker_info = NULL;
 
     /* preconditions */
     assert(p_j2k != 00);
@@ -4628,7 +4747,6 @@ static OPJ_BOOL opj_j2k_write_sod(opj_j2k_t *p_j2k,
 
     opj_write_bytes(p_data, J2K_MS_SOD,
                     2);                                 /* SOD */
-    p_data += 2;
 
     /* make room for the EOF marker */
     l_remaining_data =  total_data_size - 4;
@@ -4678,15 +4796,64 @@ static OPJ_BOOL opj_j2k_write_sod(opj_j2k_t *p_j2k,
 
     *p_data_written = 0;
 
-    if (! opj_tcd_encode_tile(p_tile_coder, p_j2k->m_current_tile_number, p_data,
+    if (p_j2k->m_specific_param.m_encoder.m_PLT) {
+        marker_info = opj_tcd_marker_info_create(
+                          p_j2k->m_specific_param.m_encoder.m_PLT);
+        if (marker_info == NULL) {
+            opj_event_msg(p_manager, EVT_ERROR,
+                          "Cannot encode tile: opj_tcd_marker_info_create() failed\n");
+            return OPJ_FALSE;
+        }
+    }
+
+    assert(l_remaining_data >
+           p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT);
+    l_remaining_data -= p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT;
+
+    if (! opj_tcd_encode_tile(p_tile_coder, p_j2k->m_current_tile_number,
+                              p_data + 2,
                               p_data_written, l_remaining_data, l_cstr_info,
+                              marker_info,
                               p_manager)) {
         opj_event_msg(p_manager, EVT_ERROR, "Cannot encode tile\n");
+        opj_tcd_marker_info_destroy(marker_info);
         return OPJ_FALSE;
     }
 
+    /* For SOD */
     *p_data_written += 2;
 
+    if (p_j2k->m_specific_param.m_encoder.m_PLT) {
+        OPJ_UINT32 l_data_written_PLT = 0;
+        OPJ_BYTE* p_PLT_buffer = (OPJ_BYTE*)opj_malloc(
+                                     p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT);
+        if (!p_PLT_buffer) {
+            opj_event_msg(p_manager, EVT_ERROR, "Cannot allocate memory\n");
+            opj_tcd_marker_info_destroy(marker_info);
+            return OPJ_FALSE;
+        }
+        if (!opj_j2k_write_plt_in_memory(p_j2k,
+                                         marker_info,
+                                         p_PLT_buffer,
+                                         &l_data_written_PLT,
+                                         p_manager)) {
+            opj_tcd_marker_info_destroy(marker_info);
+            opj_free(p_PLT_buffer);
+            return OPJ_FALSE;
+        }
+
+        assert(l_data_written_PLT <=
+               p_j2k->m_specific_param.m_encoder.m_reserved_bytes_for_PLT);
+
+        /* Move PLT marker(s) before SOD */
+        memmove(p_data + l_data_written_PLT, p_data, *p_data_written);
+        memcpy(p_data, p_PLT_buffer, l_data_written_PLT);
+        opj_free(p_PLT_buffer);
+        *p_data_written += l_data_written_PLT;
+    }
+
+    opj_tcd_marker_info_destroy(marker_info);
+
     return OPJ_TRUE;
 }
 
@@ -5189,7 +5356,7 @@ static OPJ_BOOL opj_j2k_update_rates(opj_j2k_t *p_j2k,
         return OPJ_FALSE;
     }
 
-    if (OPJ_IS_CINEMA(l_cp->rsiz)) {
+    if (OPJ_IS_CINEMA(l_cp->rsiz) || OPJ_IS_IMF(l_cp->rsiz)) {
         p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer =
             (OPJ_BYTE *) opj_malloc(5 *
                                     p_j2k->m_specific_param.m_encoder.m_total_tile_parts);
@@ -6617,7 +6784,7 @@ static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters,
     }
 
     /* Precincts */
-    parameters->csty |= 0x01;
+    parameters->csty |= J2K_CP_CSTY_PRT;
     if (parameters->numresolution == 1) {
         parameters->res_spec = 1;
         parameters->prcw_init[0] = 128;
@@ -6743,6 +6910,589 @@ static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz,
     return OPJ_TRUE;
 }
 
+static int opj_j2k_get_imf_max_NL(opj_cparameters_t *parameters,
+                                  opj_image_t *image)
+{
+    /* Decomposition levels */
+    const OPJ_UINT16 rsiz = parameters->rsiz;
+    const OPJ_UINT16 profile = OPJ_GET_IMF_PROFILE(rsiz);
+    const OPJ_UINT32 XTsiz = parameters->tile_size_on ? (OPJ_UINT32)
+                             parameters->cp_tdx : image->x1;
+    switch (profile) {
+    case OPJ_PROFILE_IMF_2K:
+        return 5;
+    case OPJ_PROFILE_IMF_4K:
+        return 6;
+    case OPJ_PROFILE_IMF_8K:
+        return 7;
+    case OPJ_PROFILE_IMF_2K_R: {
+        if (XTsiz >= 2048) {
+            return 5;
+        } else if (XTsiz >= 1024) {
+            return 4;
+        }
+        break;
+    }
+    case OPJ_PROFILE_IMF_4K_R: {
+        if (XTsiz >= 4096) {
+            return 6;
+        } else if (XTsiz >= 2048) {
+            return 5;
+        } else if (XTsiz >= 1024) {
+            return 4;
+        }
+        break;
+    }
+    case OPJ_PROFILE_IMF_8K_R: {
+        if (XTsiz >= 8192) {
+            return 7;
+        } else if (XTsiz >= 4096) {
+            return 6;
+        } else if (XTsiz >= 2048) {
+            return 5;
+        } else if (XTsiz >= 1024) {
+            return 4;
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    return -1;
+}
+
+static void opj_j2k_set_imf_parameters(opj_cparameters_t *parameters,
+                                       opj_image_t *image, opj_event_mgr_t *p_manager)
+{
+    const OPJ_UINT16 rsiz = parameters->rsiz;
+    const OPJ_UINT16 profile = OPJ_GET_IMF_PROFILE(rsiz);
+
+    OPJ_UNUSED(p_manager);
+
+    /* Override defaults set by opj_set_default_encoder_parameters */
+    if (parameters->cblockw_init == OPJ_COMP_PARAM_DEFAULT_CBLOCKW &&
+            parameters->cblockh_init == OPJ_COMP_PARAM_DEFAULT_CBLOCKH) {
+        parameters->cblockw_init = 32;
+        parameters->cblockh_init = 32;
+    }
+
+    /* One tile part for each component */
+    parameters->tp_flag = 'C';
+    parameters->tp_on = 1;
+
+    if (parameters->prog_order == OPJ_COMP_PARAM_DEFAULT_PROG_ORDER) {
+        parameters->prog_order = OPJ_CPRL;
+    }
+
+    if (profile == OPJ_PROFILE_IMF_2K ||
+            profile == OPJ_PROFILE_IMF_4K ||
+            profile == OPJ_PROFILE_IMF_8K) {
+        /* 9-7 transform */
+        parameters->irreversible = 1;
+    }
+
+    /* Adjust the number of resolutions if set to its defaults */
+    if (parameters->numresolution == OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION &&
+            image->x0 == 0 &&
+            image->y0 == 0) {
+        const int max_NL = opj_j2k_get_imf_max_NL(parameters, image);
+        if (max_NL >= 0 && parameters->numresolution > max_NL) {
+            parameters->numresolution = max_NL + 1;
+        }
+
+        /* Note: below is generic logic */
+        if (!parameters->tile_size_on) {
+            while (parameters->numresolution > 0) {
+                if (image->x1 < (1U << ((OPJ_UINT32)parameters->numresolution - 1U))) {
+                    parameters->numresolution --;
+                    continue;
+                }
+                if (image->y1 < (1U << ((OPJ_UINT32)parameters->numresolution - 1U))) {
+                    parameters->numresolution --;
+                    continue;
+                }
+                break;
+            }
+        }
+    }
+
+    /* Set defaults precincts */
+    if (parameters->csty == 0) {
+        parameters->csty |= J2K_CP_CSTY_PRT;
+        if (parameters->numresolution == 1) {
+            parameters->res_spec = 1;
+            parameters->prcw_init[0] = 128;
+            parameters->prch_init[0] = 128;
+        } else {
+            int i;
+            parameters->res_spec = parameters->numresolution - 1;
+            for (i = 0; i < parameters->res_spec; i++) {
+                parameters->prcw_init[i] = 256;
+                parameters->prch_init[i] = 256;
+            }
+        }
+    }
+}
+
+/* Table A.53 from JPEG2000 standard */
+static const OPJ_UINT16 tabMaxSubLevelFromMainLevel[] = {
+    15, /* unspecified */
+    1,
+    1,
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9
+};
+
+static OPJ_BOOL opj_j2k_is_imf_compliant(opj_cparameters_t *parameters,
+        opj_image_t *image,
+        opj_event_mgr_t *p_manager)
+{
+    OPJ_UINT32 i;
+    const OPJ_UINT16 rsiz = parameters->rsiz;
+    const OPJ_UINT16 profile = OPJ_GET_IMF_PROFILE(rsiz);
+    const OPJ_UINT16 mainlevel = OPJ_GET_IMF_MAINLEVEL(rsiz);
+    const OPJ_UINT16 sublevel = OPJ_GET_IMF_SUBLEVEL(rsiz);
+    const int NL = parameters->numresolution - 1;
+    const OPJ_UINT32 XTsiz = parameters->tile_size_on ? (OPJ_UINT32)
+                             parameters->cp_tdx : image->x1;
+    OPJ_BOOL ret = OPJ_TRUE;
+
+    /* Validate mainlevel */
+    if (mainlevel > OPJ_IMF_MAINLEVEL_MAX) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile require mainlevel <= 11.\n"
+                      "-> %d is thus not compliant\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      mainlevel);
+        ret = OPJ_FALSE;
+    }
+
+    /* Validate sublevel */
+    assert(sizeof(tabMaxSubLevelFromMainLevel) ==
+           (OPJ_IMF_MAINLEVEL_MAX + 1) * sizeof(tabMaxSubLevelFromMainLevel[0]));
+    if (sublevel > tabMaxSubLevelFromMainLevel[mainlevel]) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile require sublevel <= %d for mainlevel = %d.\n"
+                      "-> %d is thus not compliant\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      tabMaxSubLevelFromMainLevel[mainlevel],
+                      mainlevel,
+                      sublevel);
+        ret = OPJ_FALSE;
+    }
+
+    /* Number of components */
+    if (image->numcomps > 3) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profiles require at most 3 components.\n"
+                      "-> Number of components of input image (%d) is not compliant\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      image->numcomps);
+        ret = OPJ_FALSE;
+    }
+
+    if (image->x0 != 0 || image->y0 != 0) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profiles require image origin to be at 0,0.\n"
+                      "-> %d,%d is not compliant\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      image->x0, image->y0 != 0);
+        ret = OPJ_FALSE;
+    }
+
+    if (parameters->cp_tx0 != 0 || parameters->cp_ty0 != 0) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profiles require tile origin to be at 0,0.\n"
+                      "-> %d,%d is not compliant\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      parameters->cp_tx0, parameters->cp_ty0);
+        ret = OPJ_FALSE;
+    }
+
+    if (parameters->tile_size_on) {
+        if (profile == OPJ_PROFILE_IMF_2K ||
+                profile == OPJ_PROFILE_IMF_4K ||
+                profile == OPJ_PROFILE_IMF_8K) {
+            if ((OPJ_UINT32)parameters->cp_tdx < image->x1 ||
+                    (OPJ_UINT32)parameters->cp_tdy < image->y1) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 2K/4K/8K single tile profiles require tile to be greater or equal to image size.\n"
+                              "-> %d,%d is lesser than %d,%d\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              parameters->cp_tdx,
+                              parameters->cp_tdy,
+                              image->x1,
+                              image->y1);
+                ret = OPJ_FALSE;
+            }
+        } else {
+            if ((OPJ_UINT32)parameters->cp_tdx >= image->x1 &&
+                    (OPJ_UINT32)parameters->cp_tdy >= image->y1) {
+                /* ok */
+            } else if (parameters->cp_tdx == 1024 &&
+                       parameters->cp_tdy == 1024) {
+                /* ok */
+            } else if (parameters->cp_tdx == 2048 &&
+                       parameters->cp_tdy == 2048 &&
+                       (profile == OPJ_PROFILE_IMF_4K ||
+                        profile == OPJ_PROFILE_IMF_8K)) {
+                /* ok */
+            } else if (parameters->cp_tdx == 4096 &&
+                       parameters->cp_tdy == 4096 &&
+                       profile == OPJ_PROFILE_IMF_8K) {
+                /* ok */
+            } else {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 2K_R/4K_R/8K_R single/multiple tile profiles "
+                              "require tile to be greater or equal to image size,\n"
+                              "or to be (1024,1024), or (2048,2048) for 4K_R/8K_R "
+                              "or (4096,4096) for 8K_R.\n"
+                              "-> %d,%d is non conformant\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              parameters->cp_tdx,
+                              parameters->cp_tdy);
+                ret = OPJ_FALSE;
+            }
+        }
+    }
+
+    /* Bitdepth */
+    for (i = 0; i < image->numcomps; i++) {
+        if (!(image->comps[i].bpp >= 8 && image->comps[i].bpp <= 16) ||
+                (image->comps[i].sgnd)) {
+            char signed_str[] = "signed";
+            char unsigned_str[] = "unsigned";
+            char *tmp_str = image->comps[i].sgnd ? signed_str : unsigned_str;
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF profiles require precision of each component to b in [8-16] bits unsigned"
+                          "-> At least component %d of input image (%d bits, %s) is not compliant\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          i, image->comps[i].bpp, tmp_str);
+            ret = OPJ_FALSE;
+        }
+    }
+
+    /* Sub-sampling */
+    for (i = 0; i < image->numcomps; i++) {
+        if (i == 0 && image->comps[i].dx != 1) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF profiles require XRSiz1 == 1. Here it is set to %d.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          image->comps[i].dx);
+            ret = OPJ_FALSE;
+        }
+        if (i == 1 && image->comps[i].dx != 1 && image->comps[i].dx != 2) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF profiles require XRSiz2 == 1 or 2. Here it is set to %d.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          image->comps[i].dx);
+            ret = OPJ_FALSE;
+        }
+        if (i > 1 && image->comps[i].dx != image->comps[i - 1].dx) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF profiles require XRSiz%d to be the same as XRSiz2. "
+                          "Here it is set to %d instead of %d.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          i + 1, image->comps[i].dx, image->comps[i - 1].dx);
+            ret = OPJ_FALSE;
+        }
+        if (image->comps[i].dy != 1) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF profiles require YRsiz == 1. "
+                          "Here it is set to %d for component i.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          image->comps[i].dy, i);
+            ret = OPJ_FALSE;
+        }
+    }
+
+    /* Image size */
+    switch (profile) {
+    case OPJ_PROFILE_IMF_2K:
+    case OPJ_PROFILE_IMF_2K_R:
+        if (((image->comps[0].w > 2048) | (image->comps[0].h > 1556))) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 2K/2K_R profile require:\n"
+                          "width <= 2048 and height <= 1556\n"
+                          "-> Input image size %d x %d is not compliant\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          image->comps[0].w, image->comps[0].h);
+            ret = OPJ_FALSE;
+        }
+        break;
+    case OPJ_PROFILE_IMF_4K:
+    case OPJ_PROFILE_IMF_4K_R:
+        if (((image->comps[0].w > 4096) | (image->comps[0].h > 3112))) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 4K/4K_R profile require:\n"
+                          "width <= 4096 and height <= 3112\n"
+                          "-> Input image size %d x %d is not compliant\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          image->comps[0].w, image->comps[0].h);
+            ret = OPJ_FALSE;
+        }
+        break;
+    case OPJ_PROFILE_IMF_8K:
+    case OPJ_PROFILE_IMF_8K_R:
+        if (((image->comps[0].w > 8192) | (image->comps[0].h > 6224))) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 8K/8K_R profile require:\n"
+                          "width <= 8192 and height <= 6224\n"
+                          "-> Input image size %d x %d is not compliant\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          image->comps[0].w, image->comps[0].h);
+            ret = OPJ_FALSE;
+        }
+        break;
+    default :
+        assert(0);
+        return OPJ_FALSE;
+    }
+
+    if (parameters->roi_compno != -1) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile forbid RGN / region of interest marker.\n"
+                      "-> Compression parameters specify a ROI\n"
+                      "-> Non-IMF codestream will be generated\n");
+        ret = OPJ_FALSE;
+    }
+
+    if (parameters->cblockw_init != 32 || parameters->cblockh_init != 32) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile require code block size to be 32x32.\n"
+                      "-> Compression parameters set it to %dx%d.\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      parameters->cblockw_init,
+                      parameters->cblockh_init);
+        ret = OPJ_FALSE;
+    }
+
+    if (parameters->prog_order != OPJ_CPRL) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile require progression order to be CPRL.\n"
+                      "-> Compression parameters set it to %d.\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      parameters->prog_order);
+        ret = OPJ_FALSE;
+    }
+
+    if (parameters->numpocs != 0) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile forbid POC markers.\n"
+                      "-> Compression parameters set %d POC.\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      parameters->numpocs);
+        ret = OPJ_FALSE;
+    }
+
+    /* Codeblock style: no mode switch enabled */
+    if (parameters->mode != 0) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF profile forbid mode switch in code block style.\n"
+                      "-> Compression parameters set code block style to %d.\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      parameters->mode);
+        ret = OPJ_FALSE;
+    }
+
+    if (profile == OPJ_PROFILE_IMF_2K ||
+            profile == OPJ_PROFILE_IMF_4K ||
+            profile == OPJ_PROFILE_IMF_8K) {
+        /* Expect 9-7 transform */
+        if (parameters->irreversible != 1) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 2K/4K/8K profiles require 9-7 Irreversible Transform.\n"
+                          "-> Compression parameters set it to reversible.\n"
+                          "-> Non-IMF codestream will be generated\n");
+            ret = OPJ_FALSE;
+        }
+    } else {
+        /* Expect 5-3 transform */
+        if (parameters->irreversible != 0) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 2K/4K/8K profiles require 5-3 reversible Transform.\n"
+                          "-> Compression parameters set it to irreversible.\n"
+                          "-> Non-IMF codestream will be generated\n");
+            ret = OPJ_FALSE;
+        }
+    }
+
+    /* Number of layers */
+    if (parameters->tcp_numlayers != 1) {
+        opj_event_msg(p_manager, EVT_WARNING,
+                      "IMF 2K/4K/8K profiles require 1 single quality layer.\n"
+                      "-> Number of layers is %d.\n"
+                      "-> Non-IMF codestream will be generated\n",
+                      parameters->tcp_numlayers);
+        ret = OPJ_FALSE;
+    }
+
+    /* Decomposition levels */
+    switch (profile) {
+    case OPJ_PROFILE_IMF_2K:
+        if (!(NL >= 1 && NL <= 5)) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 2K profile requires 1 <= NL <= 5:\n"
+                          "-> Number of decomposition levels is %d.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          NL);
+            ret = OPJ_FALSE;
+        }
+        break;
+    case OPJ_PROFILE_IMF_4K:
+        if (!(NL >= 1 && NL <= 6)) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 4K profile requires 1 <= NL <= 6:\n"
+                          "-> Number of decomposition levels is %d.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          NL);
+            ret = OPJ_FALSE;
+        }
+        break;
+    case OPJ_PROFILE_IMF_8K:
+        if (!(NL >= 1 && NL <= 7)) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF 8K profile requires 1 <= NL <= 7:\n"
+                          "-> Number of decomposition levels is %d.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          NL);
+            ret = OPJ_FALSE;
+        }
+        break;
+    case OPJ_PROFILE_IMF_2K_R: {
+        if (XTsiz >= 2048) {
+            if (!(NL >= 1 && NL <= 5)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 2K_R profile requires 1 <= NL <= 5 for XTsiz >= 2048:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        } else if (XTsiz >= 1024) {
+            if (!(NL >= 1 && NL <= 4)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 2K_R profile requires 1 <= NL <= 4 for XTsiz in [1024,2048[:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        }
+        break;
+    }
+    case OPJ_PROFILE_IMF_4K_R: {
+        if (XTsiz >= 4096) {
+            if (!(NL >= 1 && NL <= 6)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 6 for XTsiz >= 4096:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        } else if (XTsiz >= 2048) {
+            if (!(NL >= 1 && NL <= 5)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 5 for XTsiz in [2048,4096[:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        } else if (XTsiz >= 1024) {
+            if (!(NL >= 1 && NL <= 4)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 4 for XTsiz in [1024,2048[:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        }
+        break;
+    }
+    case OPJ_PROFILE_IMF_8K_R: {
+        if (XTsiz >= 8192) {
+            if (!(NL >= 1 && NL <= 7)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 7 for XTsiz >= 8192:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        } else if (XTsiz >= 4096) {
+            if (!(NL >= 1 && NL <= 6)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 6 for XTsiz in [4096,8192[:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        } else if (XTsiz >= 2048) {
+            if (!(NL >= 1 && NL <= 5)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 5 for XTsiz in [2048,4096[:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        } else if (XTsiz >= 1024) {
+            if (!(NL >= 1 && NL <= 4)) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF 4K_R profile requires 1 <= NL <= 4 for XTsiz in [1024,2048[:\n"
+                              "-> Number of decomposition levels is %d.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        }
+        break;
+    }
+    default:
+        break;
+    }
+
+    if (parameters->numresolution == 1) {
+        if (parameters->res_spec != 1 ||
+                parameters->prcw_init[0] != 128 ||
+                parameters->prch_init[0] != 128) {
+            opj_event_msg(p_manager, EVT_WARNING,
+                          "IMF profiles require PPx = PPy = 7 for NLLL band, else 8.\n"
+                          "-> Supplied values are different from that.\n"
+                          "-> Non-IMF codestream will be generated\n",
+                          NL);
+            ret = OPJ_FALSE;
+        }
+    } else {
+        int i;
+        for (i = 0; i < parameters->res_spec; i++) {
+            if (parameters->prcw_init[i] != 256 ||
+                    parameters->prch_init[i] != 256) {
+                opj_event_msg(p_manager, EVT_WARNING,
+                              "IMF profiles require PPx = PPy = 7 for NLLL band, else 8.\n"
+                              "-> Supplied values are different from that.\n"
+                              "-> Non-IMF codestream will be generated\n",
+                              NL);
+                ret = OPJ_FALSE;
+            }
+        }
+    }
+
+    return ret;
+}
+
+
 OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
                                opj_cparameters_t *parameters,
                                opj_image_t *image,
@@ -6935,6 +7685,15 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
     } else {
         OPJ_FLOAT32 temp_rate;
         OPJ_BOOL cap = OPJ_FALSE;
+
+        if (OPJ_IS_IMF(parameters->rsiz) && parameters->max_cs_size > 0 &&
+                parameters->tcp_numlayers == 1 && parameters->tcp_rates[0] == 0) {
+            parameters->tcp_rates[0] = (OPJ_FLOAT32)(image->numcomps * image->comps[0].w *
+                                       image->comps[0].h * image->comps[0].prec) /
+                                       (OPJ_FLOAT32)(((OPJ_UINT32)parameters->max_cs_size) * 8 * image->comps[0].dx *
+                                               image->comps[0].dy);
+        }
+
         temp_rate = (OPJ_FLOAT32)(((double)image->numcomps * image->comps[0].w *
                                    image->comps[0].h * image->comps[0].prec) /
                                   (((double)parameters->max_cs_size) * 8 * image->comps[0].dx *
@@ -6975,9 +7734,10 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
                       "JPEG 2000 Broadcast profiles not yet supported\n");
         parameters->rsiz = OPJ_PROFILE_NONE;
     } else if (OPJ_IS_IMF(parameters->rsiz)) {
-        opj_event_msg(p_manager, EVT_WARNING,
-                      "JPEG 2000 IMF profiles not yet supported\n");
-        parameters->rsiz = OPJ_PROFILE_NONE;
+        opj_j2k_set_imf_parameters(parameters, image, p_manager);
+        if (!opj_j2k_is_imf_compliant(parameters, image, p_manager)) {
+            parameters->rsiz = OPJ_PROFILE_NONE;
+        }
     } else if (OPJ_IS_PART2(parameters->rsiz)) {
         if (parameters->rsiz == ((OPJ_PROFILE_PART2) | (OPJ_EXTENSION_NONE))) {
             opj_event_msg(p_manager, EVT_WARNING,
@@ -7153,7 +7913,7 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
         tcp->numlayers = (OPJ_UINT32)parameters->tcp_numlayers;
 
         for (j = 0; j < tcp->numlayers; j++) {
-            if (OPJ_IS_CINEMA(cp->rsiz)) {
+            if (OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)) {
                 if (cp->m_specific_param.m_enc.m_fixed_quality) {
                     tcp->distoratio[j] = parameters->tcp_distoratio[j];
                 }
@@ -9227,6 +9987,14 @@ static OPJ_BOOL opj_j2k_update_image_dimensions(opj_image_t* p_image,
     l_img_comp = p_image->comps;
     for (it_comp = 0; it_comp < p_image->numcomps; ++it_comp) {
         OPJ_INT32 l_h, l_w;
+        if (p_image->x0 > (OPJ_UINT32)INT_MAX ||
+                p_image->y0 > (OPJ_UINT32)INT_MAX ||
+                p_image->x1 > (OPJ_UINT32)INT_MAX ||
+                p_image->y1 > (OPJ_UINT32)INT_MAX) {
+            opj_event_msg(p_manager, EVT_ERROR,
+                          "Image coordinates above INT_MAX are not supported\n");
+            return OPJ_FALSE;
+        }
 
         l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0,
                          (OPJ_INT32)l_img_comp->dx);
@@ -11227,6 +11995,42 @@ OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k,
     return OPJ_FALSE;
 }
 
+/* ----------------------------------------------------------------------- */
+
+OPJ_BOOL opj_j2k_encoder_set_extra_options(
+    opj_j2k_t *p_j2k,
+    const char* const* p_options,
+    opj_event_mgr_t * p_manager)
+{
+    const char* const* p_option_iter;
+
+    if (p_options == NULL) {
+        return OPJ_TRUE;
+    }
+
+    for (p_option_iter = p_options; *p_option_iter != NULL; ++p_option_iter) {
+        if (strncmp(*p_option_iter, "PLT=", 4) == 0) {
+            if (strcmp(*p_option_iter, "PLT=YES") == 0) {
+                p_j2k->m_specific_param.m_encoder.m_PLT = OPJ_TRUE;
+            } else if (strcmp(*p_option_iter, "PLT=NO") == 0) {
+                p_j2k->m_specific_param.m_encoder.m_PLT = OPJ_FALSE;
+            } else {
+                opj_event_msg(p_manager, EVT_ERROR,
+                              "Invalid value for option: %s.\n", *p_option_iter);
+                return OPJ_FALSE;
+            }
+        } else {
+            opj_event_msg(p_manager, EVT_ERROR,
+                          "Invalid option: %s.\n", *p_option_iter);
+            return OPJ_FALSE;
+        }
+    }
+
+    return OPJ_TRUE;
+}
+
+/* ----------------------------------------------------------------------- */
+
 OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
                         opj_stream_private_t *p_stream,
                         opj_event_mgr_t * p_manager)
@@ -11284,7 +12088,7 @@ OPJ_BOOL opj_j2k_encode(opj_j2k_t * p_j2k,
                 }
             }
         }
-        l_current_tile_size = opj_tcd_get_encoded_tile_size(p_j2k->m_tcd);
+        l_current_tile_size = opj_tcd_get_encoder_input_buffer_size(p_j2k->m_tcd);
         if (!l_reuse_data) {
             if (l_current_tile_size > l_max_tile_size) {
                 OPJ_BYTE *l_new_current_data = (OPJ_BYTE *) opj_realloc(l_current_data,
@@ -11612,7 +12416,7 @@ static OPJ_BOOL opj_j2k_setup_end_compress(opj_j2k_t *p_j2k,
         return OPJ_FALSE;
     }
 
-    if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) {
+    if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz) || OPJ_IS_IMF(p_j2k->m_cp.rsiz)) {
         if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,
                                                (opj_procedure)opj_j2k_write_updated_tlm, p_manager)) {
             return OPJ_FALSE;
@@ -11695,7 +12499,7 @@ static OPJ_BOOL opj_j2k_setup_header_writing(opj_j2k_t *p_j2k,
         return OPJ_FALSE;
     }
 
-    if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz)) {
+    if (OPJ_IS_CINEMA(p_j2k->m_cp.rsiz) || OPJ_IS_IMF(p_j2k->m_cp.rsiz)) {
         if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,
                                                (opj_procedure)opj_j2k_write_tlm, p_manager)) {
             return OPJ_FALSE;
@@ -11722,7 +12526,8 @@ static OPJ_BOOL opj_j2k_setup_header_writing(opj_j2k_t *p_j2k,
     }
 
     /* DEVELOPER CORNER, insert your custom procedures */
-    if (p_j2k->m_cp.rsiz & OPJ_EXTENSION_MCT) {
+    if ((p_j2k->m_cp.rsiz & (OPJ_PROFILE_PART2 | OPJ_EXTENSION_MCT)) ==
+            (OPJ_PROFILE_PART2 | OPJ_EXTENSION_MCT)) {
         if (! opj_procedure_list_add_procedure(p_j2k->m_procedure_list,
                                                (opj_procedure)opj_j2k_write_mct_data_group, p_manager)) {
             return OPJ_FALSE;
@@ -11827,7 +12632,7 @@ static OPJ_BOOL opj_j2k_write_first_tile_part(opj_j2k_t *p_j2k,
     opj_write_bytes(l_begin_data + 6, l_nb_bytes_written,
                     4);                                 /* PSOT */
 
-    if (OPJ_IS_CINEMA(l_cp->rsiz)) {
+    if (OPJ_IS_CINEMA(l_cp->rsiz) || OPJ_IS_IMF(l_cp->rsiz)) {
         opj_j2k_update_tlm(p_j2k, l_nb_bytes_written);
     }
 
@@ -11897,7 +12702,7 @@ static OPJ_BOOL opj_j2k_write_all_tile_parts(opj_j2k_t *p_j2k,
         opj_write_bytes(l_begin_data + 6, l_part_tile_size,
                         4);                                   /* PSOT */
 
-        if (OPJ_IS_CINEMA(l_cp->rsiz)) {
+        if (OPJ_IS_CINEMA(l_cp->rsiz) || OPJ_IS_IMF(l_cp->rsiz)) {
             opj_j2k_update_tlm(p_j2k, l_part_tile_size);
         }
 
@@ -11943,7 +12748,7 @@ static OPJ_BOOL opj_j2k_write_all_tile_parts(opj_j2k_t *p_j2k,
             opj_write_bytes(l_begin_data + 6, l_part_tile_size,
                             4);                                   /* PSOT */
 
-            if (OPJ_IS_CINEMA(l_cp->rsiz)) {
+            if (OPJ_IS_CINEMA(l_cp->rsiz) || OPJ_IS_IMF(l_cp->rsiz)) {
                 opj_j2k_update_tlm(p_j2k, l_part_tile_size);
             }
 
index 5d393c98130f27af8ee128175e504e580e4e4e13..9eb50b50da6977500a95d7a64d20b675c1754b50 100644 (file)
@@ -531,8 +531,14 @@ typedef struct opj_j2k_enc {
     OPJ_BYTE * m_header_tile_data;
 
     /* size of the encoded_data */
+
     OPJ_UINT32 m_header_tile_data_size;
 
+    /* whether to generate PLT markers */
+    OPJ_BOOL   m_PLT;
+
+    /* reserved bytes in m_encoded_tile_size for PLT markers */
+    OPJ_UINT32 m_reserved_bytes_for_PLT;
 
 } opj_j2k_enc_t;
 
@@ -577,15 +583,16 @@ typedef struct opj_j2k {
     /** 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;
 
+    /** Image width coming from JP2 IHDR box. 0 from a pure codestream */
     OPJ_UINT32 ihdr_w;
+
+    /** Image height coming from JP2 IHDR box. 0 from a pure codestream */
     OPJ_UINT32 ihdr_h;
-    OPJ_UINT32 enumcs;
+
+    /** Set to 1 by the decoder initialization if OPJ_DPARAMETERS_DUMP_FLAG is set */
     unsigned int dump_state;
 }
 opj_j2k_t;
@@ -827,6 +834,19 @@ OPJ_BOOL opj_j2k_set_decoded_resolution_factor(opj_j2k_t *p_j2k,
         OPJ_UINT32 res_factor,
         opj_event_mgr_t * p_manager);
 
+/**
+ * Specify extra options for the encoder.
+ *
+ * @param  p_j2k        the jpeg2000 codec.
+ * @param  p_options    options
+ * @param  p_manager    the user event manager
+ *
+ * @see opj_encoder_set_extra_options() for more details.
+ */
+OPJ_BOOL opj_j2k_encoder_set_extra_options(
+    opj_j2k_t *p_j2k,
+    const char* const* p_options,
+    opj_event_mgr_t * p_manager);
 
 /**
  * Writes a tile.
index 4402ffe3c51ee347d3a0ef04a54dc89846859fd8..4809e3488c12a574afea6f25c6f4a8fdec9febe5 100644 (file)
@@ -1584,9 +1584,7 @@ static OPJ_BOOL opj_jp2_read_colr(opj_jp2_t *jp2,
                       "COLR BOX meth value is not a regular value (%d), "
                       "so we will ignore the entire Colour Specification box. \n", jp2->meth);
     }
-    if (jp2->color.jp2_has_colr) {
-        jp2->j2k->enumcs = jp2->enumcs;
-    }
+
     return OPJ_TRUE;
 }
 
@@ -3236,6 +3234,18 @@ OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
     return opj_j2k_set_decoded_resolution_factor(p_jp2->j2k, res_factor, p_manager);
 }
 
+/* ----------------------------------------------------------------------- */
+
+OPJ_BOOL opj_jp2_encoder_set_extra_options(
+    opj_jp2_t *p_jp2,
+    const char* const* p_options,
+    opj_event_mgr_t * p_manager)
+{
+    return opj_j2k_encoder_set_extra_options(p_jp2->j2k, p_options, p_manager);
+}
+
+/* ----------------------------------------------------------------------- */
+
 /* JPIP specific */
 
 #ifdef USE_JPIP
index 34abd5118e3740a02c5692ee92aba3f1a7004431..9e7fa56674cd45d8133518b2b6ebffb0e0a7b348 100644 (file)
@@ -459,6 +459,20 @@ OPJ_BOOL opj_jp2_set_decoded_resolution_factor(opj_jp2_t *p_jp2,
         OPJ_UINT32 res_factor,
         opj_event_mgr_t * p_manager);
 
+/**
+ * Specify extra options for the encoder.
+ *
+ * @param  p_jp2        the jpeg2000 codec.
+ * @param  p_options    options
+ * @param  p_manager    the user event manager
+ *
+ * @see opj_encoder_set_extra_options() for more details.
+ */
+OPJ_BOOL opj_jp2_encoder_set_extra_options(
+    opj_jp2_t *p_jp2,
+    const char* const* p_options,
+    opj_event_mgr_t * p_manager);
+
 
 /* TODO MSD: clean these 3 functions */
 /**
index b79d4b87c49b338e2a42c378c785b1b83a55f105..08bc811510d0a65e5db39fe40c1bc1af10e10a88 100644 (file)
@@ -183,7 +183,7 @@ void opj_mct_decode(
     OPJ_INT32* OPJ_RESTRICT c2,
     OPJ_SIZE_T n)
 {
-    OPJ_UINT32 i;
+    OPJ_SIZE_T i;
     for (i = 0; i < n; ++i) {
         OPJ_INT32 y = c0[i];
         OPJ_INT32 u = c1[i];
@@ -361,7 +361,7 @@ void opj_mct_encode_real(
     OPJ_INT32* OPJ_RESTRICT c2,
     OPJ_SIZE_T n)
 {
-    OPJ_UINT32 i;
+    OPJ_SIZE_T i;
     for (i = 0; i < n; ++i) {
         OPJ_INT32 r = c0[i];
         OPJ_INT32 g = c1[i];
@@ -388,7 +388,7 @@ void opj_mct_decode_real(
     OPJ_FLOAT32* OPJ_RESTRICT c2,
     OPJ_SIZE_T n)
 {
-    OPJ_UINT32 i;
+    OPJ_SIZE_T i;
 #ifdef __SSE__
     __m128 vrv, vgu, vgv, vbu;
     vrv = _mm_set1_ps(1.402f);
index 7b12303423b7ad79cf50b6f259a682dcdab25bb4..1e2d60a6a25acf3b35c0505d7605517c951d0d91 100644 (file)
@@ -652,6 +652,11 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
                 struct opj_image *,
                 struct opj_event_mgr *)) opj_j2k_setup_encoder;
 
+        l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options = (OPJ_BOOL(
+                    *)(void *,
+                       const char* const*,
+                       struct opj_event_mgr *)) opj_j2k_encoder_set_extra_options;
+
         l_codec->m_codec = opj_j2k_create_compress();
         if (! l_codec->m_codec) {
             opj_free(l_codec);
@@ -690,6 +695,11 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
                 struct opj_image *,
                 struct opj_event_mgr *)) opj_jp2_setup_encoder;
 
+        l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options = (OPJ_BOOL(
+                    *)(void *,
+                       const char* const*,
+                       struct opj_event_mgr *)) opj_jp2_encoder_set_extra_options;
+
         l_codec->m_codec = opj_jp2_create(OPJ_FALSE);
         if (! l_codec->m_codec) {
             opj_free(l_codec);
@@ -718,11 +728,11 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t
         parameters->cp_cinema = OPJ_OFF; /* DEPRECATED */
         parameters->rsiz = OPJ_PROFILE_NONE;
         parameters->max_comp_size = 0;
-        parameters->numresolution = 6;
+        parameters->numresolution = OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION;
         parameters->cp_rsiz = OPJ_STD_RSIZ; /* DEPRECATED */
-        parameters->cblockw_init = 64;
-        parameters->cblockh_init = 64;
-        parameters->prog_order = OPJ_LRCP;
+        parameters->cblockw_init = OPJ_COMP_PARAM_DEFAULT_CBLOCKW;
+        parameters->cblockh_init = OPJ_COMP_PARAM_DEFAULT_CBLOCKH;
+        parameters->prog_order = OPJ_COMP_PARAM_DEFAULT_PROG_ORDER;
         parameters->roi_compno = -1;        /* no ROI */
         parameters->subsampling_dx = 1;
         parameters->subsampling_dy = 1;
@@ -788,6 +798,27 @@ OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
     return OPJ_FALSE;
 }
 
+/* ----------------------------------------------------------------------- */
+
+OPJ_BOOL OPJ_CALLCONV opj_encoder_set_extra_options(opj_codec_t *p_codec,
+        const char* const* options)
+{
+    if (p_codec) {
+        opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
+
+        if (! l_codec->is_decompressor) {
+            return l_codec->m_codec_data.m_compression.opj_encoder_set_extra_options(
+                       l_codec->m_codec,
+                       options,
+                       &(l_codec->m_event_mgr));
+        }
+    }
+
+    return OPJ_FALSE;
+}
+
+/* ----------------------------------------------------------------------- */
+
 OPJ_BOOL OPJ_CALLCONV opj_start_compress(opj_codec_t *p_codec,
         opj_image_t * p_image,
         opj_stream_t *p_stream)
index dc1e206fded39be5db4016b36bc15d985d72ad63..da84f399b5d8eb6cc99f597eb78605f49a9cc330 100644 (file)
@@ -204,11 +204,11 @@ typedef size_t   OPJ_SIZE_T;
 #define OPJ_PROFILE_BC_MULTI    0x0200 /** Multi Tile Broadcast profile defined in 15444-1 AMD3 */
 #define OPJ_PROFILE_BC_MULTI_R  0x0300 /** Multi Tile Reversible Broadcast profile defined in 15444-1 AMD3 */
 #define OPJ_PROFILE_IMF_2K      0x0400 /** 2K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
-#define OPJ_PROFILE_IMF_4K      0x0401 /** 4K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
-#define OPJ_PROFILE_IMF_8K      0x0402 /** 8K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
-#define OPJ_PROFILE_IMF_2K_R    0x0403 /** 2K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
+#define OPJ_PROFILE_IMF_4K      0x0500 /** 4K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
+#define OPJ_PROFILE_IMF_8K      0x0600 /** 8K Single Tile Lossy IMF profile defined in 15444-1 AMD 8 */
+#define OPJ_PROFILE_IMF_2K_R    0x0700 /** 2K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
 #define OPJ_PROFILE_IMF_4K_R    0x0800 /** 4K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
-#define OPJ_PROFILE_IMF_8K_R    0x0801  /** 8K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
+#define OPJ_PROFILE_IMF_8K_R    0x0900 /** 8K Single/Multi Tile Reversible IMF profile defined in 15444-1 AMD 8 */
 
 /**
  * JPEG 2000 Part-2 extensions
@@ -225,6 +225,36 @@ typedef size_t   OPJ_SIZE_T;
 #define OPJ_IS_IMF(v)        (((v) >= OPJ_PROFILE_IMF_2K)&&((v) <= ((OPJ_PROFILE_IMF_8K_R) | (0x009b))))
 #define OPJ_IS_PART2(v)      ((v) & OPJ_PROFILE_PART2)
 
+#define OPJ_GET_IMF_PROFILE(v)   ((v) & 0xff00)      /** Extract IMF profile without mainlevel/sublevel */
+#define OPJ_GET_IMF_MAINLEVEL(v) ((v) & 0xf)         /** Extract IMF main level */
+#define OPJ_GET_IMF_SUBLEVEL(v)  (((v) >> 4) & 0xf)  /** Extract IMF sub level */
+
+#define OPJ_IMF_MAINLEVEL_MAX    11   /** Maximum main level */
+
+/** Max. Components Sampling Rate (MSamples/sec) per IMF main level */
+#define OPJ_IMF_MAINLEVEL_1_MSAMPLESEC   65      /** MSamples/sec for IMF main level 1 */
+#define OPJ_IMF_MAINLEVEL_2_MSAMPLESEC   130     /** MSamples/sec for IMF main level 2 */
+#define OPJ_IMF_MAINLEVEL_3_MSAMPLESEC   195     /** MSamples/sec for IMF main level 3 */
+#define OPJ_IMF_MAINLEVEL_4_MSAMPLESEC   260     /** MSamples/sec for IMF main level 4 */
+#define OPJ_IMF_MAINLEVEL_5_MSAMPLESEC   520     /** MSamples/sec for IMF main level 5 */
+#define OPJ_IMF_MAINLEVEL_6_MSAMPLESEC   1200    /** MSamples/sec for IMF main level 6 */
+#define OPJ_IMF_MAINLEVEL_7_MSAMPLESEC   2400    /** MSamples/sec for IMF main level 7 */
+#define OPJ_IMF_MAINLEVEL_8_MSAMPLESEC   4800    /** MSamples/sec for IMF main level 8 */
+#define OPJ_IMF_MAINLEVEL_9_MSAMPLESEC   9600    /** MSamples/sec for IMF main level 9 */
+#define OPJ_IMF_MAINLEVEL_10_MSAMPLESEC  19200   /** MSamples/sec for IMF main level 10 */
+#define OPJ_IMF_MAINLEVEL_11_MSAMPLESEC  38400   /** MSamples/sec for IMF main level 11 */
+
+/** Max. compressed Bit Rate (Mbits/s) per IMF sub level */
+#define OPJ_IMF_SUBLEVEL_1_MBITSSEC      200     /** Mbits/s for IMF sub level 1 */
+#define OPJ_IMF_SUBLEVEL_2_MBITSSEC      400     /** Mbits/s for IMF sub level 2 */
+#define OPJ_IMF_SUBLEVEL_3_MBITSSEC      800     /** Mbits/s for IMF sub level 3 */
+#define OPJ_IMF_SUBLEVEL_4_MBITSSEC     1600     /** Mbits/s for IMF sub level 4 */
+#define OPJ_IMF_SUBLEVEL_5_MBITSSEC     3200     /** Mbits/s for IMF sub level 5 */
+#define OPJ_IMF_SUBLEVEL_6_MBITSSEC     6400     /** Mbits/s for IMF sub level 6 */
+#define OPJ_IMF_SUBLEVEL_7_MBITSSEC    12800     /** Mbits/s for IMF sub level 7 */
+#define OPJ_IMF_SUBLEVEL_8_MBITSSEC    25600     /** Mbits/s for IMF sub level 8 */
+#define OPJ_IMF_SUBLEVEL_9_MBITSSEC    51200     /** Mbits/s for IMF sub level 9 */
+
 /**
  * JPEG 2000 codestream and component size limits in cinema profiles
  * */
@@ -318,6 +348,10 @@ typedef void (*opj_msg_callback)(const char *msg, void *client_data);
 ==========================================================
 */
 
+#ifndef OPJ_UINT32_SEMANTICALLY_BUT_INT32
+#define OPJ_UINT32_SEMANTICALLY_BUT_INT32 OPJ_INT32
+#endif
+
 /**
  * Progression order changes
  *
@@ -336,7 +370,7 @@ typedef struct opj_poc {
     /** Tile number (starting at 1) */
     OPJ_UINT32 tile;
     /** Start and end values for Tile width and height*/
-    OPJ_INT32 tx0, tx1, ty0, ty1;
+    OPJ_UINT32_SEMANTICALLY_BUT_INT32 tx0, tx1, ty0, ty1;
     /** Start value, initialised in pi_initialise_encode*/
     OPJ_UINT32 layS, resS, compS, prcS;
     /** End value, initialised in pi_initialise_encode */
@@ -1546,6 +1580,33 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_codec,
         opj_cparameters_t *parameters,
         opj_image_t *image);
 
+
+/**
+ * Specify extra options for the encoder.
+ *
+ * This may be called after opj_setup_encoder() and before opj_start_compress()
+ *
+ * This is the way to add new options in a fully ABI compatible way, without
+ * extending the opj_cparameters_t structure.
+ *
+ * Currently supported options are:
+ * <ul>
+ * <li>PLT=YES/NO. Defaults to NO. If set to YES, PLT marker segments,
+ *     indicating the length of each packet in the tile-part header, will be
+ *     written. Since 2.3.2</li>
+ * </ul>
+ *
+ * @param p_codec       Compressor handle
+ * @param p_options     Compression options. This should be a NULL terminated
+ *                      array of strings. Each string is of the form KEY=VALUE.
+ *
+ * @return OPJ_TRUE in case of success.
+ * @since 2.3.2
+ */
+OPJ_API OPJ_BOOL OPJ_CALLCONV opj_encoder_set_extra_options(
+    opj_codec_t *p_codec,
+    const char* const* p_options);
+
 /**
  * Start to compress the current image.
  * @param p_codec       Compressor handle
index b962b121633e1fb10c65a8b2bee5b5d99c8cdee3..8a8af9119e385033a404ad3a347814de39912589 100644 (file)
@@ -148,6 +148,11 @@ typedef struct opj_codec_private {
                                           opj_cparameters_t * p_param,
                                           struct opj_image * p_image,
                                           struct opj_event_mgr * p_manager);
+
+            OPJ_BOOL(* opj_encoder_set_extra_options)(void * p_codec,
+                    const char* const* p_options,
+                    struct opj_event_mgr * p_manager);
+
         } m_compression;
     } m_codec_data;
     /** FIXME DOC*/
index a051339154b69e295bddf24a0ca539cf7f773df8..ee8adf4725c4bcaf9e1b8489abdc33c2b04b1264 100644 (file)
 */
 #define OPJ_COMMON_CBLK_DATA_EXTRA        2    /**< Margin for a fake FFFF marker */
 
+
+#define OPJ_COMP_PARAM_DEFAULT_CBLOCKW        64
+#define OPJ_COMP_PARAM_DEFAULT_CBLOCKH        64
+#define OPJ_COMP_PARAM_DEFAULT_PROG_ORDER     OPJ_LRCP
+#define OPJ_COMP_PARAM_DEFAULT_NUMRESOLUTION  6
+
 #endif /* OPJ_COMMMON_H */
index 754b5512ff2cf64640359c21d23259076fab7159..afe69d90c072574aa735aa0e9a1947602f66a1d4 100644 (file)
@@ -208,6 +208,16 @@ static INLINE OPJ_INT32 opj_int_floordivpow2(OPJ_INT32 a, OPJ_INT32 b)
 {
     return a >> b;
 }
+
+/**
+Divide an integer by a power of 2 and round downwards
+@return Returns a divided by 2^b
+*/
+static INLINE OPJ_UINT32 opj_uint_floordivpow2(OPJ_UINT32 a, OPJ_UINT32 b)
+{
+    return a >> b;
+}
+
 /**
 Get logarithm of an integer and round downwards
 @return Returns log2(a)
index 4a6ed68e2b24f114a6307b22807112dc5d735084..3dcdd4e9d3af1ccc8d950555534a0198ee8efc32 100644 (file)
@@ -36,6 +36,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define OPJ_UINT32_SEMANTICALLY_BUT_INT32 OPJ_UINT32
+
 #include "opj_includes.h"
 
 /** @defgroup PI PI - Implementation of a packet iterator */
@@ -91,10 +93,10 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi);
  */
 static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
         OPJ_UINT32 p_tileno,
-        OPJ_INT32 p_tx0,
-        OPJ_INT32 p_tx1,
-        OPJ_INT32 p_ty0,
-        OPJ_INT32 p_ty1,
+        OPJ_UINT32 p_tx0,
+        OPJ_UINT32 p_tx1,
+        OPJ_UINT32 p_ty0,
+        OPJ_UINT32 p_ty1,
         OPJ_UINT32 p_max_prec,
         OPJ_UINT32 p_max_res,
         OPJ_UINT32 p_dx_min,
@@ -118,10 +120,10 @@ static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
 static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
         OPJ_UINT32 p_num_comps,
         OPJ_UINT32 p_tileno,
-        OPJ_INT32 p_tx0,
-        OPJ_INT32 p_tx1,
-        OPJ_INT32 p_ty0,
-        OPJ_INT32 p_ty1,
+        OPJ_UINT32 p_tx0,
+        OPJ_UINT32 p_tx1,
+        OPJ_UINT32 p_ty0,
+        OPJ_UINT32 p_ty1,
         OPJ_UINT32 p_max_prec,
         OPJ_UINT32 p_max_res,
         OPJ_UINT32 p_dx_min,
@@ -144,10 +146,10 @@ static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
 static void opj_get_encoding_parameters(const opj_image_t *p_image,
                                         const opj_cp_t *p_cp,
                                         OPJ_UINT32  tileno,
-                                        OPJ_INT32  * p_tx0,
-                                        OPJ_INT32 * p_tx1,
-                                        OPJ_INT32 * p_ty0,
-                                        OPJ_INT32 * p_ty1,
+                                        OPJ_UINT32 * p_tx0,
+                                        OPJ_UINT32 * p_tx1,
+                                        OPJ_UINT32 * p_ty0,
+                                        OPJ_UINT32 * p_ty1,
                                         OPJ_UINT32 * p_dx_min,
                                         OPJ_UINT32 * p_dy_min,
                                         OPJ_UINT32 * p_max_prec,
@@ -176,10 +178,10 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
 static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
         const opj_cp_t *p_cp,
         OPJ_UINT32 tileno,
-        OPJ_INT32 * p_tx0,
-        OPJ_INT32 * p_tx1,
-        OPJ_INT32 * p_ty0,
-        OPJ_INT32 * p_ty1,
+        OPJ_UINT32 * p_tx0,
+        OPJ_UINT32 * p_tx1,
+        OPJ_UINT32 * p_ty0,
+        OPJ_UINT32 * p_ty1,
         OPJ_UINT32 * p_dx_min,
         OPJ_UINT32 * p_dy_min,
         OPJ_UINT32 * p_max_prec,
@@ -376,16 +378,16 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
         pi->poc.tx1 = pi->tx1;
     }
     for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
-        for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1;
-                pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
-            for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1;
-                    pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
+        for (pi->y = (OPJ_UINT32)pi->poc.ty0; pi->y < (OPJ_UINT32)pi->poc.ty1;
+                pi->y += (pi->dy - (pi->y % pi->dy))) {
+            for (pi->x = (OPJ_UINT32)pi->poc.tx0; pi->x < (OPJ_UINT32)pi->poc.tx1;
+                    pi->x += (pi->dx - (pi->x % pi->dx))) {
                 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
                     OPJ_UINT32 levelno;
-                    OPJ_INT32 trx0, try0;
-                    OPJ_INT32  trx1, try1;
+                    OPJ_UINT32 trx0, try0;
+                    OPJ_UINT32  trx1, try1;
                     OPJ_UINT32  rpx, rpy;
-                    OPJ_INT32  prci, prcj;
+                    OPJ_UINT32  prci, prcj;
                     comp = &pi->comps[pi->compno];
                     if (pi->resno >= comp->numresolutions) {
                         continue;
@@ -404,10 +406,10 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
                             (comp->dy << levelno) > INT_MAX) {
                         continue;
                     }
-                    trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
-                    try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
-                    trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
-                    try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
+                    trx0 = opj_uint_ceildiv(pi->tx0, (comp->dx << levelno));
+                    try0 = opj_uint_ceildiv(pi->ty0, (comp->dy << levelno));
+                    trx1 = opj_uint_ceildiv(pi->tx1, (comp->dx << levelno));
+                    try1 = opj_uint_ceildiv(pi->ty1, (comp->dy << levelno));
                     rpx = res->pdx + levelno;
                     rpy = res->pdy + levelno;
 
@@ -421,12 +423,12 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
                     }
 
                     /* See ISO-15441. B.12.1.3 Resolution level-position-component-layer progression */
-                    if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
-                            ((try0 << levelno) % (1 << rpy))))) {
+                    if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
+                            ((try0 << levelno) % (1U << rpy))))) {
                         continue;
                     }
-                    if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
-                            ((trx0 << levelno) % (1 << rpx))))) {
+                    if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
+                            ((trx0 << levelno) % (1U << rpx))))) {
                         continue;
                     }
 
@@ -438,13 +440,13 @@ static OPJ_BOOL opj_pi_next_rpcl(opj_pi_iterator_t * pi)
                         continue;
                     }
 
-                    prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x,
-                                                (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
-                           - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
-                    prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y,
-                                                (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
-                           - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
-                    pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
+                    prci = opj_uint_floordivpow2(opj_uint_ceildiv(pi->x,
+                                                 (comp->dx << levelno)), res->pdx)
+                           - opj_uint_floordivpow2(trx0, res->pdx);
+                    prcj = opj_uint_floordivpow2(opj_uint_ceildiv(pi->y,
+                                                 (comp->dy << levelno)), res->pdy)
+                           - opj_uint_floordivpow2(try0, res->pdy);
+                    pi->precno = prci + prcj * res->pw;
                     for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
                         index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
                                 pi->step_c + pi->precno * pi->step_p;
@@ -508,19 +510,19 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
         pi->poc.ty1 = pi->ty1;
         pi->poc.tx1 = pi->tx1;
     }
-    for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1;
-            pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
-        for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1;
-                pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
+    for (pi->y = (OPJ_UINT32)pi->poc.ty0; pi->y < (OPJ_UINT32)pi->poc.ty1;
+            pi->y += (pi->dy - (pi->y % pi->dy))) {
+        for (pi->x = (OPJ_UINT32)pi->poc.tx0; pi->x < (OPJ_UINT32)pi->poc.tx1;
+                pi->x += (pi->dx - (pi->x % pi->dx))) {
             for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
                 comp = &pi->comps[pi->compno];
                 for (pi->resno = pi->poc.resno0;
                         pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
                     OPJ_UINT32 levelno;
-                    OPJ_INT32 trx0, try0;
-                    OPJ_INT32 trx1, try1;
+                    OPJ_UINT32 trx0, try0;
+                    OPJ_UINT32 trx1, try1;
                     OPJ_UINT32 rpx, rpy;
-                    OPJ_INT32 prci, prcj;
+                    OPJ_UINT32 prci, prcj;
                     res = &comp->resolutions[pi->resno];
                     levelno = comp->numresolutions - 1 - pi->resno;
                     /* Avoids division by zero */
@@ -535,10 +537,10 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
                             (comp->dy << levelno) > INT_MAX) {
                         continue;
                     }
-                    trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
-                    try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
-                    trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
-                    try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
+                    trx0 = opj_uint_ceildiv(pi->tx0, (comp->dx << levelno));
+                    try0 = opj_uint_ceildiv(pi->ty0, (comp->dy << levelno));
+                    trx1 = opj_uint_ceildiv(pi->tx1, (comp->dx << levelno));
+                    try1 = opj_uint_ceildiv(pi->ty1, (comp->dy << levelno));
                     rpx = res->pdx + levelno;
                     rpy = res->pdy + levelno;
 
@@ -552,12 +554,12 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
                     }
 
                     /* See ISO-15441. B.12.1.4 Position-component-resolution level-layer progression */
-                    if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
-                            ((try0 << levelno) % (1 << rpy))))) {
+                    if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
+                            ((try0 << levelno) % (1U << rpy))))) {
                         continue;
                     }
-                    if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
-                            ((trx0 << levelno) % (1 << rpx))))) {
+                    if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
+                            ((trx0 << levelno) % (1U << rpx))))) {
                         continue;
                     }
 
@@ -569,13 +571,13 @@ static OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi)
                         continue;
                     }
 
-                    prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x,
-                                                (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
-                           - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
-                    prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y,
-                                                (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
-                           - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
-                    pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
+                    prci = opj_uint_floordivpow2(opj_uint_ceildiv(pi->x,
+                                                 (comp->dx << levelno)), res->pdx)
+                           - opj_uint_floordivpow2(trx0, res->pdx);
+                    prcj = opj_uint_floordivpow2(opj_uint_ceildiv(pi->y,
+                                                 (comp->dy << levelno)), res->pdy)
+                           - opj_uint_floordivpow2(try0, res->pdy);
+                    pi->precno = prci + prcj * res->pw;
                     for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
                         index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
                                 pi->step_c + pi->precno * pi->step_p;
@@ -639,17 +641,17 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
             pi->poc.ty1 = pi->ty1;
             pi->poc.tx1 = pi->tx1;
         }
-        for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1;
-                pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) {
-            for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1;
-                    pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) {
+        for (pi->y = (OPJ_UINT32)pi->poc.ty0; pi->y < (OPJ_UINT32)pi->poc.ty1;
+                pi->y += (pi->dy - (pi->y % pi->dy))) {
+            for (pi->x = (OPJ_UINT32)pi->poc.tx0; pi->x < (OPJ_UINT32)pi->poc.tx1;
+                    pi->x += (pi->dx - (pi->x % pi->dx))) {
                 for (pi->resno = pi->poc.resno0;
                         pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
                     OPJ_UINT32 levelno;
-                    OPJ_INT32 trx0, try0;
-                    OPJ_INT32 trx1, try1;
+                    OPJ_UINT32 trx0, try0;
+                    OPJ_UINT32 trx1, try1;
                     OPJ_UINT32 rpx, rpy;
-                    OPJ_INT32 prci, prcj;
+                    OPJ_UINT32 prci, prcj;
                     res = &comp->resolutions[pi->resno];
                     levelno = comp->numresolutions - 1 - pi->resno;
                     /* Avoids division by zero on id_000004,sig_06,src_000679,op_arith8,pos_49,val_-17 */
@@ -663,10 +665,10 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
                             (comp->dy << levelno) > INT_MAX) {
                         continue;
                     }
-                    trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno));
-                    try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno));
-                    trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno));
-                    try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno));
+                    trx0 = opj_uint_ceildiv(pi->tx0, (comp->dx << levelno));
+                    try0 = opj_uint_ceildiv(pi->ty0, (comp->dy << levelno));
+                    trx1 = opj_uint_ceildiv(pi->tx1, (comp->dx << levelno));
+                    try1 = opj_uint_ceildiv(pi->ty1, (comp->dy << levelno));
                     rpx = res->pdx + levelno;
                     rpy = res->pdy + levelno;
 
@@ -680,12 +682,12 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
                     }
 
                     /* See ISO-15441. B.12.1.5 Component-position-resolution level-layer progression */
-                    if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
-                            ((try0 << levelno) % (1 << rpy))))) {
+                    if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) &&
+                            ((try0 << levelno) % (1U << rpy))))) {
                         continue;
                     }
-                    if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
-                            ((trx0 << levelno) % (1 << rpx))))) {
+                    if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) &&
+                            ((trx0 << levelno) % (1U << rpx))))) {
                         continue;
                     }
 
@@ -697,13 +699,13 @@ static OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi)
                         continue;
                     }
 
-                    prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x,
-                                                (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx)
-                           - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx);
-                    prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y,
-                                                (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy)
-                           - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy);
-                    pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw);
+                    prci = opj_uint_floordivpow2(opj_uint_ceildiv(pi->x,
+                                                 (comp->dx << levelno)), res->pdx)
+                           - opj_uint_floordivpow2(trx0, res->pdx);
+                    prcj = opj_uint_floordivpow2(opj_uint_ceildiv(pi->y,
+                                                 (comp->dy << levelno)), res->pdy)
+                           - opj_uint_floordivpow2(try0, res->pdy);
+                    pi->precno = (OPJ_UINT32)(prci + prcj * res->pw);
                     for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) {
                         index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno *
                                 pi->step_c + pi->precno * pi->step_p;
@@ -729,10 +731,10 @@ LABEL_SKIP:
 static void opj_get_encoding_parameters(const opj_image_t *p_image,
                                         const opj_cp_t *p_cp,
                                         OPJ_UINT32 p_tileno,
-                                        OPJ_INT32 * p_tx0,
-                                        OPJ_INT32  * p_tx1,
-                                        OPJ_INT32  * p_ty0,
-                                        OPJ_INT32  * p_ty1,
+                                        OPJ_UINT32 * p_tx0,
+                                        OPJ_UINT32  * p_tx1,
+                                        OPJ_UINT32  * p_ty0,
+                                        OPJ_UINT32  * p_ty1,
                                         OPJ_UINT32 * p_dx_min,
                                         OPJ_UINT32 * p_dy_min,
                                         OPJ_UINT32 * p_max_prec,
@@ -768,12 +770,12 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
     /* find extent of tile */
     l_tx0 = p_cp->tx0 + p *
             p_cp->tdx; /* can't be greater than p_image->x1 so won't overflow */
-    *p_tx0 = (OPJ_INT32)opj_uint_max(l_tx0, p_image->x0);
-    *p_tx1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
+    *p_tx0 = opj_uint_max(l_tx0, p_image->x0);
+    *p_tx1 = opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
     l_ty0 = p_cp->ty0 + q *
             p_cp->tdy; /* can't be greater than p_image->y1 so won't overflow */
-    *p_ty0 = (OPJ_INT32)opj_uint_max(l_ty0, p_image->y0);
-    *p_ty1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
+    *p_ty0 = opj_uint_max(l_ty0, p_image->y0);
+    *p_ty1 = opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
 
     /* max precision is 0 (can only grow) */
     *p_max_prec = 0;
@@ -786,17 +788,17 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
     for (compno = 0; compno < p_image->numcomps; ++compno) {
         /* arithmetic variables to calculate */
         OPJ_UINT32 l_level_no;
-        OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
-        OPJ_INT32 l_px0, l_py0, l_px1, py1;
+        OPJ_UINT32 l_rx0, l_ry0, l_rx1, l_ry1;
+        OPJ_UINT32 l_px0, l_py0, l_px1, py1;
         OPJ_UINT32 l_pdx, l_pdy;
         OPJ_UINT32 l_pw, l_ph;
         OPJ_UINT32 l_product;
-        OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
+        OPJ_UINT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
 
-        l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
-        l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
-        l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
-        l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);
+        l_tcx0 = opj_uint_ceildiv(*p_tx0, l_img_comp->dx);
+        l_tcy0 = opj_uint_ceildiv(*p_ty0, l_img_comp->dy);
+        l_tcx1 = opj_uint_ceildiv(*p_tx1, l_img_comp->dx);
+        l_tcy1 = opj_uint_ceildiv(*p_ty1, l_img_comp->dy);
 
         if (l_tccp->numresolutions > *p_max_res) {
             *p_max_res = l_tccp->numresolutions;
@@ -820,19 +822,19 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
             /* various calculations of extents */
             l_level_no = l_tccp->numresolutions - 1 - resno;
 
-            l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
-            l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
-            l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
-            l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
+            l_rx0 = opj_uint_ceildivpow2(l_tcx0, l_level_no);
+            l_ry0 = opj_uint_ceildivpow2(l_tcy0, l_level_no);
+            l_rx1 = opj_uint_ceildivpow2(l_tcx1, l_level_no);
+            l_ry1 = opj_uint_ceildivpow2(l_tcy1, l_level_no);
 
-            l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
-            l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
-            l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
+            l_px0 = opj_uint_floordivpow2(l_rx0, l_pdx) << l_pdx;
+            l_py0 = opj_uint_floordivpow2(l_ry0, l_pdy) << l_pdy;
+            l_px1 = opj_uint_ceildivpow2(l_rx1, l_pdx) << l_pdx;
 
-            py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
+            py1 = opj_uint_ceildivpow2(l_ry1, l_pdy) << l_pdy;
 
-            l_pw = (l_rx0 == l_rx1) ? 0 : (OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
-            l_ph = (l_ry0 == l_ry1) ? 0 : (OPJ_UINT32)((py1 - l_py0) >> l_pdy);
+            l_pw = (l_rx0 == l_rx1) ? 0 : ((l_px1 - l_px0) >> l_pdx);
+            l_ph = (l_ry0 == l_ry1) ? 0 : ((py1 - l_py0) >> l_pdy);
 
             l_product = l_pw * l_ph;
 
@@ -850,10 +852,10 @@ static void opj_get_encoding_parameters(const opj_image_t *p_image,
 static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
         const opj_cp_t *p_cp,
         OPJ_UINT32 tileno,
-        OPJ_INT32 * p_tx0,
-        OPJ_INT32 * p_tx1,
-        OPJ_INT32 * p_ty0,
-        OPJ_INT32 * p_ty1,
+        OPJ_UINT32 * p_tx0,
+        OPJ_UINT32 * p_tx1,
+        OPJ_UINT32 * p_ty0,
+        OPJ_UINT32 * p_ty1,
         OPJ_UINT32 * p_dx_min,
         OPJ_UINT32 * p_dy_min,
         OPJ_UINT32 * p_max_prec,
@@ -894,12 +896,12 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
     /* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
     l_tx0 = p_cp->tx0 + p *
             p_cp->tdx; /* can't be greater than p_image->x1 so won't overflow */
-    *p_tx0 = (OPJ_INT32)opj_uint_max(l_tx0, p_image->x0);
-    *p_tx1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
+    *p_tx0 = opj_uint_max(l_tx0, p_image->x0);
+    *p_tx1 = opj_uint_min(opj_uint_adds(l_tx0, p_cp->tdx), p_image->x1);
     l_ty0 = p_cp->ty0 + q *
             p_cp->tdy; /* can't be greater than p_image->y1 so won't overflow */
-    *p_ty0 = (OPJ_INT32)opj_uint_max(l_ty0, p_image->y0);
-    *p_ty1 = (OPJ_INT32)opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
+    *p_ty0 = opj_uint_max(l_ty0, p_image->y0);
+    *p_ty1 = opj_uint_min(opj_uint_adds(l_ty0, p_cp->tdy), p_image->y1);
 
     /* max precision and resolution is 0 (can only grow)*/
     *p_max_prec = 0;
@@ -912,18 +914,18 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
     for (compno = 0; compno < p_image->numcomps; ++compno) {
         /* aritmetic variables to calculate*/
         OPJ_UINT32 l_level_no;
-        OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
-        OPJ_INT32 l_px0, l_py0, l_px1, py1;
+        OPJ_UINT32 l_rx0, l_ry0, l_rx1, l_ry1;
+        OPJ_UINT32 l_px0, l_py0, l_px1, py1;
         OPJ_UINT32 l_product;
-        OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
+        OPJ_UINT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
         OPJ_UINT32 l_pdx, l_pdy, l_pw, l_ph;
 
-        lResolutionPtr = p_resolutions[compno];
+        lResolutionPtr = p_resolutions ? p_resolutions[compno] : NULL;
 
-        l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx);
-        l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy);
-        l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx);
-        l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy);
+        l_tcx0 = opj_uint_ceildiv(*p_tx0, l_img_comp->dx);
+        l_tcy0 = opj_uint_ceildiv(*p_ty0, l_img_comp->dy);
+        l_tcx1 = opj_uint_ceildiv(*p_tx1, l_img_comp->dx);
+        l_tcy1 = opj_uint_ceildiv(*p_ty1, l_img_comp->dy);
 
         if (l_tccp->numresolutions > *p_max_res) {
             *p_max_res = l_tccp->numresolutions;
@@ -939,33 +941,37 @@ static void opj_get_all_encoding_parameters(const opj_image_t *p_image,
             /* precinct width and height*/
             l_pdx = l_tccp->prcw[resno];
             l_pdy = l_tccp->prch[resno];
-            *lResolutionPtr++ = l_pdx;
-            *lResolutionPtr++ = l_pdy;
+            if (lResolutionPtr) {
+                *lResolutionPtr++ = l_pdx;
+                *lResolutionPtr++ = l_pdy;
+            }
             if (l_pdx + l_level_no < 32 &&
                     l_img_comp->dx <= UINT_MAX / (1u << (l_pdx + l_level_no))) {
                 l_dx = l_img_comp->dx * (1u << (l_pdx + l_level_no));
                 /* take the minimum size for l_dx for each comp and resolution*/
-                *p_dx_min = (OPJ_UINT32)opj_int_min((OPJ_INT32) * p_dx_min, (OPJ_INT32)l_dx);
+                *p_dx_min = opj_uint_min(*p_dx_min, l_dx);
             }
             if (l_pdy + l_level_no < 32 &&
                     l_img_comp->dy <= UINT_MAX / (1u << (l_pdy + l_level_no))) {
                 l_dy = l_img_comp->dy * (1u << (l_pdy + l_level_no));
-                *p_dy_min = (OPJ_UINT32)opj_int_min((OPJ_INT32) * p_dy_min, (OPJ_INT32)l_dy);
+                *p_dy_min = opj_uint_min(*p_dy_min, l_dy);
             }
 
             /* various calculations of extents*/
-            l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no);
-            l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no);
-            l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no);
-            l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no);
-            l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx;
-            l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy;
-            l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx;
-            py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy;
-            l_pw = (l_rx0 == l_rx1) ? 0 : (OPJ_UINT32)((l_px1 - l_px0) >> l_pdx);
-            l_ph = (l_ry0 == l_ry1) ? 0 : (OPJ_UINT32)((py1 - l_py0) >> l_pdy);
-            *lResolutionPtr++ = l_pw;
-            *lResolutionPtr++ = l_ph;
+            l_rx0 = opj_uint_ceildivpow2(l_tcx0, l_level_no);
+            l_ry0 = opj_uint_ceildivpow2(l_tcy0, l_level_no);
+            l_rx1 = opj_uint_ceildivpow2(l_tcx1, l_level_no);
+            l_ry1 = opj_uint_ceildivpow2(l_tcy1, l_level_no);
+            l_px0 = opj_uint_floordivpow2(l_rx0, l_pdx) << l_pdx;
+            l_py0 = opj_uint_floordivpow2(l_ry0, l_pdy) << l_pdy;
+            l_px1 = opj_uint_ceildivpow2(l_rx1, l_pdx) << l_pdx;
+            py1 = opj_uint_ceildivpow2(l_ry1, l_pdy) << l_pdy;
+            l_pw = (l_rx0 == l_rx1) ? 0 : ((l_px1 - l_px0) >> l_pdx);
+            l_ph = (l_ry0 == l_ry1) ? 0 : ((py1 - l_py0) >> l_pdy);
+            if (lResolutionPtr) {
+                *lResolutionPtr++ = l_pw;
+                *lResolutionPtr++ = l_ph;
+            }
             l_product = l_pw * l_ph;
 
             /* update precision*/
@@ -1045,10 +1051,10 @@ static opj_pi_iterator_t * opj_pi_create(const opj_image_t *image,
 
 static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
         OPJ_UINT32 p_tileno,
-        OPJ_INT32 p_tx0,
-        OPJ_INT32 p_tx1,
-        OPJ_INT32 p_ty0,
-        OPJ_INT32 p_ty1,
+        OPJ_UINT32 p_tx0,
+        OPJ_UINT32 p_tx1,
+        OPJ_UINT32 p_ty0,
+        OPJ_UINT32 p_ty1,
         OPJ_UINT32 p_max_prec,
         OPJ_UINT32 p_max_res,
         OPJ_UINT32 p_dx_min,
@@ -1125,10 +1131,10 @@ static void opj_pi_update_encode_poc_and_final(opj_cp_t *p_cp,
 static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
         OPJ_UINT32 p_num_comps,
         OPJ_UINT32 p_tileno,
-        OPJ_INT32 p_tx0,
-        OPJ_INT32 p_tx1,
-        OPJ_INT32 p_ty0,
-        OPJ_INT32 p_ty1,
+        OPJ_UINT32 p_tx0,
+        OPJ_UINT32 p_tx1,
+        OPJ_UINT32 p_ty0,
+        OPJ_UINT32 p_ty1,
         OPJ_UINT32 p_max_prec,
         OPJ_UINT32 p_max_res,
         OPJ_UINT32 p_dx_min,
@@ -1167,10 +1173,10 @@ static void opj_pi_update_encode_not_poc(opj_cp_t *p_cp,
         l_current_poc->prg  = l_tcp->prg;
         l_current_poc->prcS = 0;
         l_current_poc->prcE = p_max_prec;
-        l_current_poc->txS = (OPJ_UINT32)p_tx0;
-        l_current_poc->txE = (OPJ_UINT32)p_tx1;
-        l_current_poc->tyS = (OPJ_UINT32)p_ty0;
-        l_current_poc->tyE = (OPJ_UINT32)p_ty1;
+        l_current_poc->txS = p_tx0;
+        l_current_poc->txE = p_tx1;
+        l_current_poc->tyS = p_ty0;
+        l_current_poc->tyE = p_ty1;
         l_current_poc->dx = p_dx_min;
         l_current_poc->dy = p_dy_min;
         ++ l_current_poc;
@@ -1367,7 +1373,7 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
     /* encoding prameters to set */
     OPJ_UINT32 l_max_res;
     OPJ_UINT32 l_max_prec;
-    OPJ_INT32 l_tx0, l_tx1, l_ty0, l_ty1;
+    OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
     OPJ_UINT32 l_dx_min, l_dy_min;
     OPJ_UINT32 l_bound;
     OPJ_UINT32 l_step_p, l_step_c, l_step_r, l_step_l ;
@@ -1548,6 +1554,28 @@ opj_pi_iterator_t *opj_pi_create_decode(opj_image_t *p_image,
 }
 
 
+OPJ_UINT32 opj_get_encoding_packet_count(const opj_image_t *p_image,
+        const opj_cp_t *p_cp,
+        OPJ_UINT32 p_tile_no)
+{
+    OPJ_UINT32 l_max_res;
+    OPJ_UINT32 l_max_prec;
+    OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
+    OPJ_UINT32 l_dx_min, l_dy_min;
+
+    /* preconditions in debug*/
+    assert(p_cp != 00);
+    assert(p_image != 00);
+    assert(p_tile_no < p_cp->tw * p_cp->th);
+
+    /* get encoding parameters*/
+    opj_get_all_encoding_parameters(p_image, p_cp, p_tile_no, &l_tx0, &l_tx1,
+                                    &l_ty0, &l_ty1, &l_dx_min, &l_dy_min, &l_max_prec, &l_max_res, NULL);
+
+    return p_cp->tcps[p_tile_no].numlayers * l_max_prec * p_image->numcomps *
+           l_max_res;
+}
+
 
 opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
         opj_cp_t *p_cp,
@@ -1567,7 +1595,7 @@ opj_pi_iterator_t *opj_pi_initialise_encode(const opj_image_t *p_image,
     /* encoding prameters to set*/
     OPJ_UINT32 l_max_res;
     OPJ_UINT32 l_max_prec;
-    OPJ_INT32 l_tx0, l_tx1, l_ty0, l_ty1;
+    OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
     OPJ_UINT32 l_dx_min, l_dy_min;
     OPJ_UINT32 l_bound;
     OPJ_UINT32 l_step_p, l_step_c, l_step_r, l_step_l ;
@@ -1761,7 +1789,8 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
     pi[pino].poc.prg = tcp->prg;
 
     if (!(cp->m_specific_param.m_enc.m_tp_on && ((!OPJ_IS_CINEMA(cp->rsiz) &&
-            (t2_mode == FINAL_PASS)) || OPJ_IS_CINEMA(cp->rsiz)))) {
+            !OPJ_IS_IMF(cp->rsiz) &&
+            (t2_mode == FINAL_PASS)) || OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)))) {
         pi[pino].poc.resno0 = tcp->resS;
         pi[pino].poc.resno1 = tcp->resE;
         pi[pino].poc.compno0 = tcp->compS;
@@ -1770,10 +1799,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
         pi[pino].poc.layno1 = tcp->layE;
         pi[pino].poc.precno0 = tcp->prcS;
         pi[pino].poc.precno1 = tcp->prcE;
-        pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
-        pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
-        pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
-        pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
+        pi[pino].poc.tx0 = tcp->txS;
+        pi[pino].poc.ty0 = tcp->tyS;
+        pi[pino].poc.tx1 = tcp->txE;
+        pi[pino].poc.ty1 = tcp->tyE;
     } else {
         for (i = tppos + 1; i < 4; i++) {
             switch (prog[i]) {
@@ -1797,10 +1826,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
                     pi[pino].poc.precno1 = tcp->prcE;
                     break;
                 default:
-                    pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS;
-                    pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS;
-                    pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE;
-                    pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE;
+                    pi[pino].poc.tx0 = tcp->txS;
+                    pi[pino].poc.ty0 = tcp->tyS;
+                    pi[pino].poc.tx1 = tcp->txE;
+                    pi[pino].poc.ty1 = tcp->tyE;
                     break;
                 }
                 break;
@@ -1840,10 +1869,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
                     default:
                         tcp->tx0_t = tcp->txS;
                         tcp->ty0_t = tcp->tyS;
-                        pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
-                        pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
-                        pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
-                        pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
+                        pi[pino].poc.tx0 = tcp->tx0_t;
+                        pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
+                        pi[pino].poc.ty0 = tcp->ty0_t;
+                        pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
                         tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
                         tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
                         break;
@@ -1875,10 +1904,10 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
                         pi[pino].poc.precno1 = tcp->prc_t;
                         break;
                     default:
-                        pi[pino].poc.tx0 = (OPJ_INT32)(tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx));
-                        pi[pino].poc.tx1 = (OPJ_INT32)tcp->tx0_t ;
-                        pi[pino].poc.ty0 = (OPJ_INT32)(tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy));
-                        pi[pino].poc.ty1 = (OPJ_INT32)tcp->ty0_t ;
+                        pi[pino].poc.tx0 = tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx);
+                        pi[pino].poc.tx1 = tcp->tx0_t ;
+                        pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy);
+                        pi[pino].poc.ty1 = tcp->ty0_t ;
                         break;
                     }
                     break;
@@ -1965,8 +1994,8 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
                                 if (tcp->ty0_t >= tcp->tyE) {
                                     if (opj_pi_check_next_level(i - 1, cp, tileno, pino, prog)) {
                                         tcp->ty0_t = tcp->tyS;
-                                        pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
-                                        pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
+                                        pi[pino].poc.ty0 = tcp->ty0_t;
+                                        pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
                                         tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
                                         incr_top = 1;
                                         resetX = 1;
@@ -1975,21 +2004,21 @@ void opj_pi_create_encode(opj_pi_iterator_t *pi,
                                         resetX = 0;
                                     }
                                 } else {
-                                    pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t;
-                                    pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy));
+                                    pi[pino].poc.ty0 = tcp->ty0_t;
+                                    pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
                                     tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1;
                                     incr_top = 0;
                                     resetX = 1;
                                 }
                                 if (resetX == 1) {
                                     tcp->tx0_t = tcp->txS;
-                                    pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
-                                    pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
+                                    pi[pino].poc.tx0 = tcp->tx0_t;
+                                    pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
                                     tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
                                 }
                             } else {
-                                pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t;
-                                pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx));
+                                pi[pino].poc.tx0 = tcp->tx0_t;
+                                pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
                                 tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1;
                                 incr_top = 0;
                             }
@@ -2042,7 +2071,7 @@ void opj_pi_update_encoding_parameters(const opj_image_t *p_image,
     /* encoding parameters to set */
     OPJ_UINT32 l_max_res;
     OPJ_UINT32 l_max_prec;
-    OPJ_INT32 l_tx0, l_tx1, l_ty0, l_ty1;
+    OPJ_UINT32 l_tx0, l_tx1, l_ty0, l_ty1;
     OPJ_UINT32 l_dx_min, l_dy_min;
 
     /* pointers */
index 8c0dc25c19dd962bf9e76994609a37ee41fc0cca..7fb3417fe54edd3597db39964209320dfb8cd7c7 100644 (file)
@@ -102,9 +102,9 @@ typedef struct opj_pi_iterator {
     /** Components*/
     opj_pi_comp_t *comps;
     /** FIXME DOC*/
-    OPJ_INT32 tx0, ty0, tx1, ty1;
+    OPJ_UINT32 tx0, ty0, tx1, ty1;
     /** FIXME DOC*/
-    OPJ_INT32 x, y;
+    OPJ_UINT32 x, y;
     /** FIXME DOC*/
     OPJ_UINT32 dx, dy;
 } opj_pi_iterator_t;
@@ -182,6 +182,17 @@ Modify the packet iterator to point to the next packet
 @return Returns false if pi pointed to the last packet or else returns true
 */
 OPJ_BOOL opj_pi_next(opj_pi_iterator_t * pi);
+
+/**
+ * Return the number of packets in the tile.
+ * @param   image       the image being encoded.
+ * @param cp Coding parameters
+ * @param tileno Number that identifies the tile.
+ */
+OPJ_UINT32 opj_get_encoding_packet_count(const opj_image_t *p_image,
+        const opj_cp_t *p_cp,
+        OPJ_UINT32 p_tile_no);
+
 /* ----------------------------------------------------------------------- */
 /*@}*/
 
index 0887b9f5f4681d1c44c9c420fc94701345796ea0..71472b499c5d487388613e5ca2174706d98a3008 100644 (file)
@@ -224,6 +224,7 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
                                OPJ_UINT32 * p_data_written,
                                OPJ_UINT32 p_max_len,
                                opj_codestream_info_t *cstr_info,
+                               opj_tcd_marker_info_t* p_marker_info,
                                OPJ_UINT32 p_tp_num,
                                OPJ_INT32 p_tp_pos,
                                OPJ_UINT32 p_pino,
@@ -310,6 +311,20 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
             opj_pi_destroy(l_pi, l_nb_pocs);
             return OPJ_FALSE;
         }
+
+        if (p_marker_info && p_marker_info->need_PLT) {
+            /* One time use intended */
+            assert(p_marker_info->packet_count == 0);
+            assert(p_marker_info->p_packet_size == NULL);
+
+            p_marker_info->p_packet_size = (OPJ_UINT32*) opj_malloc(
+                                               opj_get_encoding_packet_count(l_image, l_cp, p_tile_no) * sizeof(OPJ_UINT32));
+            if (p_marker_info->p_packet_size == NULL) {
+                opj_pi_destroy(l_pi, l_nb_pocs);
+                return OPJ_FALSE;
+            }
+        }
+
         while (opj_pi_next(l_current_pi)) {
             if (l_current_pi->layno < p_maxlayers) {
                 l_nb_bytes = 0;
@@ -326,6 +341,11 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* p_t2,
 
                 * p_data_written += l_nb_bytes;
 
+                if (p_marker_info && p_marker_info->need_PLT) {
+                    p_marker_info->p_packet_size[p_marker_info->packet_count] = l_nb_bytes;
+                    p_marker_info->packet_count ++;
+                }
+
                 /* INDEX >> */
                 if (cstr_info) {
                     if (cstr_info->index_write) {
index 66500b1699334d7752f9ad86eec672379028105b..becfa91a4deef924839953e0d1a2145e34f34bc1 100644 (file)
@@ -73,6 +73,7 @@ Encode the packets of a tile to a destination buffer
 @param p_data_written   FIXME DOC
 @param len              the length of the destination buffer
 @param cstr_info        Codestream information structure
+@param p_marker_info    Marker information structure
 @param tpnum            Tile part number of the current tile
 @param tppos            The position of the tile part flag in the progression order
 @param pino             FIXME DOC
@@ -87,6 +88,7 @@ OPJ_BOOL opj_t2_encode_packets(opj_t2_t* t2,
                                OPJ_UINT32 * p_data_written,
                                OPJ_UINT32 len,
                                opj_codestream_info_t *cstr_info,
+                               opj_tcd_marker_info_t* p_marker_info,
                                OPJ_UINT32 tpnum,
                                OPJ_INT32 tppos,
                                OPJ_UINT32 pino,
index be3b84363fa224d6b915f7b52c67784bc5ab991b..3a1c3026a091e1c839940170e2d90cc0071e08f3 100644 (file)
@@ -182,6 +182,7 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
                                   OPJ_UINT32 * p_data_written,
                                   OPJ_UINT32 p_max_dest_size,
                                   opj_codestream_info_t *p_cstr_info,
+                                  opj_tcd_marker_info_t* p_marker_info,
                                   opj_event_mgr_t *p_manager);
 
 static OPJ_BOOL opj_tcd_rate_allocate_encode(opj_tcd_t *p_tcd,
@@ -573,9 +574,10 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd,
                 opj_tcd_makelayer(tcd, layno, thresh, 0);
 
                 if (cp->m_specific_param.m_enc.m_fixed_quality) {       /* fixed_quality */
-                    if (OPJ_IS_CINEMA(cp->rsiz)) {
+                    if (OPJ_IS_CINEMA(cp->rsiz) || OPJ_IS_IMF(cp->rsiz)) {
                         if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,
-                                                    p_data_written, maxlen, cstr_info, tcd->cur_tp_num, tcd->tp_pos, tcd->cur_pino,
+                                                    p_data_written, maxlen, cstr_info, NULL, tcd->cur_tp_num, tcd->tp_pos,
+                                                    tcd->cur_pino,
                                                     THRESH_CALC, p_manager)) {
 
                             lo = thresh;
@@ -605,7 +607,8 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd,
                     }
                 } else {
                     if (! opj_t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,
-                                                p_data_written, maxlen, cstr_info, tcd->cur_tp_num, tcd->tp_pos, tcd->cur_pino,
+                                                p_data_written, maxlen, cstr_info, NULL, tcd->cur_tp_num, tcd->tp_pos,
+                                                tcd->cur_pino,
                                                 THRESH_CALC, p_manager)) {
                         /* TODO: what to do with l ??? seek / tell ??? */
                         /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
@@ -905,8 +908,24 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
             /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)  */
             l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx;
             l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy;
-            l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx;
-            l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy;
+            {
+                OPJ_UINT32 tmp = ((OPJ_UINT32)opj_int_ceildivpow2(l_res->x1,
+                                  (OPJ_INT32)l_pdx)) << l_pdx;
+                if (tmp > (OPJ_UINT32)INT_MAX) {
+                    opj_event_msg(manager, EVT_ERROR, "Integer overflow\n");
+                    return OPJ_FALSE;
+                }
+                l_br_prc_x_end = (OPJ_INT32)tmp;
+            }
+            {
+                OPJ_UINT32 tmp = ((OPJ_UINT32)opj_int_ceildivpow2(l_res->y1,
+                                  (OPJ_INT32)l_pdy)) << l_pdy;
+                if (tmp > (OPJ_UINT32)INT_MAX) {
+                    opj_event_msg(manager, EVT_ERROR, "Integer overflow\n");
+                    return OPJ_FALSE;
+                }
+                l_br_prc_y_end = (OPJ_INT32)tmp;
+            }
             /*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/
 
             l_res->pw = (l_res->x0 == l_res->x1) ? 0U : (OPJ_UINT32)((
@@ -1354,6 +1373,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
                              OPJ_UINT32 * p_data_written,
                              OPJ_UINT32 p_max_length,
                              opj_codestream_info_t *p_cstr_info,
+                             opj_tcd_marker_info_t* p_marker_info,
                              opj_event_mgr_t *p_manager)
 {
 
@@ -1433,7 +1453,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
     /* FIXME _ProfStart(PGROUP_T2); */
 
     if (! opj_tcd_t2_encode(p_tcd, p_dest, p_data_written, p_max_length,
-                            p_cstr_info, p_manager)) {
+                            p_cstr_info, p_marker_info, p_manager)) {
         return OPJ_FALSE;
     }
     /* FIXME _ProfStop(PGROUP_T2); */
@@ -2017,7 +2037,8 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
     opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles;
     opj_tcp_t * l_tcp = p_tcd->tcp;
     opj_tcd_tilecomp_t * l_tile_comp = l_tile->comps;
-    OPJ_UINT32 l_samples, i;
+    OPJ_SIZE_T l_samples;
+    OPJ_UINT32 i;
 
     if (l_tcp->mct == 0 || p_tcd->used_component != NULL) {
         return OPJ_TRUE;
@@ -2030,8 +2051,8 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
         /* A bit inefficient: we process more data than needed if */
         /* resno_decoded < l_tile_comp->minimum_num_resolutions-1, */
         /* but we would need to take into account a stride then */
-        l_samples = (OPJ_UINT32)((res_comp0->x1 - res_comp0->x0) *
-                                 (res_comp0->y1 - res_comp0->y0));
+        l_samples = (OPJ_SIZE_T)(res_comp0->x1 - res_comp0->x0) *
+                    (OPJ_SIZE_T)(res_comp0->y1 - res_comp0->y0);
         if (l_tile->numcomps >= 3) {
             if (l_tile_comp->minimum_num_resolutions !=
                     l_tile->comps[1].minimum_num_resolutions ||
@@ -2065,8 +2086,8 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
         opj_tcd_resolution_t* res_comp0 = l_tile->comps[0].resolutions +
                                           p_tcd->image->comps[0].resno_decoded;
 
-        l_samples = (res_comp0->win_x1 - res_comp0->win_x0) *
-                    (res_comp0->win_y1 - res_comp0->win_y0);
+        l_samples = (OPJ_SIZE_T)(res_comp0->win_x1 - res_comp0->win_x0) *
+                    (OPJ_SIZE_T)(res_comp0->win_y1 - res_comp0->win_y0);
         if (l_tile->numcomps >= 3) {
             opj_tcd_resolution_t* res_comp1 = l_tile->comps[1].resolutions +
                                               p_tcd->image->comps[1].resno_decoded;
@@ -2332,7 +2353,7 @@ static void opj_tcd_code_block_enc_deallocate(opj_tcd_precinct_t * p_precinct)
     }
 }
 
-OPJ_SIZE_T opj_tcd_get_encoded_tile_size(opj_tcd_t *p_tcd)
+OPJ_SIZE_T opj_tcd_get_encoder_input_buffer_size(opj_tcd_t *p_tcd)
 {
     OPJ_UINT32 i;
     OPJ_SIZE_T l_data_size = 0;
@@ -2524,6 +2545,7 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
                                   OPJ_UINT32 * p_data_written,
                                   OPJ_UINT32 p_max_dest_size,
                                   opj_codestream_info_t *p_cstr_info,
+                                  opj_tcd_marker_info_t* p_marker_info,
                                   opj_event_mgr_t *p_manager)
 {
     opj_t2_t * l_t2;
@@ -2542,6 +2564,7 @@ static OPJ_BOOL opj_tcd_t2_encode(opj_tcd_t *p_tcd,
                 p_data_written,
                 p_max_dest_size,
                 p_cstr_info,
+                p_marker_info,
                 p_tcd->tp_num,
                 p_tcd->tp_pos,
                 p_tcd->cur_pino,
@@ -2600,7 +2623,7 @@ OPJ_BOOL opj_tcd_copy_tile_data(opj_tcd_t *p_tcd,
     OPJ_UINT32 l_size_comp, l_remaining;
     OPJ_SIZE_T l_nb_elem;
 
-    l_data_size = opj_tcd_get_encoded_tile_size(p_tcd);
+    l_data_size = opj_tcd_get_encoder_input_buffer_size(p_tcd);
     if (l_data_size != p_src_length) {
         return OPJ_FALSE;
     }
@@ -2802,3 +2825,29 @@ static OPJ_BOOL opj_tcd_is_whole_tilecomp_decoding(opj_tcd_t *p_tcd,
               (((OPJ_UINT32)tilec->x1 - tcx1) >> shift) == 0 &&
               (((OPJ_UINT32)tilec->y1 - tcy1) >> shift) == 0)));
 }
+
+/* ----------------------------------------------------------------------- */
+
+opj_tcd_marker_info_t* opj_tcd_marker_info_create(OPJ_BOOL need_PLT)
+{
+    opj_tcd_marker_info_t *l_tcd_marker_info =
+        (opj_tcd_marker_info_t*) opj_calloc(1, sizeof(opj_tcd_marker_info_t));
+    if (!l_tcd_marker_info) {
+        return NULL;
+    }
+
+    l_tcd_marker_info->need_PLT = need_PLT;
+
+    return l_tcd_marker_info;
+}
+
+/* ----------------------------------------------------------------------- */
+
+void opj_tcd_marker_info_destroy(opj_tcd_marker_info_t *p_tcd_marker_info)
+{
+    if (p_tcd_marker_info) {
+        opj_free(p_tcd_marker_info->p_packet_size);
+    }
+}
+
+/* ----------------------------------------------------------------------- */
index e3214c1d982ad9b4ce57d17d007d6bd562883fe2..f1b52b8dac6e7115cd65580ae89e387100d946d3 100644 (file)
@@ -284,6 +284,22 @@ typedef struct opj_tcd {
     OPJ_BOOL* used_component;
 } opj_tcd_t;
 
+/**
+ * Structure to hold information needed to generate some markers.
+ * Used by encoder.
+ */
+typedef struct opj_tcd_marker_info {
+    /** In: Whether information to generate PLT markers in needed */
+    OPJ_BOOL    need_PLT;
+
+    /** OUT: Number of elements in p_packet_size[] array */
+    OPJ_UINT32  packet_count;
+
+    /** OUT: Array of size packet_count, such that p_packet_size[i] is
+     *       the size in bytes of the ith packet */
+    OPJ_UINT32* p_packet_size;
+} opj_tcd_marker_info_t;
+
 /** @name Exported functions */
 /*@{*/
 /* ----------------------------------------------------------------------- */
@@ -306,6 +322,21 @@ Destroy a previously created TCD handle
 */
 void opj_tcd_destroy(opj_tcd_t *tcd);
 
+
+/**
+ * Create a new opj_tcd_marker_info_t* structure
+ * @param need_PLT Whether information is needed to generate PLT markers.
+ */
+opj_tcd_marker_info_t* opj_tcd_marker_info_create(OPJ_BOOL need_PLT);
+
+
+/**
+Destroy a previously created opj_tcd_marker_info_t* structure
+@param p_tcd_marker_info Structure to destroy
+*/
+void opj_tcd_marker_info_destroy(opj_tcd_marker_info_t *p_tcd_marker_info);
+
+
 /**
  * Initialize the tile coder and may reuse some memory.
  * @param   p_tcd       TCD handle.
@@ -364,6 +395,7 @@ OPJ_UINT32 opj_tcd_get_decoded_tile_size(opj_tcd_t *p_tcd,
  * @param   p_data_written  pointer to an int that is incremented by the number of bytes really written on p_dest
  * @param   p_len           Maximum length of the destination buffer
  * @param   p_cstr_info     Codestream information structure
+ * @param   p_marker_info   Marker information structure
  * @param   p_manager       the user event manager
  * @return  true if the coding is successful.
 */
@@ -373,6 +405,7 @@ OPJ_BOOL opj_tcd_encode_tile(opj_tcd_t *p_tcd,
                              OPJ_UINT32 * p_data_written,
                              OPJ_UINT32 p_len,
                              struct opj_codestream_info *p_cstr_info,
+                             opj_tcd_marker_info_t* p_marker_info,
                              opj_event_mgr_t *p_manager);
 
 
@@ -415,9 +448,11 @@ OPJ_BOOL opj_tcd_update_tile_data(opj_tcd_t *p_tcd,
                                   OPJ_UINT32 p_dest_length);
 
 /**
- *
+ * Get the size in bytes of the input buffer provided before encoded.
+ * This must be the size provided to the p_src_length argument of
+ * opj_tcd_copy_tile_data()
  */
-OPJ_SIZE_T opj_tcd_get_encoded_tile_size(opj_tcd_t *p_tcd);
+OPJ_SIZE_T opj_tcd_get_encoder_input_buffer_size(opj_tcd_t *p_tcd);
 
 /**
  * Initialize the tile coder and may reuse some meory.
@@ -433,6 +468,8 @@ OPJ_BOOL opj_tcd_init_encode_tile(opj_tcd_t *p_tcd,
 
 /**
  * Copies tile data from the given memory block onto the system.
+ *
+ * p_src_length must be equal to opj_tcd_get_encoder_input_buffer_size()
  */
 OPJ_BOOL opj_tcd_copy_tile_data(opj_tcd_t *p_tcd,
                                 OPJ_BYTE * p_src,
index a31bf83fd3e7bfc5cb3117a6ceabcebcbe8ab845..9856d1d98cb05358dce8db58658b64a91de1c008 100644 (file)
@@ -268,6 +268,7 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp,
 
 
     if (bio_flush(bio)) {
+        bio_destroy(bio);
         return -999;        /* modified to eliminate longjmp !! */
     }
 
index eba9870f54a9b574be65dfe63bdf2d160a2308cc..8f364b6d55d2bdc5af820d34769b34d070cacc38 100644 (file)
@@ -232,6 +232,9 @@ void * aux_streaming(void *arg)
             }
             break;
         }
+        if (close_socket(connected_socket) != 0) {
+            perror("close");
+        }
     }
     opj_free(chunk);
 
index ce520640fe69b1aef1b9d309e48d3097b2f5807e..eb6b9d4c11679bc26b18046f4dd6a3d6a35cb221 100644 (file)
@@ -211,6 +211,7 @@ box_param_t * gene_boxbyType(int fd, OPJ_OFF_T offset, OPJ_SIZE_T length,
                 } else {
                     fprintf(FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64
                             ", %s)\n", fd, offset, length, TBox);
+                    free(data);
                     return NULL;
                 }
             }
index 2d7d683b5cc1bc435b85f60f843e4fce86324199..8975375273b423f9783b49691ab81ae2aba9f6bf 100644 (file)
@@ -270,6 +270,7 @@ OPJ_BOOL check_JP2boxidx(boxlist_param_t *toplev_boxlist)
     ni = fetch_DBox1byte(prxy, pos);
     if (ni != 1) {
         fprintf(FCGI_stderr, "Multiple indexes not supported\n");
+        opj_free(prxy);
         return OPJ_FALSE;
     }
     pos += 1;
@@ -361,6 +362,7 @@ OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *jp2idx)
     if (!search_boxheader("mhix", manf)) {
         fprintf(FCGI_stderr, "Error: mhix box not present in manfbox\n");
         opj_free(jp2idx);
+        delete_manfbox(&manf);
         return OPJ_FALSE;
     }
     set_mainmhixdata(cidx_box, codestream, jp2idx);
@@ -368,6 +370,7 @@ OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *jp2idx)
     if (!search_boxheader("tpix", manf)) {
         fprintf(FCGI_stderr, "Error: tpix box not present in manfbox\n");
         opj_free(jp2idx);
+        delete_manfbox(&manf);
         return OPJ_FALSE;
     }
     set_tpixdata(cidx_box, jp2idx);
@@ -375,6 +378,7 @@ OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *jp2idx)
     if (!search_boxheader("thix", manf)) {
         fprintf(FCGI_stderr, "Error: thix box not present in manfbox\n");
         opj_free(jp2idx);
+        delete_manfbox(&manf);
         return OPJ_FALSE;
     }
     set_thixdata(cidx_box, jp2idx);
@@ -382,6 +386,7 @@ OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *jp2idx)
     if (!search_boxheader("ppix", manf)) {
         fprintf(FCGI_stderr, "Error: ppix box not present in manfbox\n");
         opj_free(jp2idx);
+        delete_manfbox(&manf);
         return OPJ_FALSE;
     }
     set_ppixdata(cidx_box, jp2idx);
@@ -497,6 +502,7 @@ OPJ_BOOL set_tpixdata(box_param_t *cidx_box, index_param_t *jp2idx)
     if (!(faix_box = gene_boxbyType(tpix_box->fd, get_DBoxoff(tpix_box),
                                     get_DBoxlen(tpix_box), "faix"))) {
         fprintf(FCGI_stderr, "Error: faix box not present in tpix box\n");
+        opj_free(tpix_box);
         return OPJ_FALSE;
     }
 
@@ -602,11 +608,13 @@ OPJ_BOOL set_ppixdata(box_param_t *cidx_box, index_param_t *jp2idx)
         if (jp2idx->SIZ.Csiz <= comp_idx) {
             fprintf(FCGI_stderr,
                     "Error: num of faix boxes is not identical to num of components in ppix box\n");
+            delete_manfbox(&manf);
             return OPJ_FALSE;
         }
 
         if (!(faix_box = gene_boxbyOffset(cidx_box->fd, inbox_offset))) {
             fprintf(FCGI_stderr, "Error: faix box not present in ppix box\n");
+            delete_manfbox(&manf);
             return OPJ_FALSE;
         }
 
index e6d1973b4ffdb3a1677ff42f8eb4fad0807f91cf..bb3f5eca42623350c4a6a651e8b370517b67bc21 100644 (file)
@@ -76,6 +76,8 @@ Byte_t * j2k_to_pnm(const char *fn, ihdrbox_param_t **ihdrbox)
     /* setup the decoder decoding parameters using user parameters */
     if (!opj_setup_decoder(l_codec, &parameters)) {
         fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
+        opj_stream_destroy(l_stream);
+        opj_destroy_codec(l_codec);
         return NULL;
     }
 
index 7fa53136b9714fd77761a37c2c7588e32651e370..f9eb04fdca5460a7c9ab9a8d6c052244ed794ffb 100644 (file)
@@ -357,6 +357,7 @@ OPJ_BOOL OPJ_CALLCONV fread_jpip(const char fname[], jpip_dec_param_t *dec)
     }
 
     if (!(dec->jpiplen = (Byte8_t)get_filesize(infd))) {
+        close(infd);
         return OPJ_FALSE;
     }
 
@@ -365,6 +366,7 @@ OPJ_BOOL OPJ_CALLCONV fread_jpip(const char fname[], jpip_dec_param_t *dec)
     if (read(infd, dec->jpipstream, dec->jpiplen) != (int)dec->jpiplen) {
         fprintf(stderr, "file reading error\n");
         opj_free(dec->jpipstream);
+        close(infd);
         return OPJ_FALSE;
     }
 
index 8e036f182db6bb7727e91e7800471a2fddee3b77..3cbf83f57bc7df50bb3e183bb630490d0576895a 100644 (file)
@@ -2822,16 +2822,24 @@ int OPJ_CALLCONV mj2_read_struct(FILE *file, opj_mj2_t *movie)
 
     fseek(file, foffset, SEEK_SET);
     src = (unsigned char*)opj_realloc(src, box.length);
+    if (src == NULL) {
+        opj_event_msg(cio->cinfo, EVT_ERROR, "Error reallocation memory\n");
+        opj_free(src);
+        return 1;
+    }
+
     fsresult = fread(src, box.length, 1, file);
     if (fsresult != 1) {
         opj_event_msg(cio->cinfo, EVT_ERROR,
                       "End of file reached while trying to read MOOV box\n");
+        opj_free(src);
         return 1;
     }
 
     cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, box.length);
 
     if (mj2_read_moov(movie, &img, cio)) {
+        opj_free(src);
         return 1;
     }
 
index 65aa3bc68ca29f0f1eff10e1c99a6c23b468958a..0d7816b85af165da3d2892e537c0fcf608420d1c 100644 (file)
@@ -62,6 +62,7 @@ unsigned int OPJ_CALLCONV yuv_num_frames(mj2_tk_t * tk, char *infile)
         fprintf(stderr,
                 "YUV does not contains any frame of %d x %d size\n", tk->w,
                 tk->h);
+        fclose(f);
         return 0;
     }
     fclose(f);
index 0384d1a9af6da1ed42c1da930ae982412abea856..39e1cd403d076120c36102911fd43c65e85b2d01 100644 (file)
@@ -8,5 +8,6 @@ fuzzingengine.o: fuzzingengine.c
 
 dummyfuzzers: fuzzingengine.o
        $(AR) r libFuzzingEngine.a fuzzingengine.o
-       CXX="${CXX}" CXXFLAGS="-L. ${CXXFLAGS}" SRC=/tmp OUT=/tmp ./build_google_oss_fuzzers.sh
+       LIB_FUZZING_ENGINE="-lFuzzingEngine" CXX="${CXX}" CXXFLAGS="-L. ${CXXFLAGS}" \
+           SRC=/tmp OUT=/tmp ./build_google_oss_fuzzers.sh
        OUT=/tmp ./build_seed_corpus.sh
index 88bda556dc1b4c39266c585bad5073646dd86b25..d99f639fa4a13e1787bc452485cb2135e4f25704 100755 (executable)
@@ -28,7 +28,7 @@ build_fuzzer()
     echo "Building fuzzer $fuzzerName"
     $CXX $CXXFLAGS -std=c++11 -I$SRC_DIR/src/lib/openjp2 -I$SRC_DIR/build/src/lib/openjp2 \
         $sourceFilename $* -o $OUT/$fuzzerName \
-        -lFuzzingEngine $SRC_DIR/build/bin/libopenjp2.a -lm -lpthread
+        $LIB_FUZZING_ENGINE $SRC_DIR/build/bin/libopenjp2.a -lm -lpthread
 }
 
 fuzzerFiles=$(dirname $0)/*.cpp
index 9561fd659867dc026f3cc102edd22b5e78b7bb5a..b1303ad8c58db920fe6ec5fd55295c4959cc230f 100644 (file)
@@ -234,11 +234,13 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
 
     else ()
       # Check if the first argument is equal to opj_compress
-      string(REGEX MATCH "^opj_compress$|^opj_decompress$" EXE_NAME_FOUND ${EXE_NAME})
+      string(REGEX MATCH "^opj_compress$|^opj_compress_no_raw$|^opj_compress_no_raw_lossless$|^opj_decompress$" EXE_NAME_FOUND ${EXE_NAME})
 
       if(EXE_NAME_FOUND)
 
-        string(REGEX MATCH "opj_compress" ENC_TEST_FOUND ${EXE_NAME})
+        string(REGEX MATCH "^opj_compress$|^opj_compress_no_raw$|^opj_compress_no_raw_lossless$" ENC_TEST_FOUND ${EXE_NAME})
+        string(REGEX MATCH "^opj_compress_no_raw$|^opj_compress_no_raw_lossless$" NO_RAW ${EXE_NAME})
+        string(REGEX MATCH "opj_compress_no_raw_lossless" LOSSLESS ${EXE_NAME})
 
       else()
 
@@ -332,16 +334,18 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
                                  PROPERTIES DEPENDS
                                  NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode)
 
-            # Compare the decoding file with baseline generated from the kdu_expand and baseline.j2k
-            add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
-              COMMAND compare_raw_files
-              -b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.raw
-              -t ${OUTPUT_FILENAME}.raw
-            )
+            if(NOT NO_RAW)
+                # Compare the decoding file with baseline generated from the kdu_expand and baseline.j2k
+                add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
+                COMMAND compare_raw_files
+                -b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.raw
+                -t ${OUTPUT_FILENAME}.raw
+                )
 
-            set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
-                                 PROPERTIES DEPENDS
-                                 NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref)
+                set_tests_properties(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base
+                                    PROPERTIES DEPENDS
+                                    NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref)
+            endif()
 
           endif()
 
@@ -361,7 +365,7 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST})
 
           # If lossless compression (simple test is 4 arguments), decompress & compare
           list(LENGTH CMD_ARG_LIST_2 ARG_COUNT)
-          if (ARG_COUNT EQUAL 4)
+          if ((ARG_COUNT EQUAL 4) OR LOSSLESS)
             # can we compare with the input image ?
             if (${INPUT_FILENAME_NAME} MATCHES "\\.tif$")
               add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-lossless-decode
index 75afbed05cb9f6c16cac799e9da69a13194a1f01..76e2f245f31b6b5bc1cc3066f1ceb2eac40fb8df 100644 (file)
@@ -46,10 +46,15 @@ foreach(pgxfullpath ${globfiles})
 
   string(REGEX MATCH "[0-9a-f]+  ${pgxfile}" output_var "${variable}")
 
+  # Search for variant md5sum for libtiff >= 4.1
+  string(REGEX MATCH "libtiff_4_1:[0-9a-f]+  ${pgxfile}" alternate_output_var "${variable}")
+
   set(output "${output}  ${pgxfile}")
 
   if("${output_var}" STREQUAL "${output}")
     message(STATUS "equal: [${output_var}] vs [${output}]")
+  elseif("${alternate_output_var}" STREQUAL "libtiff_4_1:${output}")
+    message(STATUS "equal: [${alternate_output_var}] vs [libtiff_4_1:${output}]")
   else()
     message(SEND_ERROR "not equal: [${output_var}] vs [${output}]")
   endif()
index a33e82a12802598a06ef2b39aafaad359e04e982..95d3d74cbc9d4d34ead6a3c9388e9568a35f0bb0 100644 (file)
@@ -180,6 +180,7 @@ dacaf60e4c430916a8c2a9ebec32e71c  issue458.jp2_3.pgx
 d33fb5dbddb9b9b4438eb51fa27445a3  issue495.jp2_0.pgx
 27db8c35e12a5d5eb94d403d2aae2909  issue495.jp2_1.pgx
 97da625d2f2d0b75bf891d8083ce8bfb  issue495.jp2_2.pgx
+
 86729c5f2b74b2dfd42cb0d8e47aef79  a1_mono_tif-1.tif
 fa9b7b896536b25a7a1d8eeeacb59141  a1_mono_tif-10.tif
 e1f194f69d1c58ce8bed62cd4f1d5b6a  a1_mono_tif-11.tif
@@ -196,6 +197,24 @@ de53251a33356e206a793fbdbaf90db2  a1_mono_tif-13.tif
 e164a6c0219737ee05a3d55d6e3a3104  a1_mono_tif-7.tif
 c3ebfcf478b1c4fc786748813f2b5d53  a1_mono_tif-8.tif
 67adb084f1fe234f240a1d0b2698507e  a1_mono_tif-9.tif
+
+libtiff_4_1:fc19057ff2d65c24daf9c9e25e34a48a  a1_mono_tif-1.tif
+libtiff_4_1:66246b6bbc83c06962f034235acb9924  a1_mono_tif-10.tif
+libtiff_4_1:ce1e07bdafe83a84a5df87fce2ffde6a  a1_mono_tif-11.tif
+libtiff_4_1:614f1ab59ca8473f5f8b1772b7a19d24  a1_mono_tif-12.tif
+libtiff_4_1:941bdcdf9103a22f7b6f66aaca3276d1  a1_mono_tif-13.tif
+libtiff_4_1:38df45296861df2b44879e8a0787d43c  a1_mono_tif-14.tif
+libtiff_4_1:387575ff38bed3d177776891e1b2804e  a1_mono_tif-15.tif
+libtiff_4_1:ee4838fbd88ddcb73ef26df523a3bb5d  a1_mono_tif-16.tif
+libtiff_4_1:6de7e8cbd95e2c465b587f2273daf9dc  a1_mono_tif-2.tif
+libtiff_4_1:e1e026d7ed26e8f3334cf25a8884abbd  a1_mono_tif-3.tif
+libtiff_4_1:c120fac03d1b3756a2deb9b92ba519d4  a1_mono_tif-4.tif
+libtiff_4_1:3a7b84ed9061e0b13996660fc2910e8a  a1_mono_tif-5.tif
+libtiff_4_1:7ac8316261d54f22e6c847fbac01542b  a1_mono_tif-6.tif
+libtiff_4_1:d714670f6746931c4e7defbfbe38b249  a1_mono_tif-7.tif
+libtiff_4_1:b28f4b92be5e3481d44f50f2cd7626aa  a1_mono_tif-8.tif
+libtiff_4_1:2a12dcda3e9927384e7344c4ecabdcf1  a1_mono_tif-9.tif
+
 31650ec40241737634179fff6ad306f8  basn4a08_tif-1.tif
 abf884080bcfbf58c044a9d86bfa5e5d  basn4a08_tif-10.tif
 b0d82c12aa2c9b3ecd96c6a5b5663a8c  basn4a08_tif-11.tif
@@ -212,6 +231,24 @@ fb5cf848d63c61dc485c87c9246ee9c7  basn4a08_tif-16.tif
 18a59ac6036ee64e92af19b7e3cd3d64  basn4a08_tif-7.tif
 dc40cc1da6de28e7e973c8ba796ca189  basn4a08_tif-8.tif
 824b776a5aa3459b77894b5f77621311  basn4a08_tif-9.tif
+
+libtiff_4_1:4c50df5b25e006041b05e8a6fb77c95e  basn4a08_tif-1.tif
+libtiff_4_1:68cc9a9bc5f95474744d06ea4efb2cf3  basn4a08_tif-10.tif
+libtiff_4_1:f643c00bd0673c8f6092125e38759a35  basn4a08_tif-11.tif
+libtiff_4_1:cfcefece2fb08a437876d85941cdaa27  basn4a08_tif-12.tif
+libtiff_4_1:1c3850831691aa8b565e4cd0d13166f9  basn4a08_tif-13.tif
+libtiff_4_1:06059e0429956946ecd3b1893ad39d18  basn4a08_tif-14.tif
+libtiff_4_1:71557ba6728e6641ad289b1d142acade  basn4a08_tif-15.tif
+libtiff_4_1:150c663277b43d0331112f24d47fd34e  basn4a08_tif-16.tif
+libtiff_4_1:9b43011e7a19079c21d65318b4a1139b  basn4a08_tif-2.tif
+libtiff_4_1:125ca7b2e45fafa4e003f5adc9f11da8  basn4a08_tif-3.tif
+libtiff_4_1:9fbc1a8f4d12c8152cde3e004cebd191  basn4a08_tif-4.tif
+libtiff_4_1:51c6b54e9d8b53355c3f73ad813bdeef  basn4a08_tif-5.tif
+libtiff_4_1:604ac42b1a9e7a75d63e97ce40e43442  basn4a08_tif-6.tif
+libtiff_4_1:360d1ce74faffa1a736d5f30c22976ed  basn4a08_tif-7.tif
+libtiff_4_1:2059aaa9e54c09f36d16107870c1546a  basn4a08_tif-8.tif
+libtiff_4_1:07496859507882401d66d70dcf392505  basn4a08_tif-9.tif
+
 59e32c45591fd3bb44fe99381a116ba1  basn6a08_tif-1.tif
 630e6fb6deba0b3efd93b610561d607a  basn6a08_tif-10.tif
 5419fec92f0e0e5907d838dacf9712b4  basn6a08_tif-11.tif
@@ -228,6 +265,24 @@ d60864a6a5c8a49a202d98ae6f5165c7  basn6a08_tif-6.tif
 086fd12fec963995fe2e405dcef7e477  basn6a08_tif-7.tif
 c3e93f61125f82a9832d0b9440468034  basn6a08_tif-8.tif
 a9723dcc0732e74c9e8cd2bf93474a7d  basn6a08_tif-9.tif
+
+libtiff_4_1:98f777ca80a132d8ab820d4533daa5b6  basn6a08_tif-1.tif
+libtiff_4_1:9c5873a1fa5571aad9e73d36d5a4206a  basn6a08_tif-10.tif
+libtiff_4_1:c05dac7d4c19bc4b78cea426e5e52430  basn6a08_tif-11.tif
+libtiff_4_1:0223432f61df2508d0195f696988ddeb  basn6a08_tif-12.tif
+libtiff_4_1:ccc64d14279063ed9daf371be62077f7  basn6a08_tif-13.tif
+libtiff_4_1:ace0bab2c2fbb5f92a8214600df9159f  basn6a08_tif-14.tif
+libtiff_4_1:9b54bda92a09bcac9870fa02b428b7e6  basn6a08_tif-15.tif
+libtiff_4_1:178665d070f54f2920521c4e1cb9d5d0  basn6a08_tif-16.tif
+libtiff_4_1:c4b1e96d19429137cd8871833af2ea5a  basn6a08_tif-2.tif
+libtiff_4_1:44e8b5591740289d0ca52a3e19f19c22  basn6a08_tif-3.tif
+libtiff_4_1:70b4f469dd29c8e99d3f0525301286b8  basn6a08_tif-4.tif
+libtiff_4_1:bf7c35a2b05eecb406aab7959431a842  basn6a08_tif-5.tif
+libtiff_4_1:7d2ecb1c35869ddbafd11b4896357b81  basn6a08_tif-6.tif
+libtiff_4_1:2cd6ec32a0256806f46706c0ca564d9d  basn6a08_tif-7.tif
+libtiff_4_1:116b611b7a358bee2c4f2695732ec357  basn6a08_tif-8.tif
+libtiff_4_1:ed9ca54d25fb5b0cd5339eedfa16cbea  basn6a08_tif-9.tif
+
 cfe04d15cf9d615fc36357dcb3b3956b  p0_14_tif-1.tif
 9ad87e7fddc77ac85e2e92509bee2365  p0_14_tif-10.tif
 f144e26d6d5aa24d98f0415f10751025  p0_14_tif-11.tif
@@ -244,6 +299,24 @@ b6f71c941e3a5b8d2547792ccec58d54  p0_14_tif-4.tif
 951c99efbd922d8f3feb015e9ef8e350  p0_14_tif-7.tif
 6808377b760b4ef3559ba8b14ed9b91a  p0_14_tif-8.tif
 96aa7dafa873d0ce33f84bb1ff78fa9b  p0_14_tif-9.tif
+
+libtiff_4_1:5f97d4bbab138f99b6b125e5a5bf96bd  p0_14_tif-1.tif
+libtiff_4_1:686c7a1561d73e53c000800ec0c5fa0a  p0_14_tif-10.tif
+libtiff_4_1:a8585d901cc1b7cbbda6e524ecb5db35  p0_14_tif-11.tif
+libtiff_4_1:17b5497c9b8a0c68739c0beae90aa432  p0_14_tif-12.tif
+libtiff_4_1:a024a04b96ccb13c81cd57a5ee6ad07a  p0_14_tif-13.tif
+libtiff_4_1:aabadca3f87437a32878fef7e265b23a  p0_14_tif-14.tif
+libtiff_4_1:5390a77296962268b73a793467092633  p0_14_tif-15.tif
+libtiff_4_1:47dc7cc71832e5739c32794a713966c3  p0_14_tif-16.tif
+libtiff_4_1:1a9247cd1fb26f5fffa870e8543f6d30  p0_14_tif-2.tif
+libtiff_4_1:e4c0c9481d4032ea6b7e6a08a39e9030  p0_14_tif-3.tif
+libtiff_4_1:c7d6ec9b235aaff146228875e69edbaa  p0_14_tif-4.tif
+libtiff_4_1:d3b8110b2284a09cfb7d5c4ffd451aff  p0_14_tif-5.tif
+libtiff_4_1:6189ee17c4a276f99302ac7e296b3daa  p0_14_tif-6.tif
+libtiff_4_1:b4a3b9b63681448abb7c460702de4df9  p0_14_tif-7.tif
+libtiff_4_1:04deb4e9679e7971c2cd0449fcd255b7  p0_14_tif-8.tif
+libtiff_4_1:254443e438ed6a5b0631d6188cc84789  p0_14_tif-9.tif
+
 dd15b3d487d36a3682be0679300a4319  issue235.jp2_0.pgx
 b9cd6dc76b141fb1fec15f50c1f70e01  issue235.jp2_1.pgx
 3edef2ae197ef30b08deda1b28825399  issue235.jp2_2.pgx
@@ -288,6 +361,7 @@ fc2844a9f3c8e924e349180ba9e122dd  p0_14_png-2.png
 8d7685f1569d446787476c0a56c93750  dwt_interleave_h.gsr105.jp2_1.pgx
 ddfff2ce2df4a9102518c92a362e6d25  dwt_interleave_h.gsr105.jp2_2.pgx
 63bf755af5a1f8a478d65079dc7c8964  issue205-tif.jp2.tif
+libtiff_4_1:f9678a9e12d540f768ebebaee2af8f14  issue205-tif.jp2.tif
 b01ed87dbac424bc820b2ac590e4884e  issue236-ESYCC-CDEF.jp2_0.pgx
 2635cc00b1e18ef11adcba09e845d459  issue236-ESYCC-CDEF.jp2_1.pgx
 f9c95d0aec2f6e7b814fa1d09edcdbda  issue236-ESYCC-CDEF.jp2_2.pgx
@@ -310,11 +384,11 @@ d1bb7f93f4c0eb984b2e9c54e544b7e9  broken.jpc_1.pgx
 b704ad4c0cfefffd78c20a54f5541265  dwt_interleave_h.gsr105.jp2_d_1_1_33_33_0.pgx
 9d7fe43cd7a50b7bbaf712926ee11980  dwt_interleave_h.gsr105.jp2_d_1_1_33_33_1.pgx
 0960b580f991ff10f693b24aa41ad58b  dwt_interleave_h.gsr105.jp2_d_1_1_33_33_2.pgx
-fa7382fd8b2e788b28b807e200dd95b9  file1.jp2-c0.tif
-ed79b7fe443955cdefba2b039ddc846a  file1.jp2-c0_1_2.tif
-ac8f6ab3acc9c692ed7c41bd62a0e1e8  file1.jp2-c0-r1.tif
-fbfcf662b6f7549574b2885490fbcf12  file1.jp2-c0-d10_20_30_40.tif
-fa7382fd8b2e788b28b807e200dd95b9  file1.jp2-c0-t0.tif
-ac8f6ab3acc9c692ed7c41bd62a0e1e8  file1.jp2-c0-t0-r1.tif
+6e23ded7d3ca0b1dd8405448e3ff931b  file1.jp2-c0.png
+5acabea0ef6d09d2c1f681773e886935  file1.jp2-c0_1_2.png
+1150acbee2c1e33c57592c05c76e565a  file1.jp2-c0-r1.png
+1b8ab42d8ee4e28d2868c04a815fb569  file1.jp2-c0-d10_20_30_40.png
+6e23ded7d3ca0b1dd8405448e3ff931b  file1.jp2-c0-t0.png
+1150acbee2c1e33c57592c05c76e565a  file1.jp2-c0-t0-r1.png
 f31bcb01c771f829054cdb013575e86a  issue1043.png
 62bc654c830efddf1b23d6e208447dab  tnsot_zero.png
index c42bad162dce82269ca131ecd0538f86b2ef324b..3ed97ab1a91f989b183f26437e864207e02fec01 100644 (file)
@@ -176,6 +176,16 @@ opj_compress -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_one_poc.j2k -n 2 -r
 opj_compress -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_one_poc_funky_bounds.j2k -n 2 -r 20,1 -POC T1=0,0,65535,33,255,CPRL -b 4,4
 opj_compress -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_one_poc_unrelated_tile.j2k -n 1 -POC T1000=0,0,1,1,1,CPRL
 
+opj_compress_no_raw -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_IMF_2K.j2k -IMF 2K
+opj_compress_no_raw -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_IMF_4K.j2k -IMF 4K
+opj_compress_no_raw -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_IMF_8K.j2k -IMF 8K
+opj_compress_no_raw_lossless -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_IMF_2K_R.j2k -IMF 2K_R
+opj_compress_no_raw_lossless -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_IMF_4K_R.j2k -IMF 4K_R
+opj_compress_no_raw_lossless -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_IMF_8K_R.j2k -IMF 8K_R
+
+opj_compress_no_raw_lossless -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_PLT.j2k -n 1 -PLT
+opj_compress_no_raw_lossless -i @INPUT_NR_PATH@/byte.tif -o @TEMP_PATH@/byte_PLT.jp2 -n 1 -PLT
+
 # DECODER TEST SUITE
 opj_decompress -i  @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx
 opj_decompress -i  @INPUT_NR_PATH@/_00042.j2k -o @TEMP_PATH@/_00042.j2k.pgx
@@ -612,22 +622,22 @@ opj_decompress -i @INPUT_NR_PATH@/issue979.j2k -o @TEMP_PATH@/issue979.j2k.pgx
 opj_decompress -i @INPUT_NR_PATH@/dwt_interleave_h.gsr105.jp2 -o @TEMP_PATH@/dwt_interleave_h.gsr105.jp2_d_1_1_33_33.pgx -d 1,1,33,33
 
 # partial component decoding with opj_decode(): one component
-opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0.tif -c 0
+opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0.png -c 0
 # partial component decoding with opj_decode(): 3 components without MCT
-opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0_1_2.tif -c 0,1,2
+opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0_1_2.png -c 0,1,2
 # partial component decoding with opj_decode() and opj_set_decode_area()
-opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-d10_20_30_40.tif -c 0 -d 10,20,30,40
+opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-d10_20_30_40.png -c 0 -d 10,20,30,40
 # partial component decoding with opj_decode() and reduced resolution
-opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-r1.tif -c 0 -r 1
+opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-r1.png -c 0 -r 1
 # partial component decoding with opj_get_decoded_tile()
-opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-t0.tif -c 0 -t 0
+opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-t0.png -c 0 -t 0
 # partial component decoding with opj_get_decoded_tile() and reduced resolution
-opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-t0-r1.tif -c 0 -t 0 -r 1
+opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0-t0-r1.png -c 0 -t 0 -r 1
 
 # try to map the same component several times
-!opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0_0.tif -c 0,0
+!opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c0_0.png -c 0,0
 # try to map an invalid component
-!opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c10.tif -c 10
+!opj_decompress -i @INPUT_CONF_PATH@/file1.jp2 -o @TEMP_PATH@/file1.jp2-c10.png -c 10
 
 opj_decompress -i @INPUT_NR_PATH@/db11217111510058.jp2 -o @TEMP_PATH@/issue1043.png
 
index f86c7028e079af5e2990426429a59eb89d49302f..4c0a8387ed792112c2d50cbf596ebbe51ab89e4d 100755 (executable)
@@ -95,6 +95,12 @@ else
 fi
 cp -rf ${OPJ_SOURCE_DIR} src/openjpeg/current
 abi-monitor -v current -build openjpeg.json
+
+rm -rf ./installed/openjpeg/${OPJ_LATEST_VERSION}
+rm -rf ./compat_report/openjpeg/${OPJ_LATEST_VERSION}
+rm -rf ./abi_dump/openjpeg/${OPJ_LATEST_VERSION}
+rm -rf ./headers_diff/openjpeg/${OPJ_LATEST_VERSION}
+rm -rf ./objects_report/openjpeg/${OPJ_LATEST_VERSION}
 abi-monitor -v ${OPJ_LATEST_VERSION} -build openjpeg.json
 if [ "${OPJ_PREVIOUS_VERSION:-}" != "" ]; then
        abi-monitor -v ${OPJ_PREVIOUS_VERSION} -build openjpeg.json
@@ -112,6 +118,9 @@ fi
 # Check ABI
 if [ "${OPJ_LIMIT_ABI_BUILDS}" != "" ]; then
        abi-compliance-checker -l openjpeg -old $(find ./abi_dump/openjpeg/$OPJ_LATEST_VERSION -name '*.dump') -new $(find ./abi_dump/openjpeg/current -name '*.dump') -header openjpeg.h -abi -s || EXIT_CODE=1
+        if [ ${EXIT_CODE} -eq 1 ]; then
+            cat "compat_reports/openjpeg/${OPJ_LATEST_VERSION}_to_current/abi_compat_report.html"
+        fi
        if [ "${OPJ_PREVIOUS_VERSION:-}" != "" ]; then
                abi-compliance-checker -l openjpeg -old $(find ./abi_dump/openjpeg/$OPJ_PREVIOUS_VERSION -name '*.dump') -new $(find ./abi_dump/openjpeg/$OPJ_LATEST_VERSION -name '*.dump') -header openjpeg.h -abi -s || EXIT_CODE=1
        fi