]> granicus.if.org Git - openjpeg/commitdiff
MJ2 module: Add two components to mj2.h: meth, enumcs ; Define or reset all component...
authorAntonin Descampe <antonin@gmail.com>
Sun, 23 Jan 2011 18:33:06 +0000 (18:33 +0000)
committerAntonin Descampe <antonin@gmail.com>
Sun, 23 Jan 2011 18:33:06 +0000 (18:33 +0000)
CHANGES
mj2/extract_j2k_from_mj2.c
mj2/frames_to_mj2.c
mj2/mj2.c
mj2/mj2.h
mj2/mj2_convert.c
mj2/mj2_to_frames.c
mj2/wrap_j2k_in_mj2.c

diff --git a/CHANGES b/CHANGES
index f83432e36228d4ed158b6acba81d6a1a008adc78..7ba7b7da4aaef97ba90d8957584e0718caa2324c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@ What's New for OpenJPEG
 + : added
 
 January 23, 2011
+! [antonin] MJ2 module: 
+                       - Add two components to mj2.h: meth, enumcs.
+                       - Define or reset all components of mj2_cparameters_t before its usage.
+                       - Add argument '-D prec' to frames_to_mj2.c and use the precision in mj2_convert.c (solves Issue 49).
 * [antonin] move 'KK' definition from rs.h to rs.c to prevent duplicate symbol error when building jpwl with autotools.
 
 January 18, 2011
index 5c1441ad246165420f57349b20361a0f1be64d7d..0872df1d5a0b80759bf716921ae5238cc5a4d8d5 100644 (file)
@@ -104,8 +104,9 @@ int main(int argc, char *argv[]) {
        opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);           
 
        /* setup the decoder decoding parameters using user parameters */
+       memset(&parameters, 0, sizeof(mj2_dparameters_t));
        movie = (opj_mj2_t*) dinfo->mj2_handle;
-       mj2_setup_decoder((opj_mj2_t*)dinfo->mj2_handle, &parameters);
+       mj2_setup_decoder(movie, &parameters);
 
   if (mj2_read_struct(file, movie)) // Creating the movie structure
     return 1;
index 6b1fd536a4589da120169f9f49c79424d1b5a12a..f689b00d4ceb4ac420dc3f7ef473d34935873bbd 100644 (file)
@@ -43,6 +43,10 @@ Size of memory first allocated for MOOV box
 */
 #define TEMP_BUF 10000 
 
