6997def917a0661ccfa431b14ce70f551a250f1a
[openjpeg.git] / src / bin / jp2 / convert.c
1 /*
2  * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3  * Copyright (c) 2002-2007, Professor Benoit Macq
4  * Copyright (c) 2001-2003, David Janssens
5  * Copyright (c) 2002-2003, Yannick Verschueren
6  * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7  * Copyright (c) 2005, Herve Drolon, FreeImage Team
8  * Copyright (c) 2006-2007, Parvatha Elangovan
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include "opj_apps_config.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38
39 #ifdef OPJ_HAVE_LIBTIFF
40 #include <tiffio.h>
41 #endif /* OPJ_HAVE_LIBTIFF */
42
43 #ifdef OPJ_HAVE_LIBPNG
44 #include <zlib.h>
45 #include <png.h>
46 #endif /* OPJ_HAVE_LIBPNG */
47
48 #include "openjpeg.h"
49 #include "convert.h"
50
51 /*
52  * Get logarithm of an integer and round downwards.
53  *
54  * log2(a)
55  */
56 static int int_floorlog2(int a) {
57     int l;
58     for (l = 0; a > 1; l++) {
59         a >>= 1;
60     }
61     return l;
62 }
63
64 /* -->> -->> -->> -->>
65
66   TGA IMAGE FORMAT
67
68  <<-- <<-- <<-- <<-- */
69
70 #ifdef INFORMATION_ONLY
71 /* TGA header definition. */
72 struct tga_header
73 {                           
74     unsigned char   id_length;              /* Image id field length    */
75     unsigned char   colour_map_type;        /* Colour map type          */
76     unsigned char   image_type;             /* Image type               */
77     /*
78     ** Colour map specification
79     */
80     unsigned short  colour_map_index;       /* First entry index        */
81     unsigned short  colour_map_length;      /* Colour map length        */
82     unsigned char   colour_map_entry_size;  /* Colour map entry size    */
83     /*
84     ** Image specification
85     */
86     unsigned short  x_origin;               /* x origin of image        */
87     unsigned short  y_origin;               /* u origin of image        */
88     unsigned short  image_width;            /* Image width              */
89     unsigned short  image_height;           /* Image height             */
90     unsigned char   pixel_depth;            /* Pixel depth              */
91     unsigned char   image_desc;             /* Image descriptor         */
92 };
93 #endif /* INFORMATION_ONLY */
94
95 static unsigned short get_ushort(unsigned short val) {
96
97 #ifdef WORDS_BIGENDIAN
98     return( ((val & 0xff) << 8) + (val >> 8) );
99 #else
100     return( val );
101 #endif
102
103 }
104
105 #define TGA_HEADER_SIZE 18
106
107 static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, 
108                           unsigned int *width, unsigned int *height, int *flip_image)
109 {
110     int palette_size;
111     unsigned char *tga ;
112     unsigned char id_len, cmap_type, image_type;
113     unsigned char pixel_depth, image_desc;
114     unsigned short cmap_index, cmap_len, cmap_entry_size;
115     unsigned short x_origin, y_origin, image_w, image_h;
116
117     if (!bits_per_pixel || !width || !height || !flip_image)
118         return 0;
119     tga = (unsigned char*)malloc(18);
120
121     if ( fread(tga, TGA_HEADER_SIZE, 1, fp) != 1 )
122     {
123         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
124         return 0 ;
125     }
126     id_len = (unsigned char)tga[0];
127     cmap_type = (unsigned char)tga[1];
128     image_type = (unsigned char)tga[2];
129     cmap_index = get_ushort(*(unsigned short*)(&tga[3]));
130     cmap_len = get_ushort(*(unsigned short*)(&tga[5]));
131     cmap_entry_size = (unsigned char)tga[7];
132
133
134     x_origin = get_ushort(*(unsigned short*)(&tga[8]));
135     y_origin = get_ushort(*(unsigned short*)(&tga[10]));
136     image_w = get_ushort(*(unsigned short*)(&tga[12]));
137     image_h = get_ushort(*(unsigned short*)(&tga[14]));
138     pixel_depth = (unsigned char)tga[16];
139     image_desc  = (unsigned char)tga[17];
140
141     free(tga);
142
143     *bits_per_pixel = (unsigned int)pixel_depth;
144     *width  = (unsigned int)image_w;
145     *height = (unsigned int)image_h;
146
147     /* Ignore tga identifier, if present ... */
148     if (id_len)
149     {
150         unsigned char *id = (unsigned char *) malloc(id_len);
151         if ( !fread(id, id_len, 1, fp) )
152         {
153             fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
154             free(id);
155             return 0 ;
156         }
157         free(id);
158     }
159
160     /* Test for compressed formats ... not yet supported ...
161     // Note :-  9 - RLE encoded palettized.
162     //             10 - RLE encoded RGB. */
163     if (image_type > 8)
164     {
165         fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n");
166         return 0 ;
167     }
168
169     *flip_image = !(image_desc & 32);
170
171     /* Palettized formats are not yet supported, skip over the palette, if present ... */
172     palette_size = cmap_len * (cmap_entry_size/8);
173
174     if (palette_size>0)
175     {
176         fprintf(stderr, "File contains a palette - not yet supported.");
177         fseek(fp, palette_size, SEEK_CUR);
178     }
179     return 1;
180 }
181
182 #if WORDS_BIGENDIAN == 1
183
184 static inline int16_t swap16(int16_t x)
185 {
186     return((((u_int16_t)x & 0x00ffU) <<  8) |
187            (((u_int16_t)x & 0xff00U) >>  8));
188 }
189
190 #endif
191
192 static int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height, 
193                            OPJ_BOOL flip_image)
194 {
195     unsigned short image_w, image_h, us0;
196     unsigned char uc0, image_type;
197     unsigned char pixel_depth, image_desc;
198
199     if (!bits_per_pixel || !width || !height)
200         return 0;
201
202     pixel_depth = 0;
203
204     if ( bits_per_pixel < 256 )
205         pixel_depth = (unsigned char)bits_per_pixel;
206     else{
207         fprintf(stderr,"ERROR: Wrong bits per pixel inside tga_header");
208         return 0;
209     }
210     uc0 = 0;
211
212     if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* id_length */
213     if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* colour_map_type */
214
215     image_type = 2; /* Uncompressed. */
216     if(fwrite(&image_type, 1, 1, fp) != 1) goto fails;
217
218     us0 = 0;
219     if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* colour_map_index */
220     if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* colour_map_length */
221     if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* colour_map_entry_size */
222
223     if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* x_origin */
224     if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* y_origin */
225
226     image_w = (unsigned short)width;
227     image_h = (unsigned short) height;
228
229 #if WORDS_BIGENDIAN == 0
230     if(fwrite(&image_w, 2, 1, fp) != 1) goto fails;
231     if(fwrite(&image_h, 2, 1, fp) != 1) goto fails;
232 #else
233     image_w = swap16(image_w);
234     image_h = swap16(image_h);
235     if(fwrite(&image_w, 2, 1, fp) != 1) goto fails;
236     if(fwrite(&image_h, 2, 1, fp) != 1) goto fails;
237 #endif
238
239     if(fwrite(&pixel_depth, 1, 1, fp) != 1) goto fails;
240
241     image_desc = 8; /* 8 bits per component. */
242
243     if (flip_image)
244         image_desc |= 32;
245     if(fwrite(&image_desc, 1, 1, fp) != 1) goto fails;
246
247     return 1;
248
249 fails:
250     fputs("\nwrite_tgaheader: write ERROR\n", stderr);
251     return 0;
252 }
253
254 opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) {
255     FILE *f;
256     opj_image_t *image;
257     unsigned int image_width, image_height, pixel_bit_depth;
258     unsigned int x, y;
259     int flip_image=0;
260     opj_image_cmptparm_t cmptparm[4];   /* maximum 4 components */
261     int numcomps;
262     OPJ_COLOR_SPACE color_space;
263     OPJ_BOOL mono ;
264     OPJ_BOOL save_alpha;
265     int subsampling_dx, subsampling_dy;
266     int i;
267
268     f = fopen(filename, "rb");
269     if (!f) {
270         fprintf(stderr, "Failed to open %s for reading !!\n", filename);
271         return 0;
272     }
273
274     if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image))
275         return NULL;
276
277     /* We currently only support 24 & 32 bit tga's ... */
278     if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32)))
279         return NULL;
280
281     /* initialize image components */
282     memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
283
284     mono = (pixel_bit_depth == 8) || (pixel_bit_depth == 16);  /* Mono with & without alpha. */
285     save_alpha = (pixel_bit_depth == 16) || (pixel_bit_depth == 32); /* Mono with alpha, or RGB with alpha */
286
287     if (mono) {
288         color_space = OPJ_CLRSPC_GRAY;
289         numcomps = save_alpha ? 2 : 1;
290     }
291     else {
292         numcomps = save_alpha ? 4 : 3;
293         color_space = OPJ_CLRSPC_SRGB;
294     }
295
296     subsampling_dx = parameters->subsampling_dx;
297     subsampling_dy = parameters->subsampling_dy;
298
299     for (i = 0; i < numcomps; i++) {
300         cmptparm[i].prec = 8;
301         cmptparm[i].bpp = 8;
302         cmptparm[i].sgnd = 0;
303         cmptparm[i].dx = subsampling_dx;
304         cmptparm[i].dy = subsampling_dy;
305         cmptparm[i].w = image_width;
306         cmptparm[i].h = image_height;
307     }
308
309     /* create the image */
310     image = opj_image_create(numcomps, &cmptparm[0], color_space);
311
312     if (!image)
313         return NULL;
314
315     /* set image offset and reference grid */
316     image->x0 = parameters->image_offset_x0;
317     image->y0 = parameters->image_offset_y0;
318     image->x1 = !image->x0 ? (image_width - 1) * subsampling_dx + 1 : image->x0 + (image_width - 1) * subsampling_dx + 1;
319     image->y1 = !image->y0 ? (image_height - 1) * subsampling_dy + 1 : image->y0 + (image_height - 1) * subsampling_dy + 1;
320
321     /* set image data */
322     for (y=0; y < image_height; y++)
323     {
324         int index;
325
326         if (flip_image)
327             index = (image_height-y-1)*image_width;
328         else
329             index = y*image_width;
330
331         if (numcomps==3)
332         {
333             for (x=0;x<image_width;x++)
334             {
335                 unsigned char r,g,b;
336
337                 if( !fread(&b, 1, 1, f) )
338                 {
339                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
340                     opj_image_destroy(image);
341                     return NULL;
342                 }
343                 if ( !fread(&g, 1, 1, f) )
344                 {
345                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
346                     opj_image_destroy(image);
347                     return NULL;
348                 }
349                 if ( !fread(&r, 1, 1, f) )
350                 {
351                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
352                     opj_image_destroy(image);
353                     return NULL;
354                 }
355
356                 image->comps[0].data[index]=r;
357                 image->comps[1].data[index]=g;
358                 image->comps[2].data[index]=b;
359                 index++;
360             }
361         }
362         else if (numcomps==4)
363         {
364             for (x=0;x<image_width;x++)
365             {
366                 unsigned char r,g,b,a;
367                 if ( !fread(&b, 1, 1, f) )
368                 {
369                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
370                     opj_image_destroy(image);
371                     return NULL;
372                 }
373                 if ( !fread(&g, 1, 1, f) )
374                 {
375                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
376                     opj_image_destroy(image);
377                     return NULL;
378                 }
379                 if ( !fread(&r, 1, 1, f) )
380                 {
381                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
382                     opj_image_destroy(image);
383                     return NULL;
384                 }
385                 if ( !fread(&a, 1, 1, f) )
386                 {
387                     fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
388                     opj_image_destroy(image);
389                     return NULL;
390                 }
391
392                 image->comps[0].data[index]=r;
393                 image->comps[1].data[index]=g;
394                 image->comps[2].data[index]=b;
395                 image->comps[3].data[index]=a;
396                 index++;
397             }
398         }
399         else {
400             fprintf(stderr, "Currently unsupported bit depth : %s\n", filename);
401         }
402     }
403     return image;
404 }
405
406 int imagetotga(opj_image_t * image, const char *outfile) {
407     int width, height, bpp, x, y;
408     OPJ_BOOL write_alpha;
409     int i, adjustR, adjustG, adjustB;
410     unsigned int alpha_channel;
411     float r,g,b,a;
412     unsigned char value;
413     float scale;
414     FILE *fdest;
415     size_t res;
416
417     fdest = fopen(outfile, "wb");
418     if (!fdest) {
419         fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
420         return 1;
421     }
422
423     for (i = 0; i < image->numcomps-1; i++)     {
424         if ((image->comps[0].dx != image->comps[i+1].dx)
425                 ||(image->comps[0].dy != image->comps[i+1].dy)
426                 ||(image->comps[0].prec != image->comps[i+1].prec))     {
427             fprintf(stderr, "Unable to create a tga file with such J2K image charateristics.");
428             return 1;
429         }
430     }
431
432     width = image->comps[0].w;
433     height = image->comps[0].h;
434
435     /* Mono with alpha, or RGB with alpha. */
436     write_alpha = (image->numcomps==2) || (image->numcomps==4);
437
438     /* Write TGA header  */
439     bpp = write_alpha ? 32 : 24;
440     if (!tga_writeheader(fdest, bpp, width , height, OPJ_TRUE))
441         return 1;
442
443     alpha_channel = image->numcomps-1;
444
445     scale = 255.0f / (float)((1<<image->comps[0].prec)-1);
446
447     adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
448     adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
449     adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
450
451     for (y=0; y < height; y++) {
452         unsigned int index=y*width;
453
454         for (x=0; x < width; x++, index++)      {
455             r = (float)(image->comps[0].data[index] + adjustR);
456
457             if (image->numcomps>2) {
458                 g = (float)(image->comps[1].data[index] + adjustG);
459                 b = (float)(image->comps[2].data[index] + adjustB);
460             }
461             else  {/* Greyscale ... */
462                 g = r;
463                 b = r;
464             }
465
466             /* TGA format writes BGR ... */
467             value = (unsigned char)(b*scale);
468             res = fwrite(&value,1,1,fdest);
469             if( res < 1 ) {
470                 fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
471                 return 1;
472             }
473
474             value = (unsigned char)(g*scale);
475             res = fwrite(&value,1,1,fdest);
476             if( res < 1 ) {
477                 fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
478                 return 1;
479             }
480
481             value = (unsigned char)(r*scale);
482             res = fwrite(&value,1,1,fdest);
483             if( res < 1 ) {
484                 fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
485                 return 1;
486             }
487
488             if (write_alpha) {
489                 a = (float)(image->comps[alpha_channel].data[index]);
490                 value = (unsigned char)(a*scale);
491                 res = fwrite(&value,1,1,fdest);
492                 if( res < 1 ) {
493                     fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
494                     return 1;
495                 }
496             }
497         }
498     }
499
500     return 0;
501 }
502
503 /* -->> -->> -->> -->>
504
505   BMP IMAGE FORMAT
506
507  <<-- <<-- <<-- <<-- */
508
509 /* WORD defines a two byte word */
510 typedef unsigned short int WORD;
511
512 /* DWORD defines a four byte word */
513 typedef unsigned int DWORD;
514
515 typedef struct {
516     WORD bfType;                        /* 'BM' for Bitmap (19776) */
517     DWORD bfSize;                       /* Size of the file        */
518     WORD bfReserved1;           /* Reserved : 0            */
519     WORD bfReserved2;           /* Reserved : 0            */
520     DWORD bfOffBits;            /* Offset                  */
521 } BITMAPFILEHEADER_t;
522
523 typedef struct {
524     DWORD biSize;                       /* Size of the structure in bytes */
525     DWORD biWidth;              /* Width of the image in pixels */
526     DWORD biHeight;             /* Heigth of the image in pixels */
527     WORD biPlanes;              /* 1 */
528     WORD biBitCount;            /* Number of color bits by pixels */
529     DWORD biCompression;                /* Type of encoding 0: none 1: RLE8 2: RLE4 */
530     DWORD biSizeImage;          /* Size of the image in bytes */
531     DWORD biXpelsPerMeter;      /* Horizontal (X) resolution in pixels/meter */
532     DWORD biYpelsPerMeter;      /* Vertical (Y) resolution in pixels/meter */
533     DWORD biClrUsed;            /* Number of color used in the image (0: ALL) */
534     DWORD biClrImportant;               /* Number of important color (0: ALL) */
535 } BITMAPINFOHEADER_t;
536
537 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) 
538 {
539     int subsampling_dx = parameters->subsampling_dx;
540     int subsampling_dy = parameters->subsampling_dy;
541
542     int i, numcomps, w, h;
543     OPJ_COLOR_SPACE color_space;
544     opj_image_cmptparm_t cmptparm[3];   /* maximum of 3 components */
545     opj_image_t * image = NULL;
546
547     FILE *IN;
548     BITMAPFILEHEADER_t File_h;
549     BITMAPINFOHEADER_t Info_h;
550     unsigned char *RGB;
551     unsigned char *table_R, *table_G, *table_B;
552     unsigned int j, PAD = 0;
553
554     int x, y, index;
555     int gray_scale = 1;
556     int has_color;
557     DWORD W, H;
558
559     IN = fopen(filename, "rb");
560     if (!IN)
561     {
562         fprintf(stderr, "Failed to open %s for reading !!\n", filename);
563         return NULL;
564     }
565
566     File_h.bfType = getc(IN);
567     File_h.bfType = (getc(IN) << 8) + File_h.bfType;
568
569     if (File_h.bfType != 19778)
570     {
571         fprintf(stderr,"Error, not a BMP file!\n");
572         fclose(IN);
573         return NULL;
574     }
575     /* FILE HEADER */
576     /* ------------- */
577     File_h.bfSize = getc(IN);
578     File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;
579     File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;
580     File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;
581
582     File_h.bfReserved1 = getc(IN);
583     File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;
584
585     File_h.bfReserved2 = getc(IN);
586     File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;
587
588     File_h.bfOffBits = getc(IN);
589     File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;
590     File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;
591     File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;
592
593     /* INFO HEADER */
594     /* ------------- */
595
596     Info_h.biSize = getc(IN);
597     Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;
598     Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
599     Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
600
601     if(Info_h.biSize != 40)
602     {
603         fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize);
604         fclose(IN);
605         return NULL;
606     }
607     Info_h.biWidth = getc(IN);
608     Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
609     Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
610     Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;
611     w = Info_h.biWidth;
612
613     Info_h.biHeight = getc(IN);
614     Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;
615     Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;
616     Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;
617     h = Info_h.biHeight;
618
619     Info_h.biPlanes = getc(IN);
620     Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;
621
622     Info_h.biBitCount = getc(IN);
623     Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;
624
625     Info_h.biCompression = getc(IN);
626     Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;
627     Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;
628     Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;
629
630     Info_h.biSizeImage = getc(IN);
631     Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;
632     Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;
633     Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;
634
635     Info_h.biXpelsPerMeter = getc(IN);
636     Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;
637     Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;
638     Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;
639
640     Info_h.biYpelsPerMeter = getc(IN);
641     Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;
642     Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;
643     Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;
644
645     Info_h.biClrUsed = getc(IN);
646     Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;
647     Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;
648     Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;
649
650     Info_h.biClrImportant = getc(IN);
651     Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;
652     Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;
653     Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;
654
655     /* Read the data and store them in the OUT file */
656
657     if (Info_h.biBitCount == 24)
658     {
659         numcomps = 3;
660         color_space = OPJ_CLRSPC_SRGB;
661         /* initialize image components */
662         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
663         for(i = 0; i < numcomps; i++)
664         {
665             cmptparm[i].prec = 8;
666             cmptparm[i].bpp = 8;
667             cmptparm[i].sgnd = 0;
668             cmptparm[i].dx = subsampling_dx;
669             cmptparm[i].dy = subsampling_dy;
670             cmptparm[i].w = w;
671             cmptparm[i].h = h;
672         }
673         /* create the image */
674         image = opj_image_create(numcomps, &cmptparm[0], color_space);
675         if(!image)
676         {
677             fclose(IN);
678             return NULL;
679         }
680
681         /* set image offset and reference grid */
682         image->x0 = parameters->image_offset_x0;
683         image->y0 = parameters->image_offset_y0;
684         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
685         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
686
687         /* set image data */
688
689         /* Place the cursor at the beginning of the image information */
690         fseek(IN, 0, SEEK_SET);
691         fseek(IN, File_h.bfOffBits, SEEK_SET);
692
693         W = Info_h.biWidth;
694         H = Info_h.biHeight;
695
696         /* PAD = 4 - (3 * W) % 4; */
697         /* PAD = (PAD == 4) ? 0 : PAD; */
698         PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
699
700         RGB = (unsigned char *)
701                 malloc((3 * W + PAD) * H * sizeof(unsigned char));
702
703         if ( fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN) != (3 * W + PAD) * H )
704         {
705             free(RGB);
706             opj_image_destroy(image);
707             fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
708             return NULL;
709         }
710
711         index = 0;
712
713         for(y = 0; y < (int)H; y++)
714         {
715             unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
716             for(x = 0; x < (int)W; x++)
717             {
718                 unsigned char *pixel = &scanline[3 * x];
719                 image->comps[0].data[index] = pixel[2]; /* R */
720                 image->comps[1].data[index] = pixel[1]; /* G */
721                 image->comps[2].data[index] = pixel[0]; /* B */
722                 index++;
723             }
724         }
725         free(RGB);
726     }/* if (Info_h.biBitCount == 24) */
727     else
728         if (Info_h.biBitCount == 8 && Info_h.biCompression == 0)/*RGB */
729         {
730             if(Info_h.biClrUsed == 0) Info_h.biClrUsed = 256;
731             else
732                 if(Info_h.biClrUsed > 256) Info_h.biClrUsed = 256;
733
734             table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
735             table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
736             table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
737
738             has_color = 0;
739             for (j = 0; j < Info_h.biClrUsed; j++)
740             {
741                 table_B[j] = (unsigned char)getc(IN);
742                 table_G[j] = (unsigned char)getc(IN);
743                 table_R[j] = (unsigned char)getc(IN);
744                 getc(IN);
745                 has_color +=
746                         !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
747             }
748             if(has_color) gray_scale = 0;
749
750             /* Place the cursor at the beginning of the image information */
751             fseek(IN, 0, SEEK_SET);
752             fseek(IN, File_h.bfOffBits, SEEK_SET);
753
754             W = Info_h.biWidth;
755             H = Info_h.biHeight;
756             if (Info_h.biWidth % 2)
757                 W++;
758
759             numcomps = gray_scale ? 1 : 3;
760             color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
761             /* initialize image components */
762             memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
763             for(i = 0; i < numcomps; i++)
764             {
765                 cmptparm[i].prec = 8;
766                 cmptparm[i].bpp = 8;
767                 cmptparm[i].sgnd = 0;
768                 cmptparm[i].dx = subsampling_dx;
769                 cmptparm[i].dy = subsampling_dy;
770                 cmptparm[i].w = w;
771                 cmptparm[i].h = h;
772             }
773             /* create the image */
774             image = opj_image_create(numcomps, &cmptparm[0], color_space);
775             if(!image)
776             {
777                 fclose(IN);
778                 free(table_R); free(table_G); free(table_B);
779                 return NULL;
780             }
781
782             /* set image offset and reference grid */
783             image->x0 = parameters->image_offset_x0;
784             image->y0 = parameters->image_offset_y0;
785             image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
786             image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
787
788             /* set image data */
789
790             RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
791
792             if ( fread(RGB, sizeof(unsigned char), W * H, IN) != W * H )
793             {
794                 free(table_R);
795                 free(table_G);
796                 free(table_B);
797                 free(RGB);
798                 opj_image_destroy(image);
799                 fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
800                 return NULL;
801             }
802             if (gray_scale)
803             {
804                 index = 0;
805                 for (j = 0; j < W * H; j++)
806                 {
807                     if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2))
808                     {
809                         image->comps[0].data[index] =
810                                 table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];
811                         index++;
812                     }
813                 }
814
815             }
816             else
817             {
818                 index = 0;
819                 for (j = 0; j < W * H; j++)
820                 {
821                     if ((j % W < W - 1 && Info_h.biWidth % 2)
822                             || !(Info_h.biWidth % 2))
823                     {
824                         unsigned char pixel_index =
825                                 RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];
826                         image->comps[0].data[index] = table_R[pixel_index];
827                         image->comps[1].data[index] = table_G[pixel_index];
828                         image->comps[2].data[index] = table_B[pixel_index];
829                         index++;
830                     }
831                 }
832             }
833             free(RGB);
834             free(table_R);
835             free(table_G);
836             free(table_B);
837         }/* RGB8 */
838         else
839             if (Info_h.biBitCount == 8 && Info_h.biCompression == 1)/*RLE8*/
840             {
841                 unsigned char *pix, *beyond;
842                 int *gray, *red, *green, *blue;
843                 unsigned int x, y, max;
844                 int i, c, c1;
845                 unsigned char uc;
846
847                 if (Info_h.biClrUsed == 0)
848                     Info_h.biClrUsed = 256;
849                 else if (Info_h.biClrUsed > 256)
850                     Info_h.biClrUsed = 256;
851
852                 table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
853                 table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
854                 table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
855
856                 has_color = 0;
857                 for (j = 0; j < Info_h.biClrUsed; j++)
858                 {
859                     table_B[j] = (unsigned char)getc(IN);
860                     table_G[j] = (unsigned char)getc(IN);
861                     table_R[j] = (unsigned char)getc(IN);
862                     getc(IN);
863                     has_color += !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
864                 }
865
866                 if (has_color)
867                     gray_scale = 0;
868
869                 numcomps = gray_scale ? 1 : 3;
870                 color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB;
871                 /* initialize image components */
872                 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
873                 for (i = 0; i < numcomps; i++)
874                 {
875                     cmptparm[i].prec = 8;
876                     cmptparm[i].bpp = 8;
877                     cmptparm[i].sgnd = 0;
878                     cmptparm[i].dx = subsampling_dx;
879                     cmptparm[i].dy = subsampling_dy;
880                     cmptparm[i].w = w;
881                     cmptparm[i].h = h;
882                 }
883                 /* create the image */
884                 image = opj_image_create(numcomps, &cmptparm[0], color_space);
885                 if (!image)
886                 {
887                     fclose(IN);
888                     free(table_R);
889                     free(table_G);
890                     free(table_B);
891                     return NULL;
892                 }
893
894                 /* set image offset and reference grid */
895                 image->x0 = parameters->image_offset_x0;
896                 image->y0 = parameters->image_offset_y0;
897                 image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w
898                                                                                      - 1) * subsampling_dx + 1;
899                 image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h
900                                                                                      - 1) * subsampling_dy + 1;
901
902                 /* set image data */
903
904                 /* Place the cursor at the beginning of the image information */
905                 fseek(IN, 0, SEEK_SET);
906                 fseek(IN, File_h.bfOffBits, SEEK_SET);
907
908                 W = Info_h.biWidth;
909                 H = Info_h.biHeight;
910                 RGB = (unsigned char *) calloc(1, W * H * sizeof(unsigned char));
911                 beyond = RGB + W * H;
912                 pix = beyond - W;
913                 x = y = 0;
914
915                 while (y < H)
916                 {
917                     c = getc(IN);
918
919                     if (c)
920                     {
921                         c1 = getc(IN);
922
923                         for (i = 0; i < c && x < W && pix < beyond; i++, x++, pix++)
924                             *pix = (unsigned char)c1;
925                     }
926                     else
927                     {
928                         c = getc(IN);
929
930                         if (c == 0x00) /* EOL */
931                         {
932                             x = 0;
933                             ++y;
934                             pix = RGB + x + (H - y - 1) * W;
935                         }
936                         else if (c == 0x01) /* EOP */
937                             break;
938                         else if (c == 0x02) /* MOVE by dxdy */
939                         {
940                             c = getc(IN);
941                             x += c;
942                             c = getc(IN);
943                             y += c;
944                             pix = RGB + (H - y - 1) * W + x;
945                         }
946                         else /* 03 .. 255 */
947                         {
948                             i = 0;
949                             for (; i < c && x < W && pix < beyond; i++, x++, pix++)
950                             {
951                                 c1 = getc(IN);
952                                 *pix = (unsigned char)c1;
953                             }
954                             if (c & 1) /* skip padding byte */
955                                 getc(IN);
956                         }
957                     }
958                 }/* while() */
959
960                 if (gray_scale)
961                 {
962                     gray = image->comps[0].data;
963                     pix = RGB;
964                     max = W * H;
965
966                     while (max--)
967                     {
968                         uc = *pix++;
969
970                         *gray++ = table_R[uc];
971                     }
972                 }
973                 else
974                 {
975                     /*int *red, *green, *blue;*/
976
977                     red = image->comps[0].data;
978                     green = image->comps[1].data;
979                     blue = image->comps[2].data;
980                     pix = RGB;
981                     max = W * H;
982
983                     while (max--)
984                     {
985                         uc = *pix++;
986
987                         *red++ = table_R[uc];
988                         *green++ = table_G[uc];
989                         *blue++ = table_B[uc];
990                     }
991                 }
992                 free(RGB);
993                 free(table_R);
994                 free(table_G);
995                 free(table_B);
996             }/* RLE8 */
997             else
998             {
999                 fprintf(stderr,
1000                         "Other system than 24 bits/pixels or 8 bits (no RLE coding) "
1001                         "is not yet implemented [%d]\n", Info_h.biBitCount);
1002             }
1003     fclose(IN);
1004     return image;
1005 }
1006
1007 int imagetobmp(opj_image_t * image, const char *outfile) {
1008     int w, h;
1009     int i, pad;
1010     FILE *fdest = NULL;
1011     int adjustR, adjustG, adjustB;
1012
1013     if (image->comps[0].prec < 8) {
1014         fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec);
1015         return 1;
1016     }
1017     if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx
1018             && image->comps[1].dx == image->comps[2].dx
1019             && image->comps[0].dy == image->comps[1].dy
1020             && image->comps[1].dy == image->comps[2].dy
1021             && image->comps[0].prec == image->comps[1].prec
1022             && image->comps[1].prec == image->comps[2].prec) {
1023
1024         /* -->> -->> -->> -->>
1025         24 bits color
1026         <<-- <<-- <<-- <<-- */
1027
1028         fdest = fopen(outfile, "wb");
1029         if (!fdest) {
1030             fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1031             return 1;
1032         }
1033
1034         w = image->comps[0].w;
1035         h = image->comps[0].h;
1036
1037         fprintf(fdest, "BM");
1038
1039         /* FILE HEADER */
1040         /* ------------- */
1041         fprintf(fdest, "%c%c%c%c",
1042                 (unsigned char) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
1043                 (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54)     >> 8) & 0xff,
1044                 (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54)     >> 16) & 0xff,
1045                 (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54)     >> 24) & 0xff);
1046         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
1047         fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
1048
1049         /* INFO HEADER   */
1050         /* ------------- */
1051         fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
1052         fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff),
1053                 (unsigned char) ((w) >> 8) & 0xff,
1054                 (unsigned char) ((w) >> 16) & 0xff,
1055                 (unsigned char) ((w) >> 24) & 0xff);
1056         fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff),
1057                 (unsigned char) ((h) >> 8) & 0xff,
1058                 (unsigned char) ((h) >> 16) & 0xff,
1059                 (unsigned char) ((h) >> 24) & 0xff);
1060         fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
1061         fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
1062         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
1063         fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * h * w + 3 * h * (w % 2)) & 0xff,
1064                 (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
1065                 (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
1066                 (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
1067         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
1068         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
1069         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
1070         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
1071
1072         if (image->comps[0].prec > 8) {
1073             adjustR = image->comps[0].prec - 8;
1074             printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
1075         }
1076         else
1077             adjustR = 0;
1078         if (image->comps[1].prec > 8) {
1079             adjustG = image->comps[1].prec - 8;
1080             printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
1081         }
1082         else
1083             adjustG = 0;
1084         if (image->comps[2].prec > 8) {
1085             adjustB = image->comps[2].prec - 8;
1086             printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
1087         }
1088         else
1089             adjustB = 0;
1090
1091         for (i = 0; i < w * h; i++) {
1092             unsigned char rc, gc, bc;
1093             int r, g, b;
1094
1095             r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
1096             r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1097             r = ((r >> adjustR)+((r >> (adjustR-1))%2));
1098             if(r > 255) r = 255; else if(r < 0) r = 0;
1099             rc = (unsigned char)r;
1100
1101             g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
1102             g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1103             g = ((g >> adjustG)+((g >> (adjustG-1))%2));
1104             if(g > 255) g = 255; else if(g < 0) g = 0;
1105             gc = (unsigned char)g;
1106
1107             b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
1108             b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1109             b = ((b >> adjustB)+((b >> (adjustB-1))%2));
1110             if(b > 255) b = 255; else if(b < 0) b = 0;
1111             bc = (unsigned char)b;
1112
1113             fprintf(fdest, "%c%c%c", bc, gc, rc);
1114
1115             if ((i + 1) % w == 0) {
1116                 for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--)   /* ADD */
1117                     fprintf(fdest, "%c", 0);
1118             }
1119         }
1120         fclose(fdest);
1121     } else {                    /* Gray-scale */
1122
1123         /* -->> -->> -->> -->>
1124         8 bits non code (Gray scale)
1125         <<-- <<-- <<-- <<-- */
1126
1127         fdest = fopen(outfile, "wb");
1128         w = image->comps[0].w;
1129         h = image->comps[0].h;
1130
1131         fprintf(fdest, "BM");
1132
1133         /* FILE HEADER */
1134         /* ------------- */
1135         fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
1136                 (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
1137                 (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
1138                 (unsigned char) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
1139         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
1140         fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff,
1141                 ((54 + 1024) >> 16) & 0xff,
1142                 ((54 + 1024) >> 24) & 0xff);
1143
1144         /* INFO HEADER */
1145         /* ------------- */
1146         fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,     ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
1147         fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff),
1148                 (unsigned char) ((w) >> 8) & 0xff,
1149                 (unsigned char) ((w) >> 16) & 0xff,
1150                 (unsigned char) ((w) >> 24) & 0xff);
1151         fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff),
1152                 (unsigned char) ((h) >> 8) & 0xff,
1153                 (unsigned char) ((h) >> 16) & 0xff,
1154                 (unsigned char) ((h) >> 24) & 0xff);
1155         fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
1156         fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
1157         fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
1158         fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + h * (w % 2)) & 0xff,
1159                 (unsigned char) ((h * w + h * (w % 2)) >> 8) &  0xff,
1160                 (unsigned char) ((h * w + h * (w % 2)) >> 16) & 0xff,
1161                 (unsigned char) ((h * w + h * (w % 2)) >> 24) & 0xff);
1162         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
1163         fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
1164         fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
1165         fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
1166
1167         if (image->comps[0].prec > 8) {
1168             adjustR = image->comps[0].prec - 8;
1169             printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
1170         }else
1171             adjustR = 0;
1172
1173         for (i = 0; i < 256; i++) {
1174             fprintf(fdest, "%c%c%c%c", i, i, i, 0);
1175         }
1176
1177         for (i = 0; i < w * h; i++) {
1178             int r;
1179
1180             r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
1181             r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1182             r = ((r >> adjustR)+((r >> (adjustR-1))%2));
1183             if(r > 255) r = 255; else if(r < 0) r = 0;
1184
1185             fprintf(fdest, "%c", (unsigned char)r);
1186
1187             if ((i + 1) % w == 0) {
1188                 for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--)       /* ADD */
1189                     fprintf(fdest, "%c", 0);
1190             }
1191         }
1192         fclose(fdest);
1193     }
1194
1195     return 0;
1196 }
1197
1198 /* -->> -->> -->> -->>
1199
1200 PGX IMAGE FORMAT
1201
1202 <<-- <<-- <<-- <<-- */
1203
1204
1205 static unsigned char readuchar(FILE * f)
1206 {
1207     unsigned char c1;
1208     if ( !fread(&c1, 1, 1, f) )
1209     {
1210         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1211         return 0;
1212     }
1213     return c1;
1214 }
1215
1216 static unsigned short readushort(FILE * f, int bigendian)
1217 {
1218     unsigned char c1, c2;
1219     if ( !fread(&c1, 1, 1, f) )
1220     {
1221         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1222         return 0;
1223     }
1224     if ( !fread(&c2, 1, 1, f) )
1225     {
1226         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1227         return 0;
1228     }
1229     if (bigendian)
1230         return (c1 << 8) + c2;
1231     else
1232         return (c2 << 8) + c1;
1233 }
1234
1235 static unsigned int readuint(FILE * f, int bigendian)
1236 {
1237     unsigned char c1, c2, c3, c4;
1238     if ( !fread(&c1, 1, 1, f) )
1239     {
1240         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1241         return 0;
1242     }
1243     if ( !fread(&c2, 1, 1, f) )
1244     {
1245         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1246         return 0;
1247     }
1248     if ( !fread(&c3, 1, 1, f) )
1249     {
1250         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1251         return 0;
1252     }
1253     if ( !fread(&c4, 1, 1, f) )
1254     {
1255         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1256         return 0;
1257     }
1258     if (bigendian)
1259         return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
1260     else
1261         return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
1262 }
1263
1264 opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
1265     FILE *f = NULL;
1266     int w, h, prec;
1267     int i, numcomps, max;
1268     OPJ_COLOR_SPACE color_space;
1269     opj_image_cmptparm_t cmptparm;      /* maximum of 1 component  */
1270     opj_image_t * image = NULL;
1271     int adjustS, ushift, dshift, force8;
1272
1273     char endian1,endian2,sign;
1274     char signtmp[32];
1275
1276     char temp[32];
1277     int bigendian;
1278     opj_image_comp_t *comp = NULL;
1279
1280     numcomps = 1;
1281     color_space = OPJ_CLRSPC_GRAY;
1282
1283     memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));
1284
1285     max = 0;
1286
1287     f = fopen(filename, "rb");
1288     if (!f) {
1289         fprintf(stderr, "Failed to open %s for reading !\n", filename);
1290         return NULL;
1291     }
1292
1293     fseek(f, 0, SEEK_SET);
1294     if( fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h) != 9){
1295         fprintf(stderr, "ERROR: Failed to read the right number of element from the fscanf() function!\n");
1296         return NULL;
1297     }
1298
1299     i=0;
1300     sign='+';
1301     while (signtmp[i]!='\0') {
1302         if (signtmp[i]=='-') sign='-';
1303         i++;
1304     }
1305
1306     fgetc(f);
1307     if (endian1=='M' && endian2=='L') {
1308         bigendian = 1;
1309     } else if (endian2=='M' && endian1=='L') {
1310         bigendian = 0;
1311     } else {
1312         fprintf(stderr, "Bad pgx header, please check input file\n");
1313         return NULL;
1314     }
1315
1316     /* initialize image component */
1317
1318     cmptparm.x0 = parameters->image_offset_x0;
1319     cmptparm.y0 = parameters->image_offset_y0;
1320     cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
1321     cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
1322
1323     if (sign == '-') {
1324         cmptparm.sgnd = 1;
1325     } else {
1326         cmptparm.sgnd = 0;
1327     }
1328     if(prec < 8)
1329     {
1330         force8 = 1;
1331         ushift = 8 - prec; dshift = prec - ushift;
1332         if(cmptparm.sgnd) adjustS = (1<<(prec - 1)); else adjustS = 0;
1333         cmptparm.sgnd = 0;
1334         prec = 8;
1335     }
1336     else ushift = dshift = force8 = adjustS = 0;
1337
1338     cmptparm.prec = prec;
1339     cmptparm.bpp = prec;
1340     cmptparm.dx = parameters->subsampling_dx;
1341     cmptparm.dy = parameters->subsampling_dy;
1342
1343     /* create the image */
1344     image = opj_image_create(numcomps, &cmptparm, color_space);
1345     if(!image) {
1346         fclose(f);
1347         return NULL;
1348     }
1349     /* set image offset and reference grid */
1350     image->x0 = cmptparm.x0;
1351     image->y0 = cmptparm.x0;
1352     image->x1 = cmptparm.w;
1353     image->y1 = cmptparm.h;
1354
1355     /* set image data */
1356
1357     comp = &image->comps[0];
1358
1359     for (i = 0; i < w * h; i++) {
1360         int v;
1361         if(force8)
1362         {
1363             v = readuchar(f) + adjustS;
1364             v = (v<<ushift) + (v>>dshift);
1365             comp->data[i] = (unsigned char)v;
1366
1367             if(v > max) max = v;
1368
1369             continue;
1370         }
1371         if (comp->prec == 8) {
1372             if (!comp->sgnd) {
1373                 v = readuchar(f);
1374             } else {
1375                 v = (char) readuchar(f);
1376             }
1377         } else if (comp->prec <= 16) {
1378             if (!comp->sgnd) {
1379                 v = readushort(f, bigendian);
1380             } else {
1381                 v = (short) readushort(f, bigendian);
1382             }
1383         } else {
1384             if (!comp->sgnd) {
1385                 v = readuint(f, bigendian);
1386             } else {
1387                 v = (int) readuint(f, bigendian);
1388             }
1389         }
1390         if (v > max)
1391             max = v;
1392         comp->data[i] = v;
1393     }
1394     fclose(f);
1395     comp->bpp = int_floorlog2(max) + 1;
1396
1397     return image;
1398 }
1399
1400 int imagetopgx(opj_image_t * image, const char *outfile) {
1401     int w, h;
1402     int i, j, compno;
1403     FILE *fdest = NULL;
1404
1405     for (compno = 0; compno < image->numcomps; compno++) {
1406         opj_image_comp_t *comp = &image->comps[compno];
1407         char bname[256]; /* buffer for name */
1408         char *name = bname; /* pointer */
1409         int nbytes = 0;
1410         size_t res;
1411         const size_t olen = strlen(outfile);
1412         const size_t dotpos = olen - 4;
1413         const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
1414         if( outfile[dotpos] != '.' ) {
1415             /* `pgx` was recognized but there is no dot at expected position */
1416             fprintf(stderr, "ERROR -> Impossible happen." );
1417             return 1;
1418         }
1419         if( total > 256 ) {
1420             name = (char*)malloc(total+1);
1421         }
1422         strncpy(name, outfile, dotpos);
1423         /*if (image->numcomps > 1) {*/
1424         sprintf(name+dotpos, "_%d.pgx", compno);
1425         /*} else {
1426             strcpy(name+dotpos, ".pgx");
1427         }*/
1428         fdest = fopen(name, "wb");
1429         if (!fdest) {
1430             fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1431             return 1;
1432         }
1433         /* dont need name anymore */
1434         if( total > 256 ) {
1435             free(name);
1436         }
1437
1438         w = image->comps[compno].w;
1439         h = image->comps[compno].h;
1440
1441         fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, w, h);
1442         if (comp->prec <= 8) {
1443             nbytes = 1;
1444         } else if (comp->prec <= 16) {
1445             nbytes = 2;
1446         } else {
1447             nbytes = 4;
1448         }
1449         for (i = 0; i < w * h; i++) {
1450             int v = image->comps[compno].data[i];
1451             for (j = nbytes - 1; j >= 0; j--) {
1452                 char byte = (char) (v >> (j * 8));
1453                 res = fwrite(&byte, 1, 1, fdest);
1454                 if( res < 1 ) {
1455                     fprintf(stderr, "failed to write 1 byte for %s\n", name);
1456                     return 1;
1457                 }
1458             }
1459         }
1460         fclose(fdest);
1461     }
1462
1463     return 0;
1464 }
1465
1466 /* -->> -->> -->> -->>
1467
1468 PNM IMAGE FORMAT
1469
1470 <<-- <<-- <<-- <<-- */
1471
1472 struct pnm_header
1473 {
1474     int width, height, maxval, depth, format;
1475     char rgb, rgba, gray, graya, bw;
1476     char ok;
1477 };
1478
1479 static char *skip_white(char *s)
1480 {
1481     while(*s)
1482     {
1483         if(*s == '\n' || *s == '\r') return NULL;
1484         if(isspace(*s)) { ++s; continue; }
1485         return s;
1486     }
1487     return NULL;
1488 }
1489
1490 static char *skip_int(char *start, int *out_n)
1491 {
1492     char *s;
1493     char c;
1494
1495     *out_n = 0; s = start;
1496
1497     s = skip_white(start);
1498     if(s == NULL) return NULL;
1499     start = s;
1500
1501     while(*s)
1502     {
1503         if( !isdigit(*s)) break;
1504         ++s;
1505     }
1506     c = *s; *s = 0; *out_n = atoi(start); *s = c;
1507     return s;
1508 }
1509
1510 static char *skip_idf(char *start, char out_idf[256])
1511 {
1512     char *s;
1513     char c;
1514
1515     s = skip_white(start);
1516     if(s == NULL) return NULL;
1517     start = s;
1518
1519     while(*s)
1520     {
1521         if(isalpha(*s) || *s == '_') { ++s; continue; }
1522         break;
1523     }
1524     c = *s; *s = 0; strncpy(out_idf, start, 255); *s = c;
1525     return s;
1526 }
1527
1528 static void read_pnm_header(FILE *reader, struct pnm_header *ph)
1529 {
1530     char *s;
1531     int format, have_wh, end, ttype;
1532     char idf[256], type[256];
1533     char line[256];
1534
1535     if (fgets(line, 250, reader) == NULL)
1536     {
1537         fprintf(stderr,"\nWARNING: fgets return a NULL value");
1538         return;
1539     }
1540
1541     if(line[0] != 'P')
1542     {
1543         fprintf(stderr,"read_pnm_header:PNM:magic P missing\n"); return;
1544     }
1545     format = atoi(line + 1);
1546     if(format < 1 || format > 7)
1547     {
1548         fprintf(stderr,"read_pnm_header:magic format %d invalid\n", format);
1549         return;
1550     }
1551     ph->format = format;
1552     ttype = end = have_wh = 0;
1553
1554     while(fgets(line, 250, reader))
1555     {
1556         if(*line == '#') continue;
1557
1558         s = line;
1559
1560         if(format == 7)
1561         {
1562             s = skip_idf(s, idf);
1563
1564             if(s == NULL || *s == 0) return;
1565
1566             if(strcmp(idf, "ENDHDR") == 0)
1567             {
1568                 end = 1; break;
1569             }
1570             if(strcmp(idf, "WIDTH") == 0)
1571             {
1572                 s = skip_int(s, &ph->width);
1573                 if(s == NULL || *s == 0) return;
1574
1575                 continue;
1576             }
1577             if(strcmp(idf, "HEIGHT") == 0)
1578             {
1579                 s = skip_int(s, &ph->height);
1580                 if(s == NULL || *s == 0) return;
1581
1582                 continue;
1583             }
1584             if(strcmp(idf, "DEPTH") == 0)
1585             {
1586                 s = skip_int(s, &ph->depth);
1587                 if(s == NULL || *s == 0) return;
1588
1589                 continue;
1590             }
1591             if(strcmp(idf, "MAXVAL") == 0)
1592             {
1593                 s = skip_int(s, &ph->maxval);
1594                 if(s == NULL || *s == 0) return;
1595
1596                 continue;
1597             }
1598             if(strcmp(idf, "TUPLTYPE") == 0)
1599             {
1600                 s = skip_idf(s, type);
1601                 if(s == NULL || *s == 0) return;
1602
1603                 if(strcmp(type, "BLACKANDWHITE") == 0)
1604                 {
1605                     ph->bw = 1; ttype = 1; continue;
1606                 }
1607                 if(strcmp(type, "GRAYSCALE") == 0)
1608                 {
1609                     ph->gray = 1; ttype = 1; continue;
1610                 }
1611                 if(strcmp(type, "GRAYSCALE_ALPHA") == 0)
1612                 {
1613                     ph->graya = 1; ttype = 1; continue;
1614                 }
1615                 if(strcmp(type, "RGB") == 0)
1616                 {
1617                     ph->rgb = 1; ttype = 1; continue;
1618                 }
1619                 if(strcmp(type, "RGB_ALPHA") == 0)
1620                 {
1621                     ph->rgba = 1; ttype = 1; continue;
1622                 }
1623                 fprintf(stderr,"read_pnm_header:unknown P7 TUPLTYPE %s\n",type);
1624                 return;
1625             }
1626             fprintf(stderr,"read_pnm_header:unknown P7 idf %s\n",idf);
1627             return;
1628         } /* if(format == 7) */
1629
1630         if( !have_wh)
1631         {
1632             s = skip_int(s, &ph->width);
1633
1634             s = skip_int(s, &ph->height);
1635
1636             have_wh = 1;
1637
1638             if(format == 1 || format == 4) break;
1639
1640             continue;
1641         }
1642         if(format == 2 || format == 3 || format == 5 || format == 6)
1643         {
1644             /* P2, P3, P5, P6: */
1645             s = skip_int(s, &ph->maxval);
1646
1647             if(ph->maxval > 65535) return;
1648         }
1649         break;
1650     }/* while(fgets( ) */
1651     if(format == 2 || format == 3 || format > 4)
1652     {
1653         if(ph->maxval < 1 || ph->maxval > 65535) return;
1654     }
1655     if(ph->width < 1 || ph->height < 1) return;
1656
1657     if(format == 7)
1658     {
1659         if(!end)
1660         {
1661             fprintf(stderr,"read_pnm_header:P7 without ENDHDR\n"); return;
1662         }
1663         if(ph->depth < 1 || ph->depth > 4) return;
1664
1665         if(ph->width && ph->height && ph->depth & ph->maxval && ttype)
1666             ph->ok = 1;
1667     }
1668     else
1669     {
1670         if(format != 1 && format != 4)
1671         {
1672             if(ph->width && ph->height && ph->maxval) ph->ok = 1;
1673         }
1674         else
1675         {
1676             if(ph->width && ph->height) ph->ok = 1;
1677             ph->maxval = 255;
1678         }
1679     }
1680 }
1681
1682 static int has_prec(int val)
1683 {
1684     if(val < 2) return 1;
1685     if(val < 4) return 2;
1686     if(val < 8) return 3;
1687     if(val < 16) return 4;
1688     if(val < 32) return 5;
1689     if(val < 64) return 6;
1690     if(val < 128) return 7;
1691     if(val < 256) return 8;
1692     if(val < 512) return 9;
1693     if(val < 1024) return 10;
1694     if(val < 2048) return 11;
1695     if(val < 4096) return 12;
1696     if(val < 8192) return 13;
1697     if(val < 16384) return 14;
1698     if(val < 32768) return 15;
1699     return 16;
1700 }
1701
1702 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
1703     int subsampling_dx = parameters->subsampling_dx;
1704     int subsampling_dy = parameters->subsampling_dy;
1705
1706     FILE *fp = NULL;
1707     int i, compno, numcomps, w, h, prec, format;
1708     OPJ_COLOR_SPACE color_space;
1709     opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */
1710     opj_image_t * image = NULL;
1711     struct pnm_header header_info;
1712
1713     if((fp = fopen(filename, "rb")) == NULL)
1714     {
1715         fprintf(stderr, "pnmtoimage:Failed to open %s for reading!\n",filename);
1716         return NULL;
1717     }
1718     memset(&header_info, 0, sizeof(struct pnm_header));
1719
1720     read_pnm_header(fp, &header_info);
1721
1722     if(!header_info.ok) { fclose(fp); return NULL; }
1723
1724     format = header_info.format;
1725
1726     switch(format)
1727     {
1728     case 1: /* ascii bitmap */
1729     case 4: /* raw bitmap */
1730         numcomps = 1;
1731         break;
1732
1733     case 2: /* ascii greymap */
1734     case 5: /* raw greymap */
1735         numcomps = 1;
1736         break;
1737
1738     case 3: /* ascii pixmap */
1739     case 6: /* raw pixmap */
1740         numcomps = 3;
1741         break;
1742
1743     case 7: /* arbitrary map */
1744         numcomps = header_info.depth;
1745         break;
1746
1747     default: fclose(fp); return NULL;
1748     }
1749     if(numcomps < 3)
1750         color_space = OPJ_CLRSPC_GRAY;/* GRAY, GRAYA */
1751     else
1752         color_space = OPJ_CLRSPC_SRGB;/* RGB, RGBA */
1753
1754     prec = has_prec(header_info.maxval);
1755
1756     if(prec < 8) prec = 8;
1757
1758     w = header_info.width;
1759     h = header_info.height;
1760     subsampling_dx = parameters->subsampling_dx;
1761     subsampling_dy = parameters->subsampling_dy;
1762
1763     memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
1764
1765     for(i = 0; i < numcomps; i++)
1766     {
1767         cmptparm[i].prec = prec;
1768         cmptparm[i].bpp = prec;
1769         cmptparm[i].sgnd = 0;
1770         cmptparm[i].dx = subsampling_dx;
1771         cmptparm[i].dy = subsampling_dy;
1772         cmptparm[i].w = w;
1773         cmptparm[i].h = h;
1774     }
1775     image = opj_image_create(numcomps, &cmptparm[0], color_space);
1776
1777     if(!image) { fclose(fp); return NULL; }
1778
1779     /* set image offset and reference grid */
1780     image->x0 = parameters->image_offset_x0;
1781     image->y0 = parameters->image_offset_y0;
1782     image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
1783     image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
1784
1785     if((format == 2) || (format == 3)) /* ascii pixmap */
1786     {
1787         unsigned int index;
1788
1789         for (i = 0; i < w * h; i++)
1790         {
1791             for(compno = 0; compno < numcomps; compno++)
1792             {
1793                 index = 0;
1794                 if (fscanf(fp, "%u", &index) != 1)
1795                     fprintf(stderr, "\nWARNING: fscanf return a number of element different from the expected.\n");
1796
1797                 image->comps[compno].data[i] = (index * 255)/header_info.maxval;
1798             }
1799         }
1800     }
1801     else
1802         if((format == 5)
1803                 || (format == 6)
1804                 ||((format == 7)
1805                    && (   header_info.gray || header_info.graya
1806                           || header_info.rgb || header_info.rgba)))/* binary pixmap */
1807         {
1808             unsigned char c0, c1, one;
1809
1810             one = (prec < 9);
1811
1812             for (i = 0; i < w * h; i++)
1813             {
1814                 for(compno = 0; compno < numcomps; compno++)
1815                 {
1816                     if ( !fread(&c0, 1, 1, fp) )
1817                         fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1818                     if(one)
1819                     {
1820                         image->comps[compno].data[i] = c0;
1821                     }
1822                     else
1823                     {
1824                         if ( !fread(&c1, 1, 1, fp) )
1825                             fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1826                         /* netpbm: */
1827                         image->comps[compno].data[i] = ((c0<<8) | c1);
1828                     }
1829                 }
1830             }
1831         }
1832         else
1833             if(format == 1) /* ascii bitmap */
1834             {
1835                 for (i = 0; i < w * h; i++)
1836                 {
1837                     unsigned int index;
1838
1839                     if ( fscanf(fp, "%u", &index) != 1)
1840                         fprintf(stderr, "\nWARNING: fscanf return a number of element different from the expected.\n");
1841
1842                     image->comps[0].data[i] = (index?0:255);
1843                 }
1844             }
1845             else
1846                 if(format == 4)
1847                 {
1848                     int x, y, bit;
1849                     unsigned char uc;
1850
1851                     i = 0;
1852                     for(y = 0; y < h; ++y)
1853                     {
1854                         bit = -1; uc = 0;
1855
1856                         for(x = 0; x < w; ++x)
1857                         {
1858                             if(bit == -1)
1859                             {
1860                                 bit = 7;
1861                                 uc = (unsigned char)getc(fp);
1862                             }
1863                             image->comps[0].data[i] = (((uc>>bit) & 1)?0:255);
1864                             --bit; ++i;
1865                         }
1866                     }
1867                 }
1868                 else
1869                     if((format == 7 && header_info.bw)) /*MONO*/
1870                     {
1871                         unsigned char uc;
1872
1873                         for(i = 0; i < w * h; ++i)
1874                         {
1875                             if ( !fread(&uc, 1, 1, fp) )
1876                                 fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
1877                             image->comps[0].data[i] = (uc & 1)?0:255;
1878                         }
1879                     }
1880     fclose(fp);
1881
1882     return image;
1883 }/* pnmtoimage() */
1884
1885 int imagetopnm(opj_image_t * image, const char *outfile) 
1886 {
1887     int *red, *green, *blue, *alpha;
1888     int wr, hr, max;
1889     int i, compno, ncomp;
1890     int adjustR, adjustG, adjustB, adjustA;
1891     int fails, two, want_gray, has_alpha, triple;
1892     int prec, v;
1893     FILE *fdest = NULL;
1894     const char *tmp = outfile;
1895     char *destname;
1896     alpha = NULL;
1897     if((prec = image->comps[0].prec) > 16)
1898     {
1899         fprintf(stderr,"%s:%d:imagetopnm\n\tprecision %d is larger than 16"
1900                 "\n\t: refused.\n",__FILE__,__LINE__,prec);
1901         return 1;
1902     }
1903     two = has_alpha = 0; fails = 1;
1904     ncomp = image->numcomps;
1905
1906     while (*tmp) ++tmp; tmp -= 2;
1907     want_gray = (*tmp == 'g' || *tmp == 'G');
1908     ncomp = image->numcomps;
1909
1910     if(want_gray) ncomp = 1;
1911
1912     if (ncomp == 2 /* GRAYA */
1913             || (ncomp > 2 /* RGB, RGBA */
1914                 && image->comps[0].dx == image->comps[1].dx
1915                 && image->comps[1].dx == image->comps[2].dx
1916                 && image->comps[0].dy == image->comps[1].dy
1917                 && image->comps[1].dy == image->comps[2].dy
1918                 && image->comps[0].prec == image->comps[1].prec
1919                 && image->comps[1].prec == image->comps[2].prec
1920                 ))
1921     {
1922         fdest = fopen(outfile, "wb");
1923
1924         if (!fdest)
1925         {
1926             fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1927             return fails;
1928         }
1929         two = (prec > 8);
1930         triple = (ncomp > 2);
1931         wr = image->comps[0].w; hr = image->comps[0].h;
1932         max = (1<<prec) - 1; has_alpha = (ncomp == 4 || ncomp == 2);
1933
1934         red = image->comps[0].data;
1935
1936         if(triple)
1937         {
1938             green = image->comps[1].data;
1939             blue = image->comps[2].data;
1940         }
1941         else green = blue = NULL;
1942
1943         if(has_alpha)
1944         {
1945             const char *tt = (triple?"RGB_ALPHA":"GRAYSCALE_ALPHA");
1946
1947             fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %d\n"
1948                     "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", opj_version(),
1949                     wr, hr, ncomp, max, tt);
1950             alpha = image->comps[ncomp - 1].data;
1951             adjustA = (image->comps[ncomp - 1].sgnd ?
1952                         1 << (image->comps[ncomp - 1].prec - 1) : 0);
1953         }
1954         else
1955         {
1956             fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n",
1957                     opj_version(), wr, hr, max);
1958             adjustA = 0;
1959         }
1960         adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1961
1962         if(triple)
1963         {
1964             adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1965             adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1966         }
1967         else adjustG = adjustB = 0;
1968
1969         for(i = 0; i < wr * hr; ++i)
1970         {
1971             if(two)
1972             {
1973                 v = *red + adjustR; ++red;
1974                 /* netpbm: */
1975                 fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v);
1976
1977                 if(triple)
1978                 {
1979                     v = *green + adjustG; ++green;
1980                     /* netpbm: */
1981                     fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v);
1982
1983                     v =  *blue + adjustB; ++blue;
1984                     /* netpbm: */
1985                     fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v);
1986
1987                 }/* if(triple) */
1988
1989                 if(has_alpha)
1990                 {
1991                     v = *alpha + adjustA; ++alpha;
1992                     /* netpbm: */
1993                     fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v);
1994                 }
1995                 continue;
1996
1997             }   /* if(two) */
1998
1999             /* prec <= 8: */
2000
2001             fprintf(fdest, "%c", (unsigned char)*red++);
2002             if(triple)
2003                 fprintf(fdest, "%c%c",(unsigned char)*green++, (unsigned char)*blue++);
2004
2005             if(has_alpha)
2006                 fprintf(fdest, "%c", (unsigned char)*alpha++);
2007
2008         }       /* for(i */
2009
2010         fclose(fdest); return 0;
2011     }
2012
2013     /* YUV or MONO: */
2014
2015     if (image->numcomps > ncomp)
2016     {
2017         fprintf(stderr,"WARNING -> [PGM file] Only the first component\n");
2018         fprintf(stderr,"           is written to the file\n");
2019     }
2020     destname = (char*)malloc(strlen(outfile) + 8);
2021
2022     for (compno = 0; compno < ncomp; compno++)
2023     {
2024         if (ncomp > 1)
2025             sprintf(destname, "%d.%s", compno, outfile);
2026         else
2027             sprintf(destname, "%s", outfile);
2028
2029         fdest = fopen(destname, "wb");
2030         if (!fdest)
2031         {
2032             fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname);
2033             free(destname);
2034             return 1;
2035         }
2036         wr = image->comps[compno].w; hr = image->comps[compno].h;
2037         prec = image->comps[compno].prec;
2038         max = (1<<prec) - 1;
2039
2040         fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n",
2041                 opj_version(), wr, hr, max);
2042
2043         red = image->comps[compno].data;
2044         adjustR =
2045                 (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
2046
2047         if(prec > 8)
2048         {
2049             for (i = 0; i < wr * hr; i++)
2050             {
2051                 v = *red + adjustR; ++red;
2052                 /* netpbm: */
2053                 fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v);
2054
2055                 if(has_alpha)
2056                 {
2057                     v = *alpha++;
2058                     /* netpbm: */
2059                     fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v);
2060                 }
2061             }/* for(i */
2062         }
2063         else /* prec <= 8 */
2064         {
2065             for(i = 0; i < wr * hr; ++i)
2066             {
2067                 fprintf(fdest, "%c", (unsigned char)(*red + adjustR)); ++red;
2068             }
2069         }
2070         fclose(fdest);
2071     } /* for (compno */
2072     free(destname);
2073
2074     return 0;
2075 }/* imagetopnm() */
2076
2077 #ifdef OPJ_HAVE_LIBTIFF
2078 /* -->> -->> -->> -->>
2079
2080     TIFF IMAGE FORMAT
2081
2082  <<-- <<-- <<-- <<-- */
2083
2084 int imagetotif(opj_image_t * image, const char *outfile) 
2085 {
2086     int width, height, imgsize;
2087     int bps,index,adjust, sgnd;
2088     int ushift, dshift, has_alpha, force16;
2089     TIFF *tif;
2090     tdata_t buf;
2091     tstrip_t strip;
2092     tsize_t strip_size;
2093
2094     ushift = dshift = force16 = has_alpha = 0;
2095     bps = image->comps[0].prec;
2096
2097     if(bps > 8 && bps < 16)
2098     {
2099         ushift = 16 - bps; dshift = bps - ushift;
2100         bps = 16; force16 = 1;
2101     }
2102
2103     if(bps != 8 && bps != 16)
2104     {
2105         fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits implemented\n",
2106                 bps);
2107         fprintf(stderr,"\tAborting\n");
2108         return 1;
2109     }
2110     tif = TIFFOpen(outfile, "wb");
2111
2112     if (!tif)
2113     {
2114         fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile);
2115         return 1;
2116     }
2117     sgnd = image->comps[0].sgnd;
2118     adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0;
2119
2120     if(image->numcomps >= 3
2121             && image->comps[0].dx == image->comps[1].dx
2122             && image->comps[1].dx == image->comps[2].dx
2123             && image->comps[0].dy == image->comps[1].dy
2124             && image->comps[1].dy == image->comps[2].dy
2125             && image->comps[0].prec == image->comps[1].prec
2126             && image->comps[1].prec == image->comps[2].prec)
2127     {
2128         has_alpha = (image->numcomps == 4);
2129
2130         width   = image->comps[0].w;
2131         height  = image->comps[0].h;
2132         imgsize = width * height ;
2133
2134         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
2135         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
2136         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3 + has_alpha);
2137         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
2138         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
2139         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
2140         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
2141         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
2142         strip_size = TIFFStripSize(tif);
2143         buf = _TIFFmalloc(strip_size);
2144         index=0;
2145
2146         for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
2147         {
2148             unsigned char *dat8;
2149             tsize_t i, ssize, last_i = 0;
2150             int step, restx;
2151             ssize = TIFFStripSize(tif);
2152             dat8 = (unsigned char*)buf;
2153
2154             if(bps == 8)
2155             {
2156                 step = 3 + has_alpha;
2157                 restx = step - 1;
2158
2159                 for(i=0; i < ssize - restx; i += step)
2160                 {
2161                     int r, g, b, a = 0;
2162
2163                     if(index < imgsize)
2164                     {
2165                         r = image->comps[0].data[index];
2166                         g = image->comps[1].data[index];
2167                         b = image->comps[2].data[index];
2168                         if(has_alpha) a = image->comps[3].data[index];
2169
2170                         if(sgnd)
2171                         {
2172                             r += adjust;
2173                             g += adjust;
2174                             b += adjust;
2175                             if(has_alpha) a += adjust;
2176                         }
2177                         dat8[i+0] = r ;
2178                         dat8[i+1] = g ;
2179                         dat8[i+2] = b ;
2180                         if(has_alpha) dat8[i+3] = a;
2181
2182                         index++;
2183                         last_i = i + step;
2184                     }
2185                     else
2186                         break;
2187                 }/*for(i = 0;)*/
2188
2189                 if(last_i < ssize)
2190                 {
2191                     for(i = last_i; i < ssize; i += step)
2192                     {
2193                         int r, g, b, a = 0;
2194
2195                         if(index < imgsize)
2196                         {
2197                             r = image->comps[0].data[index];
2198                             g = image->comps[1].data[index];
2199                             b = image->comps[2].data[index];
2200                             if(has_alpha) a = image->comps[3].data[index];
2201
2202                             if(sgnd)
2203                             {
2204                                 r += adjust;
2205                                 g += adjust;
2206                                 b += adjust;
2207                                 if(has_alpha) a += adjust;
2208                             }
2209                             dat8[i+0] = r ;
2210                             if(i+1 < ssize) dat8[i+1] = g ;  else break;
2211                             if(i+2 < ssize) dat8[i+2] = b ;  else break;
2212                             if(has_alpha)
2213                             {
2214                                 if(i+3 < ssize) dat8[i+3] = a ;  else break;
2215                             }
2216                             index++;
2217                         }
2218                         else
2219                             break;
2220                     }/*for(i)*/
2221                 }/*if(last_i < ssize)*/
2222
2223             }   /*if(bps == 8)*/
2224             else
2225                 if(bps == 16)
2226                 {
2227                     step = 6 + has_alpha + has_alpha;
2228                     restx = step - 1;
2229
2230                     for(i = 0; i < ssize - restx ; i += step)
2231                     {
2232                         int r, g, b, a = 0;
2233
2234                         if(index < imgsize)
2235                         {
2236                             r = image->comps[0].data[index];
2237                             g = image->comps[1].data[index];
2238                             b = image->comps[2].data[index];
2239                             if(has_alpha) a = image->comps[3].data[index];
2240
2241                             if(sgnd)
2242                             {
2243                                 r += adjust;
2244                                 g += adjust;
2245                                 b += adjust;
2246                                 if(has_alpha) a += adjust;
2247                             }
2248                             if(force16)
2249                             {
2250                                 r = (r<<ushift) + (r>>dshift);
2251                                 g = (g<<ushift) + (g>>dshift);
2252                                 b = (b<<ushift) + (b>>dshift);
2253                                 if(has_alpha) a = (a<<ushift) + (a>>dshift);
2254                             }
2255                             dat8[i+0] =  r;/*LSB*/
2256                             dat8[i+1] = (r >> 8);/*MSB*/
2257                             dat8[i+2] =  g;
2258                             dat8[i+3] = (g >> 8);
2259                             dat8[i+4] =  b;
2260                             dat8[i+5] = (b >> 8);
2261                             if(has_alpha)
2262                             {
2263                                 dat8[i+6] =  a;
2264                                 dat8[i+7] = (a >> 8);
2265                             }
2266                             index++;
2267                             last_i = i + step;
2268                         }
2269                         else
2270                             break;
2271                     }/*for(i = 0;)*/
2272
2273                     if(last_i < ssize)
2274                     {
2275                         for(i = last_i ; i < ssize ; i += step)
2276                         {
2277                             int r, g, b, a = 0;
2278
2279                             if(index < imgsize)
2280                             {
2281                                 r = image->comps[0].data[index];
2282                                 g = image->comps[1].data[index];
2283                                 b = image->comps[2].data[index];
2284                                 if(has_alpha) a = image->comps[3].data[index];
2285
2286                                 if(sgnd)
2287                                 {
2288                                     r += adjust;
2289                                     g += adjust;
2290                                     b += adjust;
2291                                     if(has_alpha) a += adjust;
2292                                 }
2293                                 if(force16)
2294                                 {
2295                                     r = (r<<ushift) + (r>>dshift);
2296                                     g = (g<<ushift) + (g>>dshift);
2297                                     b = (b<<ushift) + (b>>dshift);
2298                                     if(has_alpha) a = (a<<ushift) + (a>>dshift);
2299                                 }
2300                                 dat8[i+0] =  r;/*LSB*/
2301                                 if(i+1 < ssize) dat8[i+1] = (r >> 8);else break;/*MSB*/
2302                                 if(i+2 < ssize) dat8[i+2] =  g;      else break;
2303                                 if(i+3 < ssize) dat8[i+3] = (g >> 8);else break;
2304                                 if(i+4 < ssize) dat8[i+4] =  b;      else break;
2305                                 if(i+5 < ssize) dat8[i+5] = (b >> 8);else break;
2306
2307                                 if(has_alpha)
2308                                 {
2309                                     if(i+6 < ssize) dat8[i+6] = a; else break;
2310                                     if(i+7 < ssize) dat8[i+7] = (a >> 8); else break;
2311                                 }
2312                                 index++;
2313                             }
2314                             else
2315                                 break;
2316                         }/*for(i)*/
2317                     }/*if(last_i < ssize)*/
2318
2319                 }/*if(bps == 16)*/
2320             (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
2321         }/*for(strip = 0; )*/
2322
2323         _TIFFfree((void*)buf);
2324         TIFFClose(tif);
2325
2326         return 0;
2327     }/*RGB(A)*/
2328
2329     if(image->numcomps == 1 /* GRAY */
2330             || (   image->numcomps == 2 /* GRAY_ALPHA */
2331                    && image->comps[0].dx == image->comps[1].dx
2332                    && image->comps[0].dy == image->comps[1].dy
2333                    && image->comps[0].prec == image->comps[1].prec))
2334     {
2335         int step;
2336
2337         has_alpha = (image->numcomps == 2);
2338
2339         width   = image->comps[0].w;
2340         height  = image->comps[0].h;
2341         imgsize = width * height;
2342
2343         /* Set tags */
2344         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
2345         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
2346         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1 + has_alpha);
2347         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
2348         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
2349         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
2350         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
2351         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
2352
2353         /* Get a buffer for the data */
2354         strip_size = TIFFStripSize(tif);
2355         buf = _TIFFmalloc(strip_size);
2356         index = 0;
2357
2358         for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
2359         {
2360             unsigned char *dat8;
2361             tsize_t i, ssize = TIFFStripSize(tif);
2362             dat8 = (unsigned char*)buf;
2363
2364             if(bps == 8)
2365             {
2366                 step = 1 + has_alpha;
2367
2368                 for(i=0; i < ssize; i += step)
2369                 {
2370                     if(index < imgsize)
2371                     {
2372                         int r, a = 0;
2373
2374                         r = image->comps[0].data[index];
2375                         if(has_alpha) a = image->comps[1].data[index];
2376
2377                         if(sgnd)
2378                         {
2379                             r += adjust;
2380                             if(has_alpha) a += adjust;
2381                         }
2382                         dat8[i+0] = r;
2383                         if(has_alpha) dat8[i+1] = a;
2384                         index++;
2385                     }
2386                     else
2387                         break;
2388                 }/*for(i )*/
2389             }/*if(bps == 8*/
2390             else
2391                 if(bps == 16)
2392                 {
2393                     step = 2 + has_alpha + has_alpha;
2394
2395                     for(i=0; i < ssize; i += step)
2396                     {
2397                         if(index < imgsize)
2398                         {
2399                             int r, a = 0;
2400
2401                             r = image->comps[0].data[index];
2402                             if(has_alpha) a = image->comps[1].data[index];
2403
2404                             if(sgnd)
2405                             {
2406                                 r += adjust;
2407                                 if(has_alpha) a += adjust;
2408                             }
2409                             if(force16)
2410                             {
2411                                 r = (r<<ushift) + (r>>dshift);
2412                                 if(has_alpha) a = (a<<ushift) + (a>>dshift);
2413                             }
2414                             dat8[i+0] = r;/*LSB*/
2415                             dat8[i+1] = r >> 8;/*MSB*/
2416                             if(has_alpha)
2417                             {
2418                                 dat8[i+2] = a;
2419                                 dat8[i+3] = a >> 8;
2420                             }
2421                             index++;
2422                         }/*if(index < imgsize)*/
2423                         else
2424                             break;
2425                     }/*for(i )*/
2426                 }
2427             (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
2428         }/*for(strip*/
2429
2430         _TIFFfree(buf);
2431         TIFFClose(tif);
2432
2433         return 0;
2434     }
2435
2436     TIFFClose(tif);
2437
2438     fprintf(stderr,"imagetotif: Bad color format.\n"
2439             "\tOnly RGB(A) and GRAY(A) has been implemented\n");
2440     fprintf(stderr,"\tFOUND: numcomps(%d)\n\tAborting\n",
2441             image->numcomps);
2442
2443     return 1;
2444 }/* imagetotif() */
2445
2446 /*
2447  * libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
2448  * CINEMA                 : 12 bit precision
2449 */
2450 opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
2451 {
2452     int subsampling_dx = parameters->subsampling_dx;
2453     int subsampling_dy = parameters->subsampling_dy;
2454     TIFF *tif;
2455     tdata_t buf;
2456     tstrip_t strip;
2457     tsize_t strip_size;
2458     int j, numcomps, w, h,index;
2459     OPJ_COLOR_SPACE color_space;
2460     opj_image_cmptparm_t cmptparm[4]; /* RGBA */
2461     opj_image_t *image = NULL;
2462     int imgsize = 0;
2463     int has_alpha = 0;
2464     unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
2465     unsigned int tiWidth, tiHeight;
2466
2467     tif = TIFFOpen(filename, "r");
2468
2469     if(!tif)
2470     {
2471         fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
2472         return 0;
2473     }
2474     tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
2475     tiWidth = tiHeight = 0;
2476
2477     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
2478     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
2479     TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
2480     TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
2481     TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
2482     TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
2483     TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
2484     w= tiWidth;
2485     h= tiHeight;
2486
2487     if(tiBps != 8 && tiBps != 16 && tiBps != 12) tiBps = 0;
2488     if(tiPhoto != 1 && tiPhoto != 2) tiPhoto = 0;
2489
2490     if( !tiBps || !tiPhoto)
2491     {
2492         if( !tiBps)
2493             fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits"
2494                     " implemented\n",tiBps);
2495         else
2496             if( !tiPhoto)
2497                 fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A)"
2498                         " and GRAY(A) has been implemented\n",(int) tiPhoto);
2499
2500         fprintf(stderr,"\tAborting\n");
2501         TIFFClose(tif);
2502
2503         return NULL;
2504     }
2505
2506     {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
2507         uint16* sampleinfo;
2508         uint16 extrasamples;
2509
2510         TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
2511                               &extrasamples, &sampleinfo);
2512
2513         if(extrasamples >= 1)
2514         {
2515             switch(sampleinfo[0])
2516             {
2517             case EXTRASAMPLE_UNSPECIFIED:
2518                 /* Workaround for some images without correct info about alpha channel
2519 */
2520                 if(tiSpp > 3)
2521                     has_alpha = 1;
2522                 break;
2523
2524             case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
2525             case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
2526                 has_alpha = 1;
2527                 break;
2528             }
2529         }
2530         else /* extrasamples == 0 */
2531             if(tiSpp == 4 || tiSpp == 2) has_alpha = 1;
2532     }
2533
2534     /* initialize image components
2535 */ 
2536     memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
2537
2538     if ((tiPhoto == PHOTOMETRIC_RGB) && (parameters->cp_cinema)) {
2539         fprintf(stdout,"WARNING:\n"
2540                 "Input image bitdepth is %d bits\n"
2541                 "TIF conversion has automatically rescaled to 12-bits\n"
2542                 "to comply with cinema profiles.\n",
2543                 tiBps);
2544     }
2545
2546     if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */
2547     {
2548         numcomps = 3 + has_alpha;
2549         color_space = OPJ_CLRSPC_SRGB;
2550
2551         /*#define USETILEMODE*/
2552         for(j = 0; j < numcomps; j++)
2553         {
2554             if(parameters->cp_cinema)
2555             {
2556                 cmptparm[j].prec = 12;
2557                 cmptparm[j].bpp = 12;
2558             }
2559             else
2560             {
2561                 cmptparm[j].prec = tiBps;
2562                 cmptparm[j].bpp = tiBps;
2563             }
2564             cmptparm[j].dx = subsampling_dx;
2565             cmptparm[j].dy = subsampling_dy;
2566             cmptparm[j].w = w;
2567             cmptparm[j].h = h;
2568 #ifdef USETILEMODE
2569             cmptparm[j].x0 = 0;
2570             cmptparm[j].y0 = 0;
2571 #endif
2572         }
2573
2574 #ifdef USETILEMODE
2575         image = opj_image_tile_create(numcomps,&cmptparm[0],color_space);
2576 #else
2577         image = opj_image_create(numcomps, &cmptparm[0], color_space);
2578 #endif
2579
2580         if(!image)
2581         {
2582             TIFFClose(tif);
2583             return NULL;
2584         }
2585         /* set image offset and reference grid
2586 */
2587         image->x0 = parameters->image_offset_x0;
2588         image->y0 = parameters->image_offset_y0;
2589         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 :
2590                                  image->x0 + (w - 1) * subsampling_dx + 1;
2591         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 :
2592                                  image->y0 + (h - 1) * subsampling_dy + 1;
2593
2594         buf = _TIFFmalloc(TIFFStripSize(tif));
2595
2596         strip_size=TIFFStripSize(tif);
2597         index = 0;
2598         imgsize = image->comps[0].w * image->comps[0].h ;
2599         /* Read the Image components
2600 */
2601         for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
2602         {
2603             unsigned char *dat8;
2604             int step;
2605             tsize_t i, ssize;
2606             ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
2607             dat8 = (unsigned char*)buf;
2608
2609             if(tiBps == 16)
2610             {
2611                 step = 6 + has_alpha + has_alpha;
2612
2613                 for(i = 0; i < ssize; i += step)
2614                 {
2615                     if(index < imgsize)
2616                     {
2617                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; /* R */
2618                         image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; /* G */
2619                         image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; /* B */
2620                         if(has_alpha)
2621                             image->comps[3].data[index] = ( dat8[i+7] << 8 ) | dat8[i+6];
2622
2623                         if(parameters->cp_cinema)
2624                         {
2625                             /* Rounding 16 to 12 bits
2626 */
2627                             image->comps[0].data[index] =
2628                                     (image->comps[0].data[index] + 0x08) >> 4 ;
2629                             image->comps[1].data[index] =
2630                                     (image->comps[1].data[index] + 0x08) >> 4 ;
2631                             image->comps[2].data[index] =
2632                                     (image->comps[2].data[index] + 0x08) >> 4 ;
2633                             if(has_alpha)
2634                                 image->comps[3].data[index] =
2635                                         (image->comps[3].data[index] + 0x08) >> 4 ;
2636                         }
2637                         index++;
2638                     }
2639                     else
2640                         break;
2641                 }/*for(i = 0)*/
2642             }/*if(tiBps == 16)*/
2643             else
2644                 if(tiBps == 8)
2645                 {
2646                     step = 3 + has_alpha;
2647
2648                     for(i = 0; i < ssize; i += step)
2649                     {
2650                         if(index < imgsize)
2651                         {
2652 #ifndef USETILEMODE
2653                             image->comps[0].data[index] = dat8[i+0];/* R */
2654                             image->comps[1].data[index] = dat8[i+1];/* G */
2655                             image->comps[2].data[index] = dat8[i+2];/* B */
2656                             if(has_alpha)
2657                                 image->comps[3].data[index] = dat8[i+3];
2658 #endif
2659
2660                             if(parameters->cp_cinema)
2661                             {
2662                                 /* Rounding 8 to 12 bits
2663 */
2664 #ifndef USETILEMODE
2665                                 image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
2666                                 image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
2667                                 image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
2668                                 if(has_alpha)
2669                                     image->comps[3].data[index] = image->comps[3].data[index] << 4 ;
2670 #endif
2671                             }
2672                             index++;
2673                         }/*if(index*/
2674                         else
2675                             break;
2676                     }/*for(i )*/
2677                 }/*if( tiBps == 8)*/
2678                 else
2679                     if(tiBps == 12)/* CINEMA file */
2680                     {
2681                         step = 9;
2682
2683                         for(i = 0; i < ssize; i += step)
2684                         {
2685                             if((index < imgsize)&(index+1 < imgsize))
2686                             {
2687                                 image->comps[0].data[index]   = ( dat8[i+0]<<4 )        |(dat8[i+1]>>4);
2688                                 image->comps[1].data[index]   = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
2689
2690                                 image->comps[2].data[index]   = ( dat8[i+3]<<4)         |(dat8[i+4]>>4);
2691                                 image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
2692
2693                                 image->comps[1].data[index+1] = ( dat8[i+6] <<4)        |(dat8[i+7]>>4);
2694                                 image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
2695
2696                                 index += 2;
2697                             }
2698                             else
2699                                 break;
2700                         }/*for(i )*/
2701                     }
2702         }/*for(strip = 0; )*/
2703
2704         _TIFFfree(buf);
2705         TIFFClose(tif);
2706
2707         return image;
2708     }/*RGB(A)*/
2709
2710     if(tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */
2711     {
2712         numcomps = 1 + has_alpha;
2713         color_space = OPJ_CLRSPC_GRAY;
2714
2715         for(j = 0; j < numcomps; ++j)
2716         {
2717             cmptparm[j].prec = tiBps;
2718             cmptparm[j].bpp = tiBps;
2719             cmptparm[j].dx = subsampling_dx;
2720             cmptparm[j].dy = subsampling_dy;
2721             cmptparm[j].w = w;
2722             cmptparm[j].h = h;
2723         }
2724 #ifdef USETILEMODE
2725         image = opj_image_tile_create(numcomps,&cmptparm[0],color_space);
2726 #else
2727         image = opj_image_create(numcomps, &cmptparm[0], color_space);
2728 #endif
2729
2730         if(!image)
2731         {
2732             TIFFClose(tif);
2733             return NULL;
2734         }
2735         /* set image offset and reference grid
2736 */
2737         image->x0 = parameters->image_offset_x0;
2738         image->y0 = parameters->image_offset_y0;
2739         image->x1 =     !image->x0 ? (w - 1) * subsampling_dx + 1 :
2740                                  image->x0 + (w - 1) * subsampling_dx + 1;
2741         image->y1 =     !image->y0 ? (h - 1) * subsampling_dy + 1 :
2742                                  image->y0 + (h - 1) * subsampling_dy + 1;
2743
2744         buf = _TIFFmalloc(TIFFStripSize(tif));
2745
2746         strip_size = TIFFStripSize(tif);
2747         index = 0;
2748         imgsize = image->comps[0].w * image->comps[0].h ;
2749         /* Read the Image components
2750 */
2751         for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
2752         {
2753             unsigned char *dat8;
2754             tsize_t i, ssize;
2755             int step;
2756
2757             ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
2758             dat8 = (unsigned char*)buf;
2759
2760             if(tiBps == 16)
2761             {
2762                 step = 2 + has_alpha + has_alpha;
2763
2764                 for(i = 0; i < ssize; i += step)
2765                 {
2766                     if(index < imgsize)
2767                     {
2768                         image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
2769                         if(has_alpha)
2770                             image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2];
2771                         index++;
2772                     }
2773                     else
2774                         break;
2775                 }/*for(i )*/
2776             }
2777             else
2778                 if(tiBps == 8)
2779                 {
2780                     step = 1 + has_alpha;
2781
2782                     for(i = 0; i < ssize; i += step)
2783                     {
2784                         if(index < imgsize)
2785                         {
2786                             image->comps[0].data[index] = dat8[i+0];
2787                             if(has_alpha)
2788                                 image->comps[1].data[index] = dat8[i+1];
2789                             index++;
2790                         }
2791                         else
2792                             break;
2793                     }/*for(i )*/
2794                 }
2795         }/*for(strip = 0;*/
2796
2797         _TIFFfree(buf);
2798         TIFFClose(tif);
2799
2800     }/*GRAY(A)*/
2801
2802     return image;
2803
2804 }/* tiftoimage() */
2805
2806 #endif /* OPJ_HAVE_LIBTIFF */
2807
2808 /* -->> -->> -->> -->>
2809
2810     RAW IMAGE FORMAT
2811
2812  <<-- <<-- <<-- <<-- */
2813 static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp, OPJ_BOOL big_endian) {
2814     int subsampling_dx = parameters->subsampling_dx;
2815     int subsampling_dy = parameters->subsampling_dy;
2816
2817     FILE *f = NULL;
2818     int i, compno, numcomps, w, h;
2819     OPJ_COLOR_SPACE color_space;
2820     opj_image_cmptparm_t *cmptparm;
2821     opj_image_t * image = NULL;
2822     unsigned short ch;
2823
2824     if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0)
2825     {
2826         fprintf(stderr,"\nError: invalid raw image parameters\n");
2827         fprintf(stderr,"Please use the Format option -F:\n");
2828         fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
2829         fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
2830         fprintf(stderr,"Aborting\n");
2831         return NULL;
2832     }
2833
2834     f = fopen(filename, "rb");
2835     if (!f) {
2836         fprintf(stderr, "Failed to open %s for reading !!\n", filename);
2837         fprintf(stderr,"Aborting\n");
2838         return NULL;
2839     }
2840     numcomps = raw_cp->rawComp;
2841     color_space = OPJ_CLRSPC_SRGB;
2842     w = raw_cp->rawWidth;
2843     h = raw_cp->rawHeight;
2844     cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t));
2845
2846     /* initialize image components */
2847     memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
2848     for(i = 0; i < numcomps; i++) {
2849         cmptparm[i].prec = raw_cp->rawBitDepth;
2850         cmptparm[i].bpp = raw_cp->rawBitDepth;
2851         cmptparm[i].sgnd = raw_cp->rawSigned;
2852         cmptparm[i].dx = subsampling_dx;
2853         cmptparm[i].dy = subsampling_dy;
2854         cmptparm[i].w = w;
2855         cmptparm[i].h = h;
2856     }
2857     /* create the image */
2858     image = opj_image_create(numcomps, &cmptparm[0], color_space);
2859     if(!image) {
2860         fclose(f);
2861         return NULL;
2862     }
2863     /* set image offset and reference grid */
2864     image->x0 = parameters->image_offset_x0;
2865     image->y0 = parameters->image_offset_y0;
2866     image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
2867     image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
2868
2869     if(raw_cp->rawBitDepth <= 8)
2870     {
2871         unsigned char value = 0;
2872         for(compno = 0; compno < numcomps; compno++) {
2873             for (i = 0; i < w * h; i++) {
2874                 if (!fread(&value, 1, 1, f)) {
2875                     fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2876                     return NULL;
2877                 }
2878                 image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value;
2879             }
2880         }
2881     }
2882     else if(raw_cp->rawBitDepth <= 16)
2883     {
2884         unsigned short value;
2885         for(compno = 0; compno < numcomps; compno++) {
2886             for (i = 0; i < w * h; i++) {
2887                 unsigned char temp1;
2888                 unsigned char temp2;
2889                 if (!fread(&temp1, 1, 1, f)) {
2890                     fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2891                     return NULL;
2892                 }
2893                 if (!fread(&temp2, 1, 1, f)) {
2894                     fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2895                     return NULL;
2896                 }
2897                 if( big_endian )
2898                 {
2899                     value = temp1 << 8;
2900                     value += temp2;
2901                 }
2902                 else
2903                 {
2904                     value = temp2 << 8;
2905                     value += temp1;
2906                 }
2907                 image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value;
2908             }
2909         }
2910     }
2911     else {
2912         fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n");
2913         return NULL;
2914     }
2915
2916     if (fread(&ch, 1, 1, f)) {
2917         fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n");
2918     }
2919     fclose(f);
2920
2921     return image;
2922 }
2923
2924 opj_image_t* rawltoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
2925     return rawtoimage_common(filename, parameters, raw_cp, OPJ_FALSE);
2926 }
2927
2928 opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
2929     return rawtoimage_common(filename, parameters, raw_cp, OPJ_TRUE);
2930 }
2931
2932 static int imagetoraw_common(opj_image_t * image, const char *outfile, OPJ_BOOL big_endian)
2933 {
2934     FILE *rawFile = NULL;
2935     size_t res;
2936     int compno;
2937     int w, h;
2938     int line, row;
2939     int *ptr;
2940
2941     if((image->numcomps * image->x1 * image->y1) == 0)
2942     {
2943         fprintf(stderr,"\nError: invalid raw image parameters\n");
2944         return 1;
2945     }
2946
2947     rawFile = fopen(outfile, "wb");
2948     if (!rawFile) {
2949         fprintf(stderr, "Failed to open %s for writing !!\n", outfile);
2950         return 1;
2951     }
2952
2953     fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps);
2954
2955     for(compno = 0; compno < image->numcomps; compno++)
2956     {
2957         fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w,
2958                 image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned");
2959
2960         w = image->comps[compno].w;
2961         h = image->comps[compno].h;
2962
2963         if(image->comps[compno].prec <= 8)
2964         {
2965             if(image->comps[compno].sgnd == 1)
2966             {
2967                 signed char curr;
2968                 int mask = (1 << image->comps[compno].prec) - 1;
2969                 ptr = image->comps[compno].data;
2970                 for (line = 0; line < h; line++) {
2971                     for(row = 0; row < w; row++)        {
2972                         curr = (signed char) (*ptr & mask);
2973                         res = fwrite(&curr, sizeof(signed char), 1, rawFile);
2974                         if( res < 1 ) {
2975                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
2976                             return 1;
2977                         }
2978                         ptr++;
2979                     }
2980                 }
2981             }
2982             else if(image->comps[compno].sgnd == 0)
2983             {
2984                 unsigned char curr;
2985                 int mask = (1 << image->comps[compno].prec) - 1;
2986                 ptr = image->comps[compno].data;
2987                 for (line = 0; line < h; line++) {
2988                     for(row = 0; row < w; row++)        {
2989                         curr = (unsigned char) (*ptr & mask);
2990                         res = fwrite(&curr, sizeof(unsigned char), 1, rawFile);
2991                         if( res < 1 ) {
2992                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
2993                             return 1;
2994                         }
2995                         ptr++;
2996                     }
2997                 }
2998             }
2999         }
3000         else if(image->comps[compno].prec <= 16)
3001         {
3002             if(image->comps[compno].sgnd == 1)
3003             {
3004                 signed short int curr;
3005                 int mask = (1 << image->comps[compno].prec) - 1;
3006                 ptr = image->comps[compno].data;
3007                 for (line = 0; line < h; line++) {
3008                     for(row = 0; row < w; row++)        {
3009                         unsigned char temp1;
3010                         unsigned char temp2;
3011                         curr = (signed short int) (*ptr & mask);
3012                         if( big_endian )
3013                         {
3014                             temp1 = (unsigned char) (curr >> 8);
3015                             temp2 = (unsigned char) curr;
3016                         }
3017                         else
3018                         {
3019                             temp2 = (unsigned char) (curr >> 8);
3020                             temp1 = (unsigned char) curr;
3021                         }
3022                         res = fwrite(&temp1, 1, 1, rawFile);
3023                         if( res < 1 ) {
3024                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3025                             return 1;
3026                         }
3027                         res = fwrite(&temp2, 1, 1, rawFile);
3028                         if( res < 1 ) {
3029                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3030                             return 1;
3031                         }
3032                         ptr++;
3033                     }
3034                 }
3035             }
3036             else if(image->comps[compno].sgnd == 0)
3037             {
3038                 unsigned short int curr;
3039                 int mask = (1 << image->comps[compno].prec) - 1;
3040                 ptr = image->comps[compno].data;
3041                 for (line = 0; line < h; line++) {
3042                     for(row = 0; row < w; row++)        {
3043                         unsigned char temp1;
3044                         unsigned char temp2;
3045                         curr = (unsigned short int) (*ptr & mask);
3046                         if( big_endian )
3047                         {
3048                             temp1 = (unsigned char) (curr >> 8);
3049                             temp2 = (unsigned char) curr;
3050                         }
3051                         else
3052                         {
3053                             temp2 = (unsigned char) (curr >> 8);
3054                             temp1 = (unsigned char) curr;
3055                         }
3056                         res = fwrite(&temp1, 1, 1, rawFile);
3057                         if( res < 1 ) {
3058                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3059                             return 1;
3060                         }
3061                         res = fwrite(&temp2, 1, 1, rawFile);
3062                         if( res < 1 ) {
3063                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3064                             return 1;
3065                         }
3066                         ptr++;
3067                     }
3068                 }
3069             }
3070         }
3071         else if (image->comps[compno].prec <= 32)
3072         {
3073             fprintf(stderr,"More than 16 bits per component no handled yet\n");
3074             return 1;
3075         }
3076         else
3077         {
3078             fprintf(stderr,"Error: invalid precision: %d\n", image->comps[compno].prec);
3079             return 1;
3080         }
3081     }
3082     fclose(rawFile);
3083     return 0;
3084 }
3085
3086 int imagetoraw(opj_image_t * image, const char *outfile)
3087 {
3088     return imagetoraw_common(image, outfile, OPJ_TRUE);
3089 }
3090
3091 int imagetorawl(opj_image_t * image, const char *outfile)
3092 {
3093     return imagetoraw_common(image, outfile, OPJ_FALSE);
3094 }
3095
3096 #ifdef OPJ_HAVE_LIBPNG
3097
3098 #define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a"
3099 #define MAGIC_SIZE 8
3100 /* PNG allows bits per sample: 1, 2, 4, 8, 16 */
3101
3102 opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
3103 {
3104     png_structp  png;
3105     png_infop    info;
3106     double gamma, display_exponent;
3107     int bit_depth, interlace_type,compression_type, filter_type;
3108     int unit;
3109     png_uint_32 resx, resy;
3110     unsigned int i, j;
3111     png_uint_32  width, height;
3112     int color_type, has_alpha, is16;
3113     unsigned char *s;
3114     FILE *reader;
3115     unsigned char **rows;
3116     /* j2k: */
3117     opj_image_t *image;
3118     opj_image_cmptparm_t cmptparm[4];
3119     int sub_dx, sub_dy;
3120     unsigned int nr_comp;
3121     int *r, *g, *b, *a;
3122     unsigned char sigbuf[8];
3123
3124     if((reader = fopen(read_idf, "rb")) == NULL)
3125     {
3126         fprintf(stderr,"pngtoimage: can not open %s\n",read_idf);
3127         return NULL;
3128     }
3129     image = NULL; png = NULL; rows = NULL;
3130
3131     if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
3132             || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0)
3133     {
3134         fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf);
3135         goto fin;
3136     }
3137     /* libpng-VERSION/example.c:
3138  * PC : screen_gamma = 2.2;
3139  * Mac: screen_gamma = 1.7 or 1.0;
3140 */
3141     display_exponent = 2.2;
3142
3143     if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
3144                                      NULL, NULL, NULL)) == NULL)
3145         goto fin;
3146     if((info = png_create_info_struct(png)) == NULL)
3147         goto fin;
3148
3149     if(setjmp(png_jmpbuf(png)))
3150         goto fin;
3151
3152     png_init_io(png, reader);
3153     png_set_sig_bytes(png, MAGIC_SIZE);
3154
3155     png_read_info(png, info);
3156
3157     if(png_get_IHDR(png, info, &width, &height,
3158                     &bit_depth, &color_type, &interlace_type,
3159                     &compression_type, &filter_type) == 0)
3160         goto fin;
3161
3162     /* png_set_expand():
3163  * expand paletted images to RGB, expand grayscale images of
3164  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
3165  * to alpha channels.
3166 */
3167     if(color_type == PNG_COLOR_TYPE_PALETTE)
3168         png_set_expand(png);
3169     else
3170         if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
3171             png_set_expand(png);
3172
3173     if(png_get_valid(png, info, PNG_INFO_tRNS))
3174         png_set_expand(png);
3175
3176     is16 = (bit_depth == 16);
3177
3178     /* GRAY => RGB; GRAY_ALPHA => RGBA
3179 */
3180     if(color_type == PNG_COLOR_TYPE_GRAY
3181             || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3182     {
3183         png_set_gray_to_rgb(png);
3184         color_type =
3185                 (color_type == PNG_COLOR_TYPE_GRAY? PNG_COLOR_TYPE_RGB:
3186                                                     PNG_COLOR_TYPE_RGB_ALPHA);
3187     }
3188     if( !png_get_gAMA(png, info, &gamma))
3189         gamma = 0.45455;
3190
3191     png_set_gamma(png, display_exponent, gamma);
3192
3193     png_read_update_info(png, info);
3194
3195     png_get_pHYs(png, info, &resx, &resy, &unit);
3196
3197     color_type = png_get_color_type(png, info);
3198
3199     has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA);
3200
3201     nr_comp = 3 + has_alpha;
3202
3203     bit_depth = png_get_bit_depth(png, info);
3204
3205     rows = (unsigned char**)calloc(height+1, sizeof(unsigned char*));
3206     for(i = 0; i < height; ++i)
3207         rows[i] = (unsigned char*)malloc(png_get_rowbytes(png,info));
3208
3209     png_read_image(png, rows);
3210
3211     memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
3212
3213     sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy;
3214
3215     for(i = 0; i < nr_comp; ++i)
3216     {
3217         cmptparm[i].prec = bit_depth;
3218         /* bits_per_pixel: 8 or 16 */
3219         cmptparm[i].bpp = bit_depth;
3220         cmptparm[i].sgnd = 0;
3221         cmptparm[i].dx = sub_dx;
3222         cmptparm[i].dy = sub_dy;
3223         cmptparm[i].w = width;
3224         cmptparm[i].h = height;
3225     }
3226
3227     image = opj_image_create(nr_comp, &cmptparm[0], OPJ_CLRSPC_SRGB);
3228
3229     if(image == NULL) goto fin;
3230
3231     image->x0 = params->image_offset_x0;
3232     image->y0 = params->image_offset_y0;
3233     image->x1 = image->x0 + (width  - 1) * sub_dx + 1 + image->x0;
3234     image->y1 = image->y0 + (height - 1) * sub_dy + 1 + image->y0;
3235
3236     r = image->comps[0].data;
3237     g = image->comps[1].data;
3238     b = image->comps[2].data;
3239     a = image->comps[3].data;
3240
3241     for(i = 0; i < height; ++i)
3242     {
3243         s = rows[i];
3244
3245         for(j = 0; j < width; ++j)
3246         {
3247             if(is16)
3248             {
3249                 *r++ = s[0]<<8|s[1]; s += 2;
3250
3251                 *g++ = s[0]<<8|s[1]; s += 2;
3252
3253                 *b++ = s[0]<<8|s[1]; s += 2;
3254
3255                 if(has_alpha) { *a++ = s[0]<<8|s[1]; s += 2; }
3256
3257                 continue;
3258             }
3259             *r++ = *s++; *g++ = *s++; *b++ = *s++;
3260
3261             if(has_alpha) *a++ = *s++;
3262         }
3263     }
3264 fin:
3265     if(rows)
3266     {
3267         for(i = 0; i < height; ++i)
3268             free(rows[i]);
3269         free(rows);
3270     }
3271     if(png)
3272         png_destroy_read_struct(&png, &info, NULL);
3273
3274     fclose(reader);
3275
3276     return image;
3277
3278 }/* pngtoimage() */
3279
3280 int imagetopng(opj_image_t * image, const char *write_idf)
3281 {
3282     FILE *writer;
3283     png_structp png;
3284     png_infop info;
3285     int *red, *green, *blue, *alpha;
3286     unsigned char *row_buf, *d;
3287     int has_alpha, width, height, nr_comp, color_type;
3288     int adjustR, adjustG, adjustB, adjustA, x, y, fails;
3289     int prec, ushift, dshift, is16, force16, force8;
3290     unsigned short mask = 0xffff;
3291     png_color_8 sig_bit;
3292
3293     is16 = force16 = force8 = ushift = dshift = 0; fails = 1;
3294     prec = image->comps[0].prec;
3295     nr_comp = image->numcomps;
3296
3297     if(prec > 8 && prec < 16)
3298     {
3299         ushift = 16 - prec; dshift = prec - ushift;
3300         prec = 16; force16 = 1;
3301     }
3302     else
3303         if(prec < 8 && nr_comp > 1)/* GRAY_ALPHA, RGB, RGB_ALPHA */
3304         {
3305             ushift = 8 - prec; dshift = 8 - ushift;
3306             prec = 8; force8 = 1;
3307         }
3308
3309     if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16)
3310     {
3311         fprintf(stderr,"imagetopng: can not create %s"
3312                 "\n\twrong bit_depth %d\n", write_idf, prec);
3313         return fails;
3314     }
3315     writer = fopen(write_idf, "wb");
3316
3317     if(writer == NULL) return fails;
3318
3319     info = NULL; has_alpha = 0;
3320
3321     /* Create and initialize the png_struct with the desired error handler
3322  * functions.  If you want to use the default stderr and longjump method,
3323  * you can supply NULL for the last three parameters.  We also check that
3324  * the library version is compatible with the one used at compile time,
3325  * in case we are using dynamically linked libraries.  REQUIRED.
3326 */
3327     png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
3328                                   NULL, NULL, NULL);
3329     /*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */
3330
3331     if(png == NULL) goto fin;
3332
3333     /* Allocate/initialize the image information data.  REQUIRED
3334 */
3335     info = png_create_info_struct(png);
3336
3337     if(info == NULL) goto fin;
3338
3339     /* Set error handling.  REQUIRED if you are not supplying your own
3340  * error handling functions in the png_create_write_struct() call.
3341 */
3342     if(setjmp(png_jmpbuf(png))) goto fin;
3343
3344     /* I/O initialization functions is REQUIRED
3345 */
3346     png_init_io(png, writer);
3347
3348     /* Set the image information here.  Width and height are up to 2^31,
3349  * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
3350  * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
3351  * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
3352  * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
3353  * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
3354  * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE.
3355  * REQUIRED
3356  *
3357  * ERRORS:
3358  *
3359  * color_type == PNG_COLOR_TYPE_PALETTE && bit_depth > 8
3360  * color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8
3361  * color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8
3362  * color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8
3363  *
3364 */
3365     png_set_compression_level(png, Z_BEST_COMPRESSION);
3366
3367     if(prec == 16) mask = 0xffff;
3368     else
3369         if(prec == 8) mask = 0x00ff;
3370         else
3371             if(prec == 4) mask = 0x000f;
3372             else
3373                 if(prec == 2) mask = 0x0003;
3374                 else
3375                     if(prec == 1) mask = 0x0001;
3376
3377     if(nr_comp >= 3
3378             && image->comps[0].dx == image->comps[1].dx
3379             && image->comps[1].dx == image->comps[2].dx
3380             && image->comps[0].dy == image->comps[1].dy
3381             && image->comps[1].dy == image->comps[2].dy
3382             && image->comps[0].prec == image->comps[1].prec
3383             && image->comps[1].prec == image->comps[2].prec)
3384     {
3385         int v;
3386
3387         has_alpha = (nr_comp > 3);
3388
3389         is16 = (prec == 16);
3390
3391         width = image->comps[0].w;
3392         height = image->comps[0].h;
3393
3394         red = image->comps[0].data;
3395         green = image->comps[1].data;
3396         blue = image->comps[2].data;
3397
3398         sig_bit.red = sig_bit.green = sig_bit.blue = prec;
3399
3400         if(has_alpha)
3401         {
3402             sig_bit.alpha = prec;
3403             alpha = image->comps[3].data;
3404             color_type = PNG_COLOR_TYPE_RGB_ALPHA;
3405             adjustA = (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
3406         }
3407         else
3408         {
3409             sig_bit.alpha = 0; alpha = NULL;
3410             color_type = PNG_COLOR_TYPE_RGB;
3411             adjustA = 0;
3412         }
3413         png_set_sBIT(png, info, &sig_bit);
3414
3415         png_set_IHDR(png, info, width, height, prec,
3416                      color_type,
3417                      PNG_INTERLACE_NONE,
3418                      PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
3419
3420         png_set_gamma(png, 2.2, 1./2.2);
3421         png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL);
3422         /*=============================*/
3423         png_write_info(png, info);
3424         /*=============================*/
3425         if(prec < 8)
3426         {
3427             png_set_packing(png);
3428         }
3429         adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
3430         adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
3431         adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
3432
3433         row_buf = (unsigned char*)malloc(width * nr_comp * 2);
3434
3435         for(y = 0; y < height; ++y)
3436         {
3437             d = row_buf;
3438
3439             for(x = 0; x < width; ++x)
3440             {
3441                 if(is16)
3442                 {
3443                     v = *red + adjustR; ++red;
3444
3445                     if(force16) { v = (v<<ushift) + (v>>dshift); }
3446
3447                     *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
3448
3449                     v = *green + adjustG; ++green;
3450
3451                     if(force16) { v = (v<<ushift) + (v>>dshift); }
3452
3453                     *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
3454
3455                     v =  *blue + adjustB; ++blue;
3456
3457                     if(force16) { v = (v<<ushift) + (v>>dshift); }
3458
3459                     *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
3460
3461                     if(has_alpha)
3462                     {
3463                         v = *alpha + adjustA; ++alpha;
3464
3465                         if(force16) { v = (v<<ushift) + (v>>dshift); }
3466
3467                         *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
3468                     }
3469                     continue;
3470                 }/* if(is16) */
3471
3472                 v = *red + adjustR; ++red;
3473
3474                 if(force8) { v = (v<<ushift) + (v>>dshift); }
3475
3476                 *d++ = (unsigned char)(v & mask);
3477
3478                 v = *green + adjustG; ++green;
3479
3480                 if(force8) { v = (v<<ushift) + (v>>dshift); }
3481
3482                 *d++ = (unsigned char)(v & mask);
3483
3484                 v = *blue + adjustB; ++blue;
3485
3486                 if(force8) { v = (v<<ushift) + (v>>dshift); }
3487
3488                 *d++ = (unsigned char)(v & mask);
3489
3490                 if(has_alpha)
3491                 {
3492                     v = *alpha + adjustA; ++alpha;
3493
3494                     if(force8) { v = (v<<ushift) + (v>>dshift); }
3495
3496                     *d++ = (unsigned char)(v & mask);
3497                 }
3498             }   /* for(x) */
3499
3500             png_write_row(png, row_buf);
3501
3502         }       /* for(y) */
3503         free(row_buf);
3504
3505     }/* nr_comp >= 3 */
3506     else
3507         if(nr_comp == 1 /* GRAY */
3508                 || (   nr_comp == 2 /* GRAY_ALPHA */
3509                        && image->comps[0].dx == image->comps[1].dx
3510                        && image->comps[0].dy == image->comps[1].dy
3511                        && image->comps[0].prec == image->comps[1].prec))
3512         {
3513             int v;
3514
3515             red = image->comps[0].data;
3516
3517             sig_bit.gray = prec;
3518             sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0;
3519             alpha = NULL; adjustA = 0;
3520             color_type = PNG_COLOR_TYPE_GRAY;
3521
3522             if(nr_comp == 2)
3523             {
3524                 has_alpha = 1; sig_bit.alpha = prec;
3525                 alpha = image->comps[1].data;
3526                 color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3527                 adjustA = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
3528             }
3529             width = image->comps[0].w;
3530             height = image->comps[0].h;
3531
3532             png_set_IHDR(png, info, width, height, sig_bit.gray,
3533                          color_type,
3534                          PNG_INTERLACE_NONE,
3535                          PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
3536
3537             png_set_sBIT(png, info, &sig_bit);
3538
3539             png_set_gamma(png, 2.2, 1./2.2);
3540             png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL);
3541             /*=============================*/
3542             png_write_info(png, info);
3543             /*=============================*/
3544             adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
3545
3546             if(prec < 8)
3547             {
3548                 png_set_packing(png);
3549             }
3550
3551             if(prec > 8)
3552             {
3553                 row_buf = (unsigned char*)
3554                         malloc(width * nr_comp * sizeof(unsigned short));
3555
3556                 for(y = 0; y < height; ++y)
3557                 {
3558                     d = row_buf;
3559
3560                     for(x = 0; x < width; ++x)
3561                     {
3562                         v = *red + adjustR; ++red;
3563
3564                         if(force16) { v = (v<<ushift) + (v>>dshift); }
3565
3566                         *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
3567
3568                         if(has_alpha)
3569                         {
3570                             v = *alpha++;
3571
3572                             if(force16) { v = (v<<ushift) + (v>>dshift); }
3573
3574                             *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
3575                         }
3576                     }/* for(x) */
3577                     png_write_row(png, row_buf);
3578
3579                 }       /* for(y) */
3580                 free(row_buf);
3581             }
3582             else /* prec <= 8 */
3583             {
3584                 row_buf = (unsigned char*)calloc(width, nr_comp * 2);
3585
3586                 for(y = 0; y < height; ++y)
3587                 {
3588                     d = row_buf;
3589
3590                     for(x = 0; x < width; ++x)
3591                     {
3592                         v = *red + adjustR; ++red;
3593
3594                         if(force8) { v = (v<<ushift) + (v>>dshift); }
3595
3596                         *d++ = (unsigned char)(v & mask);
3597
3598                         if(has_alpha)
3599                         {
3600                             v = *alpha + adjustA; ++alpha;
3601
3602                             if(force8) { v = (v<<ushift) + (v>>dshift); }
3603
3604                             *d++ = (unsigned char)(v & mask);
3605                         }
3606                     }/* for(x) */
3607
3608                     png_write_row(png, row_buf);
3609
3610                 }       /* for(y) */
3611                 free(row_buf);
3612             }
3613         }
3614         else
3615         {
3616             fprintf(stderr,"imagetopng: can not create %s\n",write_idf);
3617             goto fin;
3618         }
3619     png_write_end(png, info);
3620
3621     fails = 0;
3622
3623 fin:
3624
3625     if(png)
3626     {
3627         png_destroy_write_struct(&png, &info);
3628     }
3629     fclose(writer);
3630
3631     if(fails) remove(write_idf);
3632
3633     return fails;
3634 }/* imagetopng() */
3635 #endif /* OPJ_HAVE_LIBPNG */