STYLE: Add a lot of comments for the CMake build system
[openjpeg.git] / mj2 / frames_to_mj2.c
1 /*
2 * Copyright (c) 2003-2004, Fran�ois-Olivier Devaux
3 * Copyright (c) 2002-2004,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <openjpeg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <math.h>
32 #include <string.h>
33 #include <setjmp.h>
34 #ifndef DONT_HAVE_GETOPT
35 #include <getopt.h>
36 #else
37 #include "compat/getopt.h"
38 #endif
39
40 #include "mj2_convert.h"
41
42 #define MJ2_MDAT  0x6d646174
43 #define JP2_JP2C 0x6a703263
44
45 //MEMORY LEAK
46 #ifdef _DEBUG
47 #define _CRTDBG_MAP_ALLOC
48 #include <stdlib.h>  // Must be included first
49 #include <crtdbg.h>
50 #endif
51 //MEM
52
53 jmp_buf j2k_error;
54
55 void help_display()
56 {
57   fprintf(stdout,"HELP\n----\n\n");
58   fprintf(stdout,"- the -h option displays this help information on screen\n\n");
59   
60   
61   fprintf(stdout,"List of parameters for the MJ2 encoder:\n");
62   fprintf(stdout,"\n");
63   fprintf(stdout,"REMARKS:\n");
64   fprintf(stdout,"---------\n");
65   fprintf(stdout,"\n");
66   fprintf
67     (stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
68   fprintf
69     (stdout,"COD and QCD never appear in the tile_header.\n");
70   fprintf(stdout,"\n");
71   fprintf
72     (stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
73   fprintf
74     (stdout,"color image.  You need enough disk space memory (twice the original) to encode \n");
75   fprintf
76     (stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
77   fprintf(stdout,"\n");
78   fprintf(stdout,"By default:\n");
79   fprintf(stdout,"------------\n");
80   fprintf(stdout,"\n");
81   fprintf(stdout," * Lossless\n");
82   fprintf(stdout," * 1 tile\n");
83   fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
84   fprintf(stdout," * Size of code-block : 64 x 64\n");
85   fprintf(stdout," * Number of resolutions: 6\n");
86   fprintf(stdout," * No SOP marker in the codestream\n");
87   fprintf(stdout," * No EPH marker in the codestream\n");
88   fprintf(stdout," * No sub-sampling in x or y direction\n");
89   fprintf(stdout," * No mode switch activated\n");
90   fprintf(stdout," * Progression order: LRCP\n");
91   fprintf(stdout," * No index file\n");
92   fprintf(stdout," * No ROI upshifted\n");
93   fprintf(stdout," * No offset of the origin of the image\n");
94   fprintf(stdout," * No offset of the origin of the tiles\n");
95   fprintf(stdout," * Reversible DWT 5-3\n");
96   fprintf(stdout,"\n");
97   fprintf(stdout,"Parameters:\n");
98   fprintf(stdout,"------------\n");
99   fprintf(stdout,"\n");
100   fprintf
101     (stdout,"Required Parameters (except with -h):\n");
102   fprintf
103     (stdout,"-i           : source file  (-i source.yuv) \n");
104   fprintf
105     (stdout,"-o           : destination file (-o dest.mj2) \n");
106   fprintf
107     (stdout,"Optional Parameters:\n");
108   fprintf(stdout,"-h           : display the help information \n");
109   fprintf(stdout,"-r           : different compression ratios for successive layers (-r 20,10,5)\n ");
110   fprintf(stdout,"               - The rate specified for each quality level is the desired \n");
111   fprintf(stdout,"                 compression factor.\n");
112   fprintf(stdout,"                 Example: -r 20,10,1 means quality 1: compress 20x, \n");
113   fprintf(stdout,"                   quality 2: compress 10x and quality 3: compress lossless\n");
114   fprintf(stdout,"               (options -r and -q cannot be used together)\n ");
115   
116   fprintf(stdout,"-q           : different psnr for successive layers (-q 30,40,50) \n ");
117   
118   fprintf(stdout,"               (options -r and -q cannot be used together)\n ");
119   
120   fprintf(stdout,"-n           : number of resolutions (-n 3) \n");
121   fprintf(stdout,"-b           : size of code block (-b 32,32) \n");
122   fprintf(stdout,"-c           : size of precinct (-c 128,128) \n");
123   fprintf(stdout,"-t           : size of tile (-t 512,512) \n");
124   fprintf
125     (stdout,"-p           : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
126   fprintf
127     (stdout,"-s           : subsampling factor (-s 2,2) [-s X,Y] \n");
128   fprintf(stdout,"           Remark: subsampling bigger than 2 can produce error\n");
129   fprintf
130     (stdout,"-SOP         : write SOP marker before each packet \n");
131   fprintf
132     (stdout,"-EPH         : write EPH marker after each header packet \n");
133   fprintf
134     (stdout,"-M           : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
135   fprintf
136     (stdout,"                 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
137   fprintf
138     (stdout,"                 Indicate multiple modes by adding their values. \n");
139   fprintf
140     (stdout,"                 ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
141   fprintf
142     (stdout,"-x           : create an index file *.Idx (-x index_name.Idx) \n");
143   fprintf
144     (stdout,"-ROI         : c=%%d,U=%%d : quantization indices upshifted \n");
145   fprintf
146     (stdout,"               for component c=%%d [%%d = 0,1,2]\n");
147   fprintf
148     (stdout,"               with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n");
149   fprintf
150     (stdout,"-d           : offset of the origin of the image (-d 150,300) \n");
151   fprintf
152     (stdout,"-T           : offset of the origin of the tiles (-T 100,75) \n");
153   fprintf(stdout,"-I           : use the irreversible DWT 9-7 (-I) \n");
154   fprintf(stdout,"-W           : image width, height and the dx and dy subsampling \n");
155   fprintf(stdout,"               of the Cb and Cr components for YUV files \n");
156   fprintf(stdout,"               (default is '352,288,2,2' for CIF format's 352x288 and 4:2:0)\n");
157   fprintf(stdout,"-F           : video frame rate (set to 25 by default)\n");
158   
159   fprintf(stdout,"\n");
160   fprintf(stdout,"IMPORTANT:\n");
161   fprintf(stdout,"-----------\n");
162   fprintf(stdout,"\n");
163   fprintf(stdout,"The index file has the structure below:\n");
164   fprintf(stdout,"---------------------------------------\n");
165   fprintf(stdout,"\n");
166   fprintf(stdout,"Image_height Image_width\n");
167   fprintf(stdout,"progression order\n");
168   fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");
169   fprintf(stdout,"Components_nb\n");
170   fprintf(stdout,"Layers_nb\n");
171   fprintf(stdout,"decomposition_levels\n");
172   fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
173   fprintf(stdout,"   [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
174   fprintf(stdout,"Main_header_end_position\n");
175   fprintf(stdout,"Codestream_size\n");
176   fprintf(stdout,"Tile_0 start_pos end_Theader end_pos TotalDisto NumPix MaxMSE\n");
177   fprintf(stdout,"Tile_1   ''           ''        ''        ''       ''    ''\n");
178   fprintf(stdout,"...\n");
179   fprintf(stdout,"Tile_Nt   ''           ''        ''        ''       ''    ''\n");
180   fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
181   fprintf(stdout,"...\n");
182   fprintf(stdout,"Tpacket_Np ''   ''    ''   ''    ''       ''       ''     ''\n");
183   
184   fprintf(stdout,"MaxDisto\n");
185   
186   fprintf(stdout,"TotalDisto\n\n");
187 }
188
189 int give_progression(char progression[4])
190 {
191   if (progression[0] == 'L' && progression[1] == 'R'
192     && progression[2] == 'C' && progression[3] == 'P') {
193     return 0;
194   } else {
195     if (progression[0] == 'R' && progression[1] == 'L'
196       && progression[2] == 'C' && progression[3] == 'P') {
197       return 1;
198     } else {
199       if (progression[0] == 'R' && progression[1] == 'P'
200         && progression[2] == 'C' && progression[3] == 'L') {
201         return 2;
202       } else {
203         if (progression[0] == 'P' && progression[1] == 'C'
204           && progression[2] == 'R' && progression[3] == 'L') {
205           return 3;
206         } else {
207           if (progression[0] == 'C' && progression[1] == 'P'
208             && progression[2] == 'R' && progression[3] == 'L') {
209             return 4;
210           } else {
211             return -1;
212           }
213         }
214       }
215     }
216   }
217 }
218
219 double dwt_norms_97[4][10] = {
220   {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
221   {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
222   {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
223   {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
224 };
225
226 int floorlog2(int a)
227 {
228   int l;
229   for (l = 0; a > 1; l++) {
230     a >>= 1;
231   }
232   return l;
233 }
234
235 void encode_stepsize(int stepsize, int numbps, int *expn, int *mant)
236 {
237   int p, n;
238   p = floorlog2(stepsize) - 13;
239   n = 11 - floorlog2(stepsize);
240   *mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
241   *expn = numbps - p;
242 }
243
244 void calc_explicit_stepsizes(j2k_tccp_t * tccp, int prec)
245 {
246   int numbands, bandno;
247   numbands = 3 * tccp->numresolutions - 2;
248   for (bandno = 0; bandno < numbands; bandno++) {
249     double stepsize;
250     
251     int resno, level, orient, gain;
252     resno = bandno == 0 ? 0 : (bandno - 1) / 3 + 1;
253     orient = bandno == 0 ? 0 : (bandno - 1) % 3 + 1;
254     level = tccp->numresolutions - 1 - resno;
255     gain =
256       tccp->qmfbid == 0 ? 0 : (orient ==
257       0 ? 0 : (orient == 1
258       || orient == 2 ? 1 : 2));
259     if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
260       stepsize = 1.0;
261     } else {
262       double norm = dwt_norms_97[orient][level];
263       stepsize = (1 << (gain + 1)) / norm;
264     }
265     encode_stepsize((int) floor(stepsize * 8192.0), prec + gain,
266                     &tccp->stepsizes[bandno].expn,
267                     &tccp->stepsizes[bandno].mant);
268   }
269 }
270
271 int main(int argc, char **argv)
272 {
273   int NumResolution, numD_min;  /*   NumResolution : number of resolution                     */
274   int Tile_arg;                 /*   Tile_arg = 0 (not in argument) ou = 1 (in argument)      */
275   int CSty;                     /*   CSty : coding style                                      */
276   int Prog_order;               /*   progression order (default LRCP)                         */
277   char progression[4];
278   int numpocs, numpocs_tile;    /*   Number of progression order change (POC) default 0       */
279   int prcw_init[J2K_MAXRLVLS];  /*   Initialisation Precinct width                            */
280   int prch_init[J2K_MAXRLVLS];  /*   Initialisation Precinct height                           */
281   //int prcw_init, prch_init;                     /*   Initialisation precincts' size                           */
282   int cblockw_init, cblockh_init;       /*   Initialisation codeblocks' size                          */
283   int mode, value;              /*   Mode switch (cblk_style)                                 */
284   int subsampling_dx, subsampling_dy;   /* subsampling value for dx and dy                    */
285   int ROI_compno, ROI_shift;    /*   region of interrest                                      */
286   int Dim[2];                   /*   portion of the image coded                               */
287   int TX0, TY0;                 /*   tile off-set                                             */
288   mj2_movie_t movie;
289   j2k_cp_t cp, cp_init;         /*   cp_init is used to initialise in multiple tiles          */
290   j2k_tcp_t *tcp, *tcp_init;    /*   tcp_init is used to initialise in multiple tile          */
291   j2k_poc_t POC[32];            /*   POC : used in case of Progression order change           */
292   j2k_poc_t *tcp_poc;
293   j2k_tccp_t *tccp;
294   int i, tileno, l, j;
295   char *infile = 0;
296   char *outfile = 0;
297   char *index = 0;
298   char *s, S1, S2, S3;
299   char *buf;
300   int ir = 0;
301   int res_spec = 0;             /*   For various precinct sizes specification                 */
302   char sep;
303   int w;                        /*   Width of YUV file                                        */
304   int h;                        /*   Height of YUV file                                       */
305   int CbCr_subsampling_dx;      /*   Sample rate of YUV 4:4:4 4:2:2 or 4:2:0                  */
306   int CbCr_subsampling_dy;      /*   Sample rate of YUV 4:4:4 4:2:2 or 4:2:0                  */
307   int frame_rate;               /*   Video Frame Rate                                         */
308   int numcomps;                 /*   In YUV files, numcomps always considered as 3            */
309   int prec;                     /*   In YUV files, precision always considered as 8           */
310   int x1, y1,  len, jp2c_initpos, m, k, pos;
311   long mdat_initpos, offset;
312   FILE *mj2file, *yuvfile;
313   unsigned int sampleno;
314   j2k_image_t img;
315   
316   /* default value */
317   /* ------------- */
318   NumResolution = 6;
319   CSty = 0;
320   cblockw_init = 64;
321   cblockh_init = 64;
322   cp.tw = 1;
323   cp.th = 1;
324   cp.index_on = 0;
325   Prog_order = 0;
326   numpocs = 0;
327   mode = 0;
328   subsampling_dx = 1;
329   subsampling_dy = 1;
330   ROI_compno = -1;              /* no ROI */
331   ROI_shift = 0;
332   Dim[0] = 0;
333   Dim[1] = 0;
334   TX0 = 0;
335   TY0 = 0;
336   cp.comment = NULL;
337   cp.disto_alloc = 0;
338   cp.fixed_alloc = 0;
339   cp.fixed_quality = 0;         //add fixed_quality
340   w = 352;                      // CIF default value
341   h = 288;                      // CIF default value
342   CbCr_subsampling_dx = 2;      // CIF default value
343   CbCr_subsampling_dy = 2;      // CIF default value
344   frame_rate = 25;
345   
346   
347   Tile_arg = 0;
348   cp_init.tcps = (j2k_tcp_t *) malloc(sizeof(j2k_tcp_t));       /* initialisation if only one tile */
349   tcp_init = &cp_init.tcps[0];
350   tcp_init->numlayers = 0;
351   
352   cp.intermed_file = 0;         // Don't store each tile in a file during processing 
353   
354   while (1) {
355     int c = getopt(argc, argv,
356       "i:o:r:q:f:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I:W:F:");
357     if (c == -1)
358       break;
359     switch (c) {
360     case 'i':                   /* IN fill */
361       infile = optarg;
362       s = optarg;
363       while (*s) {
364         s++;
365       }
366       s--;
367       S3 = *s;
368       s--;
369       S2 = *s;
370       s--;
371       S1 = *s;
372       
373       if ((S1 == 'y' && S2 == 'u' && S3 == 'v')
374         || (S1 == 'Y' && S2 == 'U' && S3 == 'V')) {
375         cp.decod_format = YUV_DFMT;
376         break;
377       }
378       fprintf(stderr,
379         "!! Unrecognized format for infile : %c%c%c [accept only *.yuv] !!\n\n",
380         S1, S2, S3);
381       return 1;
382       break;
383       /* ----------------------------------------------------- */
384     case 'o':                   /* OUT fill */
385       outfile = optarg;
386       while (*outfile) {
387         outfile++;
388       }
389       outfile--;
390       S3 = *outfile;
391       outfile--;
392       S2 = *outfile;
393       outfile--;
394       S1 = *outfile;
395       
396       outfile = optarg;
397       
398       if ((S1 == 'm' && S2 == 'j' && S3 == '2')
399         || (S1 == 'M' && S2 == 'J' && S3 == '2'))
400         cp.cod_format = MJ2_CFMT;
401       else {
402         fprintf(stderr,
403           "Unknown output format image *.%c%c%c [only *.mj2]!! \n",
404           S1, S2, S3);
405         return 1;
406       }
407       
408       
409       
410       break;
411       /* ----------------------------------------------------- */
412     case 'r':                   /* rates rates/distorsion */
413       s = optarg;
414       while (sscanf(s, "%d", &tcp_init->rates[tcp_init->numlayers])
415         == 1) {
416         tcp_init->numlayers++;
417         while (*s && *s != ',') {
418           s++;
419         }
420         if (!*s)
421           break;
422         s++;
423       }
424       cp.disto_alloc = 1;
425       cp.matrice = NULL;
426       break;
427       /* ----------------------------------------------------- */
428     case 'q':                   /* add fixed_quality */
429       s = optarg;
430       while (sscanf
431         (s, "%f", &tcp_init->distoratio[tcp_init->numlayers]) == 1) {
432         tcp_init->numlayers++;
433         while (*s && *s != ',') {
434           s++;
435         }
436         if (!*s)
437           break;
438         s++;
439       }
440       cp.fixed_quality = 1;
441       cp.matrice = NULL;
442       break;
443       /* dda */
444       /* ----------------------------------------------------- */
445     case 'f':                   /* mod fixed_quality (before : -q) */
446       s = optarg;
447       sscanf(s, "%d", &tcp_init->numlayers);
448       s++;
449       if (tcp_init->numlayers > 9)
450         s++;
451       cp.matrice =
452         (int *) malloc(tcp_init->numlayers * NumResolution * 3 *
453         sizeof(int));
454       s = s + 2;
455       for (i = 0; i < tcp_init->numlayers; i++) {
456         tcp_init->rates[i] = 1;
457         sscanf(s, "%d,", &cp.matrice[i * NumResolution * 3]);
458         s += 2;
459         if (cp.matrice[i * NumResolution * 3] > 9)
460           s++;
461         cp.matrice[i * NumResolution * 3 + 1] = 0;
462         cp.matrice[i * NumResolution * 3 + 2] = 0;
463         for (j = 1; j < NumResolution; j++) {
464           sscanf(s, "%d,%d,%d",
465             &cp.matrice[i * NumResolution * 3 + j * 3 + 0],
466             &cp.matrice[i * NumResolution * 3 + j * 3 + 1],
467             &cp.matrice[i * NumResolution * 3 + j * 3 + 2]);
468           s += 6;
469           if (cp.matrice[i * NumResolution * 3 + j * 3] > 9)
470             s++;
471           if (cp.matrice[i * NumResolution * 3 + j * 3 + 1] > 9)
472             s++;
473           if (cp.matrice[i * NumResolution * 3 + j * 3 + 2] > 9)
474             s++;
475         }
476         if (i < tcp_init->numlayers - 1)
477           s++;
478       }
479       cp.fixed_alloc = 1;
480       break;
481       /* ----------------------------------------------------- */
482     case 't':                   /* tiles */
483       sscanf(optarg, "%d,%d", &cp.tdx, &cp.tdy);
484       Tile_arg = 1;
485       break;
486       /* ----------------------------------------------------- */
487     case 'n':                   /* resolution */
488       sscanf(optarg, "%d", &NumResolution);
489       break;
490       /* ----------------------------------------------------- */
491     case 'c':                   /* precinct dimension */
492       s = optarg;
493       do {
494         sep = 0;
495         sscanf(s, "[%d,%d]%c", &prcw_init[res_spec],
496           &prch_init[res_spec], &sep);
497         CSty |= 0x01;
498         res_spec++;
499         s = strpbrk(s, "]") + 2;
500       } while (sep == ',');
501       break;
502       /* ----------------------------------------------------- */
503     case 'b':                   /* code-block dimension */
504       sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init);
505       if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
506         || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
507         fprintf(stderr,
508           "!! Size of code_block error (option -b) !!\n\nRestriction :\n    * width*height<=4096\n    * 4<=width,height<= 1024\n\n");
509         return 1;
510       }
511       break;
512       /* ----------------------------------------------------- */
513     case 'x':                   /* creation of index file */
514       index = optarg;
515       cp.index_on = 1;
516       break;
517       /* ----------------------------------------------------- */
518     case 'p':                   /* progression order */
519       s = optarg;
520       for (i = 0; i < 4; i++) {
521         progression[i] = *s;
522         s++;
523       }
524       Prog_order = give_progression(progression);
525       
526       if (Prog_order == -1) {
527         fprintf(stderr,
528           "Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
529         return 1;
530       }
531       break;
532       /* ----------------------------------------------------- */
533     case 's':                   /* subsampling factor */
534       if (sscanf(optarg, "%d,%d", &subsampling_dx, &subsampling_dy)
535         != 2) {
536         fprintf(stderr,
537           "'-s' sub-sampling argument error !  [-s dx,dy]\n");
538         return 1;
539       }
540       break;
541       /* ----------------------------------------------------- */
542     case 'd':                   /* coordonnate of the reference grid */
543       if (sscanf(optarg, "%d,%d", &Dim[0], &Dim[1]) != 2) {
544         fprintf(stderr,
545           "-d 'coordonnate of the reference grid' argument error !! [-d x0,y0]\n");
546         return 1;
547       }
548       break;
549       /* ----------------------------------------------------- */
550     case 'h':                   /* Display an help description */
551       help_display();
552       return 0;
553       break;
554       /* ----------------------------------------------------- */
555     case 'P':                   /* POC */
556       fprintf(stderr, "/----------------------------------\\\n");
557       fprintf(stderr, "|  POC option not fully tested !!  |\n");
558       fprintf(stderr, "\\----------------------------------/\n");
559       
560       s = optarg;
561       while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile,
562         &POC[numpocs].resno0, &POC[numpocs].compno0,
563         &POC[numpocs].layno1, &POC[numpocs].resno1,
564         &POC[numpocs].compno1, POC[numpocs].progorder) == 7) {
565         POC[numpocs].prg = give_progression(POC[numpocs].progorder);
566         /* POC[numpocs].tile; */
567         numpocs++;
568         while (*s && *s != '/') {
569           s++;
570         }
571         if (!*s)
572           break;
573         s++;
574       }
575       break;
576       /* ------------------------------------------------------ */
577     case 'S':                   /* SOP marker */
578       CSty |= 0x02;
579       break;
580       /* ------------------------------------------------------ */
581     case 'E':                   /* EPH marker */
582       CSty |= 0x04;
583       break;
584       /* ------------------------------------------------------ */
585     case 'M':                   /* Mode switch pas tous au point !! */
586       if (sscanf(optarg, "%d", &value) == 1) {
587         for (i = 0; i <= 5; i++) {
588           int cache = value & (1 << i);
589           if (cache)
590             mode |= (1 << i);
591         }
592       }
593       break;
594       /* ------------------------------------------------------ */
595     case 'R':                   /* ROI */
596       if (sscanf(optarg, "OI:c=%d,U=%d", &ROI_compno, &ROI_shift) != 2) {
597         fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n");
598         return 1;
599       }
600       break;
601       /* ------------------------------------------------------ */
602     case 'T':                   /* Tile offset */
603       if (sscanf(optarg, "%d,%d", &TX0, &TY0) != 2) {
604         fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
605         return 1;
606       }
607       break;
608       /* ------------------------------------------------------ */
609     case 'C':                   /* Add a comment */
610       cp.comment = optarg;
611       break;
612       /* ------------------------------------------------------ */
613     case 'I':                   /* reversible or not */
614       ir = 1;
615       break;
616       /* ------------------------------------------------------ */
617     case 'W':                   /* Width and Height and Cb and Cr subsampling in case of YUV format files */
618       if (sscanf
619         (optarg, "%d,%d,%d,%d", &w, &h, &CbCr_subsampling_dx,
620         &CbCr_subsampling_dy) != 4) {
621         fprintf(stderr, "-W argument error");
622         return 1;
623       }
624       break;
625       /* ------------------------------------------------------ */
626     case 'F':                   /* Video frame rate */
627       if (sscanf(optarg, "%d", &frame_rate) != 1) {
628         fprintf(stderr, "-F argument error");
629         return 1;
630       }
631       break;
632       /* ------------------------------------------------------ */
633     default:
634       return 1;
635     }
636   }
637   
638   cp.tx0 = TX0;
639   cp.ty0 = TY0;
640   
641   /* Error messages */
642   /* -------------- */
643   if (!infile || !outfile) {
644     fprintf(stderr,
645       "Correct usage: mj2_encoder -i yuv-file -o mj2-file (+ options)\n");
646     return 1;
647   }
648   
649   if ((cp.disto_alloc || cp.fixed_alloc || cp.fixed_quality)
650     && (!(cp.disto_alloc ^ cp.fixed_alloc ^ cp.fixed_quality))) {
651     fprintf(stderr,
652       "Error: options -r -q and -f can not be used together !!\n");
653     return 1;
654   }                             // mod fixed_quality
655   
656   /* if no rate entered, lossless by default */
657   if (tcp_init->numlayers == 0) {
658     tcp_init->rates[tcp_init->numlayers] = 0;   //MOD antonin : losslessbug
659     tcp_init->numlayers++;
660     cp.disto_alloc = 1;
661   }
662   
663   if (TX0 > Dim[0] || TY0 > Dim[1]) {
664     fprintf(stderr,
665       "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
666       TX0, Dim[0], TY0, Dim[1]);
667     return 1;
668   }
669   
670   for (i = 0; i < numpocs; i++) {
671     if (POC[i].prg == -1) {
672       fprintf(stderr,
673         "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
674         i + 1);
675     }
676   }
677   
678   /* to respect profile - 0 */
679   /* ---------------------- */
680   numD_min = 0;
681   
682   x1 = !Dim[0] ? (w - 1) * subsampling_dx + 1 : Dim[0] + (w -
683     1) *
684     subsampling_dx + 1;
685   y1 = !Dim[1] ? (h - 1) * subsampling_dy + 1 : Dim[1] + (h -
686     1) *
687     subsampling_dy + 1;
688   
689   if (Tile_arg == 1) {
690     cp.tw = int_ceildiv(x1 - cp.tx0, cp.tdx);
691     cp.th = int_ceildiv(y1 - cp.ty0, cp.tdy);
692   } else {
693     cp.tdx = x1 - cp.tx0;
694     cp.tdy = y1 - cp.ty0;
695   }
696   
697   
698   /* Initialization for PPM marker */
699   cp.ppm = 0;
700   cp.ppm_data = NULL;
701   cp.ppm_previous = 0;
702   cp.ppm_store = 0;
703   
704   numcomps = 3;                 /* Because YUV files only have 3 components */
705   
706   tcp_init->mct = 0;            /* No component transform needed */
707   
708   prec = 8;                     /* Because in YUV files, components have 8-bit depth */
709   
710   /* Init the mutiple tiles */
711   /* ---------------------- */
712   cp.tcps = (j2k_tcp_t *) malloc(cp.tw * cp.th * sizeof(j2k_tcp_t));
713   
714   for (tileno = 0; tileno < cp.tw * cp.th; tileno++) {
715     tcp = &cp.tcps[tileno];
716     tcp->numlayers = tcp_init->numlayers;
717     for (j = 0; j < tcp->numlayers; j++) {
718       if (cp.fixed_quality)     // add fixed_quality
719         tcp->distoratio[j] = tcp_init->distoratio[j];
720       else
721         tcp->rates[j] = tcp_init->rates[j];
722     }
723     tcp->csty = CSty;
724     tcp->prg = Prog_order;
725     tcp->mct = tcp_init->mct;
726     tcp->ppt = 0;
727     tcp->ppt_data = NULL;
728     tcp->ppt_store = 0;
729     
730     numpocs_tile = 0;
731     tcp->POC = 0;
732     if (numpocs) {
733       /* intialisation of POC */
734       tcp->POC = 1;
735       for (i = 0; i < numpocs; i++) {
736         if (tileno == POC[i].tile - 1 || POC[i].tile == -1) {
737           tcp_poc = &tcp->pocs[numpocs_tile];
738           tcp_poc->resno0 = POC[numpocs_tile].resno0;
739           tcp_poc->compno0 = POC[numpocs_tile].compno0;
740           tcp_poc->layno1 = POC[numpocs_tile].layno1;
741           tcp_poc->resno1 = POC[numpocs_tile].resno1;
742           tcp_poc->compno1 = POC[numpocs_tile].compno1;
743           tcp_poc->prg = POC[numpocs_tile].prg;
744           tcp_poc->tile = POC[numpocs_tile].tile;
745           numpocs_tile++;
746         }
747       }
748     }
749     tcp->numpocs = numpocs_tile;
750     tcp->tccps = (j2k_tccp_t *) malloc(numcomps * sizeof(j2k_tccp_t));
751     
752     for (i = 0; i < numcomps; i++) {
753       tccp = &tcp->tccps[i];
754       tccp->csty = CSty & 0x01; /* 0 => one precinct || 1 => custom precinct  */
755       tccp->numresolutions = NumResolution;
756       tccp->cblkw = int_floorlog2(cblockw_init);
757       tccp->cblkh = int_floorlog2(cblockh_init);
758       tccp->cblksty = mode;
759       tccp->qmfbid = ir ? 0 : 1;
760       tccp->qntsty = ir ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
761       tccp->numgbits = 2;
762       if (i == ROI_compno)
763         tccp->roishift = ROI_shift;
764       else
765         tccp->roishift = 0;
766       if (CSty & J2K_CCP_CSTY_PRT) {
767         int p = 0;
768         for (j = tccp->numresolutions - 1; j >= 0; j--) {
769           if (p < res_spec) {
770             if (prcw_init[p] < 1)
771               tccp->prcw[j] = 1;
772             else
773               tccp->prcw[j] = int_floorlog2(prcw_init[p]);
774             
775             if (prch_init[p] < 1)
776               tccp->prch[j] = 1;
777             else
778               tccp->prch[j] = int_floorlog2(prch_init[p]);
779           } else {
780             int size_prcw, size_prch;
781             size_prcw = prcw_init[res_spec - 1] >> (p - (res_spec - 1));
782             size_prch = prch_init[res_spec - 1] >> (p - (res_spec - 1));
783             if (size_prcw < 1)
784               tccp->prcw[j] = 1;
785             else
786               tccp->prcw[j] = int_floorlog2(size_prcw);
787             if (size_prch < 1)
788               tccp->prch[j] = 1;
789             else
790               tccp->prch[j] = int_floorlog2(size_prch);
791           }
792           p++;
793           /*printf("\nsize precinct pour level %d : %d,%d\n", j,
794           tccp->prcw[j], tccp->prch[j]); */
795         }
796       } else {
797         for (j = 0; j < tccp->numresolutions; j++) {
798           tccp->prcw[j] = 15;
799           tccp->prch[j] = 15;
800         }
801       }
802       calc_explicit_stepsizes(tccp, prec);
803     }
804   }
805   
806   mj2file = fopen(outfile, "wb");
807   
808   if (!mj2file) {
809     fprintf(stderr, "failed to open %s for writing\n", argv[2]);
810     return 1;
811   }
812   
813   movie.tk = (mj2_tk_t *) malloc(sizeof(mj2_tk_t));
814   movie.num_vtk = 1;
815   movie.num_stk = 0;
816   movie.num_htk = 0;
817   
818   movie.tk[0].track_type = 0;   // Video Track
819   movie.tk[0].track_ID = 1;
820   movie.tk[0].Dim[0] = Dim[0];
821   movie.tk[0].Dim[1] = Dim[1];
822   movie.tk[0].w = w;
823   movie.tk[0].h = h;
824   movie.tk[0].CbCr_subsampling_dx = CbCr_subsampling_dx;
825   movie.tk[0].CbCr_subsampling_dy = CbCr_subsampling_dy;
826   movie.tk[0].sample_rate = frame_rate;
827   movie.tk[0].jp2_struct.numcomps = 3;  // NC  
828   jp2_init_stdjp2(&movie.tk[0].jp2_struct);
829   
830   movie.tk[0].jp2_struct.w = w;
831   movie.tk[0].jp2_struct.h = h;
832   movie.tk[0].jp2_struct.bpc = 7;  
833   movie.tk[0].jp2_struct.meth = 1;
834   movie.tk[0].jp2_struct.enumcs = 18;  // YUV
835   
836   
837   yuvfile = fopen(infile,"rb");
838   if (!yuvfile) {  
839     fprintf(stderr, "failed to open %s for reading\n",infile);
840     return 1;
841   }
842   
843   movie.tk[0].num_samples = yuv_num_frames(&movie.tk[0],yuvfile); 
844   if (!movie.tk[0].num_samples) {
845     fprintf(stderr,"Unable to count the number of frames in YUV input file\n");
846   }
847   
848   // One sample per chunk
849   movie.tk[0].chunk = (mj2_chunk_t*) malloc(movie.tk[0].num_samples * sizeof(mj2_chunk_t));     
850   movie.tk[0].sample = (mj2_sample_t*) malloc(movie.tk[0].num_samples * sizeof(mj2_sample_t));
851   
852   if (mj2_init_stdmovie(&movie)) {
853     fprintf(stderr, "Error with movie initialization");
854     return 1;
855   };    
856   
857   // Writing JP, FTYP and MDAT boxes 
858   buf = (char*) malloc (300 * sizeof(char)); // Assuming that the JP and FTYP
859   // boxes won't be longer than 300 bytes
860   cio_init(buf , 300);
861   mj2_write_jp();
862   mj2_write_ftyp(&movie);
863   mdat_initpos = cio_tell();
864   cio_skip(4);
865   cio_write(MJ2_MDAT, 4);       
866   fwrite(buf,cio_tell(),1,mj2file);
867   offset = cio_tell();
868   free(buf);
869   
870   for (i = 0; i < movie.num_stk + movie.num_htk + movie.num_vtk; i++) {
871     if (movie.tk[i].track_type != 0) {
872       fprintf(stderr, "Unable to write sound or hint tracks\n");
873     } else {
874       //j2k_cp_t cp_init;
875       mj2_tk_t *tk;
876       
877       tk = &movie.tk[i];
878       
879       //tk->sample =
880         //(mj2_sample_t *) malloc(tk->num_samples * sizeof(mj2_sample_t));
881       tk->num_chunks = tk->num_samples;
882       //tk->chunk =
883         //(mj2_chunk_t *) malloc(tk->num_chunks * sizeof(mj2_chunk_t));
884             
885       fprintf(stderr, "Video Track number %d\n", i + 1);
886       
887       // Copy the first tile coding parameters (tcp) to cp_init 
888       
889       //cp_init.tcps =
890         //(j2k_tcp_t *) malloc(cp.tw * cp.th * sizeof(j2k_tcp_t));
891       for (tileno = 0; tileno < cp.tw * cp.th; tileno++) {
892         for (l = 0; l < cp.tcps[tileno].numlayers; l++) {
893           cp_init.tcps[tileno].rates[l] = cp.tcps[tileno].rates[l];
894           //tileno = cp.tcps[tileno].rates[l];
895         }
896       }
897       
898       for (sampleno = 0; sampleno < tk->num_samples; sampleno++) {
899         buf = (char *) malloc(cp.tdx * cp.tdy * cp.th * cp.tw * 2);
900         cio_init(buf, cp.tdx * cp.tdy * cp.th * cp.tw * 2);
901         
902         fprintf(stderr, "Frame number %d/%d: ", sampleno + 1, tk->num_samples);
903         
904         
905         if (!yuvtoimage(yuvfile, tk, &img, sampleno, subsampling_dx, subsampling_dy)) {
906           fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno);
907           return 1;
908         }
909         
910         jp2c_initpos = cio_tell();
911         cio_skip(4);
912         cio_write(JP2_JP2C, 4); // JP2C
913         
914         len = j2k_encode(&img, &cp, buf, cp.tdx * cp.tdy * 2, index); 
915         if (len ==0) {
916           fprintf(stderr,"Unable to encode image");
917           return 1;
918         }
919         
920         cio_seek(jp2c_initpos);
921         cio_write(len+8,4);
922         
923         for (m = 0; m < img.numcomps; m++) {
924           free(img.comps[m].data);        
925         }
926         free(img.comps);
927         
928         tk->sample[sampleno].sample_size = len+8;
929         
930         tk->sample[sampleno].offset = offset;
931         tk->chunk[sampleno].offset = offset;    // There is one sample per chunk 
932         
933         fwrite(buf, 1, len+8, mj2file);
934         
935         offset += len+8;
936         
937         free(buf);
938         
939         // Copy the cp_init parameters to cp.tcps 
940         
941         for (tileno = 0; tileno < cp.tw * cp.th; tileno++) {
942           for (k = 0; k < cp.tcps[tileno].numlayers; k++) {
943             cp.tcps[tileno].rates[k] = cp_init.tcps[tileno].rates[k];
944           }
945         }
946       }
947     }
948   }
949   
950   fseek(mj2file, mdat_initpos, SEEK_SET);
951
952   buf = (char*) malloc(4*sizeof(char));
953   
954   cio_init(buf, 4);     // Init a cio to write box length variable in a little endian way 
955   cio_write(offset - mdat_initpos, 4);
956   fwrite(buf, 4, 1, mj2file);
957   fseek(mj2file,0,SEEK_END);
958   free(buf);
959   
960   // Writing MOOV box 
961   i=1;
962   buf = (char*) malloc (10000 * sizeof(char));
963   cio_init(buf , i*10000);
964   if (setjmp(j2k_error)) {
965     i++;
966     realloc(buf,i*10000* sizeof(char));
967     pos = cio_tell();
968     cio_init(buf , i*10000);
969     cio_seek(pos);
970   }
971   mj2_write_moov(&movie);
972   fwrite(buf,cio_tell(),1,mj2file);
973   
974   // Ending program 
975   mj2_memory_free(&movie);
976   free(cp_init.tcps);
977   if (tcp_init->numlayers > 9)
978     free(cp.matrice);
979   for (tileno = 0; tileno < cp.tw * cp.th; tileno++)
980     free(cp.tcps[tileno].tccps);
981   free(cp.tcps);  
982   fclose(mj2file);
983   free(buf);
984   remove("Compo0");
985   remove("Compo1");
986   remove("Compo2");
987
988   //MEMORY LEAK
989   #ifdef _DEBUG
990     _CrtDumpMemoryLeaks();
991   #endif
992   //MEM
993     
994   return 0;
995 }
996
997