+#define ENUMCS_GRAY 16
+#define ENUMCS_SRGB 17
+#define ENUMCS_SYCC 18
+
 /* -------------------------------------------------------------------------- */
 
 /**
@@ -111,60 +115,60 @@ void help_display()
   fprintf
     (stdout,"Required Parameters (except with -h):\n");
   fprintf
-    (stdout,"-i           : source file  (-i source.yuv) \n");
+    (stdout,"-i : source file      (-i source.yuv) \n");
   fprintf
-    (stdout,"-o           : destination file (-o dest.mj2) \n");
+    (stdout,"-o : destination file (-o dest.mj2) \n");
   fprintf
     (stdout,"Optional Parameters:\n");
-  fprintf(stdout,"-h           : display the help information \n");
-  fprintf(stdout,"-r           : different compression ratios for successive layers (-r 20,10,5)\n ");
-  fprintf(stdout,"              - The rate specified for each quality level is the desired \n");
-  fprintf(stdout,"                compression factor.\n");
-  fprintf(stdout,"                Example: -r 20,10,1 means quality 1: compress 20x, \n");
-  fprintf(stdout,"                  quality 2: compress 10x and quality 3: compress lossless\n");
-  fprintf(stdout,"               (options -r and -q cannot be used together)\n ");
-  
-  fprintf(stdout,"-q           : different psnr for successive layers (-q 30,40,50) \n ");
+  fprintf(stdout,"-h : display the help information \n");
+  fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n");
+  fprintf(stdout,"     - The rate specified for each quality level is the desired \n");
+  fprintf(stdout,"       compression factor.\n");
+  fprintf(stdout,"       Example: -r 20,10,1 means quality 1: compress 20x, \n");
+  fprintf(stdout,"       quality 2: compress 10x and quality 3: compress lossless\n");
+  fprintf(stdout,"       (options -r and -q cannot be used together)\n");
   
-  fprintf(stdout,"               (options -r and -q cannot be used together)\n ");
+  fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n");
+  fprintf(stdout,"        (options -r and -q cannot be used together)\n");
   
-  fprintf(stdout,"-n           : number of resolutions (-n 3) \n");
-  fprintf(stdout,"-b           : size of code block (-b 32,32) \n");
-  fprintf(stdout,"-c           : size of precinct (-c 128,128) \n");
-  fprintf(stdout,"-t           : size of tile (-t 512,512) \n");
+  fprintf(stdout,"-n : number of resolutions (-n 3) \n");
+  fprintf(stdout,"-b : size of code block (-b 32,32) \n");
+  fprintf(stdout,"-c : size of precinct (-c 128,128) \n");
+  fprintf(stdout,"-t : size of tile (-t 512,512) \n");
   fprintf
-    (stdout,"-p           : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
+    (stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
   fprintf
-    (stdout,"-s           : subsampling factor (-s 2,2) [-s X,Y] \n");
-  fprintf(stdout,"          Remark: subsampling bigger than 2 can produce error\n");
+    (stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");
+  fprintf(stdout,"     Remark: subsampling bigger than 2 can produce error\n");
   fprintf
-    (stdout,"-SOP         : write SOP marker before each packet \n");
+    (stdout,"-S : write SOP marker before each packet \n");
   fprintf
-    (stdout,"-EPH         : write EPH marker after each header packet \n");
+    (stdout,"-E : write EPH marker after each header packet \n");
   fprintf
-    (stdout,"-M           : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
+    (stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
   fprintf
-    (stdout,"                 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
+    (stdout,"             8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
   fprintf
-    (stdout,"                 Indicate multiple modes by adding their values. \n");
+    (stdout,"             Indicate multiple modes by adding their values. \n");
   fprintf
-    (stdout,"                 ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
+    (stdout,"             Example: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
   fprintf
-    (stdout,"-ROI         : c=%%d,U=%%d : quantization indices upshifted \n");
+    (stdout,"-R : c=%%d,U=%%d : quantization indices upshifted \n");
   fprintf
-    (stdout,"               for component c=%%d [%%d = 0,1,2]\n");
+    (stdout,"             for component c=%%d [%%d = 0,1,2]\n");
   fprintf
-    (stdout,"               with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n");
+    (stdout,"             with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n");
   fprintf
-    (stdout,"-d           : offset of the origin of the image (-d 150,300) \n");
+    (stdout,"-d : offset of the origin of the image (-d 150,300) \n");
   fprintf
-    (stdout,"-T           : offset of the origin of the tiles (-T 100,75) \n");
-  fprintf(stdout,"-I           : use the irreversible DWT 9-7 (-I) \n");
-  fprintf(stdout,"-W           : image width, height and the dx and dy subsampling \n");
-  fprintf(stdout,"               of the Cb and Cr components for YUV files \n");
-  fprintf(stdout,"               (default is '352,288,2,2' for CIF format's 352x288 and 4:2:0)\n");
-  fprintf(stdout,"-F           : video frame rate (set to 25 by default)\n");
-  
+    (stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");
+  fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");
+  fprintf(stdout,"-W : image width, height and the dx and dy subsampling \n");
+  fprintf(stdout,"        of the Cb and Cr components for YUV files \n");
+  fprintf(stdout,"        (default is '352,288,2,2' for CIF format's 352x288 and 4:2:0)\n");
+  fprintf(stdout,"-F : video frame rate (set to 25 by default)\n");
+  fprintf(stdout,"-D : depth, precision in bits [8 .. 16]; default:8\n");
+  fprintf(stdout,"-C : comment\n");
   fprintf(stdout,"\n");
   fprintf(stdout,"IMPORTANT:\n");
   fprintf(stdout,"-----------\n");
@@ -235,33 +239,37 @@ int main(int argc, char **argv)
        opj_event_mgr_t event_mgr;              /* event manager */
        opj_cio_t *cio;
        int value;
-  opj_mj2_t *movie;
+       opj_mj2_t *movie;
        opj_image_t *img;
-  int i, j;
-  char *s, S1, S2, S3;
-  unsigned char *buf;
-  int x1, y1,  len;
-  long mdat_initpos, offset;
-  FILE *mj2file;
-  int sampleno;  
+       int i, j;
+       char *s, S1, S2, S3;
+       unsigned char *buf;
+       int x1, y1,  len;
+       long mdat_initpos, offset;
+       FILE *mj2file;
+       int sampleno;  
        opj_cinfo_t* cinfo;
-  bool bSuccess;
+       bool bSuccess;
        int numframes;
+       int prec = 0;
        double total_time = 0;  
 
+       memset(&mj2_parameters, 0, sizeof(mj2_cparameters_t));
   /* default value */
   /* ------------- */
-  mj2_parameters.Dim[0] = 0;
-  mj2_parameters.Dim[1] = 0;
-  mj2_parameters.w = 352;                      // CIF default value
-  mj2_parameters.h = 288;                      // CIF default value
-  mj2_parameters.CbCr_subsampling_dx = 2;      // CIF default value
-  mj2_parameters.CbCr_subsampling_dy = 2;      // CIF default value
-  mj2_parameters.frame_rate = 25;        
-       /*
+       mj2_parameters.w = 352;                 // CIF default value
+       mj2_parameters.h = 288;                 // CIF default value
+       mj2_parameters.CbCr_subsampling_dx = 2; // CIF default value
+       mj2_parameters.CbCr_subsampling_dy = 2; // CIF default value
+       mj2_parameters.frame_rate = 25;
+       mj2_parameters.prec = 8; /* DEFAULT */
+       mj2_parameters.enumcs = ENUMCS_SYCC; /* FIXME: ENUMCS_YUV420 */
+       mj2_parameters.meth = 1; /* enumerated color space */
+
+/*
        configure the event callbacks (not required)
        setting of each callback is optionnal
-       */
+*/
        memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
        event_mgr.error_handler = error_callback;
        event_mgr.warning_handler = warning_callback;
