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