Import files tiff and yuv(raw) (#1316)
[openjpeg.git] / src / bin / jp2 / opj_decompress.c
index 479d83822eee5f715d8396e01f5e999051e8eb78..2333f99962ccdf03cf1e9479104bb63bb4d47375 100644 (file)
@@ -134,7 +134,7 @@ typedef struct opj_decompress_params {
     /** Verbose mode */
     OPJ_BOOL m_verbose;
 
-    /** tile number ot the decoded tile*/
+    /** tile number of the decoded tile */
     OPJ_UINT32 tile_index;
     /** Nb of tile to decode */
     OPJ_UINT32 nb_tile_to_decode;
@@ -152,6 +152,10 @@ typedef struct opj_decompress_params {
     int num_threads;
     /* Quiet */
     int quiet;
+    /** number of components to decode */
+    OPJ_UINT32 numcomps;
+    /** indices of components to decode */
+    OPJ_UINT32* comps_indices;
 } opj_decompress_parameters;
 
 /* -------------------------------------------------------------------------- */
@@ -183,7 +187,7 @@ static void decode_help_display(void)
             "\n"
             "  -ImgDir <directory> \n"
             "  Image file Directory path \n"
-            "  -OutFor <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|RAW|RAWL|TGA>\n"
+            "  -OutFor <PBM|PGM|PPM|PNM|PAM|PGX|PNG|BMP|TIF|TIFF|RAW|YUV|RAWL|TGA>\n"
             "    REQUIRED only if -ImgDir is used\n"
             "  Output format for decompressed images.\n");
     fprintf(stdout, "  -i <compressed file>\n"
@@ -227,6 +231,10 @@ static void decode_help_display(void)
             "    If 'C' is specified (default), values are clipped.\n"
             "    If 'S' is specified, values are scaled.\n"
             "    A 0 value can be specified (meaning original bit depth).\n");
+    fprintf(stdout, "  -c first_comp_index[,second_comp_index][,...]\n"
+            "    OPTIONAL\n"
+            "    To limit the number of components to decoded.\n"
+            "    Component indices are numbered starting at 0.\n");
     fprintf(stdout, "  -force-rgb\n"
             "    Force output image colorspace to RGB\n"
             "  -upsample\n"
@@ -234,8 +242,8 @@ static void decode_help_display(void)
             "  -split-pnm\n"
             "    Split output components to different files when writing to PNM\n");
     if (opj_has_thread_support()) {
-        fprintf(stdout, "  -threads <num_threads>\n"
-                "    Number of threads to use for decoding.\n");
+        fprintf(stdout, "  -threads <num_threads|ALL_CPUS>\n"
+                "    Number of threads to use for decoding or ALL_CPUS for all available cores.\n");
     }
     fprintf(stdout, "  -quiet\n"
             "    Disable output from the library and other output.\n");
@@ -419,8 +427,8 @@ int load_images(dircnt_t *dirptr, char *imgdirpath)
 int get_file_format(const char *filename)
 {
     unsigned int i;
-    static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
-    static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
+    static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "tif", "tiff", "raw", "yuv", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
+    static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, TIF_DFMT, RAW_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
     const char * ext = strrchr(filename, '.');
     if (ext == NULL) {
         return -1;
@@ -560,7 +568,7 @@ int parse_cmdline_decoder(int argc, char **argv,
         {"quiet", NO_ARG,  NULL, 1},
     };
 
-    const char optlist[] = "i:o:r:l:x:d:t:p:"
+    const char optlist[] = "i:o:r:l:x:d:t:p:c:"
 
                            /* UniPG>> */
 #ifdef USE_JPWL
@@ -620,24 +628,17 @@ int parse_cmdline_decoder(int argc, char **argv,
             parameters->cod_format = get_file_format(outfile);
             switch (parameters->cod_format) {
             case PGX_DFMT:
-                break;
             case PXM_DFMT:
-                break;
             case BMP_DFMT:
-                break;
             case TIF_DFMT:
-                break;
             case RAW_DFMT:
-                break;
             case RAWL_DFMT:
-                break;
             case TGA_DFMT:
-                break;
             case PNG_DFMT:
                 break;
             default:
                 fprintf(stderr,
-                        "Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!!\n",
+                        "Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif(f), *.raw, *.yuv or *.tga]!!\n",
                         outfile);
                 return 1;
             }
@@ -684,7 +685,7 @@ int parse_cmdline_decoder(int argc, char **argv,
                 break;
             default:
                 fprintf(stderr,
-                        "Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!!\n",
+                        "Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif(f), *.raw, *.yuv or *.tga]!!\n",
                         outformat);
                 return 1;
                 break;
@@ -770,6 +771,25 @@ int parse_cmdline_decoder(int argc, char **argv,
                 return 1;
             }
         }
+        break;
+
+        /* ----------------------------------------------------- */
+        case 'c': { /* Componenets */
+            const char* iter = opj_optarg;
+            while (1) {
+                parameters->numcomps ++;
+                parameters->comps_indices = (OPJ_UINT32*) realloc(
+                                                parameters->comps_indices,
+                                                parameters->numcomps * sizeof(OPJ_UINT32));
+                parameters->comps_indices[parameters->numcomps - 1] =
+                    (OPJ_UINT32) atoi(iter);
+                iter = strchr(iter, ',');
+                if (iter == NULL) {
+                    break;
+                }
+                iter ++;
+            }
+        }
         break;
             /* ----------------------------------------------------- */
 
@@ -876,7 +896,7 @@ int parse_cmdline_decoder(int argc, char **argv,
             fprintf(stderr,
                     "[ERROR] When -ImgDir is used, -OutFor <FORMAT> must be used.\n");
             fprintf(stderr, "Only one format allowed.\n"
-                    "Valid format are PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA.\n");
+                    "Valid format are PGM, PPM, PNM, PGX, BMP, TIF, TIFF, RAW, YUV, and TGA.\n");
             return 1;
         }
         if (!((parameters->outfile[0] == 0))) {
@@ -1015,6 +1035,9 @@ static void destroy_parameters(opj_decompress_parameters* parameters)
             free(parameters->precision);
             parameters->precision = NULL;
         }
+
+        free(parameters->comps_indices);
+        parameters->comps_indices = NULL;
     }
 }
 
@@ -1089,11 +1112,11 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
             l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded;
 
     memcpy(l_new_image->comps[0].data, original->comps[0].data,
-           original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
+           sizeof(OPJ_INT32) * original->comps[0].w * original->comps[0].h);
     memcpy(l_new_image->comps[1].data, original->comps[0].data,
-           original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
+           sizeof(OPJ_INT32) * original->comps[0].w * original->comps[0].h);
     memcpy(l_new_image->comps[2].data, original->comps[0].data,
-           original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
+           sizeof(OPJ_INT32) * original->comps[0].w * original->comps[0].h);
 
     for (compno = 1U; compno < original->numcomps; ++compno) {
         l_new_image->comps[compno + 2U].factor        = original->comps[compno].factor;
@@ -1101,7 +1124,7 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
         l_new_image->comps[compno + 2U].resno_decoded =
             original->comps[compno].resno_decoded;
         memcpy(l_new_image->comps[compno + 2U].data, original->comps[compno].data,
-               original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32));
+               sizeof(OPJ_INT32) * original->comps[compno].w * original->comps[compno].h);
     }
     opj_image_destroy(original);
     return l_new_image;
