8650ae9c406396f2d492a07f695394fccb134617
[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                     return 1;
1528                 }
1529             }
1530         }
1531         fclose(fdest);
1532     }
1533
1534     return 0;
1535 }
1536
1537 /* -->> -->> -->> -->>
1538
1539 PNM IMAGE FORMAT
1540
1541 <<-- <<-- <<-- <<-- */
1542
1543 struct pnm_header {
1544     int width, height, maxval, depth, format;
1545     char rgb, rgba, gray, graya, bw;
1546     char ok;
1547 };
1548
1549 static char *skip_white(char *s)
1550 {
1551     while (*s) {
1552         if (*s == '\n' || *s == '\r') {
1553             return NULL;
1554         }
1555         if (isspace(*s)) {
1556             ++s;
1557             continue;
1558         }
1559         return s;
1560     }
1561     return NULL;
1562 }
1563
1564 static char *skip_int(char *start, int *out_n)
1565 {
1566     char *s;
1567     char c;
1568
1569     *out_n = 0;
1570     s = start;
1571
1572     s = skip_white(start);
1573     if (s == NULL) {
1574         return NULL;
1575     }
1576     start = s;
1577
1578     while (*s) {
1579         if (!isdigit(*s)) {
1580             break;
1581         }
1582         ++s;
1583     }
1584     c = *s;
1585     *s = 0;
1586     *out_n = atoi(start);
1587     *s = c;
1588     return s;
1589 }
1590
1591 static char *skip_idf(char *start, char out_idf[256])
1592 {
1593     char *s;
1594     char c;
1595
1596     s = skip_white(start);
1597     if (s == NULL) {
1598         return NULL;
1599     }
1600     start = s;
1601
1602     while (*s) {
1603         if (isalpha(*s) || *s == '_') {
1604             ++s;
1605             continue;
1606         }
1607         break;
1608     }
1609     c = *s;
1610     *s = 0;
1611     strncpy(out_idf, start, 255);
1612     *s = c;
1613     return s;
1614 }
1615
1616 static void read_pnm_header(FILE *reader, struct pnm_header *ph)
1617 {
1618     char *s;
1619     int format, have_wh, end, ttype;
1620     char idf[256], type[256];
1621     char line[256];
1622
1623     if (fgets(line, 250, reader) == NULL) {
1624         fprintf(stderr, "\nWARNING: fgets return a NULL value");
1625         return;
1626     }
1627
1628     if (line[0] != 'P') {
1629         fprintf(stderr, "read_pnm_header:PNM:magic P missing\n");
1630         return;
1631     }
1632     format = atoi(line + 1);
1633     if (format < 1 || format > 7) {
1634         fprintf(stderr, "read_pnm_header:magic format %d invalid\n", format);
1635         return;
1636     }
1637     ph->format = format;
1638     ttype = end = have_wh = 0;
1639
1640     while (fgets(line, 250, reader)) {
1641         if (*line == '#') {
1642             continue;
1643         }
1644
1645         s = line;
1646
1647         if (format == 7) {
1648             s = skip_idf(s, idf);
1649
1650             if (s == NULL || *s == 0) {
1651                 return;
1652             }
1653
1654             if (strcmp(idf, "ENDHDR") == 0) {
1655                 end = 1;
1656                 break;
1657             }
1658             if (strcmp(idf, "WIDTH") == 0) {
1659                 s = skip_int(s, &ph->width);
1660                 if (s == NULL || *s == 0) {
1661                     return;
1662                 }
1663
1664                 continue;
1665             }
1666             if (strcmp(idf, "HEIGHT") == 0) {
1667                 s = skip_int(s, &ph->height);
1668                 if (s == NULL || *s == 0) {
1669                     return;
1670                 }
1671
1672                 continue;
1673             }
1674             if (strcmp(idf, "DEPTH") == 0) {
1675                 s = skip_int(s, &ph->depth);
1676                 if (s == NULL || *s == 0) {
1677                     return;
1678                 }
1679
1680                 continue;
1681             }
1682             if (strcmp(idf, "MAXVAL") == 0) {
1683                 s = skip_int(s, &ph->maxval);
1684                 if (s == NULL || *s == 0) {
1685                     return;
1686                 }
1687
1688                 continue;
1689             }
1690             if (strcmp(idf, "TUPLTYPE") == 0) {
1691                 s = skip_idf(s, type);
1692                 if (s == NULL || *s == 0) {
1693                     return;
1694                 }
1695
1696                 if (strcmp(type, "BLACKANDWHITE") == 0) {
1697                     ph->bw = 1;
1698                     ttype = 1;
1699                     continue;
1700                 }
1701                 if (strcmp(type, "GRAYSCALE") == 0) {
1702                     ph->gray = 1;
1703                     ttype = 1;
1704                     continue;
1705                 }
1706                 if (strcmp(type, "GRAYSCALE_ALPHA") == 0) {
1707                     ph->graya = 1;
1708                     ttype = 1;
1709                     continue;
1710                 }
1711                 if (strcmp(type, "RGB") == 0) {
1712                     ph->rgb = 1;
1713                     ttype = 1;
1714                     continue;
1715                 }
1716                 if (strcmp(type, "RGB_ALPHA") == 0) {
1717                     ph->rgba = 1;
1718                     ttype = 1;
1719                     continue;
1720                 }
1721                 fprintf(stderr, "read_pnm_header:unknown P7 TUPLTYPE %s\n", type);
1722                 return;
1723             }
1724             fprintf(stderr, "read_pnm_header:unknown P7 idf %s\n", idf);
1725             return;
1726         } /* if(format == 7) */
1727
1728         if (!have_wh) {
1729             s = skip_int(s, &ph->width);
1730
1731             s = skip_int(s, &ph->height);
1732
1733             have_wh = 1;
1734
1735             if (format == 1 || format == 4) {
1736                 break;
1737             }
1738
1739             continue;
1740         }
1741         if (format == 2 || format == 3 || format == 5 || format == 6) {
1742             /* P2, P3, P5, P6: */
1743             s = skip_int(s, &ph->maxval);
1744
1745             if (ph->maxval > 65535) {
1746                 return;
1747             }
1748         }
1749         break;
1750     }/* while(fgets( ) */
1751     if (format == 2 || format == 3 || format > 4) {
1752         if (ph->maxval < 1 || ph->maxval > 65535) {
1753             return;
1754         }
1755     }
1756     if (ph->width < 1 || ph->height < 1) {
1757         return;
1758     }
1759
1760     if (format == 7) {
1761         if (!end) {
1762             fprintf(stderr, "read_pnm_header:P7 without ENDHDR\n");
1763             return;
1764         }
1765         if (ph->depth < 1 || ph->depth > 4) {
1766             return;
1767         }
1768
1769         if (ph->width && ph->height && ph->depth & ph->maxval && ttype) {
1770             ph->ok = 1;
1771         }
1772     } else {
1773         if (format != 1 && format != 4) {
1774             if (ph->width && ph->height && ph->maxval) {
1775                 ph->ok = 1;
1776             }
1777         } else {
1778             if (ph->width && ph->height) {
1779                 ph->ok = 1;
1780             }
1781             ph->maxval = 255;
1782         }
1783     }
1784 }
1785
1786 static int has_prec(int val)
1787 {
1788     if (val < 2) {
1789         return 1;
1790     }
1791     if (val < 4) {
1792         return 2;
1793     }
1794     if (val < 8) {
1795         return 3;
1796     }
1797     if (val < 16) {
1798         return 4;
1799     }
1800     if (val < 32) {
1801         return 5;
1802     }
1803     if (val < 64) {
1804         return 6;
1805     }
1806     if (val < 128) {
1807         return 7;
1808     }
1809     if (val < 256) {
1810         return 8;
1811     }
1812     if (val < 512) {
1813         return 9;
1814     }
1815     if (val < 1024) {
1816         return 10;
1817     }
1818     if (val < 2048) {
1819         return 11;
1820     }
1821     if (val < 4096) {
1822         return 12;
1823     }
1824     if (val < 8192) {
1825         return 13;
1826     }
1827     if (val < 16384) {
1828         return 14;
1829     }
1830     if (val < 32768) {
1831         return 15;
1832     }
1833     return 16;
1834 }
1835
1836 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters)
1837 {
1838     int subsampling_dx = parameters->subsampling_dx;
1839     int subsampling_dy = parameters->subsampling_dy;
1840
1841     FILE *fp = NULL;
1842     int i, compno, numcomps, w, h, prec, format;
1843     OPJ_COLOR_SPACE color_space;
1844     opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */
1845     opj_image_t * image = NULL;
1846     struct pnm_header header_info;
1847
1848     if ((fp = fopen(filename, "rb")) == NULL) {
1849         fprintf(stderr, "pnmtoimage:Failed to open %s for reading!\n", filename);
1850         return NULL;
1851     }
1852     memset(&header_info, 0, sizeof(struct pnm_header));
1853
1854     read_pnm_header(fp, &header_info);
1855
1856     if (!header_info.ok) {
1857         fclose(fp);
1858         return NULL;
1859     }
1860
1861     format = header_info.format;
1862
1863     switch (format) {
1864     case 1: /* ascii bitmap */
1865     case 4: /* raw bitmap */
1866         numcomps = 1;
1867         break;
1868
1869     case 2: /* ascii greymap */
1870     case 5: /* raw greymap */
1871         numcomps = 1;
1872         break;
1873
1874     case 3: /* ascii pixmap */
1875     case 6: /* raw pixmap */
1876         numcomps = 3;
1877         break;
1878
1879     case 7: /* arbitrary map */
1880         numcomps = header_info.depth;
1881         break;
1882
1883     default:
1884         fclose(fp);
1885         return NULL;
1886     }
1887     if (numcomps < 3) {
1888         color_space = CLRSPC_GRAY;    /* GRAY, GRAYA */
1889     } else {
1890         color_space = CLRSPC_SRGB;    /* RGB, RGBA */
1891     }
1892
1893     prec = has_prec(header_info.maxval);
1894
1895     if (prec < 8) {
1896         prec = 8;
1897     }
1898
1899     w = header_info.width;
1900     h = header_info.height;
1901     subsampling_dx = parameters->subsampling_dx;
1902     subsampling_dy = parameters->subsampling_dy;
1903
1904     memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
1905
1906     for (i = 0; i < numcomps; i++) {
1907         cmptparm[i].prec = prec;
1908         cmptparm[i].bpp = prec;
1909         cmptparm[i].sgnd = 0;
1910         cmptparm[i].dx = subsampling_dx;
1911         cmptparm[i].dy = subsampling_dy;
1912         cmptparm[i].w = w;
1913         cmptparm[i].h = h;
1914     }
1915     image = opj_image_create(numcomps, &cmptparm[0], color_space);
1916
1917     if (!image) {
1918         fclose(fp);
1919         return NULL;
1920     }
1921
1922     /* set image offset and reference grid */
1923     image->x0 = parameters->image_offset_x0;
1924     image->y0 = parameters->image_offset_y0;
1925     image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
1926     image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
1927
1928     if ((format == 2) || (format == 3)) { /* ascii pixmap */
1929         unsigned int index;
1930
1931         for (i = 0; i < w * h; i++) {
1932             for (compno = 0; compno < numcomps; compno++) {
1933                 index = 0;
1934                 if (fscanf(fp, "%u", &index) != 1) {
1935                     fprintf(stderr,
1936                             "\nWARNING: fscanf return a number of element different from the expected.\n");
1937                 }
1938
1939                 image->comps[compno].data[i] = (index * 255) / header_info.maxval;
1940             }
1941         }
1942     } else if ((format == 5)
1943                || (format == 6)
1944                || ((format == 7)
1945                    && (header_info.gray || header_info.graya
1946                        || header_info.rgb || header_info.rgba))) { /* binary pixmap */
1947         unsigned char c0, c1, one;
1948
1949         one = (prec < 9);
1950
1951         for (i = 0; i < w * h; i++) {
1952             for (compno = 0; compno < numcomps; compno++) {
1953                 if (!fread(&c0, 1, 1, fp)) {
1954                     fprintf(stderr,
1955                             "\nError: fread return a number of element different from the expected.\n");
1956                 }
1957                 if (one) {
1958                     image->comps[compno].data[i] = c0;
1959                 } else {
1960                     if (!fread(&c1, 1, 1, fp)) {
1961                         fprintf(stderr,
1962                                 "\nError: fread return a number of element different from the expected.\n");
1963                     }
1964                     /* netpbm: */
1965                     image->comps[compno].data[i] = ((c0 << 8) | c1);
1966                 }
1967             }
1968         }
1969     } else if (format == 1) { /* ascii bitmap */
1970         for (i = 0; i < w * h; i++) {
1971             unsigned int index;
1972
1973             if (fscanf(fp, "%u", &index) != 1) {
1974                 fprintf(stderr,
1975                         "\nWARNING: fscanf return a number of element different from the expected.\n");
1976             }
1977
1978             image->comps[0].data[i] = (index ? 0 : 255);
1979         }
1980     } else if (format == 4) {
1981         int x, y, bit;
1982         unsigned char uc;
1983
1984         i = 0;
1985         for (y = 0; y < h; ++y) {
1986             bit = -1;
1987             uc = 0;
1988
1989             for (x = 0; x < w; ++x) {
1990                 if (bit == -1) {
1991                     bit = 7;
1992                     uc = (unsigned char)getc(fp);
1993                 }
1994                 image->comps[0].data[i] = (((uc >> bit) & 1) ? 0 : 255);
1995                 --bit;
1996                 ++i;
1997             }
1998         }
1999     } else if ((format == 7 && header_info.bw)) { /*MONO*/
2000         unsigned char uc;
2001
2002         for (i = 0; i < w * h; ++i) {
2003             if (!fread(&uc, 1, 1, fp)) {
2004                 fprintf(stderr,
2005                         "\nError: fread return a number of element different from the expected.\n");
2006             }
2007             image->comps[0].data[i] = (uc & 1) ? 0 : 255;
2008         }
2009     }
2010     fclose(fp);
2011
2012     return image;
2013 }/* pnmtoimage() */
2014
2015 int imagetopnm(opj_image_t * image, const char *outfile)
2016 {
2017     int *red, *green, *blue, *alpha;
2018     int wr, hr, max;
2019     int i, compno, ncomp;
2020     int adjustR, adjustG, adjustB, adjustA;
2021     int fails, two, want_gray, has_alpha, triple;
2022     int prec, v;
2023     FILE *fdest = NULL;
2024     const char *tmp = outfile;
2025     char *destname;
2026     alpha = NULL;
2027     if ((prec = image->comps[0].prec) > 16) {
2028         fprintf(stderr, "%s:%d:imagetopnm\n\tprecision %d is larger than 16"
2029                 "\n\t: refused.\n", __FILE__, __LINE__, prec);
2030         return 1;
2031     }
2032     two = has_alpha = 0;
2033     fails = 1;
2034     ncomp = image->numcomps;
2035
2036     while (*tmp) {
2037         ++tmp;
2038     }
2039     tmp -= 2;
2040     want_gray = (*tmp == 'g' || *tmp == 'G');
2041     ncomp = image->numcomps;
2042
2043     if (want_gray) {
2044         ncomp = 1;
2045     }
2046
2047     if (ncomp == 2 /* GRAYA */
2048             || (ncomp > 2 /* RGB, RGBA */
2049                 && image->comps[0].dx == image->comps[1].dx
2050                 && image->comps[1].dx == image->comps[2].dx
2051                 && image->comps[0].dy == image->comps[1].dy
2052                 && image->comps[1].dy == image->comps[2].dy
2053                 && image->comps[0].prec == image->comps[1].prec
2054                 && image->comps[1].prec == image->comps[2].prec
2055                )) {
2056         fdest = fopen(outfile, "wb");
2057
2058         if (!fdest) {
2059             fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
2060             return fails;
2061         }
2062         two = (prec > 8);
2063         triple = (ncomp > 2);
2064         wr = image->comps[0].w;
2065         hr = image->comps[0].h;
2066         max = (1 << prec) - 1;
2067         has_alpha = (ncomp == 4 || ncomp == 2);
2068
2069         red = image->comps[0].data;
2070
2071         if (triple) {
2072             green = image->comps[1].data;
2073             blue = image->comps[2].data;
2074         } else {
2075             green = blue = NULL;
2076         }
2077
2078         if (has_alpha) {
2079             const char *tt = (triple ? "RGB_ALPHA" : "GRAYSCALE_ALPHA");
2080
2081             fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %d\n"
2082                     "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", opj_version(),
2083                     wr, hr, ncomp, max, tt);
2084             alpha = image->comps[ncomp - 1].data;
2085             adjustA = (image->comps[ncomp - 1].sgnd ?
2086                        1 << (image->comps[ncomp - 1].prec - 1) : 0);
2087         } else {
2088             fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n",
2089                     opj_version(), wr, hr, max);
2090             adjustA = 0;
2091         }
2092         adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
2093
2094         if (triple) {
2095             adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
2096             adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
2097         } else {
2098             adjustG = adjustB = 0;
2099         }
2100
2101         for (i = 0; i < wr * hr; ++i) {
2102             if (two) {
2103                 v = *red + adjustR;
2104                 ++red;
2105                 /* netpbm: */
2106                 fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v);
2107
2108                 if (triple) {
2109                     v = *green + adjustG;
2110                     ++green;
2111                     /* netpbm: */
2112                     fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v);
2113
2114                     v =  *blue + adjustB;
2115                     ++blue;
2116                     /* netpbm: */
2117                     fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v);
2118
2119                 }/* if(triple) */
2120
2121                 if (has_alpha) {
2122                     v = *alpha + adjustA;
2123                     ++alpha;
2124                     /* netpbm: */
2125                     fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v);
2126                 }
2127                 continue;
2128
2129             }  /* if(two) */
2130
2131             /* prec <= 8: */
2132
2133             fprintf(fdest, "%c", (unsigned char)*red++);
2134             if (triple) {
2135                 fprintf(fdest, "%c%c", (unsigned char)*green++, (unsigned char)*blue++);
2136             }
2137
2138             if (has_alpha) {
2139                 fprintf(fdest, "%c", (unsigned char)*alpha++);
2140             }
2141
2142         } /* for(i */
2143
2144         fclose(fdest);
2145         return 0;
2146     }
2147
2148     /* YUV or MONO: */
2149
2150     if (image->numcomps > ncomp) {
2151         fprintf(stderr, "WARNING -> [PGM file] Only the first component\n");
2152         fprintf(stderr, "           is written to the file\n");
2153     }
2154     destname = (char*)malloc(strlen(outfile) + 8);
2155
2156     for (compno = 0; compno < ncomp; compno++) {
2157         if (ncomp > 1) {
2158             sprintf(destname, "%d.%s", compno, outfile);
2159         } else {
2160             sprintf(destname, "%s", outfile);
2161         }
2162
2163         fdest = fopen(destname, "wb");
2164         if (!fdest) {
2165             fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname);
2166             free(destname);
2167             return 1;
2168         }
2169         wr = image->comps[compno].w;
2170         hr = image->comps[compno].h;
2171         prec = image->comps[compno].prec;
2172         max = (1 << prec) - 1;
2173
2174         fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n",
2175                 opj_version(), wr, hr, max);
2176
2177         red = image->comps[compno].data;
2178         adjustR =
2179             (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
2180
2181         if (prec > 8) {
2182             for (i = 0; i < wr * hr; i++) {
2183                 v = *red + adjustR;
2184                 ++red;
2185                 /* netpbm: */
2186                 fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v);
2187
2188                 if (has_alpha) {
2189                     v = *alpha++;
2190                     /* netpbm: */
2191                     fprintf(fdest, "%c%c", (unsigned char)(v >> 8), (unsigned char)v);
2192                 }
2193             }/* for(i */
2194         } else { /* prec <= 8 */
2195             for (i = 0; i < wr * hr; ++i) {
2196                 fprintf(fdest, "%c", (unsigned char)(*red + adjustR));
2197                 ++red;
2198             }
2199         }
2200         fclose(fdest);
2201     } /* for (compno */
2202     free(destname);
2203
2204     return 0;
2205 }/* imagetopnm() */
2206
2207 #ifdef OPJ_HAVE_LIBTIFF
2208 /* -->> -->> -->> -->>
2209
2210     TIFF IMAGE FORMAT
2211
2212  <<-- <<-- <<-- <<-- */
2213
2214 int imagetotif(opj_image_t * image, const char *outfile)
2215 {
2216     int width, height, imgsize;
2217     int bps, index, adjust, sgnd;
2218     int ushift, dshift, has_alpha, force16;
2219     TIFF *tif;
2220     tdata_t buf;
2221     tstrip_t strip;
2222     tsize_t strip_size;
2223
2224     ushift = dshift = force16 = has_alpha = 0;
2225     bps = image->comps[0].prec;
2226
2227     if (bps > 8 && bps < 16) {
2228         ushift = 16 - bps;
2229         dshift = bps - ushift;
2230         bps = 16;
2231         force16 = 1;
2232     }
2233
2234     if (bps != 8 && bps != 16) {
2235         fprintf(stderr, "imagetotif: Bits=%d, Only 8 and 16 bits implemented\n",
2236                 bps);
2237         fprintf(stderr, "\tAborting\n");
2238         return 1;
2239     }
2240     tif = TIFFOpen(outfile, "wb");
2241
2242     if (!tif) {
2243         fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile);
2244         return 1;
2245     }
2246     sgnd = image->comps[0].sgnd;
2247     adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0;
2248
2249     if (image->numcomps >= 3
2250             && image->comps[0].dx == image->comps[1].dx
2251             && image->comps[1].dx == image->comps[2].dx
2252             && image->comps[0].dy == image->comps[1].dy
2253             && image->comps[1].dy == image->comps[2].dy
2254             && image->comps[0].prec == image->comps[1].prec
2255             && image->comps[1].prec == image->comps[2].prec) {
2256         has_alpha = (image->numcomps == 4);
2257
2258         width   = image->comps[0].w;
2259         height  = image->comps[0].h;
2260         imgsize = width * height ;
2261
2262         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
2263         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
2264         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3 + has_alpha);
2265         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
2266         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
2267         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
2268         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
2269         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
2270         strip_size = TIFFStripSize(tif);
2271         buf = _TIFFmalloc(strip_size);
2272         index = 0;
2273
2274         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
2275             unsigned char *dat8;
2276             tsize_t i, ssize, last_i = 0;
2277             int step, restx;
2278             ssize = TIFFStripSize(tif);
2279             dat8 = (unsigned char*)buf;
2280
2281             if (bps == 8) {
2282                 step = 3 + has_alpha;
2283                 restx = step - 1;
2284
2285                 for (i = 0; i < ssize - restx; i += step) {
2286                     int r, g, b, a = 0;
2287
2288                     if (index < imgsize) {
2289                         r = image->comps[0].data[index];
2290                         g = image->comps[1].data[index];
2291                         b = image->comps[2].data[index];
2292                         if (has_alpha) {
2293                             a = image->comps[3].data[index];
2294                         }
2295
2296                         if (sgnd) {
2297                             r += adjust;
2298                             g += adjust;
2299                             b += adjust;
2300                             if (has_alpha) {
2301                                 a += adjust;
2302                             }
2303                         }
2304                         dat8[i + 0] = r ;
2305                         dat8[i + 1] = g ;
2306                         dat8[i + 2] = b ;
2307                         if (has_alpha) {
2308                             dat8[i + 3] = a;
2309                         }
2310
2311                         index++;
2312                         last_i = i + step;
2313                     } else {
2314                         break;
2315                     }
2316                 }/*for(i = 0;)*/
2317
2318                 if (last_i < ssize) {
2319                     for (i = last_i; i < ssize; i += step) {
2320                         int r, g, b, a = 0;
2321
2322                         if (index < imgsize) {
2323                             r = image->comps[0].data[index];
2324                             g = image->comps[1].data[index];
2325                             b = image->comps[2].data[index];
2326                             if (has_alpha) {
2327                                 a = image->comps[3].data[index];
2328                             }
2329
2330                             if (sgnd) {
2331                                 r += adjust;
2332                                 g += adjust;
2333                                 b += adjust;
2334                                 if (has_alpha) {
2335                                     a += adjust;
2336                                 }
2337                             }
2338                             dat8[i + 0] = r ;
2339                             if (i + 1 < ssize) {
2340                                 dat8[i + 1] = g ;
2341                             }  else {
2342                                 break;
2343                             }
2344                             if (i + 2 < ssize) {
2345                                 dat8[i + 2] = b ;
2346                             }  else {
2347                                 break;
2348                             }
2349                             if (has_alpha) {
2350                                 if (i + 3 < ssize) {
2351                                     dat8[i + 3] = a ;
2352                                 }  else {
2353                                     break;
2354                                 }
2355                             }
2356                             index++;
2357                         } else {
2358                             break;
2359                         }
2360                     }/*for(i)*/
2361                 }/*if(last_i < ssize)*/
2362
2363             }  /*if(bps == 8)*/
2364             else if (bps == 16) {
2365                 step = 6 + has_alpha + has_alpha;
2366                 restx = step - 1;
2367
2368                 for (i = 0; i < ssize - restx ; i += step) {
2369                     int r, g, b, a = 0;
2370
2371                     if (index < imgsize) {
2372                         r = image->comps[0].data[index];
2373                         g = image->comps[1].data[index];
2374                         b = image->comps[2].data[index];
2375                         if (has_alpha) {
2376                             a = image->comps[3].data[index];
2377                         }
2378
2379                         if (sgnd) {
2380                             r += adjust;
2381                             g += adjust;
2382                             b += adjust;
2383                             if (has_alpha) {
2384                                 a += adjust;
2385                             }
2386                         }
2387                         if (force16) {
2388                             r = (r << ushift) + (r >> dshift);
2389                             g = (g << ushift) + (g >> dshift);
2390                             b = (b << ushift) + (b >> dshift);
2391                             if (has_alpha) {
2392                                 a = (a << ushift) + (a >> dshift);
2393                             }
2394                         }
2395                         dat8[i + 0] =  r; /*LSB*/
2396                         dat8[i + 1] = (r >> 8); /*MSB*/
2397                         dat8[i + 2] =  g;
2398                         dat8[i + 3] = (g >> 8);
2399                         dat8[i + 4] =  b;
2400                         dat8[i + 5] = (b >> 8);
2401                         if (has_alpha) {
2402                             dat8[i + 6] =  a;
2403                             dat8[i + 7] = (a >> 8);
2404                         }
2405                         index++;
2406                         last_i = i + step;
2407                     } else {
2408                         break;
2409                     }
2410                 }/*for(i = 0;)*/
2411
2412                 if (last_i < ssize) {
2413                     for (i = last_i ; i < ssize ; i += step) {
2414                         int r, g, b, a = 0;
2415
2416                         if (index < imgsize) {
2417                             r = image->comps[0].data[index];
2418                             g = image->comps[1].data[index];
2419                             b = image->comps[2].data[index];
2420                             if (has_alpha) {
2421                                 a = image->comps[3].data[index];
2422                             }
2423
2424                             if (sgnd) {
2425                                 r += adjust;
2426                                 g += adjust;
2427                                 b += adjust;
2428                                 if (has_alpha) {
2429                                     a += adjust;
2430                                 }
2431                             }
2432                             if (force16) {
2433                                 r = (r << ushift) + (r >> dshift);
2434                                 g = (g << ushift) + (g >> dshift);
2435                                 b = (b << ushift) + (b >> dshift);
2436                                 if (has_alpha) {
2437                                     a = (a << ushift) + (a >> dshift);
2438                                 }
2439                             }
2440                             dat8[i + 0] =  r; /*LSB*/
2441                             if (i + 1 < ssize) {
2442                                 dat8[i + 1] = (r >> 8);
2443                             } else {
2444                                 break;    /*MSB*/
2445                             }
2446                             if (i + 2 < ssize) {
2447                                 dat8[i + 2] =  g;
2448                             }      else {
2449                                 break;
2450                             }
2451                             if (i + 3 < ssize) {
2452                                 dat8[i + 3] = (g >> 8);
2453                             } else {
2454                                 break;
2455                             }
2456                             if (i + 4 < ssize) {
2457                                 dat8[i + 4] =  b;
2458                             }      else {
2459                                 break;
2460                             }
2461                             if (i + 5 < ssize) {
2462                                 dat8[i + 5] = (b >> 8);
2463                             } else {
2464                                 break;
2465                             }
2466
2467                             if (has_alpha) {
2468                                 if (i + 6 < ssize) {
2469                                     dat8[i + 6] = a;
2470                                 } else {
2471                                     break;
2472                                 }
2473                                 if (i + 7 < ssize) {
2474                                     dat8[i + 7] = (a >> 8);
2475                                 } else {
2476                                     break;
2477                                 }
2478                             }
2479                             index++;
2480                         } else {
2481                             break;
2482                         }
2483                     }/*for(i)*/
2484                 }/*if(last_i < ssize)*/
2485
2486             }/*if(bps == 16)*/
2487             (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
2488         }/*for(strip = 0; )*/
2489
2490         _TIFFfree((void*)buf);
2491         TIFFClose(tif);
2492
2493         return 0;
2494     }/*RGB(A)*/
2495
2496     if (image->numcomps == 1 /* GRAY */
2497             || (image->numcomps == 2    /* GRAY_ALPHA */
2498                 && image->comps[0].dx == image->comps[1].dx
2499                 && image->comps[0].dy == image->comps[1].dy
2500                 && image->comps[0].prec == image->comps[1].prec)) {
2501         int step;
2502
2503         has_alpha = (image->numcomps == 2);
2504
2505         width   = image->comps[0].w;
2506         height  = image->comps[0].h;
2507         imgsize = width * height;
2508
2509         /* Set tags */
2510         TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
2511         TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
2512         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1 + has_alpha);
2513         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
2514         TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
2515         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
2516         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
2517         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
2518
2519         /* Get a buffer for the data */
2520         strip_size = TIFFStripSize(tif);
2521         buf = _TIFFmalloc(strip_size);
2522         index = 0;
2523
2524         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
2525             unsigned char *dat8;
2526             tsize_t i, ssize = TIFFStripSize(tif);
2527             dat8 = (unsigned char*)buf;
2528
2529             if (bps == 8) {
2530                 step = 1 + has_alpha;
2531
2532                 for (i = 0; i < ssize; i += step) {
2533                     if (index < imgsize) {
2534                         int r, a = 0;
2535
2536                         r = image->comps[0].data[index];
2537                         if (has_alpha) {
2538                             a = image->comps[1].data[index];
2539                         }
2540
2541                         if (sgnd) {
2542                             r += adjust;
2543                             if (has_alpha) {
2544                                 a += adjust;
2545                             }
2546                         }
2547                         dat8[i + 0] = r;
2548                         if (has_alpha) {
2549                             dat8[i + 1] = a;
2550                         }
2551                         index++;
2552                     } else {
2553                         break;
2554                     }
2555                 }/*for(i )*/
2556             }/*if(bps == 8*/
2557             else if (bps == 16) {
2558                 step = 2 + has_alpha + has_alpha;
2559
2560                 for (i = 0; i < ssize; i += step) {
2561                     if (index < imgsize) {
2562                         int r, a = 0;
2563
2564                         r = image->comps[0].data[index];
2565                         if (has_alpha) {
2566                             a = image->comps[1].data[index];
2567                         }
2568
2569                         if (sgnd) {
2570                             r += adjust;
2571                             if (has_alpha) {
2572                                 a += adjust;
2573                             }
2574                         }
2575                         if (force16) {
2576                             r = (r << ushift) + (r >> dshift);
2577                             if (has_alpha) {
2578                                 a = (a << ushift) + (a >> dshift);
2579                             }
2580                         }
2581                         dat8[i + 0] = r; /*LSB*/
2582                         dat8[i + 1] = r >> 8; /*MSB*/
2583                         if (has_alpha) {
2584                             dat8[i + 2] = a;
2585                             dat8[i + 3] = a >> 8;
2586                         }
2587                         index++;
2588                     }/*if(index < imgsize)*/
2589                     else {
2590                         break;
2591                     }
2592                 }/*for(i )*/
2593             }
2594             (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
2595         }/*for(strip*/
2596
2597         _TIFFfree(buf);
2598         TIFFClose(tif);
2599
2600         return 0;
2601     }
2602
2603     TIFFClose(tif);
2604
2605     fprintf(stderr, "imagetotif: Bad color format.\n"
2606             "\tOnly RGB(A) and GRAY(A) has been implemented\n");
2607     fprintf(stderr, "\tFOUND: numcomps(%d)\n\tAborting\n",
2608             image->numcomps);
2609
2610     return 1;
2611 }/* imagetotif() */
2612
2613 /*
2614  * libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
2615  * CINEMA                 : 12 bit precision
2616 */
2617 opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
2618 {
2619     int subsampling_dx = parameters->subsampling_dx;
2620     int subsampling_dy = parameters->subsampling_dy;
2621     TIFF *tif;
2622     tdata_t buf;
2623     tstrip_t strip;
2624     tsize_t strip_size;
2625     int j, numcomps, w, h, index;
2626     OPJ_COLOR_SPACE color_space;
2627     opj_image_cmptparm_t cmptparm[4]; /* RGBA */
2628     opj_image_t *image = NULL;
2629     int imgsize = 0;
2630     int has_alpha = 0;
2631     unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
2632     unsigned int tiWidth, tiHeight;
2633
2634     tif = TIFFOpen(filename, "r");
2635
2636     if (!tif) {
2637         fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
2638         return 0;
2639     }
2640     tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
2641     tiWidth = tiHeight = 0;
2642
2643     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
2644     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
2645     TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
2646     TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
2647     TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
2648     TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
2649     TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
2650     w = tiWidth;
2651     h = tiHeight;
2652
2653     {
2654         unsigned short b = tiBps, p = tiPhoto;
2655
2656         if (tiBps != 8 && tiBps != 16 && tiBps != 12) {
2657             b = 0;
2658         }
2659         if (tiPhoto != 1 && tiPhoto != 2) {
2660             p = 0;
2661         }
2662
2663         if (!b || !p) {
2664             if (!b)
2665                 fprintf(stderr, "imagetotif: Bits=%d, Only 8 and 16 bits"
2666                         " implemented\n", tiBps);
2667             else if (!p)
2668                 fprintf(stderr, "tiftoimage: Bad color format %d.\n\tOnly RGB(A)"
2669                         " and GRAY(A) has been implemented\n", (int) tiPhoto);
2670
2671             fprintf(stderr, "\tAborting\n");
2672             TIFFClose(tif);
2673
2674             return NULL;
2675         }
2676     }
2677     {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
2678         uint16* sampleinfo;
2679         uint16 extrasamples;
2680
2681         TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
2682                               &extrasamples, &sampleinfo);
2683
2684         if (extrasamples >= 1) {
2685             switch (sampleinfo[0]) {
2686             case EXTRASAMPLE_UNSPECIFIED:
2687                 /* Workaround for some images without correct info about alpha channel
2688                 */
2689                 if (tiSpp > 3) {
2690                     has_alpha = 1;
2691                 }
2692                 break;
2693
2694             case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
2695             case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
2696                 has_alpha = 1;
2697                 break;
2698             }
2699         } else /* extrasamples == 0 */
2700             if (tiSpp == 4 || tiSpp == 2) {
2701                 has_alpha = 1;
2702             }
2703     }
2704
2705     /* initialize image components
2706     */
2707     memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
2708
2709     if (tiPhoto == PHOTOMETRIC_RGB) { /* RGB(A) */
2710         numcomps = 3 + has_alpha;
2711         color_space = CLRSPC_SRGB;
2712
2713         for (j = 0; j < numcomps; j++) {
2714             if (parameters->cp_cinema) {
2715                 cmptparm[j].prec = 12;
2716                 cmptparm[j].bpp = 12;
2717             } else {
2718                 cmptparm[j].prec = tiBps;
2719                 cmptparm[j].bpp = tiBps;
2720             }
2721             cmptparm[j].dx = subsampling_dx;
2722             cmptparm[j].dy = subsampling_dy;
2723             cmptparm[j].w = w;
2724             cmptparm[j].h = h;
2725         }
2726
2727         image = opj_image_create(numcomps, &cmptparm[0], color_space);
2728
2729         if (!image) {
2730             TIFFClose(tif);
2731             return NULL;
2732         }
2733         /* set image offset and reference grid
2734         */
2735         image->x0 = parameters->image_offset_x0;
2736         image->y0 = parameters->image_offset_y0;
2737         image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 :
2738                     image->x0 + (w - 1) * subsampling_dx + 1;
2739         image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 :
2740                     image->y0 + (h - 1) * subsampling_dy + 1;
2741
2742         buf = _TIFFmalloc(TIFFStripSize(tif));
2743
2744         strip_size = TIFFStripSize(tif);
2745         index = 0;
2746         imgsize = image->comps[0].w * image->comps[0].h ;
2747         /* Read the Image components
2748         */
2749         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
2750             unsigned char *dat8;
2751             int step;
2752             tsize_t i, ssize;
2753             ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
2754             dat8 = (unsigned char*)buf;
2755
2756             if (tiBps == 16) {
2757                 step = 6 + has_alpha + has_alpha;
2758
2759                 for (i = 0; i < ssize; i += step) {
2760                     if (index < imgsize) {
2761                         image->comps[0].data[index] = (dat8[i + 1] << 8) | dat8[i + 0]; /* R */
2762                         image->comps[1].data[index] = (dat8[i + 3] << 8) | dat8[i + 2]; /* G */
2763                         image->comps[2].data[index] = (dat8[i + 5] << 8) | dat8[i + 4]; /* B */
2764                         if (has_alpha) {
2765                             image->comps[3].data[index] = (dat8[i + 7] << 8) | dat8[i + 6];
2766                         }
2767
2768                         if (parameters->cp_cinema) {
2769                             /* Rounding 16 to 12 bits
2770                             */
2771                             image->comps[0].data[index] =
2772                                 (image->comps[0].data[index] + 0x08) >> 4 ;
2773                             image->comps[1].data[index] =
2774                                 (image->comps[1].data[index] + 0x08) >> 4 ;
2775                             image->comps[2].data[index] =
2776                                 (image->comps[2].data[index] + 0x08) >> 4 ;
2777                             if (has_alpha)
2778                                 image->comps[3].data[index] =
2779                                     (image->comps[3].data[index] + 0x08) >> 4 ;
2780                         }
2781                         index++;
2782                     } else {
2783                         break;
2784                     }
2785                 }/*for(i = 0)*/
2786             }/*if(tiBps == 16)*/
2787             else if (tiBps == 8) {
2788                 step = 3 + has_alpha;
2789
2790                 for (i = 0; i < ssize; i += step) {
2791                     if (index < imgsize) {
2792                         image->comps[0].data[index] = dat8[i + 0]; /* R */
2793                         image->comps[1].data[index] = dat8[i + 1]; /* G */
2794                         image->comps[2].data[index] = dat8[i + 2]; /* B */
2795                         if (has_alpha) {
2796                             image->comps[3].data[index] = dat8[i + 3];
2797                         }
2798
2799                         if (parameters->cp_cinema) {
2800                             /* Rounding 8 to 12 bits
2801                             */
2802                             image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
2803                             image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
2804                             image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
2805                             if (has_alpha) {
2806                                 image->comps[3].data[index] = image->comps[3].data[index] << 4 ;
2807                             }
2808                         }
2809                         index++;
2810                     }/*if(index*/
2811                     else {
2812                         break;
2813                     }
2814                 }/*for(i )*/
2815             }/*if( tiBps == 8)*/
2816             else if (tiBps == 12) { /* CINEMA file */
2817                 step = 9;
2818
2819                 for (i = 0; i < ssize; i += step) {
2820                     if ((index < imgsize) & (index + 1 < imgsize)) {
2821                         image->comps[0].data[index]   = (dat8[i + 0] << 4)        | (dat8[i + 1] >> 4);
2822                         image->comps[1].data[index]   = ((dat8[i + 1] & 0x0f) << 8) | dat8[i + 2];
2823
2824                         image->comps[2].data[index]   = (dat8[i + 3] << 4)         | (dat8[i + 4] >> 4);
2825                         image->comps[0].data[index + 1] = ((dat8[i + 4] & 0x0f) << 8) | dat8[i + 5];
2826
2827                         image->comps[1].data[index + 1] = (dat8[i + 6] << 4)        |
2828                                                           (dat8[i + 7] >> 4);
2829                         image->comps[2].data[index + 1] = ((dat8[i + 7] & 0x0f) << 8) | dat8[i + 8];
2830
2831                         index += 2;
2832                     } else {
2833                         break;
2834                     }
2835                 }/*for(i )*/
2836             }
2837         }/*for(strip = 0; )*/
2838
2839         _TIFFfree(buf);
2840         TIFFClose(tif);
2841
2842         return image;
2843     }/*RGB(A)*/
2844
2845     if (tiPhoto == PHOTOMETRIC_MINISBLACK) { /* GRAY(A) */
2846         numcomps = 1 + has_alpha;
2847         color_space = CLRSPC_GRAY;
2848
2849         for (j = 0; j < numcomps; ++j) {
2850             cmptparm[j].prec = tiBps;
2851             cmptparm[j].bpp = tiBps;
2852             cmptparm[j].dx = subsampling_dx;
2853             cmptparm[j].dy = subsampling_dy;
2854             cmptparm[j].w = w;
2855             cmptparm[j].h = h;
2856         }
2857         image = opj_image_create(numcomps, &cmptparm[0], color_space);
2858
2859         if (!image) {
2860             TIFFClose(tif);
2861             return NULL;
2862         }
2863         /* set image offset and reference grid
2864         */
2865         image->x0 = parameters->image_offset_x0;
2866         image->y0 = parameters->image_offset_y0;
2867         image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 :
2868                     image->x0 + (w - 1) * subsampling_dx + 1;
2869         image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 :
2870                     image->y0 + (h - 1) * subsampling_dy + 1;
2871
2872         buf = _TIFFmalloc(TIFFStripSize(tif));
2873
2874         strip_size = TIFFStripSize(tif);
2875         index = 0;
2876         imgsize = image->comps[0].w * image->comps[0].h ;
2877         /* Read the Image components
2878         */
2879         for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
2880             unsigned char *dat8;
2881             tsize_t i, ssize;
2882             int step;
2883
2884             ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
2885             dat8 = (unsigned char*)buf;
2886
2887             if (tiBps == 16) {
2888                 step = 2 + has_alpha + has_alpha;
2889
2890                 for (i = 0; i < ssize; i += step) {
2891                     if (index < imgsize) {
2892                         image->comps[0].data[index] = (dat8[i + 1] << 8) | dat8[i + 0];
2893                         if (has_alpha) {
2894                             image->comps[1].data[index] = (dat8[i + 3] << 8) | dat8[i + 2];
2895                         }
2896                         index++;
2897                     } else {
2898                         break;
2899                     }
2900                 }/*for(i )*/
2901             } else if (tiBps == 8) {
2902                 step = 1 + has_alpha;
2903
2904                 for (i = 0; i < ssize; i += step) {
2905                     if (index < imgsize) {
2906                         image->comps[0].data[index] = dat8[i + 0];
2907                         if (has_alpha) {
2908                             image->comps[1].data[index] = dat8[i + 1];
2909                         }
2910                         index++;
2911                     } else {
2912                         break;
2913                     }
2914                 }/*for(i )*/
2915             }
2916         }/*for(strip = 0;*/
2917
2918         _TIFFfree(buf);
2919         TIFFClose(tif);
2920
2921     }/*GRAY(A)*/
2922
2923     return image;
2924
2925 }/* tiftoimage() */
2926
2927 #endif /* OPJ_HAVE_LIBTIFF */
2928
2929 /* -->> -->> -->> -->>
2930
2931     RAW IMAGE FORMAT
2932
2933  <<-- <<-- <<-- <<-- */
2934
2935 opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters,
2936                         raw_cparameters_t *raw_cp)
2937 {
2938     int subsampling_dx = parameters->subsampling_dx;
2939     int subsampling_dy = parameters->subsampling_dy;
2940
2941     FILE *f = NULL;
2942     int i, compno, numcomps, w, h;
2943     OPJ_COLOR_SPACE color_space;
2944     opj_image_cmptparm_t *cmptparm;
2945     opj_image_t * image = NULL;
2946     unsigned short ch;
2947
2948     if ((!(raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp &
2949             raw_cp->rawBitDepth)) == 0) {
2950         fprintf(stderr, "\nError: invalid raw image parameters\n");
2951         fprintf(stderr, "Please use the Format option -F:\n");
2952         fprintf(stderr,
2953                 "-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
2954         fprintf(stderr, "Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
2955         fprintf(stderr, "Aborting\n");
2956         return NULL;
2957     }
2958
2959     f = fopen(filename, "rb");
2960     if (!f) {
2961         fprintf(stderr, "Failed to open %s for reading !!\n", filename);
2962         fprintf(stderr, "Aborting\n");
2963         return NULL;
2964     }
2965     numcomps = raw_cp->rawComp;
2966     color_space = CLRSPC_SRGB;
2967     w = raw_cp->rawWidth;
2968     h = raw_cp->rawHeight;
2969     cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(
2970                    opj_image_cmptparm_t));
2971
2972     /* initialize image components */
2973     memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
2974     for (i = 0; i < numcomps; i++) {
2975         cmptparm[i].prec = raw_cp->rawBitDepth;
2976         cmptparm[i].bpp = raw_cp->rawBitDepth;
2977         cmptparm[i].sgnd = raw_cp->rawSigned;
2978         cmptparm[i].dx = subsampling_dx;
2979         cmptparm[i].dy = subsampling_dy;
2980         cmptparm[i].w = w;
2981         cmptparm[i].h = h;
2982     }
2983     /* create the image */
2984     image = opj_image_create(numcomps, &cmptparm[0], color_space);
2985     if (!image) {
2986         fclose(f);
2987         return NULL;
2988     }
2989     /* set image offset and reference grid */
2990     image->x0 = parameters->image_offset_x0;
2991     image->y0 = parameters->image_offset_y0;
2992     image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
2993     image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
2994
2995     if (raw_cp->rawBitDepth <= 8) {
2996         unsigned char value = 0;
2997         for (compno = 0; compno < numcomps; compno++) {
2998             for (i = 0; i < w * h; i++) {
2999                 if (!fread(&value, 1, 1, f)) {
3000                     fprintf(stderr, "Error reading raw file. End of file probably reached.\n");
3001                     fclose(f);
3002                     return NULL;
3003                 }
3004                 image->comps[compno].data[i] = raw_cp->rawSigned ? (char)value : value;
3005             }
3006         }
3007     } else if (raw_cp->rawBitDepth <= 16) {
3008         unsigned short value;
3009         for (compno = 0; compno < numcomps; compno++) {
3010             for (i = 0; i < w * h; i++) {
3011                 unsigned char temp;
3012                 if (!fread(&temp, 1, 1, f)) {
3013                     fprintf(stderr, "Error reading raw file. End of file probably reached.\n");
3014                     fclose(f);
3015                     return NULL;
3016                 }
3017                 value = temp << 8;
3018                 if (!fread(&temp, 1, 1, f)) {
3019                     fprintf(stderr, "Error reading raw file. End of file probably reached.\n");
3020                     fclose(f);
3021                     return NULL;
3022                 }
3023                 value += temp;
3024                 image->comps[compno].data[i] = raw_cp->rawSigned ? (short)value : value;
3025             }
3026         }
3027     } else {
3028         fprintf(stderr,
3029                 "OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n");
3030         fclose(f);
3031         return NULL;
3032     }
3033
3034     if (fread(&ch, 1, 1, f)) {
3035         fprintf(stderr, "Warning. End of raw file not reached... processing anyway\n");
3036     }
3037     fclose(f);
3038
3039     return image;
3040 }
3041
3042 int imagetoraw(opj_image_t * image, const char *outfile)
3043 {
3044     FILE *rawFile = NULL;
3045     size_t res;
3046     int compno;
3047     int w, h;
3048     int line, row;
3049     int *ptr;
3050
3051     if ((image->numcomps * image->x1 * image->y1) == 0) {
3052         fprintf(stderr, "\nError: invalid raw image parameters\n");
3053         return 1;
3054     }
3055
3056     rawFile = fopen(outfile, "wb");
3057     if (!rawFile) {
3058         fprintf(stderr, "Failed to open %s for writing !!\n", outfile);
3059         return 1;
3060     }
3061
3062     fprintf(stdout, "Raw image characteristics: %d components\n", image->numcomps);
3063
3064     for (compno = 0; compno < image->numcomps; compno++) {
3065         fprintf(stdout, "Component %d characteristics: %dx%dx%d %s\n", compno,
3066                 image->comps[compno].w,
3067                 image->comps[compno].h, image->comps[compno].prec,
3068                 image->comps[compno].sgnd == 1 ? "signed" : "unsigned");
3069
3070         w = image->comps[compno].w;
3071         h = image->comps[compno].h;
3072
3073         if (image->comps[compno].prec <= 8) {
3074             if (image->comps[compno].sgnd == 1) {
3075                 signed char curr;
3076                 int mask = (1 << image->comps[compno].prec) - 1;
3077                 ptr = image->comps[compno].data;
3078                 for (line = 0; line < h; line++) {
3079                     for (row = 0; row < w; row++)    {
3080                         curr = (signed char)(*ptr & mask);
3081                         res = fwrite(&curr, sizeof(signed char), 1, rawFile);
3082                         if (res < 1) {
3083                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3084                             return 1;
3085                         }
3086                         ptr++;
3087                     }
3088                 }
3089             } else if (image->comps[compno].sgnd == 0) {
3090                 unsigned char curr;
3091                 int mask = (1 << image->comps[compno].prec) - 1;
3092                 ptr = image->comps[compno].data;
3093                 for (line = 0; line < h; line++) {
3094                     for (row = 0; row < w; row++)    {
3095                         curr = (unsigned char)(*ptr & mask);
3096                         res = fwrite(&curr, sizeof(unsigned char), 1, rawFile);
3097                         if (res < 1) {
3098                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3099                             return 1;
3100                         }
3101                         ptr++;
3102                     }
3103                 }
3104             }
3105         } else if (image->comps[compno].prec <= 16) {
3106             if (image->comps[compno].sgnd == 1) {
3107                 signed short int curr;
3108                 int mask = (1 << image->comps[compno].prec) - 1;
3109                 ptr = image->comps[compno].data;
3110                 for (line = 0; line < h; line++) {
3111                     for (row = 0; row < w; row++)    {
3112                         unsigned char temp;
3113                         curr = (signed short int)(*ptr & mask);
3114                         temp = (unsigned char)(curr >> 8);
3115                         res = fwrite(&temp, 1, 1, rawFile);
3116                         if (res < 1) {
3117                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3118                             return 1;
3119                         }
3120                         temp = (unsigned char) curr;
3121                         res = fwrite(&temp, 1, 1, rawFile);
3122                         if (res < 1) {
3123                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3124                             return 1;
3125                         }
3126                         ptr++;
3127                     }
3128                 }
3129             } else if (image->comps[compno].sgnd == 0) {
3130                 unsigned short int curr;
3131                 int mask = (1 << image->comps[compno].prec) - 1;
3132                 ptr = image->comps[compno].data;
3133                 for (line = 0; line < h; line++) {
3134                     for (row = 0; row < w; row++)    {
3135                         unsigned char temp;
3136                         curr = (unsigned short int)(*ptr & mask);
3137                         temp = (unsigned char)(curr >> 8);
3138                         res = fwrite(&temp, 1, 1, rawFile);
3139                         if (res < 1) {
3140                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3141                             return 1;
3142                         }
3143                         temp = (unsigned char) curr;
3144                         res = fwrite(&temp, 1, 1, rawFile);
3145                         if (res < 1) {
3146                             fprintf(stderr, "failed to write 1 byte for %s\n", outfile);
3147                             return 1;
3148                         }
3149                         ptr++;
3150                     }
3151                 }
3152             }
3153         } else if (image->comps[compno].prec <= 32) {
3154             fprintf(stderr, "More than 16 bits per component no handled yet\n");
3155             return 1;
3156         } else {
3157             fprintf(stderr, "Error: invalid precision: %d\n", image->comps[compno].prec);
3158             return 1;
3159         }
3160     }
3161     fclose(rawFile);
3162     return 0;
3163 }
3164
3165 #ifdef OPJ_HAVE_LIBPNG
3166
3167 #define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a"
3168 #define MAGIC_SIZE 8
3169 /* PNG allows bits per sample: 1, 2, 4, 8, 16 */
3170
3171 opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
3172 {
3173     png_structp  png;
3174     png_infop    info;
3175     double gamma, display_exponent;
3176     int bit_depth, interlace_type, compression_type, filter_type;
3177     int unit;
3178     png_uint_32 resx, resy;
3179     unsigned int i, j;
3180     png_uint_32  width, height;
3181     int color_type, has_alpha, is16;
3182     unsigned char *s;
3183     FILE *reader;
3184     unsigned char **rows;
3185     /* j2k: */
3186     opj_image_t *image;
3187     opj_image_cmptparm_t cmptparm[4];
3188     int sub_dx, sub_dy;
3189     unsigned int nr_comp;
3190     int *r, *g, *b, *a;
3191     unsigned char sigbuf[8];
3192
3193     if ((reader = fopen(read_idf, "rb")) == NULL) {
3194         fprintf(stderr, "pngtoimage: can not open %s\n", read_idf);
3195         return NULL;
3196     }
3197     image = NULL;
3198     png = NULL;
3199     rows = NULL;
3200
3201     if (fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
3202             || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0) {
3203         fprintf(stderr, "pngtoimage: %s is no valid PNG file\n", read_idf);
3204         goto fin;
3205     }
3206     /* libpng-VERSION/example.c:
3207      * PC : screen_gamma = 2.2;
3208      * Mac: screen_gamma = 1.7 or 1.0;
3209     */
3210     display_exponent = 2.2;
3211
3212     if ((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
3213                                       NULL, NULL, NULL)) == NULL) {
3214         goto fin;
3215     }
3216     if ((info = png_create_info_struct(png)) == NULL) {
3217         goto fin;
3218     }
3219
3220     if (setjmp(png_jmpbuf(png))) {
3221         goto fin;
3222     }
3223
3224     png_init_io(png, reader);
3225     png_set_sig_bytes(png, MAGIC_SIZE);
3226
3227     png_read_info(png, info);
3228
3229     if (png_get_IHDR(png, info, &width, &height,
3230                      &bit_depth, &color_type, &interlace_type,
3231                      &compression_type, &filter_type) == 0) {
3232         goto fin;
3233     }
3234
3235     /* png_set_expand():
3236      * expand paletted images to RGB, expand grayscale images of
3237      * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
3238      * to alpha channels.
3239     */
3240     if (color_type == PNG_COLOR_TYPE_PALETTE) {
3241         png_set_expand(png);
3242     } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
3243         png_set_expand(png);
3244     }
3245
3246     if (png_get_valid(png, info, PNG_INFO_tRNS)) {
3247         png_set_expand(png);
3248     }
3249
3250     is16 = (bit_depth == 16);
3251
3252     /* GRAY => RGB; GRAY_ALPHA => RGBA
3253     */
3254     if (color_type == PNG_COLOR_TYPE_GRAY
3255             || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
3256         png_set_gray_to_rgb(png);
3257         color_type =
3258             (color_type == PNG_COLOR_TYPE_GRAY ? PNG_COLOR_TYPE_RGB :
3259              PNG_COLOR_TYPE_RGB_ALPHA);
3260     }
3261     if (!png_get_gAMA(png, info, &gamma)) {
3262         gamma = 0.45455;
3263     }
3264
3265     png_set_gamma(png, display_exponent, gamma);
3266
3267     png_read_update_info(png, info);
3268
3269     png_get_pHYs(png, info, &resx, &resy, &unit);
3270
3271     color_type = png_get_color_type(png, info);
3272
3273     has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA);
3274
3275     nr_comp = 3 + has_alpha;
3276
3277     bit_depth = png_get_bit_depth(png, info);
3278
3279     rows = (unsigned char**)calloc(height + 1, sizeof(unsigned char*));
3280     for (i = 0; i < height; ++i) {
3281         rows[i] = (unsigned char*)malloc(png_get_rowbytes(png, info));
3282     }
3283
3284     png_read_image(png, rows);
3285
3286     memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
3287
3288     sub_dx = params->subsampling_dx;
3289     sub_dy = params->subsampling_dy;
3290
3291     for (i = 0; i < nr_comp; ++i) {
3292         cmptparm[i].prec = bit_depth;
3293         /* bits_per_pixel: 8 or 16 */
3294         cmptparm[i].bpp = bit_depth;
3295         cmptparm[i].sgnd = 0;
3296         cmptparm[i].dx = sub_dx;
3297         cmptparm[i].dy = sub_dy;
3298         cmptparm[i].w = width;
3299         cmptparm[i].h = height;
3300     }
3301
3302     image = opj_image_create(nr_comp, &cmptparm[0], CLRSPC_SRGB);
3303
3304     if (image == NULL) {
3305         goto fin;
3306     }
3307
3308     image->x0 = params->image_offset_x0;
3309     image->y0 = params->image_offset_y0;
3310     image->x1 = image->x0 + (width  - 1) * sub_dx + 1 + image->x0;
3311     image->y1 = image->y0 + (height - 1) * sub_dy + 1 + image->y0;
3312
3313     r = image->comps[0].data;
3314     g = image->comps[1].data;
3315     b = image->comps[2].data;
3316     a = image->comps[3].data;
3317
3318     for (i = 0; i < height; ++i) {
3319         s = rows[i];
3320
3321         for (j = 0; j < width; ++j) {
3322             if (is16) {
3323                 *r++ = s[0] << 8 | s[1];
3324                 s += 2;
3325
3326                 *g++ = s[0] << 8 | s[1];
3327                 s += 2;
3328
3329                 *b++ = s[0] << 8 | s[1];
3330                 s += 2;
3331
3332                 if (has_alpha) {
3333                     *a++ = s[0] << 8 | s[1];
3334                     s += 2;
3335                 }
3336
3337                 continue;
3338             }
3339             *r++ = *s++;
3340             *g++ = *s++;
3341             *b++ = *s++;
3342
3343             if (has_alpha) {
3344                 *a++ = *s++;
3345             }
3346         }
3347     }
3348 fin:
3349     if (rows) {
3350         for (i = 0; i < height; ++i) {
3351             free(rows[i]);
3352         }
3353         free(rows);
3354     }
3355     if (png) {
3356         png_destroy_read_struct(&png, &info, NULL);
3357     }
3358
3359     fclose(reader);
3360
3361     return image;
3362
3363 }/* pngtoimage() */
3364
3365 int imagetopng(opj_image_t * image, const char *write_idf)
3366 {
3367     FILE *writer;
3368     png_structp png;
3369     png_infop info;
3370     int *red, *green, *blue, *alpha;
3371     unsigned char *row_buf, *d;
3372     int has_alpha, width, height, nr_comp, color_type;
3373     int adjustR, adjustG, adjustB, adjustA, x, y, fails;
3374     int prec, ushift, dshift, is16, force16, force8;
3375     unsigned short mask = 0xffff;
3376     png_color_8 sig_bit;
3377
3378     is16 = force16 = force8 = ushift = dshift = 0;
3379     fails = 1;
3380     prec = image->comps[0].prec;
3381     nr_comp = image->numcomps;
3382
3383     if (prec > 8 && prec < 16) {
3384         ushift = 16 - prec;
3385         dshift = prec - ushift;
3386         prec = 16;
3387         force16 = 1;
3388     } else if (prec < 8 && nr_comp > 1) { /* GRAY_ALPHA, RGB, RGB_ALPHA */
3389         ushift = 8 - prec;
3390         dshift = 8 - ushift;
3391         prec = 8;
3392         force8 = 1;
3393     }
3394
3395     if (prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16) {
3396         fprintf(stderr, "imagetopng: can not create %s"
3397                 "\n\twrong bit_depth %d\n", write_idf, prec);
3398         return fails;
3399     }
3400     writer = fopen(write_idf, "wb");
3401
3402     if (writer == NULL) {
3403         return fails;
3404     }
3405
3406     info = NULL;
3407     has_alpha = 0;
3408
3409     /* Create and initialize the png_struct with the desired error handler
3410      * functions.  If you want to use the default stderr and longjump method,
3411      * you can supply NULL for the last three parameters.  We also check that
3412      * the library version is compatible with the one used at compile time,
3413      * in case we are using dynamically linked libraries.  REQUIRED.
3414     */
3415     png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
3416                                   NULL, NULL, NULL);
3417     /*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */
3418
3419     if (png == NULL) {
3420         goto fin;
3421     }
3422
3423     /* Allocate/initialize the image information data.  REQUIRED
3424     */
3425     info = png_create_info_struct(png);
3426
3427     if (info == NULL) {
3428         goto fin;
3429     }
3430
3431     /* Set error handling.  REQUIRED if you are not supplying your own
3432      * error handling functions in the png_create_write_struct() call.
3433     */
3434     if (setjmp(png_jmpbuf(png))) {
3435         goto fin;
3436     }
3437
3438     /* I/O initialization functions is REQUIRED
3439     */
3440     png_init_io(png, writer);
3441
3442     /* Set the image information here.  Width and height are up to 2^31,
3443      * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
3444      * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
3445      * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
3446      * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
3447      * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
3448      * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE.
3449      * REQUIRED
3450      *
3451      * ERRORS:
3452      *
3453      * color_type == PNG_COLOR_TYPE_PALETTE && bit_depth > 8
3454      * color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8
3455      * color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8
3456      * color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8
3457      *
3458     */
3459     png_set_compression_level(png, Z_BEST_COMPRESSION);
3460
3461     if (prec == 16) {
3462         mask = 0xffff;
3463     } else if (prec == 8) {
3464         mask = 0x00ff;
3465     } else if (prec == 4) {
3466         mask = 0x000f;
3467     } else if (prec == 2) {
3468         mask = 0x0003;
3469     } else if (prec == 1) {
3470         mask = 0x0001;
3471     }
3472
3473     if (nr_comp >= 3
3474             && image->comps[0].dx == image->comps[1].dx
3475             && image->comps[1].dx == image->comps[2].dx
3476             && image->comps[0].dy == image->comps[1].dy
3477             && image->comps[1].dy == image->comps[2].dy
3478             && image->comps[0].prec == image->comps[1].prec
3479             && image->comps[1].prec == image->comps[2].prec) {
3480         int v;
3481
3482         has_alpha = (nr_comp > 3);
3483
3484         is16 = (prec == 16);
3485
3486         width = image->comps[0].w;
3487         height = image->comps[0].h;
3488
3489         red = image->comps[0].data;
3490         green = image->comps[1].data;
3491         blue = image->comps[2].data;
3492
3493         sig_bit.red = sig_bit.green = sig_bit.blue = prec;
3494
3495         if (has_alpha) {
3496             sig_bit.alpha = prec;
3497             alpha = image->comps[3].data;
3498             color_type = PNG_COLOR_TYPE_RGB_ALPHA;
3499             adjustA = (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
3500         } else {
3501             sig_bit.alpha = 0;
3502             alpha = NULL;
3503             color_type = PNG_COLOR_TYPE_RGB;
3504             adjustA = 0;
3505         }
3506         png_set_sBIT(png, info, &sig_bit);
3507
3508         png_set_IHDR(png, info, width, height, prec,
3509                      color_type,
3510                      PNG_INTERLACE_NONE,
3511                      PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
3512         /*=============================*/
3513         png_write_info(png, info);
3514         /*=============================*/
3515         if (prec < 8) {
3516             png_set_packing(png);
3517         }
3518         adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
3519         adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
3520         adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
3521
3522         row_buf = (unsigned char*)malloc(width * nr_comp * 2);
3523
3524         for (y = 0; y < height; ++y) {
3525             d = row_buf;
3526
3527             for (x = 0; x < width; ++x) {
3528                 if (is16) {
3529                     v = *red + adjustR;
3530                     ++red;
3531
3532                     if (force16) {
3533                         v = (v << ushift) + (v >> dshift);
3534                     }
3535
3536                     *d++ = (unsigned char)(v >> 8);
3537                     *d++ = (unsigned char)v;
3538
3539                     v = *green + adjustG;
3540                     ++green;
3541
3542                     if (force16) {
3543                         v = (v << ushift) + (v >> dshift);
3544                     }
3545
3546                     *d++ = (unsigned char)(v >> 8);
3547                     *d++ = (unsigned char)v;
3548
3549                     v =  *blue + adjustB;
3550                     ++blue;
3551
3552                     if (force16) {
3553                         v = (v << ushift) + (v >> dshift);
3554                     }
3555
3556                     *d++ = (unsigned char)(v >> 8);
3557                     *d++ = (unsigned char)v;
3558
3559                     if (has_alpha) {
3560                         v = *alpha + adjustA;
3561                         ++alpha;
3562
3563                         if (force16) {
3564                             v = (v << ushift) + (v >> dshift);
3565                         }
3566
3567                         *d++ = (unsigned char)(v >> 8);
3568                         *d++ = (unsigned char)v;
3569                     }
3570                     continue;
3571                 }/* if(is16) */
3572
3573                 v = *red + adjustR;
3574                 ++red;
3575
3576                 if (force8) {
3577                     v = (v << ushift) + (v >> dshift);
3578                 }
3579
3580                 *d++ = (unsigned char)(v & mask);
3581
3582                 v = *green + adjustG;
3583                 ++green;
3584
3585                 if (force8) {
3586                     v = (v << ushift) + (v >> dshift);
3587                 }
3588
3589                 *d++ = (unsigned char)(v & mask);
3590
3591                 v = *blue + adjustB;
3592                 ++blue;
3593
3594                 if (force8) {
3595                     v = (v << ushift) + (v >> dshift);
3596                 }
3597
3598                 *d++ = (unsigned char)(v & mask);
3599
3600                 if (has_alpha) {
3601                     v = *alpha + adjustA;
3602                     ++alpha;
3603
3604                     if (force8) {
3605                         v = (v << ushift) + (v >> dshift);
3606                     }
3607
3608                     *d++ = (unsigned char)(v & mask);
3609                 }
3610             }  /* for(x) */
3611
3612             png_write_row(png, row_buf);
3613
3614         } /* for(y) */
3615         free(row_buf);
3616
3617     }/* nr_comp >= 3 */
3618     else if (nr_comp == 1 /* GRAY */
3619              || (nr_comp == 2    /* GRAY_ALPHA */
3620                  && image->comps[0].dx == image->comps[1].dx
3621                  && image->comps[0].dy == image->comps[1].dy
3622                  && image->comps[0].prec == image->comps[1].prec)) {
3623         int v;
3624
3625         red = image->comps[0].data;
3626
3627         sig_bit.gray = prec;
3628         sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0;
3629         alpha = NULL;
3630         adjustA = 0;
3631         color_type = PNG_COLOR_TYPE_GRAY;
3632
3633         if (nr_comp == 2) {
3634             has_alpha = 1;
3635             sig_bit.alpha = prec;
3636             alpha = image->comps[1].data;
3637             color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3638             adjustA = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
3639         }
3640         width = image->comps[0].w;
3641         height = image->comps[0].h;
3642
3643         png_set_IHDR(png, info, width, height, sig_bit.gray,
3644                      color_type,
3645                      PNG_INTERLACE_NONE,
3646                      PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
3647
3648         png_set_sBIT(png, info, &sig_bit);
3649         /*=============================*/
3650         png_write_info(png, info);
3651         /*=============================*/
3652         adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
3653
3654         if (prec < 8) {
3655             png_set_packing(png);
3656         }
3657
3658         if (prec > 8) {
3659             row_buf = (unsigned char*)
3660                       malloc(width * nr_comp * sizeof(unsigned short));
3661
3662             for (y = 0; y < height; ++y) {
3663                 d = row_buf;
3664
3665                 for (x = 0; x < width; ++x) {
3666                     v = *red + adjustR;
3667                     ++red;
3668
3669                     if (force16) {
3670                         v = (v << ushift) + (v >> dshift);
3671                     }
3672
3673                     *d++ = (unsigned char)(v >> 8);
3674                     *d++ = (unsigned char)v;
3675
3676                     if (has_alpha) {
3677                         v = *alpha++;
3678
3679                         if (force16) {
3680                             v = (v << ushift) + (v >> dshift);
3681                         }
3682
3683                         *d++ = (unsigned char)(v >> 8);
3684                         *d++ = (unsigned char)v;
3685                     }
3686                 }/* for(x) */
3687                 png_write_row(png, row_buf);
3688
3689             }  /* for(y) */
3690             free(row_buf);
3691         } else { /* prec <= 8 */
3692             row_buf = (unsigned char*)calloc(width, nr_comp * 2);
3693
3694             for (y = 0; y < height; ++y) {
3695                 d = row_buf;
3696
3697                 for (x = 0; x < width; ++x) {
3698                     v = *red + adjustR;
3699                     ++red;
3700
3701                     if (force8) {
3702                         v = (v << ushift) + (v >> dshift);
3703                     }
3704
3705                     *d++ = (unsigned char)(v & mask);
3706
3707                     if (has_alpha) {
3708                         v = *alpha + adjustA;
3709                         ++alpha;
3710
3711                         if (force8) {
3712                             v = (v << ushift) + (v >> dshift);
3713                         }
3714
3715                         *d++ = (unsigned char)(v & mask);
3716                     }
3717                 }/* for(x) */
3718
3719                 png_write_row(png, row_buf);
3720
3721             }  /* for(y) */
3722             free(row_buf);
3723         }
3724     } else {
3725         fprintf(stderr, "imagetopng: can not create %s\n", write_idf);
3726         goto fin;
3727     }
3728     png_write_end(png, info);
3729
3730     fails = 0;
3731
3732 fin:
3733
3734     if (png) {
3735         png_destroy_write_struct(&png, &info);
3736     }
3737     fclose(writer);
3738
3739     if (fails) {
3740         remove(write_idf);
3741     }
3742
3743     return fails;
3744 }/* imagetopng() */
3745 #endif /* OPJ_HAVE_LIBPNG */