@@ -280,12 +288,9 @@ int main(int argc, char **argv)
                sprintf(j2k_parameters->cp_comment,"%s%s", comment, version);
        }
 
-       mj2_parameters.decod_format = 0;
-       mj2_parameters.cod_format = 0;
-
   while (1) {
     int c = getopt(argc, argv,
-      "i:o:r:q:f:t:n:c:b:p:s:d:P:S:E:M:R:T:C:I:W:F:h");
+      "i:o:r:q:f:t:n:c:b:p:s:d:P:S:E:M:R:T:C:I:W:F:D:h");
     if (c == -1)
       break;
     switch (c) {
@@ -602,6 +607,10 @@ int main(int argc, char **argv)
       }
       break;
       /* ------------------------------------------------------ */
+       case 'D': /* Depth: the precision */
+               if(sscanf(optarg, "%d", &prec) != 1) prec = 0;
+               break;
+
     default:
       return 1;
     }
@@ -657,17 +666,21 @@ int main(int argc, char **argv)
                + 1 : mj2_parameters.Dim[0] + (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx + 1;
   y1 = !mj2_parameters.Dim[1] ? (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy 
                + 1 : mj2_parameters.Dim[1] + (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy + 1;   
-  mj2_parameters.numcomps = 3;                 /* Because YUV files only have 3 components */ 
-  mj2_parameters.prec = 8;                     /* Because in YUV files, components have 8-bit depth */
+       mj2_parameters.numcomps = 3; /* YUV files only have 3 components */ 
+
+
+       if(prec < 1 || prec > 32) prec = 8; /* DEFAULT */
+
+       mj2_parameters.prec = prec;
 
        j2k_parameters->tcp_mct = 0;
     
-  mj2file = fopen(mj2_parameters.outfile, "wb");
+       mj2file = fopen(mj2_parameters.outfile, "wb");
   
-  if (!mj2file) {
+       if (!mj2file) {
     fprintf(stderr, "failed to open %s for writing\n", argv[2]);
     return 1;
-  }
+       }
     
        /* get a MJ2 decompressor handle */
        cinfo = mj2_create_compress();
@@ -679,128 +692,151 @@ int main(int argc, char **argv)
        /* setup encoder parameters */
        mj2_setup_encoder(movie, &mj2_parameters);   
   
-  movie->tk[0].num_samples = yuv_num_frames(&movie->tk[0],mj2_parameters.infile); 
-  if (movie->tk[0].num_samples == -1) {
+       movie->tk[0].num_samples = 
+        yuv_num_frames(&movie->tk[0],mj2_parameters.infile);
+
+       if (movie->tk[0].num_samples == -1) {
                return 1;
-  }
-  
+       }
+
   // One sample per chunk
-  movie->tk[0].chunk = (mj2_chunk_t*) malloc(movie->tk[0].num_samples * sizeof(mj2_chunk_t));     
-  movie->tk[0].sample = (mj2_sample_t*) malloc(movie->tk[0].num_samples * sizeof(mj2_sample_t));
+       movie->tk[0].chunk = (mj2_chunk_t*) 
+        malloc(movie->tk[0].num_samples * sizeof(mj2_chunk_t));     
+       movie->tk[0].sample = (mj2_sample_t*) 
+        malloc(movie->tk[0].num_samples * sizeof(mj2_sample_t));
   
-  if (mj2_init_stdmovie(movie)) {
+       if (mj2_init_stdmovie(movie)) {
     fprintf(stderr, "Error with movie initialization");
     return 1;
-  };    
+       }    
   
-  // Writing JP, FTYP and MDAT boxes 
-  buf = (unsigned char*) malloc (300 * sizeof(unsigned char)); // Assuming that the JP and FTYP
-  // boxes won't be longer than 300 bytes
+// Writing JP, FTYP and MDAT boxes 
+// Assuming that the JP and FTYP boxes won't be longer than 300 bytes:
+       buf = (unsigned char*) 
+        malloc (300 * sizeof(unsigned char));
+
        cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, 300);
-  mj2_write_jp(cio);
-  mj2_write_ftyp(movie, cio);
-  mdat_initpos = cio_tell(cio);
-  cio_skip(cio, 4);
-  cio_write(cio, MJ2_MDAT, 4); 
-  fwrite(buf,cio_tell(cio),1,mj2file);
-  offset = cio_tell(cio);
-  opj_cio_close(cio);
-  free(buf);
-
-  for (i = 0; i < movie->num_stk + movie->num_htk + movie->num_vtk; i++) {
-    if (movie->tk[i].track_type != 0) {
-      fprintf(stderr, "Unable to write sound or hint tracks\n");
-    } else {
-      mj2_tk_t *tk;
-                       int buflen = 0;
-      
-      tk = &movie->tk[i];     
-      tk->num_chunks = tk->num_samples;
-                       numframes = tk->num_samples;
-
-      fprintf(stderr, "Video Track number %d\n", i + 1);
-                       
-                       img = mj2_image_create(tk, j2k_parameters);          
-                       buflen = 2 * (tk->w * tk->h * 8);
-                       buf = (unsigned char *) malloc(buflen*sizeof(unsigned char));   
-
-      for (sampleno = 0; sampleno < numframes; sampleno++) {           
-                               double init_time = opj_clock();
-                               double elapsed_time;
-                               if (yuvtoimage(tk, img, sampleno, j2k_parameters, mj2_parameters.infile)) {
-                                       fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno);
-                                       return 1;
-                               }
 
-                               /* setup the encoder parameters using the current image and user parameters */
-                               opj_setup_encoder(cinfo, j2k_parameters, img);
+       mj2_write_jp(cio);
+       mj2_write_ftyp(movie, cio);
+
+       mdat_initpos = cio_tell(cio);
+       cio_skip(cio, 4);
+
+       cio_write(cio, MJ2_MDAT, 4);    
+
+       fwrite(buf,cio_tell(cio),1,mj2file);
+
+       offset = cio_tell(cio);
+       opj_cio_close(cio);
+       free(buf);
+
+       for(i = 0; i < movie->num_stk + movie->num_htk + movie->num_vtk; i++) 
+   {
+    if(movie->tk[i].track_type != 0) 
+  {
+       fprintf(stderr, "Unable to write sound or hint tracks\n");
+  }
+       else 
+  {
+       mj2_tk_t *tk;
+       int buflen = 0;
+  
+       tk = &movie->tk[i];     
+       tk->num_chunks = tk->num_samples;
+       numframes = tk->num_samples;
+       tk->depth = prec; 
+
+       fprintf(stderr, "Video Track number %d\n", i);
+
+       img = mj2_image_create(tk, j2k_parameters);          
+
+       buflen = 2 * (tk->w * tk->h * 8);
+       buf = (unsigned char *) malloc(buflen*sizeof(unsigned char));   
+
+       for(sampleno = 0; sampleno < numframes; sampleno++) 
+ {
+       double init_time = opj_clock();
+       double elapsed_time;
 
-                               cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, buflen);
+               if(yuvtoimage(tk, img, sampleno, j2k_parameters, 
+                       mj2_parameters.infile))
+          {
+               fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno);
+               return 1;
+          }
+
+/* setup the encoder parameters using the current image and user parameters */
+       opj_setup_encoder(cinfo, j2k_parameters, img);
+
+       cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, buflen);
                                                                
-                               cio_skip(cio, 4);
-                               cio_write(cio, JP2_JP2C, 4);    // JP2C
-
-                               /* encode the image */
-                               bSuccess = opj_encode(cinfo, cio, img, NULL);
-                               if (!bSuccess) {
-                                       opj_cio_close(cio);
-                                       fprintf(stderr, "failed to encode image\n");
-                                       return 1;
-                               }
+       cio_skip(cio, 4);
+       cio_write(cio, JP2_JP2C, 4);    // JP2C
 
-                               len = cio_tell(cio) - 8;
-                               cio_seek(cio, 0);
-                               cio_write(cio, len+8,4);
-                               opj_cio_close(cio);
-                               tk->sample[sampleno].sample_size = len+8;                               
-                               tk->sample[sampleno].offset = offset;
-                               tk->chunk[sampleno].offset = offset;    // There is one sample per chunk 
-                               fwrite(buf, 1, len+8, mj2file);                         
-                               offset += len+8;                                
-                               elapsed_time = opj_clock()-init_time;
-                               fprintf(stderr, "Frame number %d/%d encoded in %.2f mseconds\n", sampleno + 1, numframes, elapsed_time*1000);
-                               total_time += elapsed_time;
+/* encode the image */
+       bSuccess = opj_encode(cinfo, cio, img, NULL);
 
-      }
-                       /* free buffer data */
-                       free(buf);
-                       /* free image data */
-                       opj_image_destroy(img);
-    }
+       if (!bSuccess) {
+       opj_cio_close(cio);
+       fprintf(stderr, "failed to encode image\n");
+       return 1;
+       }
+
+       len = cio_tell(cio) - 8;
+       cio_seek(cio, 0);
+       cio_write(cio, len+8,4);
+       opj_cio_close(cio);
+
+       tk->sample[sampleno].sample_size = len+8;                               
+       tk->sample[sampleno].offset = offset;
+       tk->chunk[sampleno].offset = offset;    // There is one sample per chunk 
+       fwrite(buf, 1, len+8, mj2file);                         
+       offset += len+8;                                
+
+       elapsed_time = opj_clock()-init_time;
+       fprintf(stderr, "Frame number %d/%d encoded in %.2f mseconds\n", 
+               sampleno + 1, numframes, elapsed_time*1000);
+       total_time += elapsed_time;
+ }     /* for(sampleno */
+
+       free(buf);
+       opj_image_destroy(img);
   }