@@ -1271,7 +1294,7 @@ static opj_image_t* upsample_image_components(opj_image_t* original)
             }
         } else {
             memcpy(l_new_cmp->data, l_org_cmp->data,
-                   l_org_cmp->w * l_org_cmp->h * sizeof(OPJ_INT32));
+                   sizeof(OPJ_INT32) * l_org_cmp->w * l_org_cmp->h);
         }
     }
     opj_image_destroy(original);
@@ -1286,10 +1309,6 @@ static opj_image_t* upsample_image_components(opj_image_t* original)
 int main(int argc, char **argv)
 {
     opj_decompress_parameters parameters;           /* decompression parameters */
-    opj_image_t* image = NULL;
-    opj_stream_t *l_stream = NULL;              /* Stream */
-    opj_codec_t* l_codec = NULL;                /* Handle to a decompressor */
-    opj_codestream_index_t* cstr_index = NULL;
 
     OPJ_INT32 num_images, imageno;
     img_fol_t img_fol;
@@ -1330,8 +1349,9 @@ int main(int argc, char **argv)
             destroy_parameters(&parameters);
             return EXIT_FAILURE;
         }
-        dirptr->filename_buf = (char*)malloc((size_t)num_images * OPJ_PATH_LEN * sizeof(
-                char)); /* Stores at max 10 image file names*/
+        /* Stores at max 10 image file names */
+        dirptr->filename_buf = (char*)malloc(sizeof(char) *
+                                             (size_t)num_images * OPJ_PATH_LEN);
         if (!dirptr->filename_buf) {
             failed = 1;
             goto fin;
@@ -1362,6 +1382,10 @@ int main(int argc, char **argv)
 
     /*Decoding image one by one*/
     for (imageno = 0; imageno < num_images ; imageno++)  {
+        opj_image_t* image = NULL;
+        opj_stream_t *l_stream = NULL;              /* Stream */
+        opj_codec_t* l_codec = NULL;                /* Handle to a decompressor */
+        opj_codestream_index_t* cstr_index = NULL;
 
         if (!parameters.quiet) {
             fprintf(stderr, "\n");
@@ -1455,6 +1479,21 @@ int main(int argc, char **argv)
             goto fin;
         }
 
+        if (parameters.numcomps) {
+            if (! opj_set_decoded_components(l_codec,
+                                             parameters.numcomps,
+                                             parameters.comps_indices,
+                                             OPJ_FALSE)) {
+                fprintf(stderr,
+                        "ERROR -> opj_decompress: failed to set the component indices!\n");
+                opj_destroy_codec(l_codec);
+                opj_stream_destroy(l_stream);
+                opj_image_destroy(image);
+                failed = 1;
+                goto fin;
+            }
+        }
+
         if (getenv("USE_OPJ_SET_DECODED_RESOLUTION_FACTOR") != NULL) {
             /* For debugging/testing purposes, and also an illustration on how to */
             /* use the alternative API opj_set_decoded_resolution_factor() instead */
@@ -1503,6 +1542,14 @@ int main(int argc, char **argv)
                 goto fin;
             }
         } else {
+            if (!(parameters.DA_x0 == 0 &&
+                    parameters.DA_y0 == 0 &&
+                    parameters.DA_x1 == 0 &&
+                    parameters.DA_y1 == 0)) {
+                if (!(parameters.quiet)) {
+                    fprintf(stderr, "WARNING: -d option ignored when used together with -t\n");
+                }
+            }
 
             if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_index)) {
                 fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n");
@@ -1517,17 +1564,6 @@ int main(int argc, char **argv)
             }
         }
 
