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