+   }/* for(i */
   
-  fseek(mj2file, mdat_initpos, SEEK_SET);
+       fseek(mj2file, mdat_initpos, SEEK_SET);
        
-  buf = (unsigned char*) malloc(4*sizeof(unsigned char));
+       buf = (unsigned char*) malloc(4*sizeof(unsigned char));
 
-       // Init a cio to write box length variable in a little endian way 
+// Init a cio to write box length variable in a little endian way 
        cio = opj_cio_open(NULL, buf, 4);
-  cio_write(cio, offset - mdat_initpos, 4);
-  fwrite(buf, 4, 1, mj2file);
-  fseek(mj2file,0,SEEK_END);
-  free(buf);
-
-  // Writing MOOV box 
-       buf = (unsigned char*) malloc ((TEMP_BUF+numframes*20) * sizeof(unsigned char));
+       cio_write(cio, offset - mdat_initpos, 4);
+       fwrite(buf, 4, 1, mj2file);
+       fseek(mj2file,0,SEEK_END);
+       free(buf);
+
+// Writing MOOV box 
+       buf = (unsigned char*) 
+        malloc ((TEMP_BUF+numframes*20) * sizeof(unsigned char));
        cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF+numframes*20));
        mj2_write_moov(movie, cio);
-  fwrite(buf,cio_tell(cio),1,mj2file);
-  free(buf);
+       fwrite(buf,cio_tell(cio),1,mj2file);
+       free(buf);
+
+       fprintf(stdout,"Total encoding time: %.2f s for %d frames (%.1f fps)\n",
+        total_time, numframes, (float)numframes/total_time);
 
