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