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