Allow to write 3/5/7/9/11/13/15 bpp TIF files
[openjpeg.git] / src / bin / jp2 / opj_dump.c
index 6c63c2cacfd877384ce538d6a80c65a737a0cad7..bd608c2b7efa8f7f55a2117f4bc174e9e81117dc 100644 (file)
@@ -1,6 +1,12 @@
 /*
+ * 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) 2010, Mathieu Malaterre, GDCM
- * Copyright (c) 2011, Mickael Savinaud, Communications & Systemes <mickael.savinaud@c-s.fr>
+ * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France 
+ * Copyright (c) 2012, CS Systemes d'Information, France
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,6 +57,7 @@
 #include "index.h"
 
 #include "format_defs.h"
+#include "opj_string.h"
 
 typedef struct dircnt{
        /** Buffer for holding images read from Directory*/
@@ -70,34 +77,29 @@ typedef struct img_folder{
        /** Enable Cod Format for output*/
        char set_out_format;
 
+  int flag;
 }img_fol_t;
 
 /* -------------------------------------------------------------------------- */
 /* Declarations                                                               */
-int get_num_images(char *imgdirpath);
-int load_images(dircnt_t *dirptr, char *imgdirpath);
-int get_file_format(const char *filename);
-char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters);
+static int get_num_images(char *imgdirpath);
+static int load_images(dircnt_t *dirptr, char *imgdirpath);
+static int get_file_format(const char *filename);
+static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters);
 static int infile_format(const char *fname);
 
-int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol);
-int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsigned int *DA_x1, unsigned int *DA_y1);
+static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol);
 
 /* -------------------------------------------------------------------------- */
-void decode_help_display(void) {
-       fprintf(stdout,"HELP for j2k_dump\n----\n\n");
-       fprintf(stdout,"- the -h option displays this help information on screen\n\n");
-
-/* UniPG>> */
-       fprintf(stdout,"List of parameters for the JPEG 2000 "
-#ifdef USE_JPWL
-               "+ JPWL "
-#endif /* USE_JPWL */
-               "decoder:\n");
-/* <<UniPG */
-       fprintf(stdout,"\n");
-       fprintf(stdout,"\n");
-       fprintf(stdout,"  -ImgDir \n");
+static void decode_help_display(void) {
+    fprintf(stdout,"\nThis is the opj_dump utility from the OpenJPEG project.\n"
+            "It dumps JPEG 2000 codestream info to stdout or a given file.\n"
+            "It has been compiled against openjp2 library v%s.\n\n",opj_version());
+
+    fprintf(stdout,"Parameters:\n");
+    fprintf(stdout,"-----------\n");
+    fprintf(stdout,"\n");
+    fprintf(stdout,"  -ImgDir <directory>\n");
        fprintf(stdout,"        Image file Directory path \n");
        fprintf(stdout,"  -i <compressed file>\n");
        fprintf(stdout,"    REQUIRED only if an Input image directory not specified\n");
@@ -107,15 +109,15 @@ void decode_help_display(void) {
        fprintf(stdout,"    OPTIONAL\n");
        fprintf(stdout,"    Output file where file info will be dump.\n");
        fprintf(stdout,"    By default it will be in the stdout.\n");
-       fprintf(stdout,"  -v "); /* FIXME WIP_MSD */
+    fprintf(stdout,"  -v "); /* FIXME WIP_MSD */
        fprintf(stdout,"    OPTIONAL\n");
-       fprintf(stdout,"    Activate or not the verbose mode (display info and warning message)\n");
-       fprintf(stdout,"    By default verbose mode is off.\n");
+    fprintf(stdout,"    Enable informative messages\n");
+    fprintf(stdout,"    By default verbose mode is off.\n");
        fprintf(stdout,"\n");
 }
 
 /* -------------------------------------------------------------------------- */
-int get_num_images(char *imgdirpath){
+static int get_num_images(char *imgdirpath){
        DIR *dir;
        struct dirent* content; 
        int num_images = 0;
@@ -133,11 +135,12 @@ int get_num_images(char *imgdirpath){
                        continue;
                num_images++;
        }
+       closedir(dir);
        return num_images;
 }
 
 /* -------------------------------------------------------------------------- */
-int load_images(dircnt_t *dirptr, char *imgdirpath){
+static int load_images(dircnt_t *dirptr, char *imgdirpath){
        DIR *dir;
        struct dirent* content; 
        int i = 0;
@@ -159,15 +162,16 @@ int load_images(dircnt_t *dirptr, char *imgdirpath){
                strcpy(dirptr->filename[i],content->d_name);
                i++;
        }
+       closedir(dir);
        return 0;       
 }
 
 /* -------------------------------------------------------------------------- */
-int get_file_format(const char *filename) {
+static int get_file_format(const char *filename) {
        unsigned int i;
        static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "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, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
-       char * ext = strrchr(filename, '.');
+       const char *ext = strrchr(filename, '.');
        if (ext == NULL)
                return -1;
        ext++;
@@ -183,7 +187,7 @@ int get_file_format(const char *filename) {
 }
 
 /* -------------------------------------------------------------------------- */
-char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){
+static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){
        char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN];
        char *temp_p, temp1[OPJ_PATH_LEN]="";
 
@@ -193,7 +197,9 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet
        if (parameters->decod_format == -1)
                return 1;
        sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename);
-       strncpy(parameters->infile, infilename, sizeof(infilename));
+       if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infilename) != 0) {
+               return 1;
+       }
 
        /*Set output file*/
        strcpy(temp_ofname,strtok(image_filename,"."));
@@ -203,7 +209,9 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet
        }
        if(img_fol->set_out_format==1){
                sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format);
-               strncpy(parameters->outfile, outfilename, sizeof(outfilename));
+               if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfilename) != 0) {
+                       return 1;
+               }
        }
        return 0;
 }
