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