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