@@ -220,7 +228,7 @@ static int infile_format(const char *fname)
        const char *s, *magic_s;
        int ext_format, magic_format;
        unsigned char buf[12];
-       unsigned int l_nb_read; 
+       size_t l_nb_read; 
 
        reader = fopen(fname, "rb");
 
@@ -268,12 +276,12 @@ static int infile_format(const char *fname)
  * Parse the command line
  */
 /* -------------------------------------------------------------------------- */
-int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) {
+static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) {
        int totlen, c;
        opj_option_t long_option[]={
-               {"ImgDir",REQ_ARG, NULL ,'y'},
+        {"ImgDir",REQ_ARG, NULL ,'y'}
        };
-       const char optlist[] = "i:o:hv";
+    const char optlist[] = "i:o:f:hv";
 
        totlen=sizeof(long_option);
        img_fol->set_out_format = 0;
@@ -292,14 +300,18 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
                                        case JP2_CFMT:
                                                break;
                                        case JPT_CFMT:
-                                               break;
-                                       default:
-                                               fprintf(stderr, 
-                                                       "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n", 
-                                                       infile);
-                                               return 1;
+                    break;
+                default:
+                    fprintf(stderr,
+                            "[ERROR] Unknown input file format: %s \n"
+                            "        Known file formats are *.j2k, *.jp2, *.jpc or *.jpt\n",
+                            infile);
+                    return 1;
+                               }
+                               if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infile) != 0) {
+                                       fprintf(stderr, "[ERROR] Path is too long\n");
+                                       return 1;
                                }
-                               strncpy(parameters->infile, infile, sizeof(parameters->infile)-1);
                        }
                        break;
 
@@ -307,12 +319,18 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
 
                        case 'o':     /* output file */
                        {
-                         char *outfile = opj_optarg;
-                         strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
+                               if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), opj_optarg) != 0) {
+                                       fprintf(stderr, "[ERROR] Path is too long\n");
+                                       return 1;
+                               }
                        }
                        break;
                                
                                /* ----------------------------------------------------- */
+      case 'f':                        /* flag */
+        img_fol->flag = atoi(opj_optarg);
+        break;
+                               /* ----------------------------------------------------- */
 
                        case 'h':                       /* display an help description */
                                decode_help_display();
@@ -330,38 +348,40 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
 
                        /* ----------------------------------------------------- */
 
-                       case 'v':               /* Verbose mode */
+            case 'v':                  /* Verbose mode */
                        {
-                               parameters->m_verbose = 1;
+                parameters->m_verbose = 1;
                        }
                        break;
                        
                                /* ----------------------------------------------------- */
-                       default:
-                               fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, opj_optarg);
-                               break;
-               }
+        default:
+            fprintf(stderr, "[WARNING] An invalid option has been ignored.\n");
+            break;
+        }
        }while(c != -1);
 
        /* check for possible errors */
        if(img_fol->set_imgdir==1){
                if(!(parameters->infile[0]==0)){
-                       fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n");
+            fprintf(stderr, "[ERROR] options -ImgDir and -i cannot be used together.\n");
                        return 1;
                }
                if(img_fol->set_out_format == 0){
-                       fprintf(stderr, "Error: When -ImgDir is used, -OutFor <FORMAT> must be used !!\n");
-                       fprintf(stderr, "Only one format allowed! Valid format PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA!!\n");
+            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");
                        return 1;
                }
                if(!(parameters->outfile[0] == 0)){
-                       fprintf(stderr, "Error: options -ImgDir and -o cannot be used together !!\n");
+            fprintf(stderr, "[ERROR] options -ImgDir and -o cannot be used together\n");
                        return 1;
                }
        }else{
                if(parameters->infile[0] == 0) {
+            fprintf(stderr, "[ERROR] Required parameter is missing\n");
                        fprintf(stderr, "Example: %s -i image.j2k\n",argv[0]);
-                       fprintf(stderr, "    Try: %s -h\n",argv[0]);
+            fprintf(stderr, "   Help: %s -h\n",argv[0]);
                        return 1;
                }
        }
@@ -374,33 +394,33 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i
 /**
 sample error debug callback expecting no client object
 */
