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