-        /* FIXME? Shouldn't that situation be considered as an error of */
-        /* opj_decode() / opj_get_decoded_tile() ? */
-        if (image->comps[0].data == NULL) {
-            fprintf(stderr, "ERROR -> opj_decompress: no image data!\n");
-            opj_destroy_codec(l_codec);
-            opj_stream_destroy(l_stream);
-            opj_image_destroy(image);
-            failed = 1;
-            goto fin;
-        }
-
         tCumulative += opj_clock() - t;
         numDecompressedImages++;
 
@@ -1662,7 +1698,7 @@ int main(int argc, char **argv)
             }
             break;
 #ifdef OPJ_HAVE_LIBTIFF
-        case TIF_DFMT:          /* TIFF */
+        case TIF_DFMT:          /* TIF(F) */
             if (imagetotif(image, parameters.outfile)) {
                 fprintf(stderr, "[ERROR] Outfile %s not generated\n", parameters.outfile);
                 failed = 1;
@@ -1673,7 +1709,8 @@ int main(int argc, char **argv)
 #endif /* OPJ_HAVE_LIBTIFF */
         case RAW_DFMT:          /* RAW */
             if (imagetoraw(image, parameters.outfile)) {
-                fprintf(stderr, "[ERROR] Error generating raw file. Outfile %s not generated\n",
+                fprintf(stderr,
+                        "[ERROR] Error generating raw or yuv file. Outfile %s not generated\n",
                         parameters.outfile);
                 failed = 1;
             } else if (!(parameters.quiet)) {
@@ -1712,7 +1749,7 @@ int main(int argc, char **argv)
             }
             break;
 #endif /* OPJ_HAVE_LIBPNG */
-        /* Can happen if output file is TIFF or PNG
+        /* Can happen if output file is TIF(F) or PNG
          * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined
         */
         default: