[trunk] refactoring of rsiz, profiles, and extensions management
[openjpeg.git] / src / bin / jp2 / convert.c
index 72babbaad903db8f619df89edc52cfda0e31161b..1b2d3618ef8debf5977147b97b3b29ae1d542d73 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
  * All rights reserved.
@@ -94,7 +100,7 @@ struct tga_header
 
 static unsigned short get_ushort(unsigned short val) {
 
-#ifdef WORDS_BIGENDIAN
+#ifdef OPJ_BIG_ENDIAN
     return( ((val & 0xff) << 8) + (val >> 8) );
 #else
     return( val );
@@ -181,9 +187,9 @@ static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel,
     return 1;
 }
 
-#if WORDS_BIGENDIAN == 1
+#ifdef OPJ_BIG_ENDIAN
 
-static inline int16_t swap16(int16_t x)
+static INLINE int16_t swap16(int16_t x)
 {
     return((((u_int16_t)x & 0x00ffU) <<  8) |
            (((u_int16_t)x & 0xff00U) >>  8));
@@ -228,7 +234,7 @@ static int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height,
     image_w = (unsigned short)width;
     image_h = (unsigned short) height;
 
-#if WORDS_BIGENDIAN == 0
+#ifndef OPJ_BIG_ENDIAN
     if(fwrite(&image_w, 2, 1, fp) != 1) goto fails;
     if(fwrite(&image_h, 2, 1, fp) != 1) goto fails;
 #else
@@ -416,6 +422,7 @@ int imagetotga(opj_image_t * image, const char *outfile) {
     float scale;
     FILE *fdest;
     size_t res;
+    fails = 1;
 
     fdest = fopen(outfile, "wb");
     if (!fdest) {
@@ -711,7 +718,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
 
         /* Place the cursor at the beginning of the image information */
         fseek(IN, 0, SEEK_SET);
-        fseek(IN, File_h.bfOffBits, SEEK_SET);
+        fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
 
         W = Info_h.biWidth;
         H = Info_h.biHeight;
@@ -772,7 +779,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
 
             /* Place the cursor at the beginning of the image information */
             fseek(IN, 0, SEEK_SET);
-            fseek(IN, File_h.bfOffBits, SEEK_SET);
+            fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
 
             W = Info_h.biWidth;
             H = Info_h.biHeight;
@@ -924,7 +931,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
 
                 /* Place the cursor at the beginning of the image information */
                 fseek(IN, 0, SEEK_SET);
-                fseek(IN, File_h.bfOffBits, SEEK_SET);
+                fseek(IN, (long)File_h.bfOffBits, SEEK_SET);
 
                 W = Info_h.biWidth;
                 H = Info_h.biHeight;
@@ -1420,13 +1427,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
 
 #define CLAMP(x,a,b) x < a ? a : (x > b ? b : x)
 
-#ifdef _MSC_VER
-#define STIN static __inline
-#else
-#define STIN static inline
-#endif
-
-STIN int clamp( const int value, const int prec, const int sgnd )
+static INLINE int clamp( const int value, const int prec, const int sgnd )
 {
   if( sgnd )
     {
@@ -1721,7 +1722,7 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
         }
         if(ph->depth < 1 || ph->depth > 4) return;
 
-        if(ph->width && ph->height && ph->depth & ph->maxval && ttype)
+        if(ph->width && ph->height && ph->depth && ph->maxval && ttype)
             ph->ok = 1;
     }
     else
@@ -1872,8 +1873,12 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
             {
                 for(compno = 0; compno < numcomps; compno++)
                 {
-                    if ( !fread(&c0, 1, 1, fp) )
-                        fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
+                if ( !fread(&c0, 1, 1, fp) )
+                  {
+                  fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
+                  opj_image_destroy(image);
+                  return NULL;
+                  }
                     if(one)
                     {
                         image->comps[compno].data[i] = c0;
@@ -2105,8 +2110,15 @@ if(v > 65535) v = 65535; else if(v < 0) v = 0;
 
     for (compno = 0; compno < ncomp; compno++)
     {
-        if (ncomp > 1)
-            sprintf(destname, "%d.%s", compno, outfile);
+    if (ncomp > 1)
+      {
+      /*sprintf(destname, "%d.%s", compno, outfile);*/
+      const size_t olen = strlen(outfile);
+      const size_t dotpos = olen - 4;
+
+      strncpy(destname, outfile, dotpos);
+      sprintf(destname+dotpos, "_%d.pgm", compno);
+      }
         else
             sprintf(destname, "%s", outfile);
 
@@ -2585,6 +2597,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
     int has_alpha = 0;
     unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
     unsigned int tiWidth, tiHeight;
+    OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
 
     tif = TIFFOpen(filename, "r");
 
@@ -2657,7 +2670,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
 */ 
     memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
 
-    if ((tiPhoto == PHOTOMETRIC_RGB) && (parameters->cp_cinema)) {
+    if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema)) {
         fprintf(stdout,"WARNING:\n"
                 "Input image bitdepth is %d bits\n"
                 "TIF conversion has automatically rescaled to 12-bits\n"
@@ -2673,7 +2686,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
         /*#define USETILEMODE*/
         for(j = 0; j < numcomps; j++)
         {
-            if(parameters->cp_cinema)
+            if(is_cinema)
             {
                 cmptparm[j].prec = 12;
                 cmptparm[j].bpp = 12;
@@ -2742,7 +2755,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
                         if(has_alpha)
                             image->comps[3].data[index] = ( dat8[i+7] << 8 ) | dat8[i+6];
 
-                        if(parameters->cp_cinema)
+                        if(is_cinema)
                         {
                             /* Rounding 16 to 12 bits
 */
@@ -2779,7 +2792,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
                                 image->comps[3].data[index] = dat8[i+3];
 #endif
 
-                            if(parameters->cp_cinema)
+                            if(is_cinema)
                             {
                                 /* Rounding 8 to 12 bits
 */
@@ -2947,9 +2960,11 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
     {
         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 NULL;
     }
 
@@ -2960,7 +2975,17 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
         return NULL;
     }
     numcomps = raw_cp->rawComp;
-    color_space = OPJ_CLRSPC_SRGB;
+
+    /* FIXME ADE at this point, tcp_mct has not been properly set in calling function */
+    if (numcomps == 0) {
+        color_space = OPJ_CLRSPC_GRAY;
+    } else if ((numcomps >= 3) && (parameters->tcp_mct == 0)) {
+        color_space = OPJ_CLRSPC_SYCC;
+    } else if ((numcomps >= 3) && (parameters->tcp_mct != 2)) {
+        color_space = OPJ_CLRSPC_SRGB;
+    } else {
+        color_space = OPJ_CLRSPC_UNKNOWN;
+    }
     w = raw_cp->rawWidth;
     h = raw_cp->rawHeight;
     cmptparm = (opj_image_cmptparm_t*) malloc((size_t)numcomps * sizeof(opj_image_cmptparm_t));
@@ -2971,8 +2996,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
         cmptparm[i].prec = (OPJ_UINT32)raw_cp->rawBitDepth;
         cmptparm[i].bpp = (OPJ_UINT32)raw_cp->rawBitDepth;
         cmptparm[i].sgnd = (OPJ_UINT32)raw_cp->rawSigned;
-        cmptparm[i].dx = (OPJ_UINT32)subsampling_dx;
-        cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
+        cmptparm[i].dx = (OPJ_UINT32)(subsampling_dx * raw_cp->rawComps[i].dx);
+        cmptparm[i].dy = (OPJ_UINT32)(subsampling_dy * raw_cp->rawComps[i].dy);
         cmptparm[i].w = (OPJ_UINT32)w;
         cmptparm[i].h = (OPJ_UINT32)h;
     }
@@ -2993,7 +3018,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
     {
         unsigned char value = 0;
         for(compno = 0; compno < numcomps; compno++) {
-            for (i = 0; i < w * h; i++) {
+            int nloop = (w*h)/(raw_cp->rawComps[compno].dx*raw_cp->rawComps[compno].dx);
+            for (i = 0; i < nloop; i++) {
                 if (!fread(&value, 1, 1, f)) {
                     fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
                     return NULL;
@@ -3006,7 +3032,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
     {
         unsigned short value;
         for(compno = 0; compno < numcomps; compno++) {
-            for (i = 0; i < w * h; i++) {
+            int nloop = (w*h)/(raw_cp->rawComps[compno].dx*raw_cp->rawComps[compno].dx);
+            for (i = 0; i < nloop; i++) {
                 unsigned char temp1;
                 unsigned char temp2;
                 if (!fread(&temp1, 1, 1, f)) {
@@ -3216,7 +3243,7 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
     opj_image_cmptparm_t cmptparm[4];
     int sub_dx, sub_dy;
     unsigned int nr_comp;
-    int *r, *g, *b, *a;
+    int *r, *g, *b, *a = NULL;
     unsigned char sigbuf[8];
 
     if((reader = fopen(read_idf, "rb")) == NULL)
@@ -3306,7 +3333,7 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
 
     png_read_image(png, rows);
 
-    memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
+    memset(cmptparm, 0, sizeof(cmptparm));
 
     sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy;
 
@@ -3334,7 +3361,7 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
     r = image->comps[0].data;
     g = image->comps[1].data;
     b = image->comps[2].data;
-    a = image->comps[3].data;
+    if(has_alpha) a = image->comps[3].data;
 
     for(i = 0; i < height; ++i)
     {