00fca99c586d4809161345209ac5a4b5857e1e0e
[openjpeg.git] / codec / j2k_to_image.c
1 /* Copyright (c) 2001 David Janssens
2 * Copyright (c) 2002-2003 Yannick Verschueren
3 * Copyright (c) 2002-2003 Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
4
5 * All rights reserved. 
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
29
30 //MEMORY LEAK
31
32 #ifdef _DEBUG
33
34 #define _CRTDBG_MAP_ALLOC
35
36 #include <stdlib.h>  // Must be included first
37
38 #include <crtdbg.h>
39
40 #endif
41
42 //MEM
43
44
45
46 #include <openjpeg.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #ifndef DONT_HAVE_GETOPT
51 #include <getopt.h>
52 #else
53 #include "compat/getopt.h"
54 #endif
55
56 void usage_display(char *prgm)
57 {
58   fprintf(stdout,"Usage:\n");
59   fprintf(stdout,"  %s...\n",prgm);
60   fprintf(stdout,"  -i <compressed file>\n");
61   fprintf(stdout,"    REQUIRED\n");
62   fprintf(stdout,"    Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");
63   fprintf(stdout,"    is identified based on its suffix.\n");
64   fprintf(stdout,"  -o <decompressed file>\n");
65   fprintf(stdout,"    REQUIRED\n");
66   fprintf(stdout,"    Currently accepts PGM-files, PPM-files, PNM-files, PGX-files and\n");
67   fprintf(stdout,"    BMP-files. Binary data is written to the file (not ascii). If a PGX\n");
68   fprintf(stdout,"    filename is given, there will be as many output files as there are\n");
69   fprintf(stdout,"    components: an indice starting from 0 will then be appended to the\n");
70   fprintf(stdout,"    output filename, just before the \"pgx\" extension. If a PGM filename\n");
71   fprintf(stdout,"    is given and there are more than one component, only the first component\n");
72   fprintf(stdout,"    will be written to the file.\n");
73   fprintf(stdout,"  -r <reduce factor>\n");
74   fprintf(stdout,"    Set the number of highest resolution levels to be discarded. The\n");
75   fprintf(stdout,"    image resolution is effectively divided by 2 to the power of the\n");
76   fprintf(stdout,"    number of discarded levels. The reduce factor is limited by the\n");
77   fprintf(stdout,"    smallest total number of decomposition levels among tiles.\n");
78   fprintf(stdout,"  -l <number of quality layers to decode>\n");
79   fprintf(stdout,"    Set the maximum number of quality layers to decode. If there are\n");
80   fprintf(stdout,"    less quality layers than the specified number, all the quality layers\n");
81   fprintf(stdout,"    are decoded.\n");
82   fprintf(stdout,"  -u\n");
83   fprintf(stdout,"    print an usage statement\n");
84   fprintf(stdout,"\n");
85 }
86
87 int main(int argc, char **argv)
88 {
89   FILE *fsrc=NULL;
90   FILE *fdest=NULL;
91   char *infile=NULL;
92   char *outfile=NULL;
93   char *tmp=NULL;
94   char S1, S2, S3;
95   
96   char *src=NULL; 
97   
98   int len;
99   
100   j2k_image_t img;
101   j2k_cp_t cp;
102   jp2_struct_t *jp2_struct=NULL;
103   
104   int w, wr, wrr, h, hr, hrr, max;
105   int i, compno, pad, j;
106   int adjust;
107   
108   cp.layer=0;
109   cp.reduce=0;
110   cp.decod_format=-1;
111   cp.cod_format=-1;
112   
113   while (1) {
114     int c = getopt(argc, argv,"i:o:r:l:u");
115     if (c == -1)
116       break;
117     switch (c) {
118       
119       //Input file
120     case 'i':
121       infile = optarg;
122       tmp = optarg;
123       while (*tmp) {
124         tmp++;
125       }
126       tmp--;
127       S3 = *tmp;
128       tmp--;
129       S2 = *tmp;
130       tmp--;
131       S1 = *tmp;
132       
133       /* J2K format */
134       if ((S1 == 'j' && S2 == '2' && S3 == 'k')
135         || (S1 == 'J' && S2 == '2' && S3 == 'K') 
136         || (S1 == 'j' && S2 == '2' && S3 == 'c')
137         || (S1 == 'J' && S2 == '2' && S3 == 'C')) {
138         cp.cod_format=J2K_CFMT;
139         break;
140       }
141       
142       /* JP2 format */
143       if ((S1 == 'j' && S2 == 'p' && S3 == '2')
144         || (S1 == 'J' && S2 == 'P' && S3 == '2')) {
145         cp.cod_format=JP2_CFMT;
146         break;
147       }
148       
149       /* JPT format */
150       if ((S1 == 'j' && S2 == 'p' && S3 == 't')
151         || (S1 == 'J' && S2 == 'P' && S3 == 'T')) {
152         cp.cod_format=JPT_CFMT;
153         break;
154       }
155       
156       fprintf(stderr,
157         "j2k_to_image : Unknown input image format *.%c%c%c [only *.j2k, *.jp2, *.jpc or *.jpt]!! \n",
158         S1, S2, S3);
159       return 1;
160       break;
161       
162       /* ----------------------------------------------------- */
163       
164       //Output file
165     case 'o':
166       outfile = optarg;
167       tmp = optarg;
168       while (*tmp) {
169         tmp++;
170       }
171       tmp--;
172       S3 = *tmp;
173       tmp--;
174       S2 = *tmp;
175       tmp--;
176       S1 = *tmp;
177       
178       // PGX format      
179       if ((S1 == 'p' && S2 == 'g' && S3 == 'x')
180         || (S1 == 'P' && S2 == 'G' && S3 == 'X')) {
181         cp.decod_format = PGX_DFMT;
182         break;
183       }
184       
185       // PxM format 
186       if ((S1 == 'p' && S2 == 'n' && S3 == 'm')
187         || (S1 == 'P' && S2 == 'N' && S3 == 'M') 
188         || (S1 == 'p' && S2 == 'g' && S3 == 'm')
189         || (S1 == 'P' && S2 == 'G' && S3 == 'M') 
190         || (S1 == 'P' && S2 == 'P' && S3 == 'M')
191         || (S1 == 'p' && S2 == 'p' && S3 == 'm')) {
192         cp.decod_format = PXM_DFMT;
193         break;
194       }
195       
196       // BMP format 
197       if ((S1 == 'b' && S2 == 'm' && S3 == 'p')
198         || (S1 == 'B' && S2 == 'M' && S3 == 'P')) {
199         cp.decod_format = BMP_DFMT;
200         break;
201       }
202       
203       // otherwise : error
204       fprintf(stderr,
205         "!! Unrecognized output image format *.%c%c%c [only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n",
206         S1, S2, S3);
207       
208       return 1;
209       break;
210       
211       /* ----------------------------------------------------- */
212       
213       //Reduce option
214     case 'r':
215       tmp=optarg;
216       sscanf(tmp, "%d", &cp.reduce);
217       break;
218       
219       /* ----------------------------------------------------- */
220       
221       //Layering option
222     case 'l':
223       tmp=optarg;
224       sscanf(tmp, "%d", &cp.layer);
225       break;
226       
227       /* ----------------------------------------------------- */
228       
229     case 'u':                   
230       usage_display(argv[0]);
231       return 0;
232       break;
233       /* ----------------------------------------------------- */
234       
235     default:
236       fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c,optarg);
237       break;
238       
239     }
240   }
241   
242   //Check required arguments
243   //------------------------
244   if (!infile || !outfile) {
245     fprintf(stderr,"ERROR -> At least one required argument is missing\nCheck j2k_to_image -u for usage information\n");
246     return 1;
247   }
248   
249   //Read the input file and put it in memory
250   //----------------------------------------
251   fsrc = fopen(infile, "rb");
252   if (!fsrc) {
253     fprintf(stderr, "ERROR -> failed to open %s for reading\n", infile);
254     return 1;
255   }
256   fseek(fsrc, 0, SEEK_END);
257   len = ftell(fsrc);
258   fseek(fsrc, 0, SEEK_SET);
259   src = (char *) malloc(len);
260   fread(src, 1, len, fsrc);
261   fclose(fsrc);
262   
263   //Decode the code-stream
264   //----------------------
265   switch(cp.cod_format) {
266     
267   case J2K_CFMT:
268     if (!j2k_decode(src, len, &img, &cp)) {
269       fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
270       return 1;
271     }
272     break;
273     
274   case JP2_CFMT:
275     jp2_struct = (jp2_struct_t *) malloc(sizeof(jp2_struct_t));
276     jp2_struct->image = &img;
277     
278     if (jp2_read_struct(src, jp2_struct, len)) {
279       fprintf(stderr, "ERROR -> j2k_to_image: failed to decode jp2 structure!\n");
280       return 1;
281     }
282     
283     if (!j2k_decode(src + jp2_struct->j2k_codestream_offset, jp2_struct->j2k_codestream_len, &img, &cp)) {
284       fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
285       return 1;
286     }
287     
288     /* Insert code here if you want to create actions on jp2_struct before deleting it */
289     
290     free(jp2_struct);
291     break;
292     
293   case JPT_CFMT:
294     if (!j2k_decode_jpt_stream(src, len, &img, &cp)) {
295       fprintf(stderr, "ERROR -> j2k_to_image: failed to decode JPT-file!\n");
296       return 1;
297     }
298     break;
299     
300   default:
301     fprintf(stderr,
302       "ERROR -> j2k_to_image : Unknown input image format\n");
303     return 1;
304     break;
305   }
306   
307   //Free the memory containing the code-stream
308   //------------------------------------------
309   
310   free(src);
311   
312   
313   //Create output image
314   //-------------------
315   
316   /* ---------------------------- / */
317   /* /                            / */
318   /* /  FORMAT : PNM, PGM or PPM  / */
319   /* /                            / */
320   /* ---------------------------- / */
321   
322   switch (cp.decod_format) {
323   case PXM_DFMT:                        /* PNM PGM PPM */
324     
325     tmp=outfile;
326     while (*tmp) {
327       tmp++;
328     }
329     tmp--;
330     tmp--;
331     S2 = *tmp;
332     
333     if (img.numcomps == 3 && img.comps[0].dx == img.comps[1].dx
334       && img.comps[1].dx == img.comps[2].dx
335       && img.comps[0].dy == img.comps[1].dy
336       && img.comps[1].dy == img.comps[2].dy
337       && img.comps[0].prec == img.comps[1].prec
338       && img.comps[1].prec == img.comps[2].prec
339       && S2 !='g' && S2 !='G') {
340       
341       fdest = fopen(outfile, "wb");
342       if (!fdest) {
343         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
344         return 1;
345       }
346       
347       w = int_ceildiv(img.x1 - img.x0, img.comps[0].dx);
348       // wr = int_ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor),img.comps[0].dx);
349       wr = img.comps[0].w;
350       wrr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor);
351       
352       h = int_ceildiv(img.y1 - img.y0, img.comps[0].dy);
353       // hr = int_ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy);
354       hr = img.comps[0].h;
355       hrr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor);
356       
357       max = img.comps[0].prec > 8 ? 255 : (1 << img.comps[0].prec) - 1;
358       
359       img.comps[0].x0 =
360         int_ceildivpow2(img.comps[0].x0 -
361         int_ceildiv(img.x0, img.comps[0].dx),
362         img.comps[0].factor);
363       img.comps[0].y0 =
364         int_ceildivpow2(img.comps[0].y0 -
365         int_ceildiv(img.y0, img.comps[0].dy),
366         img.comps[0].factor);
367       
368       
369       fprintf(fdest, "P6\n# %d %d %d %d %d\n%d %d\n%d\n",
370         cp.tcps[cp.tileno[0]].tccps[0].numresolutions, w, h,
371         img.comps[0].x0, img.comps[0].y0, wrr, hrr, max);
372       adjust = img.comps[0].prec > 8 ? img.comps[0].prec - 8 : 0;
373       for (i = 0; i < wrr * hrr; i++) {
374         char r, g, b;
375         r = img.comps[0].data[i / wrr * wr + i % wrr];
376         r += (img.comps[0].sgnd ? 1 << (img.comps[0].prec - 1) : 0);
377         r = r >> adjust;
378         
379         g = img.comps[1].data[i / wrr * wr + i % wrr];
380         g += (img.comps[1].sgnd ? 1 << (img.comps[1].prec - 1) : 0);
381         g = g >> adjust;
382         
383         b = img.comps[2].data[i / wrr * wr + i % wrr];
384         b += (img.comps[2].sgnd ? 1 << (img.comps[2].prec - 1) : 0);
385         b = b >> adjust;
386         
387         fprintf(fdest, "%c%c%c", r, g, b);
388       }
389       free(img.comps[0].data);
390       free(img.comps[1].data);
391       free(img.comps[2].data);
392       fclose(fdest);
393       
394     } else {
395       int ncomp=(S2=='g' || S2=='G')?1:img.numcomps;
396       if (img.numcomps>ncomp) {
397         fprintf(stderr,"WARNING -> [PGM files] Only the first component\n");
398         fprintf(stderr,"           is written to the file\n");
399       }
400       for (compno = 0; compno < ncomp; compno++) {
401         char name[256];
402         if (ncomp > 1) {
403           sprintf(name, "%d.%s", compno, outfile);
404         } else {
405           sprintf(name, "%s", outfile);
406         }
407         
408         fdest = fopen(name, "wb");
409         if (!fdest) {
410           fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
411           return 1;
412         }
413         
414         w = int_ceildiv(img.x1 - img.x0, img.comps[compno].dx);
415         // wr = int_ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor),img.comps[compno].dx);
416         wr = img.comps[compno].w;
417         wrr =
418           int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor);
419         
420         h = int_ceildiv(img.y1 - img.y0, img.comps[compno].dy);
421         // hr = int_ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[compno].dy);
422         hr = img.comps[compno].h;
423         hrr =
424           int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor);
425         
426         max =
427           img.comps[compno].prec >
428           8 ? 255 : (1 << img.comps[compno].prec) - 1;
429         
430         img.comps[compno].x0 =
431           int_ceildivpow2(img.comps[compno].x0 -
432           int_ceildiv(img.x0,
433                                       img.comps[compno].dx),
434                                       img.comps[compno].factor);
435         img.comps[compno].y0 =
436           int_ceildivpow2(img.comps[compno].y0 -
437           int_ceildiv(img.y0,
438                                       img.comps[compno].dy),
439                                       img.comps[compno].factor);
440         
441         fprintf(fdest, "P5\n# %d %d %d %d %d\n%d %d\n%d\n",
442           cp.tcps[cp.tileno[0]].tccps[compno].
443           numresolutions, w, h, img.comps[compno].x0,
444           img.comps[compno].y0, wrr, hrr, max);
445         adjust =
446           img.comps[compno].prec > 8 ? img.comps[compno].prec - 8 : 0;
447         for (i = 0; i < wrr * hrr; i++) {
448           char l;
449           l = img.comps[compno].data[i / wrr * wr + i % wrr];
450           l += (img.comps[compno].
451             sgnd ? 1 << (img.comps[compno].prec - 1) : 0);
452           l = l >> adjust;
453           fprintf(fdest, "%c", l);
454         }
455         fclose(fdest);
456         free(img.comps[compno].data);
457       }
458     }
459     break;
460     
461     /* ------------------------ / */
462     /* /                        / */
463     /* /     FORMAT : PGX       / */
464     /* /                        / */
465     /* /----------------------- / */
466   case PGX_DFMT:                        /* PGX */
467     for (compno = 0; compno < img.numcomps; compno++) {
468       j2k_comp_t *comp = &img.comps[compno];
469       char name[256];
470       int nbytes = 0;
471       tmp = outfile;
472       while (*tmp) {
473         tmp++;
474       }
475       while (*tmp!='.') {
476         tmp--;
477       }
478       *tmp='\0';
479       //if (img.numcomps > 1)
480       sprintf(name, "%s-%d.pgx", outfile, compno);
481       
482       //else
483       
484       //sprintf(name, "%s.pgx", outfile);
485       
486       fdest = fopen(name, "wb");
487       if (!fdest) {
488         fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
489         return 1;
490       }
491       
492       // w = int_ceildiv(img.x1 - img.x0, comp->dx);
493       // wr = int_ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), comp->dx);
494       w = img.comps[compno].w;
495       wr = int_ceildivpow2(img.comps[compno].w, img.comps[compno].factor);
496       
497       // h = int_ceildiv(img.y1 - img.y0, comp->dy);
498       // hr = int_ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), comp->dy);
499       h = img.comps[compno].h;
500       hr = int_ceildivpow2(img.comps[compno].h, img.comps[compno].factor);
501       
502       fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+',
503         comp->prec, wr, hr);
504       
505       if (comp->prec <= 8)
506         nbytes = 1;
507       
508       else if (comp->prec <= 16)
509         nbytes = 2;
510       
511       else
512         nbytes = 4;
513       for (i = 0; i < wr * hr; i++) {
514         int v = img.comps[compno].data[i / wr * w + i % wr];
515         
516         for (j = nbytes - 1; j >= 0; j--) {
517           
518           char byte = (char) (v >> (j * 8));
519           
520           fwrite(&byte, 1, 1, fdest);
521           
522         }
523       }
524       free(img.comps[compno].data);
525       fclose(fdest);
526     }
527     break;
528     
529     /* ------------------------ / */
530     /* /                        / */
531     /* /     FORMAT : BMP       / */
532     /* /                        / */
533     /* /----------------------- / */
534     
535   case BMP_DFMT:                        /* BMP */
536     if (img.numcomps == 3 && img.comps[0].dx == img.comps[1].dx
537       && img.comps[1].dx == img.comps[2].dx
538       && img.comps[0].dy == img.comps[1].dy
539       && img.comps[1].dy == img.comps[2].dy
540       && img.comps[0].prec == img.comps[1].prec
541       && img.comps[1].prec == img.comps[2].prec) {
542       /* -->> -->> -->> -->>
543       
544        24 bits color
545        
546       <<-- <<-- <<-- <<-- */
547       
548       fdest = fopen(outfile, "wb");
549       if (!fdest) {
550         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
551         return 1;
552       }
553       
554       // w = int_ceildiv(img.x1 - img.x0, img.comps[0].dx);
555       // wr = int_ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), img.comps[0].dx);
556       w = img.comps[0].w;
557       wr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor);
558       
559       // h = int_ceildiv(img.y1 - img.y0, img.comps[0].dy);
560       // hr = int_ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy);
561       h = img.comps[0].h;
562       hr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor);
563       
564       fprintf(fdest, "BM");
565       
566       /* FILE HEADER */
567       /* ------------- */
568       fprintf(fdest, "%c%c%c%c",
569         (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) +
570         54) & 0xff,
571         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
572         >> 8) & 0xff,
573         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
574         >> 16) & 0xff,
575         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
576         >> 24) & 0xff);
577       fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
578         ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
579       fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,
580         ((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
581       
582       /* INFO HEADER   */
583       /* ------------- */
584       fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,
585         ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
586       fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
587         (unsigned char) ((wr) >> 8) & 0xff,
588         (unsigned char) ((wr) >> 16) & 0xff,
589         (unsigned char) ((wr) >> 24) & 0xff);
590       fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
591         (unsigned char) ((hr) >> 8) & 0xff,
592         (unsigned char) ((hr) >> 16) & 0xff,
593         (unsigned char) ((hr) >> 24) & 0xff);
594       fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
595       fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
596       fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
597         ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
598       fprintf(fdest, "%c%c%c%c",
599         (unsigned char) (3 * hr * wr +
600         3 * hr * (wr % 2)) & 0xff,
601         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >>
602         8) & 0xff,
603         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >>
604         16) & 0xff,
605         (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >>
606         24) & 0xff);
607       fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
608         ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
609       fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
610         ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
611       fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
612         ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
613       fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
614         ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
615       
616       for (i = 0; i < wr * hr; i++) {
617         unsigned char R, G, B;
618         /* a modifier */
619         // R = img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
620         R = img.comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
621         // G = img.comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
622         G = img.comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
623         // B = img.comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
624         B = img.comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
625         fprintf(fdest, "%c%c%c", B, G, R);
626         
627         if ((i + 1) % wr == 0) {
628           for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--)       /* ADD */
629             fprintf(fdest, "%c", 0);
630         }
631       }
632       fclose(fdest);
633       free(img.comps[1].data);
634       free(img.comps[2].data);
635     } else {                    /* Gray-scale */
636       
637                                 /* -->> -->> -->> -->>
638                                 
639                                  8 bits non code (Gray scale)
640                                  
641         <<-- <<-- <<-- <<-- */
642       fdest = fopen(outfile, "wb");
643       // w = int_ceildiv(img.x1 - img.x0, img.comps[0].dx);
644       // wr = int_ceildiv(int_ceildivpow2(img.x1 - img.x0,img.factor), img.comps[0].dx);
645       w = img.comps[0].w;
646       wr = int_ceildivpow2(img.comps[0].w, img.comps[0].factor);
647       
648       // h = int_ceildiv(img.y1 - img.y0, img.comps[0].dy);
649       // hr = int_ceildiv(int_ceildivpow2(img.y1 - img.y0,img.factor), img.comps[0].dy);
650       h = img.comps[0].h;
651       hr = int_ceildivpow2(img.comps[0].h, img.comps[0].factor);
652       
653       fprintf(fdest, "BM");
654       
655       /* FILE HEADER */
656       /* ------------- */
657       fprintf(fdest, "%c%c%c%c",
658         (unsigned char) (hr * wr + 54 + 1024 +
659         hr * (wr % 2)) & 0xff,
660         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2))
661         >> 8) & 0xff,
662         (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2))
663         >> 16) & 0xff,
664         (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2))
665         >> 24) & 0xff);
666       fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
667         ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
668       fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff,
669         ((54 + 1024) >> 8) & 0xff, ((54 + 1024) >> 16) & 0xff,
670         ((54 + 1024) >> 24) & 0xff);
671       
672       /* INFO HEADER */
673       /* ------------- */
674       fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,
675         ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
676       fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
677         (unsigned char) ((wr) >> 8) & 0xff,
678         (unsigned char) ((wr) >> 16) & 0xff,
679         (unsigned char) ((wr) >> 24) & 0xff);
680       fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
681         (unsigned char) ((hr) >> 8) & 0xff,
682         (unsigned char) ((hr) >> 16) & 0xff,
683         (unsigned char) ((hr) >> 24) & 0xff);
684       fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
685       fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
686       fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
687         ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
688       fprintf(fdest, "%c%c%c%c",
689         (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff,
690         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) &
691         0xff,
692         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) &
693         0xff,
694         (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff);
695       fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
696         ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
697       fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
698         ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
699       fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff,
700         ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
701       fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff,
702         ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
703     }
704     
705     for (i = 0; i < 256; i++) {
706       fprintf(fdest, "%c%c%c%c", i, i, i, 0);
707     }
708     
709     for (i = 0; i < wr * hr; i++) {
710       /* a modifier !! */
711       // fprintf(fdest, "%c", img.comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]);
712       fprintf(fdest, "%c",
713         img.comps[0].data[w * hr - ((i) / (wr) + 1) * w +
714         (i) % (wr)]);
715         /*if (((i + 1) % w == 0 && w % 2))
716       fprintf(fdest, "%c", 0); */
717       if ((i + 1) % wr == 0) {
718         for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--)     /* ADD */
719           fprintf(fdest, "%c", 0);
720       }
721     }
722     fclose(fdest);
723     free(img.comps[0].data);
724     break;
725
726   default:
727     fprintf(stderr,
728       "ERROR -> j2k_to_image : Unknown output image format\n");
729     return 1;
730     break;
731   }
732   
733   
734   // Free remaining structures
735   //--------------------------
736   j2k_dec_release();
737   
738   
739   
740   // Check memory leaks if debug mode
741   //---------------------------------
742   
743 #ifdef _DEBUG
744   
745   _CrtDumpMemoryLeaks();
746   
747 #endif
748   
749   return 0;
750 }