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