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