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