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