-void error_callback(const char *msg, void *client_data) {
+static void error_callback(const char *msg, void *client_data) {
        (void)client_data;
        fprintf(stdout, "[ERROR] %s", msg);
 }
 /**
 sample warning debug callback expecting no client object
 */
-void warning_callback(const char *msg, void *client_data) {
+static void warning_callback(const char *msg, void *client_data) {
        (void)client_data;
        fprintf(stdout, "[WARNING] %s", msg);
 }
 /**
 sample debug callback expecting no client object
 */
-void info_callback(const char *msg, void *client_data) {
+static void info_callback(const char *msg, void *client_data) {
        (void)client_data;
        fprintf(stdout, "[INFO] %s", msg);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
- * J2K_DUMP MAIN
+ * OPJ_DUMP MAIN
  */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[])
 {
-       FILE *fsrc = NULL, *fout = NULL;
+       FILE *fout = NULL;
 
        opj_dparameters_t parameters;                   /* Decompression parameters */
        opj_image_t* image = NULL;                                      /* Image structure */
@@ -413,17 +433,12 @@ int main(int argc, char *argv[])
        img_fol_t img_fol;
        dircnt_t *dirptr = NULL;
 
-#ifdef MSD
-       opj_bool l_go_on = OPJ_TRUE;
-       OPJ_UINT32 l_max_data_size = 1000;
-       OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000);
-#endif
-
        /* Set decoding parameters to default values */
        opj_set_default_decoder_parameters(&parameters);
 
        /* Initialize img_fol */
        memset(&img_fol,0,sizeof(img_fol_t));
+  img_fol.flag = OPJ_IMG_INFO | OPJ_J2K_MH_INFO | OPJ_J2K_MH_IND;
 
        /* Parse input and get user encoding parameters */
        if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol) == 1) {
@@ -437,8 +452,8 @@ int main(int argc, char *argv[])
 
                dirptr=(dircnt_t*)malloc(sizeof(dircnt_t));
                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*));
+                       dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char));     /* Stores at max 10 image file names*/
+                       dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*));
 
                        if(!dirptr->filename_buf){
                                return EXIT_FAILURE;
@@ -485,16 +500,10 @@ int main(int argc, char *argv[])
 
                /* Read the input file and put it in memory */
                /* ---------------------------------------- */
-               fsrc = fopen(parameters.infile, "rb");
-               if (!fsrc) {
-                       fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
-                       return EXIT_FAILURE;
-               }
 
-               l_stream = opj_stream_create_default_file_stream(fsrc,1);
+               l_stream = opj_stream_create_default_file_stream(parameters.infile,1);
                if (!l_stream){
-                       fclose(fsrc);
-                       fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
+                       fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n",parameters.infile);
                        return EXIT_FAILURE;
                }
 
@@ -505,19 +514,19 @@ int main(int argc, char *argv[])
                        case J2K_CFMT:  /* JPEG-2000 codestream */
                        {
                                /* Get a decoder handle */
-                               l_codec = opj_create_decompress(CODEC_J2K);
+                               l_codec = opj_create_decompress(OPJ_CODEC_J2K);
                                break;
                        }
                        case JP2_CFMT:  /* JPEG 2000 compressed image data */
                        {
                                /* Get a decoder handle */
-                               l_codec = opj_create_decompress(CODEC_JP2);
+                               l_codec = opj_create_decompress(OPJ_CODEC_JP2);
                                break;
                        }
                        case JPT_CFMT:  /* JPEG 2000, JPIP */
                        {
                                /* Get a decoder handle */
-                               l_codec = opj_create_decompress(CODEC_JPT);
+                               l_codec = opj_create_decompress(OPJ_CODEC_JPT);
                                break;
                        }
                        default:
@@ -533,9 +542,8 @@ int main(int argc, char *argv[])
 
                /* 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");
+                       fprintf(stderr, "ERROR -> opj_dump: failed to setup the decoder\n");
                        opj_stream_destroy(l_stream);
-                       fclose(fsrc);
                        opj_destroy_codec(l_codec);
                        fclose(fout);
                        return EXIT_FAILURE;
@@ -543,16 +551,15 @@ int main(int argc, char *argv[])
 
                /* Read the main header of the codestream and if necessary the JP2 boxes*/
                if(! opj_read_header(l_stream, l_codec, &image)){
-                       fprintf(stderr, "ERROR -> j2k_dump: failed to read the header\n");
+                       fprintf(stderr, "ERROR -> opj_dump: failed to read the header\n");
                        opj_stream_destroy(l_stream);
-                       fclose(fsrc);
                        opj_destroy_codec(l_codec);
                        opj_image_destroy(image);
                        fclose(fout);
                        return EXIT_FAILURE;
                }
 
-               opj_dump_codec(l_codec, OPJ_IMG_INFO | OPJ_J2K_MH_INFO | OPJ_J2K_MH_IND, fout );
+               opj_dump_codec(l_codec, img_fol.flag, fout );
 
                cstr_info = opj_get_cstr_info(l_codec);
 
@@ -560,7 +567,6 @@ int main(int argc, char *argv[])
 
                /* close the byte stream */
                opj_stream_destroy(l_stream);
-               fclose(fsrc);
 
                /* free remaining structures */
                if (l_codec) {