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