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
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
32 #include <opj_config.h>
33 #define TEST_WITH_GAMMA
44 #endif /* HAVE_LIBTIFF */
52 #endif /* HAVE_LIBPNG */
58 * Get logarithm of an integer and round downwards.
62 static int int_floorlog2(int a) {
64 for (l = 0; a > 1; l++) {
71 * Divide an integer by a power of 2 and round upwards.
75 static int int_ceildivpow2(int a, int b) {
76 return (a + (1 << b) - 1) >> b;
80 * Divide an integer and round upwards.
84 static int int_ceildiv(int a, int b) {
85 return (a + b - 1) / b;
89 /* -->> -->> -->> -->>
93 <<-- <<-- <<-- <<-- */
95 // TGA header definition.
96 #pragma pack(push,1) // Pack structure byte aligned
97 typedef struct tga_header
99 unsigned char id_length; /* Image id field length */
100 unsigned char colour_map_type; /* Colour map type */
101 unsigned char image_type; /* Image type */
103 ** Colour map specification
105 unsigned short colour_map_index; /* First entry index */
106 unsigned short colour_map_length; /* Colour map length */
107 unsigned char colour_map_entry_size; /* Colour map entry size */
109 ** Image specification
111 unsigned short x_origin; /* x origin of image */
112 unsigned short y_origin; /* u origin of image */
113 unsigned short image_width; /* Image width */
114 unsigned short image_height; /* Image height */
115 unsigned char pixel_depth; /* Pixel depth */
116 unsigned char image_desc; /* Image descriptor */
118 #pragma pack(pop) // Return to normal structure packing alignment.
120 int tga_readheader(FILE *fp, unsigned int *bits_per_pixel,
121 unsigned int *width, unsigned int *height, int *flip_image)
126 if (!bits_per_pixel || !width || !height || !flip_image)
130 fread((unsigned char*)&tga, sizeof(tga_header), 1, fp);
132 *bits_per_pixel = tga.pixel_depth;
134 *width = tga.image_width;
135 *height = tga.image_height ;
137 // Ignore tga identifier, if present ...
140 unsigned char *id = (unsigned char *) malloc(tga.id_length);
141 fread(id, tga.id_length, 1, fp);
145 // Test for compressed formats ... not yet supported ...
146 // Note :- 9 - RLE encoded palettized.
147 // 10 - RLE encoded RGB.
148 if (tga.image_type > 8)
150 fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n");
154 *flip_image = !(tga.image_desc & 32);
156 // Palettized formats are not yet supported, skip over the palette, if present ...
157 palette_size = tga.colour_map_length * (tga.colour_map_entry_size/8);
161 fprintf(stderr, "File contains a palette - not yet supported.");
162 fseek(fp, palette_size, SEEK_CUR);
167 int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height,
172 if (!bits_per_pixel || !width || !height)
175 memset(&tga, 0, sizeof(tga_header));
177 tga.pixel_depth = bits_per_pixel;
178 tga.image_width = width;
179 tga.image_height = height;
180 tga.image_type = 2; // Uncompressed.
181 tga.image_desc = 8; // 8 bits per component.
184 tga.image_desc |= 32;
187 fwrite((unsigned char*)&tga, sizeof(tga_header), 1, fp);
192 opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) {
195 unsigned int image_width, image_height, pixel_bit_depth;
198 opj_image_cmptparm_t cmptparm[4]; /* maximum 4 components */
200 OPJ_COLOR_SPACE color_space;
203 int subsampling_dx, subsampling_dy;
206 f = fopen(filename, "rb");
208 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
212 if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image))
215 // We currently only support 24 & 32 bit tga's ...
216 if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32)))
219 /* initialize image components */
220 memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
222 mono = (pixel_bit_depth == 8) || (pixel_bit_depth == 16); // Mono with & without alpha.
223 save_alpha = (pixel_bit_depth == 16) || (pixel_bit_depth == 32); // Mono with alpha, or RGB with alpha
226 color_space = CLRSPC_GRAY;
227 numcomps = save_alpha ? 2 : 1;
230 numcomps = save_alpha ? 4 : 3;
231 color_space = CLRSPC_SRGB;
234 subsampling_dx = parameters->subsampling_dx;
235 subsampling_dy = parameters->subsampling_dy;
237 for (i = 0; i < numcomps; i++) {
238 cmptparm[i].prec = 8;
240 cmptparm[i].sgnd = 0;
241 cmptparm[i].dx = subsampling_dx;
242 cmptparm[i].dy = subsampling_dy;
243 cmptparm[i].w = image_width;
244 cmptparm[i].h = image_height;
247 /* create the image */
248 image = opj_image_create(numcomps, &cmptparm[0], color_space);
253 /* set image offset and reference grid */
254 image->x0 = parameters->image_offset_x0;
255 image->y0 = parameters->image_offset_y0;
256 image->x1 = !image->x0 ? (image_width - 1) * subsampling_dx + 1 : image->x0 + (image_width - 1) * subsampling_dx + 1;
257 image->y1 = !image->y0 ? (image_height - 1) * subsampling_dy + 1 : image->y0 + (image_height - 1) * subsampling_dy + 1;
260 for (y=0; y < image_height; y++)
265 index = (image_height-y-1)*image_width;
267 index = y*image_width;
271 for (x=0;x<image_width;x++)
278 image->comps[0].data[index]=r;
279 image->comps[1].data[index]=g;
280 image->comps[2].data[index]=b;
284 else if (numcomps==4)
286 for (x=0;x<image_width;x++)
288 unsigned char r,g,b,a;
294 image->comps[0].data[index]=r;
295 image->comps[1].data[index]=g;
296 image->comps[2].data[index]=b;
297 image->comps[3].data[index]=a;
302 fprintf(stderr, "Currently unsupported bit depth : %s\n", filename);
308 int imagetotga(opj_image_t * image, const char *outfile) {
309 int width, height, bpp, x, y;
312 unsigned int alpha_channel;
318 fdest = fopen(outfile, "wb");
320 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
324 for (i = 0; i < image->numcomps-1; i++) {
325 if ((image->comps[0].dx != image->comps[i+1].dx)
326 ||(image->comps[0].dy != image->comps[i+1].dy)
327 ||(image->comps[0].prec != image->comps[i+1].prec)) {
328 fprintf(stderr, "Unable to create a tga file with such J2K image charateristics.");
333 width = image->comps[0].w;
334 height = image->comps[0].h;
336 // Mono with alpha, or RGB with alpha.
337 write_alpha = (image->numcomps==2) || (image->numcomps==4);
340 bpp = write_alpha ? 32 : 24;
341 if (!tga_writeheader(fdest, bpp, width , height, true))
344 alpha_channel = image->numcomps-1;
346 scale = 255.0f / (float)((1<<image->comps[0].prec)-1);
348 for (y=0; y < height; y++) {
349 unsigned int index=y*width;
351 for (x=0; x < width; x++, index++) {
352 r = (float)(image->comps[0].data[index]);
354 if (image->numcomps>2) {
355 g = (float)(image->comps[1].data[index]);
356 b = (float)(image->comps[2].data[index]);
358 else {// Greyscale ...
363 // TGA format writes BGR ...
364 value = (unsigned char)(b*scale);
365 fwrite(&value,1,1,fdest);
367 value = (unsigned char)(g*scale);
368 fwrite(&value,1,1,fdest);
370 value = (unsigned char)(r*scale);
371 fwrite(&value,1,1,fdest);
374 a = (float)(image->comps[alpha_channel].data[index]);
375 value = (unsigned char)(a*scale);
376 fwrite(&value,1,1,fdest);
384 /* -->> -->> -->> -->>
388 <<-- <<-- <<-- <<-- */
390 /* WORD defines a two byte word */
391 typedef unsigned short int WORD;
393 /* DWORD defines a four byte word */
394 typedef unsigned long int DWORD;
397 WORD bfType; /* 'BM' for Bitmap (19776) */
398 DWORD bfSize; /* Size of the file */
399 WORD bfReserved1; /* Reserved : 0 */
400 WORD bfReserved2; /* Reserved : 0 */
401 DWORD bfOffBits; /* Offset */
402 } BITMAPFILEHEADER_t;
405 DWORD biSize; /* Size of the structure in bytes */
406 DWORD biWidth; /* Width of the image in pixels */
407 DWORD biHeight; /* Heigth of the image in pixels */
408 WORD biPlanes; /* 1 */
409 WORD biBitCount; /* Number of color bits by pixels */
410 DWORD biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */
411 DWORD biSizeImage; /* Size of the image in bytes */
412 DWORD biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */
413 DWORD biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */
414 DWORD biClrUsed; /* Number of color used in the image (0: ALL) */
415 DWORD biClrImportant; /* Number of important color (0: ALL) */
416 } BITMAPINFOHEADER_t;
418 opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) {
419 int subsampling_dx = parameters->subsampling_dx;
420 int subsampling_dy = parameters->subsampling_dy;
422 int i, numcomps, w, h;
423 OPJ_COLOR_SPACE color_space;
424 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
425 opj_image_t * image = NULL;
428 BITMAPFILEHEADER_t File_h;
429 BITMAPINFOHEADER_t Info_h;
431 unsigned char *table_R, *table_G, *table_B;
432 unsigned int j, PAD = 0;
435 int gray_scale = 1, not_end_file = 1;
437 unsigned int line = 0, col = 0;
441 IN = fopen(filename, "rb");
443 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
447 File_h.bfType = getc(IN);
448 File_h.bfType = (getc(IN) << 8) + File_h.bfType;
450 if (File_h.bfType != 19778) {
451 fprintf(stderr,"Error, not a BMP file!\n");
456 File_h.bfSize = getc(IN);
457 File_h.bfSize = (getc(IN) << 8) + File_h.bfSize;
458 File_h.bfSize = (getc(IN) << 16) + File_h.bfSize;
459 File_h.bfSize = (getc(IN) << 24) + File_h.bfSize;
461 File_h.bfReserved1 = getc(IN);
462 File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1;
464 File_h.bfReserved2 = getc(IN);
465 File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2;
467 File_h.bfOffBits = getc(IN);
468 File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits;
469 File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits;
470 File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits;
475 Info_h.biSize = getc(IN);
476 Info_h.biSize = (getc(IN) << 8) + Info_h.biSize;
477 Info_h.biSize = (getc(IN) << 16) + Info_h.biSize;
478 Info_h.biSize = (getc(IN) << 24) + Info_h.biSize;
480 Info_h.biWidth = getc(IN);
481 Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth;
482 Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth;
483 Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth;
486 Info_h.biHeight = getc(IN);
487 Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight;
488 Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight;
489 Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight;
492 Info_h.biPlanes = getc(IN);
493 Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes;
495 Info_h.biBitCount = getc(IN);
496 Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount;
498 Info_h.biCompression = getc(IN);
499 Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression;
500 Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression;
501 Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression;
503 Info_h.biSizeImage = getc(IN);
504 Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage;
505 Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage;
506 Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage;
508 Info_h.biXpelsPerMeter = getc(IN);
509 Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter;
510 Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter;
511 Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter;
513 Info_h.biYpelsPerMeter = getc(IN);
514 Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter;
515 Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter;
516 Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter;
518 Info_h.biClrUsed = getc(IN);
519 Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed;
520 Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed;
521 Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed;
523 Info_h.biClrImportant = getc(IN);
524 Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant;
525 Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant;
526 Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant;
528 /* Read the data and store them in the OUT file */
530 if (Info_h.biBitCount == 24) {
532 color_space = CLRSPC_SRGB;
533 /* initialize image components */
534 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
535 for(i = 0; i < numcomps; i++) {
536 cmptparm[i].prec = 8;
538 cmptparm[i].sgnd = 0;
539 cmptparm[i].dx = subsampling_dx;
540 cmptparm[i].dy = subsampling_dy;
544 /* create the image */
545 image = opj_image_create(numcomps, &cmptparm[0], color_space);
551 /* set image offset and reference grid */
552 image->x0 = parameters->image_offset_x0;
553 image->y0 = parameters->image_offset_y0;
554 image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
555 image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
559 /* Place the cursor at the beginning of the image information */
560 fseek(IN, 0, SEEK_SET);
561 fseek(IN, File_h.bfOffBits, SEEK_SET);
566 /* PAD = 4 - (3 * W) % 4; */
567 /* PAD = (PAD == 4) ? 0 : PAD; */
568 PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0;
570 RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char));
572 fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN);
576 for(y = 0; y < (int)H; y++) {
577 unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y);
578 for(x = 0; x < (int)W; x++) {
579 unsigned char *pixel = &scanline[3 * x];
580 image->comps[0].data[index] = pixel[2]; /* R */
581 image->comps[1].data[index] = pixel[1]; /* G */
582 image->comps[2].data[index] = pixel[0]; /* B */
589 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) {
590 table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
591 table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
592 table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
594 for (j = 0; j < Info_h.biClrUsed; j++) {
595 table_B[j] = getc(IN);
596 table_G[j] = getc(IN);
597 table_R[j] = getc(IN);
599 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
603 /* Place the cursor at the beginning of the image information */
604 fseek(IN, 0, SEEK_SET);
605 fseek(IN, File_h.bfOffBits, SEEK_SET);
609 if (Info_h.biWidth % 2)
612 numcomps = gray_scale ? 1 : 3;
613 color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
614 /* initialize image components */
615 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
616 for(i = 0; i < numcomps; i++) {
617 cmptparm[i].prec = 8;
619 cmptparm[i].sgnd = 0;
620 cmptparm[i].dx = subsampling_dx;
621 cmptparm[i].dy = subsampling_dy;
625 /* create the image */
626 image = opj_image_create(numcomps, &cmptparm[0], color_space);
632 /* set image offset and reference grid */
633 image->x0 = parameters->image_offset_x0;
634 image->y0 = parameters->image_offset_y0;
635 image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
636 image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
640 RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
642 fread(RGB, sizeof(unsigned char), W * H, IN);
645 for (j = 0; j < W * H; j++) {
646 if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
647 image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]];
654 for (j = 0; j < W * H; j++) {
655 if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) {
656 unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)];
657 image->comps[0].data[index] = table_R[pixel_index];
658 image->comps[1].data[index] = table_G[pixel_index];
659 image->comps[2].data[index] = table_B[pixel_index];
668 } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) {
669 table_R = (unsigned char *) malloc(256 * sizeof(unsigned char));
670 table_G = (unsigned char *) malloc(256 * sizeof(unsigned char));
671 table_B = (unsigned char *) malloc(256 * sizeof(unsigned char));
673 for (j = 0; j < Info_h.biClrUsed; j++) {
674 table_B[j] = getc(IN);
675 table_G[j] = getc(IN);
676 table_R[j] = getc(IN);
678 if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j])
682 numcomps = gray_scale ? 1 : 3;
683 color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB;
684 /* initialize image components */
685 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
686 for(i = 0; i < numcomps; i++) {
687 cmptparm[i].prec = 8;
689 cmptparm[i].sgnd = 0;
690 cmptparm[i].dx = subsampling_dx;
691 cmptparm[i].dy = subsampling_dy;
695 /* create the image */
696 image = opj_image_create(numcomps, &cmptparm[0], color_space);
702 /* set image offset and reference grid */
703 image->x0 = parameters->image_offset_x0;
704 image->y0 = parameters->image_offset_y0;
705 image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
706 image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
710 /* Place the cursor at the beginning of the image information */
711 fseek(IN, 0, SEEK_SET);
712 fseek(IN, File_h.bfOffBits, SEEK_SET);
714 RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char));
716 while (not_end_file) {
720 for (i = 0; i < (int) v; i++) {
721 RGB[line * Info_h.biWidth + col] = v2;
736 fprintf(stderr,"No Delta supported\n");
737 opj_image_destroy(image);
741 for (i = 0; i < v; i++) {
743 RGB[line * Info_h.biWidth + col] = v2;
754 for (line = 0; line < Info_h.biHeight; line++) {
755 for (col = 0; col < Info_h.biWidth; col++) {
756 image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]];
762 for (line = 0; line < Info_h.biHeight; line++) {
763 for (col = 0; col < Info_h.biWidth; col++) {
764 unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col];
765 image->comps[0].data[index] = table_R[pixel_index];
766 image->comps[1].data[index] = table_G[pixel_index];
767 image->comps[2].data[index] = table_B[pixel_index];
778 "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount);
786 int imagetobmp(opj_image_t * image, const char *outfile) {
790 int adjustR, adjustG, adjustB;
792 if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
793 && image->comps[1].dx == image->comps[2].dx
794 && image->comps[0].dy == image->comps[1].dy
795 && image->comps[1].dy == image->comps[2].dy
796 && image->comps[0].prec == image->comps[1].prec
797 && image->comps[1].prec == image->comps[2].prec) {
799 /* -->> -->> -->> -->>
801 <<-- <<-- <<-- <<-- */
803 fdest = fopen(outfile, "wb");
805 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
809 w = image->comps[0].w;
810 h = image->comps[0].h;
812 fprintf(fdest, "BM");
816 fprintf(fdest, "%c%c%c%c",
817 (unsigned char) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff,
818 (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff,
819 (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff,
820 (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff);
821 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
822 fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
826 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
827 fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff),
828 (unsigned char) ((w) >> 8) & 0xff,
829 (unsigned char) ((w) >> 16) & 0xff,
830 (unsigned char) ((w) >> 24) & 0xff);
831 fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff),
832 (unsigned char) ((h) >> 8) & 0xff,
833 (unsigned char) ((h) >> 16) & 0xff,
834 (unsigned char) ((h) >> 24) & 0xff);
835 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
836 fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
837 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
838 fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * h * w + 3 * h * (w % 2)) & 0xff,
839 (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff,
840 (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff,
841 (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff);
842 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
843 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
844 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
845 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
847 if (image->comps[0].prec > 8) {
848 adjustR = image->comps[0].prec - 8;
849 printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
853 if (image->comps[1].prec > 8) {
854 adjustG = image->comps[1].prec - 8;
855 printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
859 if (image->comps[2].prec > 8) {
860 adjustB = image->comps[2].prec - 8;
861 printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
866 for (i = 0; i < w * h; i++) {
867 unsigned char rc, gc, bc;
870 r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
871 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
872 rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
873 g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
874 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
875 gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2));
876 b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
877 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
878 bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2));
880 fprintf(fdest, "%c%c%c", bc, gc, rc);
882 if ((i + 1) % w == 0) {
883 for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */
884 fprintf(fdest, "%c", 0);
888 } else { /* Gray-scale */
890 /* -->> -->> -->> -->>
891 8 bits non code (Gray scale)
892 <<-- <<-- <<-- <<-- */
894 fdest = fopen(outfile, "wb");
895 w = image->comps[0].w;
896 h = image->comps[0].h;
898 fprintf(fdest, "BM");
902 fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + 54 + 1024 + h * (w % 2)) & 0xff,
903 (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff,
904 (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff,
905 (unsigned char) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff);
906 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
907 fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff,
908 ((54 + 1024) >> 16) & 0xff,
909 ((54 + 1024) >> 24) & 0xff);
913 fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
914 fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff),
915 (unsigned char) ((w) >> 8) & 0xff,
916 (unsigned char) ((w) >> 16) & 0xff,
917 (unsigned char) ((w) >> 24) & 0xff);
918 fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff),
919 (unsigned char) ((h) >> 8) & 0xff,
920 (unsigned char) ((h) >> 16) & 0xff,
921 (unsigned char) ((h) >> 24) & 0xff);
922 fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
923 fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff);
924 fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
925 fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + h * (w % 2)) & 0xff,
926 (unsigned char) ((h * w + h * (w % 2)) >> 8) & 0xff,
927 (unsigned char) ((h * w + h * (w % 2)) >> 16) & 0xff,
928 (unsigned char) ((h * w + h * (w % 2)) >> 24) & 0xff);
929 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
930 fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
931 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
932 fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff);
934 if (image->comps[0].prec > 8) {
935 adjustR = image->comps[0].prec - 8;
936 printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
940 for (i = 0; i < 256; i++) {
941 fprintf(fdest, "%c%c%c%c", i, i, i, 0);
944 for (i = 0; i < w * h; i++) {
948 r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
949 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
950 rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
952 fprintf(fdest, "%c", rc);
954 if ((i + 1) % w == 0) {
955 for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */
956 fprintf(fdest, "%c", 0);
965 /* -->> -->> -->> -->>
969 <<-- <<-- <<-- <<-- */
972 unsigned char readuchar(FILE * f)
979 unsigned short readushort(FILE * f, int bigendian)
981 unsigned char c1, c2;
985 return (c1 << 8) + c2;
987 return (c2 << 8) + c1;
990 unsigned int readuint(FILE * f, int bigendian)
992 unsigned char c1, c2, c3, c4;
998 return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
1000 return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
1003 opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
1006 int i, numcomps, max;
1007 OPJ_COLOR_SPACE color_space;
1008 opj_image_cmptparm_t cmptparm; /* maximum of 1 component */
1009 opj_image_t * image = NULL;
1011 char endian1,endian2,sign;
1016 opj_image_comp_t *comp = NULL;
1019 color_space = CLRSPC_GRAY;
1021 memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t));
1025 f = fopen(filename, "rb");
1027 fprintf(stderr, "Failed to open %s for reading !\n", filename);
1031 fseek(f, 0, SEEK_SET);
1032 fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);
1036 while (signtmp[i]!='\0') {
1037 if (signtmp[i]=='-') sign='-';
1042 if (endian1=='M' && endian2=='L') {
1044 } else if (endian2=='M' && endian1=='L') {
1047 fprintf(stderr, "Bad pgx header, please check input file\n");
1051 /* initialize image component */
1053 cmptparm.x0 = parameters->image_offset_x0;
1054 cmptparm.y0 = parameters->image_offset_y0;
1055 cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
1056 cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
1063 cmptparm.prec = prec;
1064 cmptparm.bpp = prec;
1065 cmptparm.dx = parameters->subsampling_dx;
1066 cmptparm.dy = parameters->subsampling_dy;
1068 /* create the image */
1069 image = opj_image_create(numcomps, &cmptparm, color_space);
1074 /* set image offset and reference grid */
1075 image->x0 = cmptparm.x0;
1076 image->y0 = cmptparm.x0;
1077 image->x1 = cmptparm.w;
1078 image->y1 = cmptparm.h;
1080 /* set image data */
1082 comp = &image->comps[0];
1084 for (i = 0; i < w * h; i++) {
1086 if (comp->prec <= 8) {
1090 v = (char) readuchar(f);
1092 } else if (comp->prec <= 16) {
1094 v = readushort(f, bigendian);
1096 v = (short) readushort(f, bigendian);
1100 v = readuint(f, bigendian);
1102 v = (int) readuint(f, bigendian);
1110 comp->bpp = int_floorlog2(max) + 1;
1115 int imagetopgx(opj_image_t * image, const char *outfile) {
1120 for (compno = 0; compno < image->numcomps; compno++) {
1121 opj_image_comp_t *comp = &image->comps[compno];
1122 char bname[256]; /* buffer for name */
1123 char *name = bname; /* pointer */
1125 const size_t olen = strlen(outfile);
1126 const size_t dotpos = olen - 4;
1127 const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */
1128 if( outfile[dotpos] != '.' ) {
1129 /* `pgx` was recognized but there is no dot at expected position */
1130 fprintf(stderr, "ERROR -> Impossible happen." );
1134 name = (char*)malloc(total+1);
1136 strncpy(name, outfile, dotpos);
1137 if (image->numcomps > 1) {
1138 sprintf(name+dotpos, "-%d.pgx", compno);
1140 strcpy(name+dotpos, ".pgx");
1142 fdest = fopen(name, "wb");
1144 fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1147 /* dont need name anymore */
1152 w = image->comps[compno].w;
1153 h = image->comps[compno].h;
1155 fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, w, h);
1156 if (comp->prec <= 8) {
1158 } else if (comp->prec <= 16) {
1163 for (i = 0; i < w * h; i++) {
1164 int v = image->comps[compno].data[i];
1165 for (j = nbytes - 1; j >= 0; j--) {
1166 char byte = (char) (v >> (j * 8));
1167 fwrite(&byte, 1, 1, fdest);
1176 /* -->> -->> -->> -->>
1180 <<-- <<-- <<-- <<-- */
1182 opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
1183 int subsampling_dx = parameters->subsampling_dx;
1184 int subsampling_dy = parameters->subsampling_dy;
1187 int i, compno, numcomps, w, h;
1188 OPJ_COLOR_SPACE color_space;
1189 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
1190 opj_image_t * image = NULL;
1193 f = fopen(filename, "rb");
1195 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
1199 if (fgetc(f) != 'P')
1204 case '2': /* greyscale image type */
1207 color_space = CLRSPC_GRAY;
1210 case '3': /* RGB image type */
1213 color_space = CLRSPC_SRGB;
1224 while(fgetc(f) == '#') while(fgetc(f) != '\n');
1226 fseek(f, -1, SEEK_CUR);
1227 fscanf(f, "%d %d\n255", &w, &h);
1228 fgetc(f); /* <cr><lf> */
1230 /* initialize image components */
1231 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1232 for(i = 0; i < numcomps; i++) {
1233 cmptparm[i].prec = 8;
1234 cmptparm[i].bpp = 8;
1235 cmptparm[i].sgnd = 0;
1236 cmptparm[i].dx = subsampling_dx;
1237 cmptparm[i].dy = subsampling_dy;
1241 /* create the image */
1242 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1248 /* set image offset and reference grid */
1249 image->x0 = parameters->image_offset_x0;
1250 image->y0 = parameters->image_offset_y0;
1251 image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
1252 image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
1254 /* set image data */
1256 if ((value == '2') || (value == '3')) { /* ASCII */
1257 for (i = 0; i < w * h; i++) {
1258 for(compno = 0; compno < numcomps; compno++) {
1259 unsigned int index = 0;
1260 fscanf(f, "%u", &index);
1261 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
1262 image->comps[compno].data[i] = index;
1265 } else if ((value == '5') || (value == '6')) { /* BINARY */
1266 for (i = 0; i < w * h; i++) {
1267 for(compno = 0; compno < numcomps; compno++) {
1268 unsigned char index = 0;
1269 fread(&index, 1, 1, f);
1270 /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
1271 image->comps[compno].data[i] = index;
1281 int imagetopnm(opj_image_t * image, const char *outfile) {
1282 int w, wr, h, hr, max;
1284 int adjustR, adjustG, adjustB, adjustX;
1287 const char *tmp = outfile;
1296 if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
1297 && image->comps[1].dx == image->comps[2].dx
1298 && image->comps[0].dy == image->comps[1].dy
1299 && image->comps[1].dy == image->comps[2].dy
1300 && image->comps[0].prec == image->comps[1].prec
1301 && image->comps[1].prec == image->comps[2].prec
1302 && S2 !='g' && S2 !='G') {
1304 fdest = fopen(outfile, "wb");
1306 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1310 w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
1311 wr = image->comps[0].w;
1313 h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
1314 hr = image->comps[0].h;
1316 max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1;
1318 image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor);
1319 image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 - int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor);
1321 fprintf(fdest, "P6\n%d %d\n%d\n", wr, hr, max);
1323 if (image->comps[0].prec > 8) {
1324 adjustR = image->comps[0].prec - 8;
1325 printf("PNM CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
1329 if (image->comps[1].prec > 8) {
1330 adjustG = image->comps[1].prec - 8;
1331 printf("PNM CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
1335 if (image->comps[2].prec > 8) {
1336 adjustB = image->comps[2].prec - 8;
1337 printf("PNM CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
1343 for (i = 0; i < wr * hr; i++) {
1345 unsigned char rc,gc,bc;
1346 r = image->comps[0].data[i];
1347 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
1348 rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2));
1350 g = image->comps[1].data[i];
1351 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
1352 gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2));
1354 b = image->comps[2].data[i];
1355 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
1356 bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2));
1358 fprintf(fdest, "%c%c%c", rc, gc, bc);
1363 int ncomp=(S2=='g' || S2=='G')?1:image->numcomps;
1364 if (image->numcomps > ncomp) {
1365 fprintf(stderr,"WARNING -> [PGM files] Only the first component\n");
1366 fprintf(stderr," is written to the file\n");
1368 for (compno = 0; compno < ncomp; compno++) {
1371 sprintf(name, "%d.%s", compno, outfile);
1373 sprintf(name, "%s", outfile);
1376 fdest = fopen(name, "wb");
1378 fprintf(stderr, "ERROR -> failed to open %s for writing\n", name);
1382 w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx);
1383 wr = image->comps[compno].w;
1385 h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy);
1386 hr = image->comps[compno].h;
1388 max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1;
1390 image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor);
1391 image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor);
1393 fprintf(fdest, "P5\n%d %d\n%d\n", wr, hr, max);
1395 if (image->comps[compno].prec > 8) {
1396 adjustX = image->comps[0].prec - 8;
1397 printf("PNM CONVERSION: Truncating component %d from %d bits to 8 bits\n",compno, image->comps[compno].prec);
1402 for (i = 0; i < wr * hr; i++) {
1405 l = image->comps[compno].data[i];
1406 l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);
1407 lc = (unsigned char) ((l >> adjustX)+((l >> (adjustX-1))%2));
1408 fprintf(fdest, "%c", lc);
1418 /* -->> -->> -->> -->>
1422 <<-- <<-- <<-- <<-- */
1424 typedef struct tiff_infoheader{
1425 DWORD tiWidth; // Width of Image in pixel
1426 DWORD tiHeight; // Height of Image in pixel
1427 DWORD tiPhoto; // Photometric
1428 WORD tiBps; // Bits per sample
1429 WORD tiSf; // Sample Format
1430 WORD tiSpp; // Sample per pixel 1-bilevel,gray scale , 2- RGB
1431 WORD tiPC; // Planar config (1-Interleaved, 2-Planarcomp)
1434 int imagetotif(opj_image_t * image, const char *outfile) {
1435 int width, height, imgsize;
1436 int bps,index,adjust = 0;
1443 if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx
1444 && image->comps[1].dx == image->comps[2].dx
1445 && image->comps[0].dy == image->comps[1].dy
1446 && image->comps[1].dy == image->comps[2].dy
1447 && image->comps[0].prec == image->comps[1].prec
1448 && image->comps[1].prec == image->comps[2].prec) {
1454 tif = TIFFOpen(outfile, "wb");
1456 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1460 width = image->comps[0].w;
1461 height = image->comps[0].h;
1462 imgsize = width * height ;
1463 bps = image->comps[0].prec;
1465 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1466 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1467 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
1468 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1469 TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1470 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1471 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1472 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1474 /* Get a buffer for the data */
1475 strip_size=TIFFStripSize(tif);
1476 buf = _TIFFmalloc(strip_size);
1478 adjust = image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0;
1479 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1480 unsigned char *dat8;
1482 ssize = TIFFStripSize(tif);
1483 dat8 = (unsigned char*)buf;
1484 if (image->comps[0].prec == 8){
1485 for (i=0; i<ssize-2; i+=3) { // 8 bits per pixel
1486 int r = 0,g = 0,b = 0;
1487 if(index < imgsize){
1488 r = image->comps[0].data[index];
1489 g = image->comps[1].data[index];
1490 b = image->comps[2].data[index];
1491 if (image->comps[0].sgnd){
1496 dat8[i+0] = r ; // R
1497 dat8[i+1] = g ; // G
1498 dat8[i+2] = b ; // B
1505 for (i=last_i; i<ssize; i+=3) { // 8 bits per pixel
1506 int r = 0,g = 0,b = 0;
1507 if(index < imgsize){
1508 r = image->comps[0].data[index];
1509 g = image->comps[1].data[index];
1510 b = image->comps[2].data[index];
1511 if (image->comps[0].sgnd){
1516 dat8[i+0] = r ; // R
1517 if(i+1 <ssize) dat8[i+1] = g ; else break;// G
1518 if(i+2 <ssize) dat8[i+2] = b ; else break;// B
1524 }else if (image->comps[0].prec == 12){
1525 for (i=0; i<ssize-8; i+=9) { // 12 bits per pixel
1526 int r = 0,g = 0,b = 0;
1527 int r1 = 0,g1 = 0,b1 = 0;
1528 if((index < imgsize)&(index+1 < imgsize)){
1529 r = image->comps[0].data[index];
1530 g = image->comps[1].data[index];
1531 b = image->comps[2].data[index];
1532 r1 = image->comps[0].data[index+1];
1533 g1 = image->comps[1].data[index+1];
1534 b1 = image->comps[2].data[index+1];
1535 if (image->comps[0].sgnd){
1543 dat8[i+0] = (r >> 4);
1544 dat8[i+1] = ((r & 0x0f) << 4 )|((g >> 8)& 0x0f);
1546 dat8[i+3] = (b >> 4);
1547 dat8[i+4] = ((b & 0x0f) << 4 )|((r1 >> 8)& 0x0f);
1549 dat8[i+6] = (g1 >> 4);
1550 dat8[i+7] = ((g1 & 0x0f)<< 4 )|((b1 >> 8)& 0x0f);
1558 for (i= last_i; i<ssize; i+=9) { // 12 bits per pixel
1559 int r = 0,g = 0,b = 0;
1560 int r1 = 0,g1 = 0,b1 = 0;
1561 if((index < imgsize)&(index+1 < imgsize)){
1562 r = image->comps[0].data[index];
1563 g = image->comps[1].data[index];
1564 b = image->comps[2].data[index];
1565 r1 = image->comps[0].data[index+1];
1566 g1 = image->comps[1].data[index+1];
1567 b1 = image->comps[2].data[index+1];
1568 if (image->comps[0].sgnd){
1576 dat8[i+0] = (r >> 4);
1577 if(i+1 <ssize) dat8[i+1] = ((r & 0x0f) << 4 )|((g >> 8)& 0x0f); else break;
1578 if(i+2 <ssize) dat8[i+2] = g ; else break;
1579 if(i+3 <ssize) dat8[i+3] = (b >> 4); else break;
1580 if(i+4 <ssize) dat8[i+4] = ((b & 0x0f) << 4 )|((r1 >> 8)& 0x0f);else break;
1581 if(i+5 <ssize) dat8[i+5] = r1; else break;
1582 if(i+6 <ssize) dat8[i+6] = (g1 >> 4); else break;
1583 if(i+7 <ssize) dat8[i+7] = ((g1 & 0x0f)<< 4 )|((b1 >> 8)& 0x0f);else break;
1584 if(i+8 <ssize) dat8[i+8] = b1; else break;
1590 }else if (image->comps[0].prec == 16){
1591 for (i=0 ; i<ssize-5 ; i+=6) { // 16 bits per pixel
1592 int r = 0,g = 0,b = 0;
1593 if(index < imgsize){
1594 r = image->comps[0].data[index];
1595 g = image->comps[1].data[index];
1596 b = image->comps[2].data[index];
1597 if (image->comps[0].sgnd){
1603 dat8[i+1] = (r >> 8);//MSB
1605 dat8[i+3] = (g >> 8);
1607 dat8[i+5] = (b >> 8);
1614 for (i=0 ; i<ssize ; i+=6) { // 16 bits per pixel
1615 int r = 0,g = 0,b = 0;
1616 if(index < imgsize){
1617 r = image->comps[0].data[index];
1618 g = image->comps[1].data[index];
1619 b = image->comps[2].data[index];
1620 if (image->comps[0].sgnd){
1626 if(i+1 <ssize) dat8[i+1] = (r >> 8);else break;//MSB
1627 if(i+2 <ssize) dat8[i+2] = g; else break;
1628 if(i+3 <ssize) dat8[i+3] = (g >> 8);else break;
1629 if(i+4 <ssize) dat8[i+4] = b; else break;
1630 if(i+5 <ssize) dat8[i+5] = (b >> 8);else break;
1637 fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1638 fprintf(stderr,"Aborting\n");
1641 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1645 }else if (image->numcomps == 1){
1650 tif = TIFFOpen(outfile, "wb");
1652 fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile);
1656 width = image->comps[0].w;
1657 height = image->comps[0].h;
1658 imgsize = width * height;
1659 bps = image->comps[0].prec;
1662 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
1663 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
1664 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
1665 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
1666 TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
1667 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1668 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
1669 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
1671 /* Get a buffer for the data */
1672 strip_size = TIFFStripSize(tif);
1673 buf = _TIFFmalloc(strip_size);
1675 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1676 unsigned char *dat8;
1678 dat8 = (unsigned char*)buf;
1679 if (image->comps[0].prec == 8){
1680 for (i=0; i<TIFFStripSize(tif); i+=1) { // 8 bits per pixel
1681 if(index < imgsize){
1683 r = image->comps[0].data[index];
1684 if (image->comps[0].sgnd){
1692 }else if (image->comps[0].prec == 12){
1693 for (i = 0; i<TIFFStripSize(tif); i+=3) { // 12 bits per pixel
1694 if(index < imgsize){
1696 r = image->comps[0].data[index];
1697 r1 = image->comps[0].data[index+1];
1698 if (image->comps[0].sgnd){
1702 dat8[i+0] = (r >> 4);
1703 dat8[i+1] = ((r & 0x0f) << 4 )|((r1 >> 8)& 0x0f);
1709 }else if (image->comps[0].prec == 16){
1710 for (i=0; i<TIFFStripSize(tif); i+=2) { // 16 bits per pixel
1711 if(index < imgsize){
1713 r = image->comps[0].data[index];
1714 if (image->comps[0].sgnd){
1724 fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec);
1725 fprintf(stderr,"Aborting\n");
1728 TIFFWriteEncodedStrip(tif, strip, buf, strip_size);
1733 fprintf(stderr,"TIFF file creation. Bad color format. Only RGB & Grayscale has been implemented\n");
1734 fprintf(stderr,"Aborting\n");
1740 opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
1742 int subsampling_dx = parameters->subsampling_dx;
1743 int subsampling_dy = parameters->subsampling_dy;
1745 tiff_infoheader_t Info;
1749 int j, numcomps, w, h,index;
1750 OPJ_COLOR_SPACE color_space;
1751 opj_image_cmptparm_t cmptparm[3];
1752 opj_image_t * image = NULL;
1755 tif = TIFFOpen(filename, "r");
1758 fprintf(stderr, "Failed to open %s for reading\n", filename);
1762 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &Info.tiWidth);
1763 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &Info.tiHeight);
1764 TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &Info.tiBps);
1765 TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &Info.tiSf);
1766 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &Info.tiSpp);
1768 TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &Info.tiPhoto);
1769 TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &Info.tiPC);
1773 if (Info.tiPhoto == 2) {
1779 color_space = CLRSPC_SRGB;
1780 /* initialize image components*/
1781 memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
1782 for(j = 0; j < numcomps; j++) {
1783 if (parameters->cp_cinema) {
1784 cmptparm[j].prec = 12;
1785 cmptparm[j].bpp = 12;
1787 cmptparm[j].prec = Info.tiBps;
1788 cmptparm[j].bpp = Info.tiBps;
1790 cmptparm[j].sgnd = 0;
1791 cmptparm[j].dx = subsampling_dx;
1792 cmptparm[j].dy = subsampling_dy;
1796 /* create the image*/
1797 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1803 /* set image offset and reference grid */
1804 image->x0 = parameters->image_offset_x0;
1805 image->y0 = parameters->image_offset_y0;
1806 image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1807 image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1809 buf = _TIFFmalloc(TIFFStripSize(tif));
1811 strip_size=TIFFStripSize(tif);
1813 imgsize = image->comps[0].w * image->comps[0].h ;
1814 /* Read the Image components*/
1815 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1816 unsigned char *dat8;
1818 ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1819 dat8 = (unsigned char*)buf;
1821 if (Info.tiBps==12){
1822 for (i=0; i<ssize; i+=9) { /*12 bits per pixel*/
1823 if((index < imgsize)&(index+1 < imgsize)){
1824 image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4);
1825 image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1826 image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4);
1827 image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
1828 image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4);
1829 image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
1835 else if( Info.tiBps==16){
1836 for (i=0; i<ssize; i+=6) { /* 16 bits per pixel */
1837 if(index < imgsize){
1838 image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; // R
1839 image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; // G
1840 image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; // B
1841 if(parameters->cp_cinema){/* Rounding to 12 bits*/
1842 image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ;
1843 image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ;
1844 image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ;
1851 else if ( Info.tiBps==8){
1852 for (i=0; i<ssize; i+=3) { /* 8 bits per pixel */
1853 if(index < imgsize){
1854 image->comps[0].data[index] = dat8[i+0];// R
1855 image->comps[1].data[index] = dat8[i+1];// G
1856 image->comps[2].data[index] = dat8[i+2];// B
1857 if(parameters->cp_cinema){/* Rounding to 12 bits*/
1858 image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
1859 image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
1860 image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
1868 fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1869 fprintf(stderr,"Aborting\n");
1876 }else if(Info.tiPhoto == 1) {
1882 color_space = CLRSPC_GRAY;
1883 /* initialize image components*/
1884 memset(&cmptparm[0], 0, sizeof(opj_image_cmptparm_t));
1885 cmptparm[0].prec = Info.tiBps;
1886 cmptparm[0].bpp = Info.tiBps;
1887 cmptparm[0].sgnd = 0;
1888 cmptparm[0].dx = subsampling_dx;
1889 cmptparm[0].dy = subsampling_dy;
1893 /* create the image*/
1894 image = opj_image_create(numcomps, &cmptparm[0], color_space);
1899 /* set image offset and reference grid */
1900 image->x0 = parameters->image_offset_x0;
1901 image->y0 = parameters->image_offset_y0;
1902 image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1;
1903 image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1;
1905 buf = _TIFFmalloc(TIFFStripSize(tif));
1907 strip_size = TIFFStripSize(tif);
1909 imgsize = image->comps[0].w * image->comps[0].h ;
1910 /* Read the Image components*/
1911 for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
1912 unsigned char *dat8;
1914 ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
1915 dat8 = (unsigned char*)buf;
1917 if (Info.tiBps==12){
1918 for (i=0; i<ssize; i+=3) { /* 12 bits per pixel*/
1919 if(index < imgsize){
1920 image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4) ;
1921 image->comps[0].data[index+1] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
1927 else if( Info.tiBps==16){
1928 for (i=0; i<ssize; i+=2) { /* 16 bits per pixel */
1929 if(index < imgsize){
1930 image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
1936 else if ( Info.tiBps==8){
1937 for (i=0; i<ssize; i+=1) { /* 8 bits per pixel */
1938 if(index < imgsize){
1939 image->comps[0].data[index] = dat8[i+0];
1946 fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps);
1947 fprintf(stderr,"Aborting\n");
1955 fprintf(stderr,"TIFF file creation. Bad color format. Only RGB & Grayscale has been implemented\n");
1956 fprintf(stderr,"Aborting\n");
1962 #endif /* HAVE_LIBTIFF */
1964 /* -->> -->> -->> -->>
1968 <<-- <<-- <<-- <<-- */
1970 opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) {
1971 int subsampling_dx = parameters->subsampling_dx;
1972 int subsampling_dy = parameters->subsampling_dy;
1975 int i, compno, numcomps, w, h;
1976 OPJ_COLOR_SPACE color_space;
1977 opj_image_cmptparm_t *cmptparm;
1978 opj_image_t * image = NULL;
1981 if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0)
1983 fprintf(stderr,"\nError: invalid raw image parameters\n");
1984 fprintf(stderr,"Please use the Format option -F:\n");
1985 fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
1986 fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
1987 fprintf(stderr,"Aborting\n");
1991 f = fopen(filename, "rb");
1993 fprintf(stderr, "Failed to open %s for reading !!\n", filename);
1994 fprintf(stderr,"Aborting\n");
1997 numcomps = raw_cp->rawComp;
1998 color_space = CLRSPC_SRGB;
1999 w = raw_cp->rawWidth;
2000 h = raw_cp->rawHeight;
2001 cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t));
2003 /* initialize image components */
2004 memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
2005 for(i = 0; i < numcomps; i++) {
2006 cmptparm[i].prec = raw_cp->rawBitDepth;
2007 cmptparm[i].bpp = raw_cp->rawBitDepth;
2008 cmptparm[i].sgnd = raw_cp->rawSigned;
2009 cmptparm[i].dx = subsampling_dx;
2010 cmptparm[i].dy = subsampling_dy;
2014 /* create the image */
2015 image = opj_image_create(numcomps, &cmptparm[0], color_space);
2020 /* set image offset and reference grid */
2021 image->x0 = parameters->image_offset_x0;
2022 image->y0 = parameters->image_offset_y0;
2023 image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
2024 image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
2026 if(raw_cp->rawBitDepth <= 8)
2028 unsigned char value = 0;
2029 for(compno = 0; compno < numcomps; compno++) {
2030 for (i = 0; i < w * h; i++) {
2031 if (!fread(&value, 1, 1, f)) {
2032 fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2035 image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value;
2039 else if(raw_cp->rawBitDepth <= 16)
2041 unsigned short value;
2042 for(compno = 0; compno < numcomps; compno++) {
2043 for (i = 0; i < w * h; i++) {
2045 if (!fread(&temp, 1, 1, f)) {
2046 fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2050 if (!fread(&temp, 1, 1, f)) {
2051 fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
2055 image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value;
2060 fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n");
2064 if (fread(&ch, 1, 1, f)) {
2065 fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n");
2072 int imagetoraw(opj_image_t * image, const char *outfile)
2074 FILE *rawFile = NULL;
2080 if((image->numcomps * image->x1 * image->y1) == 0)
2082 fprintf(stderr,"\nError: invalid raw image parameters\n");
2086 rawFile = fopen(outfile, "wb");
2088 fprintf(stderr, "Failed to open %s for writing !!\n", outfile);
2092 fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps);
2094 for(compno = 0; compno < image->numcomps; compno++)
2096 fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w,
2097 image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned");
2099 w = image->comps[compno].w;
2100 h = image->comps[compno].h;
2102 if(image->comps[compno].prec <= 8)
2104 if(image->comps[compno].sgnd == 1)
2107 int mask = (1 << image->comps[compno].prec) - 1;
2108 ptr = image->comps[compno].data;
2109 for (line = 0; line < h; line++) {
2110 for(row = 0; row < w; row++) {
2111 curr = (signed char) (*ptr & mask);
2112 fwrite(&curr, sizeof(signed char), 1, rawFile);
2117 else if(image->comps[compno].sgnd == 0)
2120 int mask = (1 << image->comps[compno].prec) - 1;
2121 ptr = image->comps[compno].data;
2122 for (line = 0; line < h; line++) {
2123 for(row = 0; row < w; row++) {
2124 curr = (unsigned char) (*ptr & mask);
2125 fwrite(&curr, sizeof(unsigned char), 1, rawFile);
2131 else if(image->comps[compno].prec <= 16)
2133 if(image->comps[compno].sgnd == 1)
2135 signed short int curr;
2136 int mask = (1 << image->comps[compno].prec) - 1;
2137 ptr = image->comps[compno].data;
2138 for (line = 0; line < h; line++) {
2139 for(row = 0; row < w; row++) {
2141 curr = (signed short int) (*ptr & mask);
2142 temp = (unsigned char) (curr >> 8);
2143 fwrite(&temp, 1, 1, rawFile);
2144 temp = (unsigned char) curr;
2145 fwrite(&temp, 1, 1, rawFile);
2150 else if(image->comps[compno].sgnd == 0)
2152 unsigned short int curr;
2153 int mask = (1 << image->comps[compno].prec) - 1;
2154 ptr = image->comps[compno].data;
2155 for (line = 0; line < h; line++) {
2156 for(row = 0; row < w; row++) {
2158 curr = (unsigned short int) (*ptr & mask);
2159 temp = (unsigned char) (curr >> 8);
2160 fwrite(&temp, 1, 1, rawFile);
2161 temp = (unsigned char) curr;
2162 fwrite(&temp, 1, 1, rawFile);
2168 else if (image->comps[compno].prec <= 32)
2170 fprintf(stderr,"More than 16 bits per component no handled yet\n");
2175 fprintf(stderr,"Error: invalid precision: %d\n", image->comps[compno].prec);
2185 #define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a"
2186 #define MAGIC_SIZE 8
2187 /* PNG allows bits per sample: 1, 2, 4, 8, 16 */
2189 opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
2192 printf("Error. PNG format is not yet handled under windows\n");
2199 double gamma, display_exponent;
2200 int bit_depth, interlace_type,compression_type, filter_type;
2202 png_uint_32 resx, resy;
2204 png_uint_32 width, height;
2205 int color_type, has_alpha, is16;
2208 unsigned char **rows;
2211 opj_image_cmptparm_t cmptparm[4];
2213 unsigned int nr_comp;
2215 unsigned char sigbuf[8];
2217 if((reader = fopen(read_idf, "rb")) == NULL)
2219 fprintf(stderr,"pngtoimage: can not open %s\n",read_idf);
2222 image = NULL; png = NULL; rows = NULL;
2224 if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE
2225 || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0)
2227 fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf);
2230 /* libpng-VERSION/example.c:
2231 * PC : screen_gamma = 2.2;
2232 * Mac: screen_gamma = 1.7 or 1.0;
2234 display_exponent = 2.2;
2236 if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
2237 NULL, NULL, NULL)) == NULL)
2239 if((info = png_create_info_struct(png)) == NULL)
2242 if(setjmp(png_jmpbuf(png)))
2245 png_init_io(png, reader);
2246 png_set_sig_bytes(png, MAGIC_SIZE);
2248 png_read_info(png, info);
2250 if(png_get_IHDR(png, info, &width, &height,
2251 &bit_depth, &color_type, &interlace_type,
2252 &compression_type, &filter_type) == 0)
2255 /* png_set_expand():
2256 * expand paletted images to RGB, expand grayscale images of
2257 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
2258 * to alpha channels.
2260 if(color_type == PNG_COLOR_TYPE_PALETTE)
2261 png_set_expand(png);
2263 if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
2264 png_set_expand(png);
2266 if(png_get_valid(png, info, PNG_INFO_tRNS))
2267 png_set_expand(png);
2269 is16 = (bit_depth == 16);
2271 /* GRAY => RGB; GRAY_ALPHA => RGBA
2273 if(color_type == PNG_COLOR_TYPE_GRAY
2274 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2276 png_set_gray_to_rgb(png);
2278 (color_type == PNG_COLOR_TYPE_GRAY? PNG_COLOR_TYPE_RGB:
2279 PNG_COLOR_TYPE_RGB_ALPHA);
2281 if( !png_get_gAMA(png, info, &gamma))
2284 png_set_gamma(png, display_exponent, gamma);
2286 png_read_update_info(png, info);
2288 png_get_pHYs(png, info, &resx, &resy, &unit);
2290 color_type = png_get_color_type(png, info);
2292 has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA);
2294 nr_comp = 3 + has_alpha;
2296 bit_depth = png_get_bit_depth(png, info);
2298 rows = (unsigned char**)calloc(height+1, sizeof(unsigned char*));
2299 for(i = 0; i < height; ++i)
2300 rows[i] = (unsigned char*)malloc(png_get_rowbytes(png,info));
2302 png_read_image(png, rows);
2304 memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
2306 sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy;
2308 for(i = 0; i < nr_comp; ++i)
2310 cmptparm[i].prec = bit_depth;
2311 /* bits_per_pixel: 8 or 16 */
2312 cmptparm[i].bpp = bit_depth;
2313 cmptparm[i].sgnd = 0;
2314 cmptparm[i].dx = sub_dx;
2315 cmptparm[i].dy = sub_dy;
2316 cmptparm[i].w = width;
2317 cmptparm[i].h = height;
2320 image = opj_image_create(nr_comp, &cmptparm[0], CLRSPC_SRGB);
2322 if(image == NULL) goto fin;
2324 image->x0 = params->image_offset_x0;
2325 image->y0 = params->image_offset_y0;
2326 image->x1 = image->x0 + (width - 1) * sub_dx + 1 + image->x0;
2327 image->y1 = image->y0 + (height - 1) * sub_dy + 1 + image->y0;
2329 r = image->comps[0].data;
2330 g = image->comps[1].data;
2331 b = image->comps[2].data;
2332 a = image->comps[3].data;
2334 for(i = 0; i < height; ++i)
2338 for(j = 0; j < width; ++j)
2342 *r++ = s[0]<<8|s[1]; s += 2;
2344 *g++ = s[0]<<8|s[1]; s += 2;
2346 *b++ = s[0]<<8|s[1]; s += 2;
2348 if(has_alpha) { *a++ = s[0]<<8|s[1]; s += 2; }
2352 *r++ = *s++; *g++ = *s++; *b++ = *s++;
2354 if(has_alpha) *a++ = *s++;
2360 for(i = 0; i < height; ++i)
2365 png_destroy_read_struct(&png, &info, NULL);
2374 int imagetopng(opj_image_t * image, const char *write_idf)
2377 printf("Error. PNG format is not yet handled under windows\n");
2385 int *red, *green, *blue, *alpha;
2386 unsigned char *row_buf, *d;
2387 int has_alpha, width, height, nr_comp, color_type;
2388 int adjust, x, y, fails, is16;
2390 unsigned short mask;
2391 png_color_8 sig_bit;
2393 prec = opj_prec = image->comps[0].prec;
2395 if(prec > 8) prec = 16;
2397 if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16)
2399 fprintf(stderr,"imagetopng: can not create %s"
2400 "\n\twrong bit_depth %d\n", write_idf, prec);
2403 writer = fopen(write_idf, "wb");
2405 if(writer == NULL) return 1;
2407 info = NULL; fails = 1; has_alpha = 0;
2409 /* Create and initialize the png_struct with the desired error handler
2410 * functions. If you want to use the default stderr and longjump method,
2411 * you can supply NULL for the last three parameters. We also check that
2412 * the library version is compatible with the one used at compile time,
2413 * in case we are using dynamically linked libraries. REQUIRED.
2415 png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2417 /*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */
2419 if(png == NULL) goto fin;
2421 /* Allocate/initialize the image information data. REQUIRED
2423 info = png_create_info_struct(png);
2425 if(info == NULL) goto fin;
2427 /* Set error handling. REQUIRED if you are not supplying your own
2428 * error handling functions in the png_create_write_struct() call.
2430 if(setjmp(png_jmpbuf(png))) goto fin;
2432 /* I/O initialization functions is REQUIRED
2434 png_init_io(png, writer);
2436 /* Set the image information here. Width and height are up to 2^31,
2437 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
2438 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
2439 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
2440 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
2441 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
2442 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE.
2445 png_set_compression_level(png, Z_BEST_COMPRESSION);
2448 if(image->comps[0].sgnd) adjust = 1 << (opj_prec - 1);
2450 if(prec == 8) mask = 0x00ff;
2452 if(prec == 4) mask = 0x000f;
2454 if(prec == 2) mask = 0x0003;
2456 if(prec == 1) mask = 0x0001;
2458 if(opj_prec == 12) mask = 0x0fff;
2462 nr_comp = image->numcomps;
2465 && image->comps[0].dx == image->comps[1].dx
2466 && image->comps[1].dx == image->comps[2].dx
2467 && image->comps[0].dy == image->comps[1].dy
2468 && image->comps[1].dy == image->comps[2].dy
2469 && image->comps[0].prec == image->comps[1].prec
2470 && image->comps[1].prec == image->comps[2].prec)
2472 has_alpha = (nr_comp > 3);
2474 is16 = (prec == 16);
2476 width = image->comps[0].w;
2477 height = image->comps[0].h;
2479 red = image->comps[0].data;
2480 green = image->comps[1].data;
2481 blue = image->comps[2].data;
2483 sig_bit.red = sig_bit.green = sig_bit.blue = prec;
2487 sig_bit.alpha = prec;
2488 alpha = image->comps[3].data;
2489 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
2493 sig_bit.alpha = 0; alpha = NULL;
2494 color_type = PNG_COLOR_TYPE_RGB;
2496 png_set_sBIT(png, info, &sig_bit);
2498 png_set_IHDR(png, info, width, height, prec,
2501 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2503 /*=============================*/
2504 png_write_info(png, info);
2505 /*=============================*/
2507 /* Shift the pixels up to a legal bit depth and fill in
2508 * as appropriate to correctly scale the image.
2510 if(opj_prec > 8 && opj_prec < 16)
2512 png_set_shift(png, &sig_bit);
2516 png_set_packing(png);
2519 row_buf = (unsigned char*)malloc(width * nr_comp * 2);
2521 for(y = 0; y < height; ++y)
2525 for(x = 0; x < width; ++x)
2529 /* Network byte order */
2532 v = (unsigned short)((*red + adjust) & mask); ++red;
2533 *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2534 v = (unsigned short)((*green + adjust) & mask); ++green;
2535 *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2536 v = (unsigned short)((*blue + adjust) & mask); ++blue;
2537 *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2541 v = (unsigned short)((*alpha + adjust) & mask); ++alpha;
2542 *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
2546 *d++ = (unsigned char)((*red + adjust) & mask); ++red;
2547 *d++ = (unsigned char)((*green + adjust) & mask); ++green;
2548 *d++ = (unsigned char)((*blue + adjust) & mask); ++blue;
2552 *d++ = (unsigned char)((*alpha + adjust) & mask); ++alpha;
2556 png_write_row(png, row_buf);
2563 if(nr_comp == 1 /* GRAY */
2564 || ( nr_comp == 2 /* GRAY_ALPHA */
2565 && image->comps[0].dx == image->comps[1].dx
2566 && image->comps[0].dy == image->comps[1].dy
2567 && image->comps[0].prec == image->comps[1].prec))
2569 red = image->comps[0].data;
2571 sig_bit.gray = prec;
2572 sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0;
2574 color_type = PNG_COLOR_TYPE_GRAY;
2578 has_alpha = 1; sig_bit.alpha = prec;
2579 alpha = image->comps[1].data;
2580 color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
2582 width = image->comps[0].w;
2583 height = image->comps[0].h;
2585 png_set_IHDR(png, info, width, height, sig_bit.gray,
2588 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2590 png_set_sBIT(png, info, &sig_bit);
2591 #ifdef TEST_WITH_GAMMA
2592 png_set_gAMA(png, info, 1.0);
2594 /*=============================*/
2595 png_write_info(png, info);
2596 /*=============================*/
2598 /* Shift the pixels up to a legal bit depth and fill in
2599 * as appropriate to correctly scale the image.
2601 if(opj_prec > 8 && opj_prec < 16)
2603 png_set_shift(png, &sig_bit);
2607 png_set_packing(png);
2612 /* Network byte order */
2615 row_buf = (unsigned char*)
2616 malloc(width * nr_comp * sizeof(unsigned short));
2618 if(opj_prec == 12) mask = 0x0fff;
2620 for(y = 0; y < height; ++y)
2624 for(x = 0; x < width; ++x)
2626 v = (unsigned short)((*red + adjust) & mask); ++red;
2627 *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)(v & 0xff);
2631 v = (unsigned short)((*alpha + adjust) & mask); ++alpha;
2632 *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)(v & 0xff);
2635 png_write_row(png, row_buf);
2640 else /* prec <= 8 */
2642 row_buf = (unsigned char*)calloc(width, nr_comp * 2);
2644 for(y = 0; y < height; ++y)
2648 for(x = 0; x < width; ++x)
2650 *d++ = (unsigned char)((*red + adjust) & mask); ++red;
2654 *d++ = (unsigned char)((*alpha + adjust) & mask); ++alpha;
2658 png_write_row(png, row_buf);
2666 fprintf(stderr,"imagetopng: can not create %s\n",write_idf);
2669 png_write_end(png, info);
2677 png_destroy_write_struct(&png, &info);
2684 #endif /* HAVE_LIBPNG */