[trunk] refactoring of rsiz, profiles, and extensions management
[openjpeg.git] / src / bin / jp2 / opj_compress.c
index 1934bf7616b2de96fd87f4dc52ecd138977f4508..aba30ef949fa591af5b34d5ae7d23e2026a87a25 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * The copyright in this software is being made available under the 2-clauses 
+ * BSD License, included below. This software may be subject to other third 
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
  * Copyright (c) 2001-2003, David Janssens
  * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * Copyright (c) 2006-2007, Parvatha Elangovan
  * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
 
 #include "format_defs.h"
 
-#define CINEMA_24_CS 1302083   /*Codestream length for 24fps*/
-#define CINEMA_48_CS 651041            /*Codestream length for 48fps*/
-#define COMP_24_CS 1041666             /*Maximum size per color component for 2K & 4K @ 24fps*/
-#define COMP_48_CS 520833              /*Maximum size per color component for 2K @ 48fps*/
-
 typedef struct dircnt{
     /** Buffer for holding images read from Directory*/
     char *filename_buf;
@@ -107,6 +108,7 @@ static void encode_help_display(void) {
     fprintf(stdout,"\n");
     fprintf(stdout," * Lossless\n");
     fprintf(stdout," * 1 tile\n");
+    fprintf(stdout," * RGB->YCC conversion if at least 3 components\n");
     fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
     fprintf(stdout," * Size of code-block : 64 x 64\n");
     fprintf(stdout," * Number of resolutions: 6\n");
@@ -138,7 +140,7 @@ static void encode_help_display(void) {
     fprintf(stdout,"-OutFor \n");
     fprintf(stdout,"    REQUIRED only if -ImgDir is used\n");
     fprintf(stdout,"     Need to specify only format without filename <BMP>  \n");
-    fprintf(stdout,"    Currently accepts PBM, PGM, PPM, PNM, PAM, PGX, PNG, BMP, TIF, RAW, RAWL and TGA formats\n");
+    fprintf(stdout,"    Currently accepts PBM, PGM, PPM, PNM, PAM, PGX, PNG, BMP, TIF, RAW (MSB), RAWL (LSB) and TGA formats\n");
     fprintf(stdout,"\n");
     fprintf(stdout,"-i           : source file  (-i source.pnm also *pbm, *.pgm, *.ppm, *.pam, *.pgx, *png, *.bmp, *.tif, *.raw, *.tga) \n");
     fprintf(stdout,"    When using this option -o must be used\n");
@@ -213,8 +215,14 @@ static void encode_help_display(void) {
     fprintf(stdout,"               -F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
     fprintf(stdout,"               Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
     fprintf(stdout,"\n");
-    fprintf(stdout,"-m           : use array-based MCT, values are coma separated, line by line\n");
-    fprintf(stdout,"                      no specific separators between lines, no space allowed between values\n");
+    fprintf(stdout,"-mct {0,1,2} : explicitely specifies if a Multiple Component Transform has to be used.\n");
+    fprintf(stdout,"               0: no MCT ; 1: RGB->YCC conversion ; 2: custom MCT.\n");
+    fprintf(stdout,"               If custom MCT, \"-m\" option has to be used (see hereunder).\n");
+    fprintf(stdout,"               By default, RGB->YCC conversion is used if there are 3 components or more,\n");
+    fprintf(stdout,"               no conversion otherwise.\n");
+    fprintf(stdout,"-m <file>    : use array-based MCT, values are coma separated, line by line\n");
+    fprintf(stdout,"               no specific separators between lines, no space allowed between values\n");
+    fprintf(stdout,"               If this option is used, it automatically sets \"-mct\" option to 2.\n");
     fprintf(stdout,"-jpip        : write jpip codestream index box in JP2 output file\n");
     fprintf(stdout,"               NOTICE: currently supports only RPCL order\n");
     fprintf(stdout,"\n");
@@ -413,9 +421,7 @@ static int get_file_format(char *filename) {
 }
 
 static char * get_file_name(char *name){
-    char *fname;
-    fname= (char*)malloc(OPJ_PATH_LEN*sizeof(char));
-    fname= strtok(name,".");
+    char *fname = strtok(name,".");
     return fname;
 }
 
@@ -444,249 +450,6 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_c
     return 0;
 }
 
-static int initialise_4K_poc(opj_poc_t *POC, int numres){
-    POC[0].tile  = 1;
-    POC[0].resno0  = 0;
-    POC[0].compno0 = 0;
-    POC[0].layno1  = 1;
-    POC[0].resno1  = numres-1;
-    POC[0].compno1 = 3;
-    POC[0].prg1 = OPJ_CPRL;
-    POC[1].tile  = 1;
-    POC[1].resno0  = numres-1;
-    POC[1].compno0 = 0;
-    POC[1].layno1  = 1;
-    POC[1].resno1  = numres;
-    POC[1].compno1 = 3;
-    POC[1].prg1 = OPJ_CPRL;
-    return 2;
-}
-
-static void set_cinema_parameters(opj_cparameters_t *parameters)
-{
-    /* Configure cinema parameters */
-    float max_rate = 0;
-    float temp_rate = 0;
-    int i;
-
-    /* profile (Rsiz) */
-    switch (parameters->cp_cinema){
-    case OPJ_CINEMA2K_24:
-    case OPJ_CINEMA2K_48:
-        parameters->cp_rsiz = OPJ_CINEMA2K;
-        break;
-    case OPJ_CINEMA4K_24:
-        parameters->cp_rsiz = OPJ_CINEMA4K;
-        break;
-    }
-
-    /* No tiling */
-    parameters->tile_size_on = OPJ_FALSE;
-    parameters->cp_tdx=1;
-    parameters->cp_tdy=1;
-
-    /* One tile part for each component */
-    parameters->tp_flag = 'C';
-    parameters->tp_on = 1;
-
-    /* Tile and Image shall be at (0,0) */
-    parameters->cp_tx0 = 0;
-    parameters->cp_ty0 = 0;
-    parameters->image_offset_x0 = 0;
-    parameters->image_offset_y0 = 0;
-
-    /* Codeblock size= 32*32 */
-    parameters->cblockw_init = 32;
-    parameters->cblockh_init = 32;
-
-    /* Codeblock style: no mode switch enabled */
-    parameters->mode = 0;
-
-    /* No ROI */
-    parameters->roi_compno = -1;
-
-    /* No subsampling */
-    parameters->subsampling_dx = 1;
-    parameters->subsampling_dy = 1;
-
-    /* 9-7 transform */
-    parameters->irreversible = 1;
-
-    /* Number of layers */
-    if (parameters->tcp_numlayers > 1){
-        fprintf(stdout,"JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n"
-                "1 single quality layer"
-                "-> Number of layers forced to 1 (rather than %d)\n",
-                parameters->tcp_numlayers);
-        parameters->tcp_numlayers = 1;
-    }
-
-    /* Resolution levels */
-    switch (parameters->cp_cinema){
-    case OPJ_CINEMA2K_24:
-    case OPJ_CINEMA2K_48:
-        if(parameters->numresolution > 6){
-            fprintf(stdout,"JPEG 2000 Profile-3 (2k dc profile) requires:\n"
-                    "Number of decomposition levels <= 5\n"
-                    "-> Number of decomposition levels forced to 5 (rather than %d)\n",
-                    parameters->numresolution+1);
-            parameters->numresolution = 6;
-        }
-        break;
-    case OPJ_CINEMA4K_24:
-        if(parameters->numresolution < 2){
-            fprintf(stdout,"JPEG 2000 Profile-4 (4k dc profile) requires:\n"
-                    "Number of decomposition levels >= 1 && <= 6\n"
-                    "-> Number of decomposition levels forced to 1 (rather than %d)\n",
-                    parameters->numresolution+1);
-            parameters->numresolution = 1;
-        }else if(parameters->numresolution > 7){
-            fprintf(stdout,"JPEG 2000 Profile-4 (4k dc profile) requires:\n"
-                    "Number of decomposition levels >= 1 && <= 6\n"
-                    "-> Number of decomposition levels forced to 6 (rather than %d)\n",
-                    parameters->numresolution+1);
-            parameters->numresolution = 7;
-        }
-        break;
-    default :
-        break;
-    }
-
-    /* Precincts */
-    parameters->csty |= 0x01;
-    parameters->res_spec = parameters->numresolution-1;
-    for (i = 0; i<parameters->res_spec; i++) {
-        parameters->prcw_init[i] = 256;
-        parameters->prch_init[i] = 256;
-    }
-
-    /* The progression order shall be CPRL */
-    parameters->prog_order = OPJ_CPRL;
-
-    /* Progression order changes for 4K, disallowed for 2K */
-    if (parameters->cp_cinema == OPJ_CINEMA4K_24) {
-        parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
-    } else {
-        parameters->numpocs = 0;
-    }
-}
-
-static void set_cinema_rate(opj_cparameters_t *parameters, opj_image_t *image)
-{
-    /* Limited bit-rate */
-    float max_rate = 0;
-    float temp_rate = 0;
-    parameters->cp_disto_alloc = 1;
-    switch (parameters->cp_cinema){
-    case OPJ_CINEMA2K_24:
-    case OPJ_CINEMA4K_24:
-        max_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
-                (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
-        if (parameters->tcp_rates[0] == 0){
-            parameters->tcp_rates[0] = max_rate;
-        }else{
-            temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
-                    (parameters->tcp_rates[0] * 8 * image->comps[0].dx * image->comps[0].dy);
-            if (temp_rate > CINEMA_24_CS ){
-                fprintf(stdout,"JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n"
-                        "Maximum 1302083 compressed bytes @ 24fps\n"
-                        "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n",
-                        parameters->tcp_rates[0], max_rate);
-                parameters->tcp_rates[0]= max_rate;
-            }else{
-                fprintf(stdout,"JPEG 2000 Profile-3 and 4 (2k/4k dc profile):\n"
-                        "INFO : Specified rate (%3.1f) is below the 2k/4k limit @ 24fps.\n",
-                        parameters->tcp_rates[0]);
-            }
-        }
-        parameters->max_comp_size = COMP_24_CS;
-        break;
-    case OPJ_CINEMA2K_48:
-        max_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
-                (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
-        if (parameters->tcp_rates[0] == 0){
-            parameters->tcp_rates[0] = max_rate;
-        }else{
-            temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
-                    (parameters->tcp_rates[0] * 8 * image->comps[0].dx * image->comps[0].dy);
-            if (temp_rate > CINEMA_48_CS ){
-                fprintf(stdout,"JPEG 2000 Profile-3 (2k dc profile) requires:\n"
-                        "Maximum 651041 compressed bytes @ 48fps\n"
-                        "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n",
-                        parameters->tcp_rates[0], max_rate);
-                parameters->tcp_rates[0]= max_rate;
-            }else{
-                fprintf(stdout,"JPEG 2000 Profile-3 (2k dc profile):\n"
-                        "INFO : Specified rate (%3.1f) is below the 2k limit @ 48 fps.\n",
-                        parameters->tcp_rates[0]);
-            }
-        }
-        parameters->max_comp_size = COMP_48_CS;
-        break;
-    default:
-        break;
-    }
-}
-
-static OPJ_BOOL is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode)
-{
-    OPJ_UINT32 i;
-
-    /* Number of components */
-    if (image->numcomps != 3){
-        fprintf(stdout,"JPEG 2000 Profile-3 (2k dc profile) requires:\n"
-                "3 components"
-                "-> Number of components of input image (%d) is not compliant\n"
-                "-> Non-profile-3 codestream will be generated\n",
-                image->numcomps);
-        return OPJ_FALSE;
-    }
-
-    /* Bitdepth */
-    for (i = 0; i < image->numcomps; i++) {
-        if ((image->comps[i].bpp != 12) | (image->comps[i].sgnd)){
-            char signed_str[] = "signed";
-            char unsigned_str[] = "unsigned";
-            char *tmp_str = image->comps[i].sgnd?signed_str:unsigned_str;
-            fprintf(stdout,"JPEG 2000 Profile-3 (2k dc profile) requires:\n"
-                    "Precision of each component shall be 12 bits unsigned"
-                    "-> At least component %d of input image (%d bits, %s) is not compliant\n"
-                    "-> Non-profile-3 codestream will be generated\n",
-                    i,image->comps[i].bpp, tmp_str);
-            return OPJ_FALSE;
-        }
-    }
-
-    /* Image size */
-    switch (cinema_mode){
-    case OPJ_CINEMA2K_24:
-    case OPJ_CINEMA2K_48:
-        if (!((image->comps[0].w > 2048) | (image->comps[0].h > 1080))){
-            fprintf(stdout,"JPEG 2000 Profile-3 (2k dc profile) requires:\n"
-                    "width <= 2048 and height <= 1080\n"
-                    "-> Input image size %d x %d is not compliant\n"
-                    "-> Non-profile-3 codestream will be generated\n",
-                    image->comps[0].w,image->comps[0].h);
-            return OPJ_FALSE;
-        }
-        break;
-    case OPJ_CINEMA4K_24:
-        if (!((image->comps[0].w > 4096) | (image->comps[0].h > 2160))){
-            fprintf(stdout,"JPEG 2000 Profile-4 (4k dc profile) requires:\n"
-                    "width <= 4096 and height <= 2160\n"
-                    "-> Image size %d x %d is not compliant\n"
-                    "-> Non-profile-4 codestream will be generated\n",
-                    image->comps[0].w,image->comps[0].h);
-            return OPJ_FALSE;
-        }
-        break;
-    default :
-        break;
-    }
-
-    return OPJ_TRUE;
-}
-
 /* ------------------------------------------------------------------------------------ */
 
 static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
@@ -703,11 +466,12 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
         {"OutFor",REQ_ARG, NULL ,'O'},
         {"POC",REQ_ARG, NULL ,'P'},
         {"ROI",REQ_ARG, NULL ,'R'},
-        {"jpip",NO_ARG, NULL, 'J'}
+        {"jpip",NO_ARG, NULL, 'J'},
+        {"mct",REQ_ARG, NULL, 'Y'}
     };
 
     /* parse the command line */
-    const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:J"
+    const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:JY:"
         #ifdef USE_JPWL
             "W:"
         #endif /* USE_JPWL */
@@ -811,31 +575,82 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
 
         case 'F':                      /* Raw image format parameters */
         {
+            OPJ_BOOL wrong = OPJ_FALSE;
+            char *substr1;
+            char *substr2;
+            char *sep;
             char signo;
-            char *s = opj_optarg;
-            if (sscanf(s, "%d,%d,%d,%d,%c", &raw_cp->rawWidth, &raw_cp->rawHeight, &raw_cp->rawComp, &raw_cp->rawBitDepth, &signo) == 5) {
+            int width,height,bitdepth,ncomp;
+            OPJ_UINT32 len;
+            OPJ_BOOL raw_signed;
+            substr2 = strchr(opj_optarg,'@');
+            if (substr2 == NULL) {
+                len = (OPJ_UINT32) strlen(opj_optarg);
+            } else {
+                len = (OPJ_UINT32) (substr2 - opj_optarg);
+                substr2++; /* skip '@' character */
+            }
+            substr1 = (char*) malloc((len+1)*sizeof(char));
+            memcpy(substr1,opj_optarg,len);
+            substr1[len] = '\0';
+            if (sscanf(substr1, "%d,%d,%d,%d,%c", &width, &height, &ncomp, &bitdepth, &signo) == 5) {
                 if (signo == 's') {
-                    raw_cp->rawSigned = OPJ_TRUE;
-                    fprintf(stdout,"\nRaw file parameters: %d,%d,%d,%d Signed\n", raw_cp->rawWidth, raw_cp->rawHeight, raw_cp->rawComp, raw_cp->rawBitDepth);
+                    raw_signed = OPJ_TRUE;
+                } else if (signo == 'u') {
+                    raw_signed = OPJ_FALSE;
+                } else {
+                    wrong = OPJ_TRUE;
                 }
-                else if (signo == 'u') {
-                    raw_cp->rawSigned = OPJ_FALSE;
-                    fprintf(stdout,"\nRaw file parameters: %d,%d,%d,%d Unsigned\n", raw_cp->rawWidth, raw_cp->rawHeight, raw_cp->rawComp, raw_cp->rawBitDepth);
-                }
-                else {
-                    fprintf(stderr,"\nError: invalid raw image parameters: Unknown sign of raw file\n");
-                    fprintf(stderr,"Please use the Format option -F:\n");
-                    fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
-                    fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
-                    fprintf(stderr,"Aborting\n");
+            } else {
+                wrong = OPJ_TRUE;
+            }
+            if (!wrong) {
+                int i;
+                int lastdx = 1;
+                int lastdy = 1;
+                raw_cp->rawWidth = width;
+                raw_cp->rawHeight = height;
+                raw_cp->rawComp = ncomp;
+                raw_cp->rawBitDepth = bitdepth;
+                raw_cp->rawSigned  = raw_signed;
+                raw_cp->rawComps = (raw_comp_cparameters_t*) malloc(((OPJ_UINT32)(ncomp))*sizeof(raw_comp_cparameters_t));
+                for (i = 0; i < ncomp && !wrong; i++) {
+                    if (substr2 == NULL) {
+                        raw_cp->rawComps[i].dx = lastdx;
+                        raw_cp->rawComps[i].dy = lastdy;
+                    } else {
+                        int dx,dy;
+                        sep = strchr(substr2,':');
+                        if (sep == NULL) {
+                            if (sscanf(substr2, "%dx%d", &dx, &dy) == 2) {
+                                lastdx = dx;
+                                lastdy = dy;
+                                raw_cp->rawComps[i].dx = dx;
+                                raw_cp->rawComps[i].dy = dy;
+                                substr2 = NULL;
+                            } else {
+                                wrong = OPJ_TRUE;
+                            }
+                        } else {
+                            if (sscanf(substr2, "%dx%d:%s", &dx, &dy, substr2) == 3) {
+                                raw_cp->rawComps[i].dx = dx;
+                                raw_cp->rawComps[i].dy = dy;
+                            } else {
+                                wrong = OPJ_TRUE;
+                            }
+                        }
+                    }
                 }
             }
-            else {
+            if (substr1) free(substr1);
+            if (wrong) {
                 fprintf(stderr,"\nError: invalid raw image parameters\n");
                 fprintf(stderr,"Please use the Format option -F:\n");
-                fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
-                fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
-                fprintf(stderr,"Aborting\n");
+                fprintf(stderr,"-F <width>,<height>,<ncomp>,<bitdepth>,{s,u}@<dx1>x<dy1>:...:<dxn>x<dyn>\n");
+                fprintf(stderr,"If subsampling is omitted, 1x1 is assumed for all components\n");
+                fprintf(stderr,"Example: -i image.raw -o image.j2k -F 512,512,3,8,u@1x1:2x2:2x2\n");
+                fprintf(stderr,"         for raw 512x512 image with 4:2:0 subsampling\n");
+                fprintf(stderr,"Aborting.\n");
                 return 1;
             }
         }
@@ -868,13 +683,13 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
             OPJ_UINT32 numlayers = 0, numresolution = 0, matrix_width = 0;
 
             char *s = opj_optarg;
-            sscanf(s, "%d", &numlayers);
+            sscanf(s, "%ud", &numlayers);
             s++;
             if (numlayers > 9)
                 s++;
 
-            parameters->tcp_numlayers = numlayers;
-            numresolution = parameters->numresolution;
+            parameters->tcp_numlayers = (int)numlayers;
+            numresolution = (OPJ_UINT32)parameters->numresolution;
             matrix_width = numresolution * 3;
             parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
             s = s + 2;
@@ -931,10 +746,17 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
             int res_spec = 0;
 
             char *s = opj_optarg;
+            int ret;
             do {
                 sep = 0;
-                sscanf(s, "[%d,%d]%c", &parameters->prcw_init[res_spec],
+                ret = sscanf(s, "[%d,%d]%c", &parameters->prcw_init[res_spec],
                        &parameters->prch_init[res_spec], &sep);
+                if( !(ret == 2 && sep == 0) && !(ret == 3 && sep == ',') )
+                  {
+                  fprintf(stderr,"\nError: could not parse precinct dimension: '%s' %x\n", s, sep);
+                  fprintf(stderr,"Example: -i lena.raw -o lena.j2k -c [128,128],[128,128]\n");
+                  return 1;
+                  }
                 parameters->csty |= 0x01;
                 res_spec++;
                 s = strpbrk(s, "]") + 2;
@@ -1028,7 +850,7 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
             char *s = opj_optarg;
             POC = parameters->POC;
 
-            while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
+            while (sscanf(s, "T%ud=%ud,%ud,%ud,%ud,%ud,%4s", &POC[numpocs].tile,
                           &POC[numpocs].resno0, &POC[numpocs].compno0,
                           &POC[numpocs].layno1, &POC[numpocs].resno1,
                           &POC[numpocs].compno1, POC[numpocs].progorder) == 7) {
@@ -1042,7 +864,7 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
                 }
                 s++;
             }
-            parameters->numpocs = numpocs;
+            parameters->numpocs = (OPJ_UINT32)numpocs;
         }
             break;
 
@@ -1146,9 +968,13 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
             int fps=0;
             sscanf(opj_optarg,"%d",&fps);
             if(fps == 24){
-                parameters->cp_cinema = OPJ_CINEMA2K_24;
+                parameters->rsiz = OPJ_PROFILE_CINEMA_2K;
+                parameters->max_comp_size = OPJ_CINEMA_24_COMP;
+                parameters->max_cs_size = OPJ_CINEMA_24_CS;
             }else if(fps == 48 ){
-                parameters->cp_cinema = OPJ_CINEMA2K_48;
+                parameters->rsiz = OPJ_PROFILE_CINEMA_2K;
+                parameters->max_comp_size = OPJ_CINEMA_48_COMP;
+                parameters->max_cs_size = OPJ_CINEMA_48_CS;
             }else {
                 fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
                 return 1;
@@ -1163,13 +989,29 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
 
         case 'y':                      /* Digital Cinema 4K profile compliance*/
         {
-            parameters->cp_cinema = OPJ_CINEMA4K_24;
+            parameters->rsiz = OPJ_PROFILE_CINEMA_4K;
             fprintf(stdout,"CINEMA 4K profile activated\n"
                     "Other options specified could be overriden\n");
         }
             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);
+            if(mct_mode < 0 || mct_mode > 2){
+                fprintf(stderr,"MCT incorrect value!! Current accepted values are 0, 1 or 2.\n");
+                return 1;
+            }
+            parameters->tcp_mct = (char) mct_mode;
+        }
+            break;
+
+            /* ------------------------------------------------------ */
+
+
         case 'm':                      /* mct input file */
         {
             char *lFilename = opj_optarg;
@@ -1178,7 +1020,8 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
             float *lCurrentDoublePtr;
             float *lSpace;
             int *l_int_ptr;
-            int lNbComp = 0, lTotalComp, lMctComp, i, lStrLen;
+            int lNbComp = 0, lTotalComp, lMctComp, i2;
+            size_t lStrLen, lStrFread;
 
             /* Open file */
             FILE * lFile = fopen(lFilename,"r");
@@ -1188,11 +1031,12 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
 
             /* Set size of file and read its content*/
             fseek(lFile,0,SEEK_END);
-            lStrLen = ftell(lFile);
+            lStrLen = (size_t)ftell(lFile);
             fseek(lFile,0,SEEK_SET);
             lMatrix = (char *) malloc(lStrLen + 1);
-            fread(lMatrix, lStrLen, 1, lFile);
+            lStrFread = fread(lMatrix, 1, lStrLen, lFile);
             fclose(lFile);
+            if( lStrLen != lStrFread ) return 1;
 
             lMatrix[lStrLen] = 0;
             lCurrentPtr = lMatrix;
@@ -1211,23 +1055,23 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
             lNbComp = (int) (sqrt(4*lNbComp + 1)/2. - 0.5);
             lMctComp = lNbComp * lNbComp;
             lTotalComp = lMctComp + lNbComp;
-            lSpace = (float *) malloc(lTotalComp * sizeof(float));
+            lSpace = (float *) malloc((size_t)lTotalComp * sizeof(float));
             lCurrentDoublePtr = lSpace;
-            for (i=0;i<lMctComp;++i) {
+            for (i2=0;i2<lMctComp;++i2) {
                 lStrLen = strlen(lCurrentPtr) + 1;
                 *lCurrentDoublePtr++ = (float) atof(lCurrentPtr);
                 lCurrentPtr += lStrLen;
             }
 
             l_int_ptr = (int*) lCurrentDoublePtr;
-            for (i=0;i<lNbComp;++i) {
+            for (i2=0;i2<lNbComp;++i2) {
                 lStrLen = strlen(lCurrentPtr) + 1;
                 *l_int_ptr++ = atoi(lCurrentPtr);
                 lCurrentPtr += lStrLen;
             }
 
             /* TODO should not be here ! */
-            opj_set_MCT(parameters, lSpace, (int *)(lSpace + lMctComp), lNbComp);
+            opj_set_MCT(parameters, lSpace, (int *)(lSpace + lMctComp), (OPJ_UINT32)lNbComp);
 
             /* Free memory*/
             free(lSpace);
@@ -1639,28 +1483,6 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param
 
 /* -------------------------------------------------------------------------- */
 
-/**
-sample error callback expecting a FILE* client object
-*/
-static void error_file_callback(const char *msg, void *client_data) {
-    FILE *stream = (FILE*)client_data;
-    fprintf(stream, "[ERROR] %s", msg);
-}
-/**
-sample warning callback expecting a FILE* client object
-*/
-static void warning_file_callback(const char *msg, void *client_data) {
-    FILE *stream = (FILE*)client_data;
-    fprintf(stream, "[WARNING] %s", msg);
-}
-/**
-sample debug callback expecting a FILE* client object
-*/
-static void info_file_callback(const char *msg, void *client_data) {
-    FILE *stream = (FILE*)client_data;
-    fprintf(stream, "[INFO] %s", msg);
-}
-
 /**
 sample error debug callback expecting no client object
 */
@@ -1714,15 +1536,20 @@ int main(int argc, char **argv) {
     *indexfilename = 0;
     memset(&img_fol,0,sizeof(img_fol_t));
 
+    /* raw_cp initialization */
+    raw_cp.rawBitDepth = 0;
+    raw_cp.rawComp = 0;
+    raw_cp.rawComps = 0;
+    raw_cp.rawHeight = 0;
+    raw_cp.rawSigned = 0;
+    raw_cp.rawWidth = 0;
+
     /* parse input and get user encoding parameters */
+    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) == 1) {
         return 1;
     }
 
-    if (parameters.cp_cinema){
-        set_cinema_parameters(&parameters);
-    }
-
     /* Create comment for codestream */
     if(parameters.cp_comment == NULL) {
         const char comment[] = "Created by OpenJPEG version ";
@@ -1769,7 +1596,7 @@ int main(int argc, char **argv) {
         fprintf(stderr,"\n");
 
         if(img_fol.set_imgdir==1){
-            if (get_next_file(imageno, dirptr,&img_fol, &parameters)) {
+            if (get_next_file((int)imageno, dirptr,&img_fol, &parameters)) {
                 fprintf(stderr,"skipping file...\n");
                 continue;
             }
@@ -1878,14 +1705,19 @@ int main(int argc, char **argv) {
         }
 
         /* Decide if MCT should be used */
-        parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
-
-        if(parameters.cp_cinema){
-            if (!is_cinema_compliant(image,parameters.cp_cinema)) {
-                parameters.cp_rsiz = OPJ_STD_RSIZ;
+        if (parameters.tcp_mct == (char) 255) { /* mct mode has not been set in commandline */
+            parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0;
+        } else {            /* mct mode has been set in commandline */
+            if ((parameters.tcp_mct == 1) && (image->numcomps < 3)){
+                fprintf(stderr, "RGB->YCC conversion cannot be used:\n");
+                fprintf(stderr, "Input image has less than 3 components\n");
+                return 1;
+            }
+            if ((parameters.tcp_mct == 2) && (!parameters.mct_data)){
+                fprintf(stderr, "Custom MCT has been set but no array-based MCT\n");
+                fprintf(stderr, "has been provided. Aborting.\n");
+                return 1;
             }
-            /* This cannot be in set_cinema_parameters because we need size and precision of the input image */
-            set_cinema_rate(&parameters,image);
         }
 
         /* encode the destination image */
@@ -1986,6 +1818,7 @@ int main(int argc, char **argv) {
     /* free user parameters structure */
     if(parameters.cp_comment)   free(parameters.cp_comment);
     if(parameters.cp_matrice)   free(parameters.cp_matrice);
+    if(raw_cp.rawComps) free(raw_cp.rawComps);
 
     return 0;
 }