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