-       fprintf(stdout,"Total encoding time: %.2f s for %d frames (%.1f fps)\n", total_time, numframes, (float)numframes/total_time);
-  
   // Ending program 
   
-  fclose(mj2file);
-       /* free remaining compression structures */
+       fclose(mj2file);
+/* free remaining compression structures */
        mj2_destroy_compress(movie);
        free(cinfo);
-       /* free user parameters structure */
-  if(j2k_parameters->cp_comment) free(j2k_parameters->cp_comment);
+
+       if(j2k_parameters->cp_comment) free(j2k_parameters->cp_comment);
        if(j2k_parameters->cp_matrice) free(j2k_parameters->cp_matrice);
        opj_cio_close(cio);
 
-  return 0;
+       return 0;
 }
-
-
index 01ee90c5373360bb280f5a61b2bf2a14d36e5f1b..131eaceaff78d92a66da6ed46d40af8d9cfc3d61 100644 (file)
--- a/mj2/mj2.c
+++ b/mj2/mj2.c
@@ -90,7 +90,8 @@ int mj2_read_boxhdr(mj2_box_t * box, opj_cio_t *cio)
 
 int mj2_init_stdmovie(opj_mj2_t * movie)
 {
-  int i;
+  mj2_tk_t *tk0;
+  int i, w, h, prec;
   unsigned int j;
   time_t ltime;
        
@@ -117,17 +118,24 @@ int mj2_init_stdmovie(opj_mj2_t * movie)
   movie->trans_matrix[7] = 0;
   movie->trans_matrix[8] = 0x40000000;
   movie->next_tk_id = 1;
-       
-  for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++) {
+
+  tk0 = &movie->tk[0];
+  w = tk0->w; h = tk0->h; prec = tk0->depth;
+
+       for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++) 
+   {
     mj2_tk_t *tk = &movie->tk[i];
+
     movie->next_tk_id++;
     tk->jp2_struct.comps = NULL;
     tk->jp2_struct.cl = NULL;
-    
-    if (tk->track_type == 0) {
-      if (tk->num_samples == 0)
+  
+    if (tk->track_type == 0) /* no sound or hint track */
+   {
+    if (tk->num_samples == 0)
                                return 1;
                        
+    tk->w = w; tk->h = h; tk->depth = prec;
       tk->Dim[0] = 0;
       tk->Dim[1] = 0;
                        
@@ -138,22 +146,24 @@ int mj2_init_stdmovie(opj_mj2_t * movie)
                        
       tk->same_sample_size = 0;
                        
-      tk->num_samplestochunk = 1;      /* One sample per chunk                                      */
+      tk->num_samplestochunk = 1;      /* One sample per chunk  */
                tk->sampletochunk = (mj2_sampletochunk_t*) opj_malloc(tk->num_samplestochunk * sizeof(mj2_sampletochunk_t));
       tk->sampletochunk[0].first_chunk = 1;
       tk->sampletochunk[0].samples_per_chunk = 1;
       tk->sampletochunk[0].sample_descr_idx = 1;
       
-      if (tk->sample_rate == 0) {
-                               opj_event_msg(tk->cinfo, EVT_ERROR,
-                                       "Error while initializing MJ2 movie: Sample rate of track %d must be different from zero\n",
-                                       tk->track_ID);
-                               return 1;
-      }
+      if (tk->sample_rate == 0) 
+  {
+       opj_event_msg(tk->cinfo, EVT_ERROR,
+       "Error while initializing MJ2 movie: Sample rate of track"
+       " %d must be different from zero\n", tk->track_ID);
+       return 1;
+  }
                        
-      for (j = 0; j < tk->num_samples; j++) {
-                               tk->sample[j].sample_delta = tk->timescale / tk->sample_rate;
-      }
+      for (j = 0; j < tk->num_samples; j++) 
+  {
+       tk->sample[j].sample_delta = tk->timescale / tk->sample_rate;
+  }
                        
       tk->num_tts = 1;
                tk->tts = (mj2_tts_t*) opj_malloc(tk->num_tts * sizeof(mj2_tts_t));
@@ -2842,9 +2852,10 @@ void mj2_setup_encoder(opj_mj2_t *movie, mj2_cparameters_t *parameters) {
                movie->tk[0].name_size = 0;
                movie->tk[0].chunk = (mj2_chunk_t*) opj_malloc(sizeof(mj2_chunk_t));  
                movie->tk[0].sample = (mj2_sample_t*) opj_malloc(sizeof(mj2_sample_t));
+               movie->tk[0].depth = parameters->prec;
 
                jp2_struct = &movie->tk[0].jp2_struct;
-               jp2_struct->numcomps = 3;       // NC           
+               jp2_struct->numcomps = parameters->numcomps;    // NC           
                jp2_struct->comps = (opj_jp2_comps_t*) opj_malloc(jp2_struct->numcomps * sizeof(opj_jp2_comps_t));
                jp2_struct->precedence = 0;   /* PRECEDENCE*/
                jp2_struct->approx = 0;   /* APPROX*/           
@@ -2859,8 +2870,8 @@ void mj2_setup_encoder(opj_mj2_t *movie, mj2_cparameters_t *parameters) {
                jp2_struct->w = parameters->w;
                jp2_struct->h = parameters->h;
                jp2_struct->bpc = 7;  
-               jp2_struct->meth = 1;
-               jp2_struct->enumcs = 18;  // YUV
+               jp2_struct->meth = parameters->meth;
+               jp2_struct->enumcs = parameters->enumcs;
   }
 }
 
index 97cf8ede22b6181b346388a1b3c889e3237dab35..0ddb6b8977ec261171a62d6f1cb080ab49bf8ec0 100644 (file)
--- a/mj2/mj2.h
+++ b/mj2/mj2.h
@@ -295,6 +295,8 @@ typedef struct mj2_cparameters {
   int numcomps;                        
        /*   In YUV files, precision always considered as 8 */
   int prec;            
+  unsigned int meth;
+  unsigned int enumcs;
 } mj2_cparameters_t;
 
 
index 3f4c2e75ccca573fe53a8856f8ff240b2b228a39..d0c1860f5ee62119f39cd3e9bf3829cc73159ca9 100644 (file)
@@ -39,7 +39,7 @@
 
 int yuv_num_frames(mj2_tk_t * tk, char *infile)
 {
-  int numimages, frame_size;
+  int numimages, frame_size, prec_size;
   long end_of_f;
        FILE *f;
 
@@ -48,8 +48,10 @@ int yuv_num_frames(mj2_tk_t * tk, char *infile)
     fprintf(stderr, "failed to open %s for reading\n",infile);
     return -1;
   }
-       
+       prec_size = (tk->depth + 7)/8;/* bytes of precision */
+
   frame_size = (int) (tk->w * tk->h * (1.0 + (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy)));      /* Calculate frame size */
+       frame_size *= prec_size; 
        
   fseek(f, 0, SEEK_END);
   end_of_f = ftell(f);         /* Calculate file size */
@@ -86,8 +88,8 @@ opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters)
        /* initialize image components */
        memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
        for(i = 0; i < numcomps; i++) {
-               cmptparm[i].prec = 8;
-               cmptparm[i].bpp = 8;
+               cmptparm[i].prec = tk->depth;
+               cmptparm[i].bpp = tk->depth;
                cmptparm[i].sgnd = 0;           
                cmptparm[i].dx = i ? subsampling_dx * tk->CbCr_subsampling_dx : subsampling_dx;
                cmptparm[i].dy = i ? subsampling_dy * tk->CbCr_subsampling_dy : subsampling_dy;
@@ -102,7 +104,7 @@ opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters)
 char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile)
 {
   int i, compno;
-  int offset;
+  int offset, size, max, prec_size;
   long end_of_f, position;
        int numcomps = 3;
        int subsampling_dx = parameters->subsampling_dx;
@@ -114,9 +116,12 @@ char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters
     fprintf(stderr, "failed to open %s for readings\n",parameters->infile);
     return 1;
   }
+       prec_size = (tk->depth + 7)/8;/* bytes of precision */
 
   offset = (int) ((double) (frame_num * tk->w * tk->h) * (1.0 +
                1.0 * (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy)));
+  offset *= prec_size;
+
   fseek(yuvfile, 0, SEEK_END);
   end_of_f = ftell(yuvfile);
   fseek(yuvfile, sizeof(unsigned char) * offset, SEEK_SET);
@@ -134,16 +139,22 @@ char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters
     (tk->w - 1) * subsampling_dx + 1;
   img->y1 = !tk->Dim[1] ? (tk->h - 1) * subsampling_dy + 1 : tk->Dim[1] +
     (tk->h - 1) * subsampling_dy + 1;
+
+       size = tk->w * tk->h * prec_size;
        
-       for(compno = 0; compno < numcomps; compno++) {
-               for (i = 0; i < (tk->w * tk->h / (img->comps[compno].dx * img->comps[compno].dy))
-                       && !feof(yuvfile); i++) {
-                       if (!fread(&img->comps[compno].data[i], 1, 1, yuvfile)) {
-                               fprintf(stderr, "Error reading %s file !!\n", infile);                          
-                               return 1;
-                       }
-               }
-       }
+       for(compno = 0; compno < numcomps; compno++) 
+   {
+       max = size/(img->comps[compno].dx * img->comps[compno].dy);
+
+       for (i = 0; i < max && !feof(yuvfile); i++)
+  {
+       if (!fread(&img->comps[compno].data[i], 1, 1, yuvfile)) 
+ {
+       fprintf(stderr, "Error reading %s file !!\n", infile);                          
+       return 1;
+ }
+  }
+   }
        fclose(yuvfile);
        
   return 0;
index 63869ea97e34889c36214f63b127512f2be63b5a..156a101c71c69d176b28ee2264144c12f6f852b4 100644 (file)
@@ -124,11 +124,12 @@ int main(int argc, char *argv[]) {
        /* catch events using our callbacks and give a local context */
        opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);           
 
+       memset(&mj2_parameters, 0, sizeof(mj2_dparameters_t));
        /* set J2K decoding parameters to default values */
        opj_set_default_decoder_parameters(&mj2_parameters.j2k_parameters);
        
        /* setup the decoder decoding parameters using user parameters */
-       mj2_setup_decoder((opj_mj2_t*)dinfo->mj2_handle, &mj2_parameters);
+       mj2_setup_decoder(movie, &mj2_parameters);
                        
   if (mj2_read_struct(file, movie)) // Creating the movie structure
     return 1;  
index 77b495981df923733e22d578be255f4ee9979425..7766dd37957ca5c5c6c048c0e18f6ac2a5d80c60 100644 (file)
@@ -45,9 +45,143 @@ Size of memory first allocated for MOOV box
 */
 #define TEMP_BUF 10000 
 
+#define ENUMCS_GRAY 16
+#define ENUMCS_SRGB 17
+#define ENUMCS_SYCC 18
+
+#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
 
 /* -------------------------------------------------------------------------- */
 
+static int test_image(const char *fname, mj2_cparameters_t *cp)
+{
+       FILE *reader;
+       opj_image_t *image;
+       unsigned char *src;
+       opj_dinfo_t *dinfo;
+       opj_cio_t *cio;
+       opj_dparameters_t dparameters;
+       int success;
+       long src_len;
+
+       success = 0;
+
+       if((reader = fopen(fname, "rb")) == NULL) return success;
+
+       fseek(reader, 0, SEEK_END);
+       src_len = ftell(reader);
+       fseek(reader, 0, SEEK_SET);
+       src = (unsigned char*) malloc(src_len);
+       fread(src, 1, src_len, reader);
+       fclose(reader);
+
+       if(memcmp(src, J2K_CODESTREAM_MAGIC, 4) != 0)
+   {
+       free(src); return success;
+   }
+       memset(&dparameters, 0, sizeof(opj_dparameters_t));
+
+       opj_set_default_decoder_parameters(&dparameters);
+
+       dinfo = opj_create_decompress(CODEC_J2K);
+
+       opj_setup_decoder(dinfo, &dparameters);
+
+       cio = opj_cio_open((opj_common_ptr)dinfo, src, src_len);
+
+       image = opj_decode(dinfo, cio);
+
+       free(src); cio->buffer = NULL;
+       opj_cio_close(cio);
+
+       if(image == NULL) goto fin;
+
+       cp->numcomps = image->numcomps;
+       cp->w = image->comps[0].w;
+       cp->h = image->comps[0].h;
+       cp->prec = image->comps[0].prec;
+
+       if(image->numcomps > 2 )
+   {
+       if((image->comps[0].dx == 1)
+       && (image->comps[1].dx == 2)
+       && (image->comps[2].dx == 2)
+       && (image->comps[0].dy == 1)
+       && (image->comps[1].dy == 2)
+       && (image->comps[2].dy == 2))// horizontal and vertical
+  {
+//   Y420
+       cp->enumcs = ENUMCS_SYCC;
+       cp->CbCr_subsampling_dx = 2;
+       cp->CbCr_subsampling_dy = 2;
+  }
+       else
+       if((image->comps[0].dx == 1)
+       && (image->comps[1].dx == 2)
+       && (image->comps[2].dx == 2)
+       && (image->comps[0].dy == 1)
+       && (image->comps[1].dy == 1)
+       && (image->comps[2].dy == 1))// horizontal only
+  {
+//   Y422
+       cp->enumcs = ENUMCS_SYCC;
+       cp->CbCr_subsampling_dx = 2;
+       cp->CbCr_subsampling_dy = 1;
+  }
+       else
+       if((image->comps[0].dx == 1)
+       && (image->comps[1].dx == 1)
+       && (image->comps[2].dx == 1)
+       && (image->comps[0].dy == 1)
+       && (image->comps[1].dy == 1)
+       && (image->comps[2].dy == 1))
+  {
+//   Y444 or RGB
+
+       if(image->color_space ==  CLRSPC_SRGB)
+ {
+       cp->enumcs = ENUMCS_SRGB;
+
+//    cp->CbCr_subsampling_dx = 0;
+//    cp->CbCr_subsampling_dy = 0;
+ }
+       else
+ {
+       cp->enumcs = ENUMCS_SYCC;
+
+       cp->CbCr_subsampling_dx = 1;
+       cp->CbCr_subsampling_dy = 1;
+ }
+  }
+       else
+  {
+       goto fin;
+  }
+   }
+       else
+   {
+       cp->enumcs = ENUMCS_GRAY;
+//  cp->CbCr_subsampling_dx = 0;
+//  cp->CbCr_subsampling_dy = 0;
+   }
+       if(image->icc_profile_buf)
+   {
+       cp->meth = 2;
+       free(image->icc_profile_buf); image->icc_profile_buf = NULL;
+   }
+       else cp->meth = 1;
+
+       success = 1;
+fin:
+       if(dinfo)
+        opj_destroy_decompress(dinfo);
+
+       if(image)
+        opj_image_destroy(image);
+
+       return success;
+}
+
 /**
 sample error callback expecting a FILE* client object
 */
@@ -125,7 +259,6 @@ static void read_siz_marker(FILE *file, opj_image_t *image)
 static void setparams(opj_mj2_t *movie, opj_image_t *image) {
   int i, depth_0, depth, sign;
   
-  movie->tk[0].sample_rate = 25;
   movie->tk[0].w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
   movie->tk[0].h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
   mj2_init_stdmovie(movie);
@@ -233,7 +366,7 @@ int main(int argc, char *argv[]) {
   mj2_sample_t *sample;
   unsigned char* frame_codestream;
   FILE *mj2file, *j2kfile;
-  char j2kfilename[50];
+  char *j2kfilename;
   unsigned char *buf;
   int offset, mdat_initpos;
   opj_image_t img;
@@ -252,7 +385,7 @@ int main(int argc, char *argv[]) {
     fprintf(stderr, "failed to open %s for writing\n", argv[2]);
     return 1;
   }
-
+       memset(&img, 0, sizeof(opj_image_t));
        /*
        configure the event callbacks (not required)
        setting of each callback is optionnal
@@ -269,8 +402,17 @@ int main(int argc, char *argv[]) {
        opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);   
        
        /* setup the decoder encoding parameters using user parameters */
+       memset(&parameters, 0, sizeof(mj2_cparameters_t));
        movie = (opj_mj2_t*) cinfo->mj2_handle;
-       mj2_setup_encoder((opj_mj2_t*)cinfo->mj2_handle, &parameters);
+
+       j2kfilename = (char*)malloc(strlen(argv[1]) + 12);/* max. '%6d' */
+       sprintf(j2kfilename, "%s_00001.j2k",argv[1]);
+
+       if(test_image(j2kfilename, &parameters) == 0) goto fin;
+
+       parameters.frame_rate = 25; /* DEFAULT */
+
+       mj2_setup_encoder(movie, &parameters);
 
   
        /* Writing JP, FTYP and MDAT boxes 
@@ -362,10 +504,13 @@ int main(int argc, char *argv[]) {
   fwrite(buf,cio_tell(cio),1,mj2file);
        
   // Ending program
-  fclose(mj2file);
   free(img.comps);
   opj_cio_close(cio);
+
+fin:
+  fclose(mj2file);
   mj2_destroy_compress(movie);
-       
+  free(j2kfilename);
+
   return 0;
 }