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