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