X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=codec%2Fconvert.c;h=9493e8b66132d8d0651e0d805c095d5b6e5e04cf;hb=2f9e80da9c96a278da7e608a7007a64cb6430ccd;hp=3ff6eb88d2d6af3aff587eebd862f3d8b63d353b;hpb=192e46c32f7baededf8df7b1777f8c5409110e8a;p=openjpeg.git diff --git a/codec/convert.c b/codec/convert.c index 3ff6eb88..9493e8b6 100644 --- a/codec/convert.c +++ b/codec/convert.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,8 +32,15 @@ #include #include #include -#include "openjpeg.h" +#ifdef WIN32 #include "../libs/libtiff/tiffio.h" +#include "../libs/libpng/png.h" +#else +#include +#include +#endif /* WIN32 */ +#include "openjpeg.h" +#include "convert.h" /* * Get logarithm of an integer and round downwards. @@ -65,6 +73,300 @@ static int int_ceildiv(int a, int b) { return (a + b - 1) / b; } + +/* -->> -->> -->> -->> + + TGA IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +// TGA header definition. +#pragma pack(push,1) // Pack structure byte aligned +typedef struct tga_header +{ + uint8 id_length; /* Image id field length */ + uint8 colour_map_type; /* Colour map type */ + uint8 image_type; /* Image type */ + /* + ** Colour map specification + */ + uint16 colour_map_index; /* First entry index */ + uint16 colour_map_length; /* Colour map length */ + uint8 colour_map_entry_size; /* Colour map entry size */ + /* + ** Image specification + */ + uint16 x_origin; /* x origin of image */ + uint16 y_origin; /* u origin of image */ + uint16 image_width; /* Image width */ + uint16 image_height; /* Image height */ + uint8 pixel_depth; /* Pixel depth */ + uint8 image_desc; /* Image descriptor */ +} tga_header; +#pragma pack(pop) // Return to normal structure packing alignment. + +int tga_readheader(FILE *fp, uint32 *bits_per_pixel, uint32 *width, uint32 *height, int *flip_image) +{ + int palette_size; + tga_header tga ; + + if (!bits_per_pixel || !width || !height || !flip_image) + return 0; + + // Read TGA header + fread((uint8*)&tga, sizeof(tga_header), 1, fp); + + *bits_per_pixel = tga.pixel_depth; + + *width = tga.image_width; + *height = tga.image_height ; + + // Ignore tga identifier, if present ... + if (tga.id_length) + { + uint8 *id = (uint8 *) malloc(tga.id_length); + fread(id, tga.id_length, 1, fp); + free(id); + } + + // Test for compressed formats ... not yet supported ... + // Note :- 9 - RLE encoded palettized. + // 10 - RLE encoded RGB. + if (tga.image_type > 8) + { + fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n"); + return 0 ; + } + + *flip_image = !(tga.image_desc & 32); + + // Palettized formats are not yet supported, skip over the palette, if present ... + palette_size = tga.colour_map_length * (tga.colour_map_entry_size/8); + + if (palette_size>0) + { + fprintf(stderr, "File contains a palette - not yet supported."); + fseek(fp, palette_size, SEEK_CUR); + } + return 1; +} + +int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height, bool flip_image) +{ + tga_header tga; + + if (!bits_per_pixel || !width || !height) + return 0; + + memset(&tga, 0, sizeof(tga_header)); + + tga.pixel_depth = bits_per_pixel; + tga.image_width = width; + tga.image_height = height; + tga.image_type = 2; // Uncompressed. + tga.image_desc = 8; // 8 bits per component. + + if (flip_image) + tga.image_desc |= 32; + + // Write TGA header + fwrite((uint8*)&tga, sizeof(tga_header), 1, fp); + + return 1; +} + +opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { + FILE *f; + opj_image_t *image; + uint32 image_width, image_height, pixel_bit_depth; + uint32 x, y; + int flip_image=0; + opj_image_cmptparm_t cmptparm[4]; /* maximum 4 components */ + int numcomps; + OPJ_COLOR_SPACE color_space; + bool mono ; + bool save_alpha; + int subsampling_dx, subsampling_dy; + int i; + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !!\n", filename); + return 0; + } + + if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image)) + return NULL; + + // We currently only support 24 & 32 bit tga's ... + if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32))) + return NULL; + + /* initialize image components */ + memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); + + mono = (pixel_bit_depth == 8) || (pixel_bit_depth == 16); // Mono with & without alpha. + save_alpha = (pixel_bit_depth == 16) || (pixel_bit_depth == 32); // Mono with alpha, or RGB with alpha + + if (mono) { + color_space = CLRSPC_GRAY; + numcomps = save_alpha ? 2 : 1; + } + else { + numcomps = save_alpha ? 4 : 3; + color_space = CLRSPC_SRGB; + } + + subsampling_dx = parameters->subsampling_dx; + subsampling_dy = parameters->subsampling_dy; + + for (i = 0; i < numcomps; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = image_width; + cmptparm[i].h = image_height; + } + + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + + if (!image) + return NULL; + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (image_width - 1) * subsampling_dx + 1 : image->x0 + (image_width - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (image_height - 1) * subsampling_dy + 1 : image->y0 + (image_height - 1) * subsampling_dy + 1; + + /* set image data */ + for (y=0; y < image_height; y++) + { + int index; + + if (flip_image) + index = (image_height-y-1)*image_width; + else + index = y*image_width; + + if (numcomps==3) + { + for (x=0;xcomps[0].data[index]=r; + image->comps[1].data[index]=g; + image->comps[2].data[index]=b; + index++; + } + } + else if (numcomps==4) + { + for (x=0;xcomps[0].data[index]=r; + image->comps[1].data[index]=g; + image->comps[2].data[index]=b; + image->comps[3].data[index]=a; + index++; + } + } + else { + fprintf(stderr, "Currently unsupported bit depth : %s\n", filename); + } + } + return image; +} + +int imagetotga(opj_image_t * image, const char *outfile) { + int width, height, bpp, x, y; + bool write_alpha; + unsigned int i; + uint32 alpha_channel; + float r,g,b,a; + uint8 value; + float scale; + FILE *fdest; + + fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return 1; + } + + for (i = 0; i < image->numcomps-1; i++) { + if ((image->comps[0].dx != image->comps[i+1].dx) + ||(image->comps[0].dy != image->comps[i+1].dy) + ||(image->comps[0].prec != image->comps[i+1].prec)) { + fprintf(stderr, "Unable to create a tga file with such J2K image charateristics."); + return 1; + } + } + + width = image->comps[0].w; + height = image->comps[0].h; + + // Mono with alpha, or RGB with alpha. + write_alpha = (image->numcomps==2) || (image->numcomps==4); + + // Write TGA header + bpp = write_alpha ? 32 : 24; + if (!tga_writeheader(fdest, bpp, width , height, true)) + return 1; + + alpha_channel = image->numcomps-1; + + scale = 255.0f / (float)((1<comps[0].prec)-1); + + for (y=0; y < height; y++) { + uint32 index=y*width; + + for (x=0; x < width; x++, index++) { + r = (float)(image->comps[0].data[index]); + + if (image->numcomps>2) { + g = (float)(image->comps[1].data[index]); + b = (float)(image->comps[2].data[index]); + } + else {// Greyscale ... + g = r; + b = r; + } + + // TGA format writes BGR ... + value = (uint8)(b*scale); + fwrite(&value,1,1,fdest); + + value = (uint8)(g*scale); + fwrite(&value,1,1,fdest); + + value = (uint8)(r*scale); + fwrite(&value,1,1,fdest); + + if (write_alpha) { + a = (float)(image->comps[alpha_channel].data[index]); + value = (uint8)(a*scale); + fwrite(&value,1,1,fdest); + } + } + } + + return 0; +} + /* -->> -->> -->> -->> BMP IMAGE FORMAT @@ -468,9 +770,10 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) { } int imagetobmp(opj_image_t * image, const char *outfile) { - int w, wr, h, hr; + int w, h; int i, pad; FILE *fdest = NULL; + int adjustR, adjustG, adjustB; if (image->numcomps == 3 && image->comps[0].dx == image->comps[1].dx && image->comps[1].dx == image->comps[2].dx @@ -489,64 +792,81 @@ int imagetobmp(opj_image_t * image, const char *outfile) { return 1; } - /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */ - /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */ - w = image->comps[0].w; - wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor); - - /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */ - /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */ + w = image->comps[0].w; h = image->comps[0].h; - hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor); fprintf(fdest, "BM"); /* FILE HEADER */ /* ------------- */ fprintf(fdest, "%c%c%c%c", - (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + 54) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 8) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 16) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) >> 24) & 0xff); + (unsigned char) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff); /* INFO HEADER */ /* ------------- */ fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff), - (unsigned char) ((wr) >> 8) & 0xff, - (unsigned char) ((wr) >> 16) & 0xff, - (unsigned char) ((wr) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff), - (unsigned char) ((hr) >> 8) & 0xff, - (unsigned char) ((hr) >> 16) & 0xff, - (unsigned char) ((hr) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff), + (unsigned char) ((w) >> 8) & 0xff, + (unsigned char) ((w) >> 16) & 0xff, + (unsigned char) ((w) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff), + (unsigned char) ((h) >> 8) & 0xff, + (unsigned char) ((h) >> 16) & 0xff, + (unsigned char) ((h) >> 24) & 0xff); fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * hr * wr + 3 * hr * (wr % 2)) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 8) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 16) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * h * w + 3 * h * (w % 2)) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - for (i = 0; i < wr * hr; i++) { - unsigned char R, G, B; - /* a modifier */ - /* R = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */ - R = image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; - /* G = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */ - G = image->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; - /* B = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; */ - B = image->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; - fprintf(fdest, "%c%c%c", B, G, R); + if (image->comps[0].prec > 8) { + adjustR = image->comps[0].prec - 8; + printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); + } + else + adjustR = 0; + if (image->comps[1].prec > 8) { + adjustG = image->comps[1].prec - 8; + printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec); + } + else + adjustG = 0; + if (image->comps[2].prec > 8) { + adjustB = image->comps[2].prec - 8; + printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec); + } + else + adjustB = 0; + + for (i = 0; i < w * h; i++) { + unsigned char rc, gc, bc; + int r, g, b; + + r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2)); + g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2)); + b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2)); + + fprintf(fdest, "%c%c%c", bc, gc, rc); - if ((i + 1) % wr == 0) { - for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */ + if ((i + 1) % w == 0) { + for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */ fprintf(fdest, "%c", 0); } } @@ -558,24 +878,17 @@ int imagetobmp(opj_image_t * image, const char *outfile) { <<-- <<-- <<-- <<-- */ fdest = fopen(outfile, "wb"); - /* w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); */ - /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), image->comps[0].dx); */ - w = image->comps[0].w; - wr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor); - - /* h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); */ - /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */ + w = image->comps[0].w; h = image->comps[0].h; - hr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor); fprintf(fdest, "BM"); /* FILE HEADER */ /* ------------- */ - fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + 54 + 1024 + hr * (wr % 2)) & 0xff, - (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 8) & 0xff, - (unsigned char) ((hr * wr + 54 + 1024 + hr * (wr % 2)) >> 16) & 0xff, - (unsigned char) ((hr * wr + 54 + 1024 + wr * (wr % 2)) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + 54 + 1024 + h * (w % 2)) & 0xff, + (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff, + (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff, + (unsigned char) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, ((54 + 1024) >> 16) & 0xff, @@ -584,38 +897,47 @@ int imagetobmp(opj_image_t * image, const char *outfile) { /* INFO HEADER */ /* ------------- */ fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((wr) & 0xff), - (unsigned char) ((wr) >> 8) & 0xff, - (unsigned char) ((wr) >> 16) & 0xff, - (unsigned char) ((wr) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((hr) & 0xff), - (unsigned char) ((hr) >> 8) & 0xff, - (unsigned char) ((hr) >> 16) & 0xff, - (unsigned char) ((hr) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff), + (unsigned char) ((w) >> 8) & 0xff, + (unsigned char) ((w) >> 16) & 0xff, + (unsigned char) ((w) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff), + (unsigned char) ((h) >> 8) & 0xff, + (unsigned char) ((h) >> 16) & 0xff, + (unsigned char) ((h) >> 24) & 0xff); fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) (hr * wr + hr * (wr % 2)) & 0xff, - (unsigned char) ((hr * wr + hr * (wr % 2)) >> 8) & 0xff, - (unsigned char) ((hr * wr + hr * (wr % 2)) >> 16) & 0xff, - (unsigned char) ((hr * wr + hr * (wr % 2)) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + h * (w % 2)) & 0xff, + (unsigned char) ((h * w + h * (w % 2)) >> 8) & 0xff, + (unsigned char) ((h * w + h * (w % 2)) >> 16) & 0xff, + (unsigned char) ((h * w + h * (w % 2)) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + if (image->comps[0].prec > 8) { + adjustR = image->comps[0].prec - 8; + printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); + } + for (i = 0; i < 256; i++) { fprintf(fdest, "%c%c%c%c", i, i, i, 0); } - for (i = 0; i < wr * hr; i++) { - /* a modifier !! */ - /* fprintf(fdest, "%c", image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]); */ - fprintf(fdest, "%c", image->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]); - /*if (((i + 1) % w == 0 && w % 2)) - fprintf(fdest, "%c", 0); */ - if ((i + 1) % wr == 0) { - for (pad = wr % 4 ? 4 - wr % 4 : 0; pad > 0; pad--) /* ADD */ + for (i = 0; i < w * h; i++) { + unsigned char rc; + int r; + + r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2)); + + fprintf(fdest, "%c", rc); + + if ((i + 1) % w == 0) { + for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */ fprintf(fdest, "%c", 0); } } @@ -770,14 +1092,15 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) { comp->data[i] = v; } fclose(f); - comp->bpp = int_floorlog2(max) + 1; + //comp->bpp = int_floorlog2(max) + 1; return image; } int imagetopgx(opj_image_t * image, const char *outfile) { - int w, wr, h, hr; - int i, j, compno; + int w, h; + int i, j; + unsigned int compno; FILE *fdest = NULL; for (compno = 0; compno < image->numcomps; compno++) { @@ -811,17 +1134,11 @@ int imagetopgx(opj_image_t * image, const char *outfile) { if( total > 256 ) { free(name); } - /* w = int_ceildiv(image->x1 - image->x0, comp->dx); */ - /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor), comp->dx); */ + w = image->comps[compno].w; - wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor); - - /* h = int_ceildiv(image->y1 - image->y0, comp->dy); */ - /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), comp->dy); */ h = image->comps[compno].h; - hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor); - fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, wr, hr); + fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, w, h); if (comp->prec <= 8) { nbytes = 1; } else if (comp->prec <= 16) { @@ -829,8 +1146,8 @@ int imagetopgx(opj_image_t * image, const char *outfile) { } else { nbytes = 4; } - for (i = 0; i < wr * hr; i++) { - int v = image->comps[compno].data[i / wr * w + i % wr]; + for (i = 0; i < w * h; i++) { + int v = image->comps[compno].data[i]; for (j = nbytes - 1; j >= 0; j--) { char byte = (char) (v >> (j * 8)); fwrite(&byte, 1, 1, fdest); @@ -948,9 +1265,10 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) { } int imagetopnm(opj_image_t * image, const char *outfile) { - int w, wr, wrr, h, hr, hrr, max; - int i, compno; - int adjust; + int w, wr, h, hr, max; + int i; + unsigned int compno; + int adjustR, adjustG, adjustB, adjustX; FILE *fdest = NULL; char S2; const char *tmp = outfile; @@ -977,43 +1295,60 @@ int imagetopnm(opj_image_t * image, const char *outfile) { } w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); - /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[0].dx); */ wr = image->comps[0].w; - wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor); h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); - /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[0].dy); */ hr = image->comps[0].h; - hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor); max = image->comps[0].prec > 8 ? 255 : (1 << image->comps[0].prec) - 1; image->comps[0].x0 = int_ceildivpow2(image->comps[0].x0 - int_ceildiv(image->x0, image->comps[0].dx), image->comps[0].factor); image->comps[0].y0 = int_ceildivpow2(image->comps[0].y0 - int_ceildiv(image->y0, image->comps[0].dy), image->comps[0].factor); - fprintf(fdest, "P6\n%d %d\n%d\n", wrr, hrr, max); - adjust = image->comps[0].prec > 8 ? image->comps[0].prec - 8 : 0; - for (i = 0; i < wrr * hrr; i++) { + fprintf(fdest, "P6\n%d %d\n%d\n", wr, hr, max); + + if (image->comps[0].prec > 8) { + adjustR = image->comps[0].prec - 8; + printf("PNM CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); + } + else + adjustR = 0; + if (image->comps[1].prec > 8) { + adjustG = image->comps[1].prec - 8; + printf("PNM CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec); + } + else + adjustG = 0; + if (image->comps[2].prec > 8) { + adjustB = image->comps[2].prec - 8; + printf("PNM CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec); + } + else + adjustB = 0; + + + for (i = 0; i < wr * hr; i++) { int r, g, b; unsigned char rc,gc,bc; - r = image->comps[0].data[i / wrr * wr + i % wrr]; + r = image->comps[0].data[i]; r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - rc = (unsigned char) ((r >> adjust)+((r >> (adjust-1))%2)); + rc = (unsigned char) ((r >> adjustR)+((r >> (adjustR-1))%2)); - g = image->comps[1].data[i / wrr * wr + i % wrr]; + g = image->comps[1].data[i]; g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - gc = (unsigned char) ((g >> adjust)+((g >> (adjust-1))%2)); + gc = (unsigned char) ((g >> adjustG)+((g >> (adjustG-1))%2)); - b = image->comps[2].data[i / wrr * wr + i % wrr]; + b = image->comps[2].data[i]; b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); - bc = (unsigned char) ((b >> adjust)+((b >> (adjust-1))%2)); + bc = (unsigned char) ((b >> adjustB)+((b >> (adjustB-1))%2)); fprintf(fdest, "%c%c%c", rc, gc, bc); } fclose(fdest); + } else { - int ncomp=(S2=='g' || S2=='G')?1:image->numcomps; - if (image->numcomps>ncomp) { + unsigned int ncomp=(S2=='g' || S2=='G')?1:image->numcomps; + if (image->numcomps > ncomp) { fprintf(stderr,"WARNING -> [PGM files] Only the first component\n"); fprintf(stderr," is written to the file\n"); } @@ -1032,29 +1367,31 @@ int imagetopnm(opj_image_t * image, const char *outfile) { } w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx); - /* wr = int_ceildiv(int_ceildivpow2(image->x1 - image->x0,image->factor),image->comps[compno].dx); */ wr = image->comps[compno].w; - wrr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor); h = int_ceildiv(image->y1 - image->y0, image->comps[compno].dy); - /* hr = int_ceildiv(int_ceildivpow2(image->y1 - image->y0,image->factor), image->comps[compno].dy); */ hr = image->comps[compno].h; - hrr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor); max = image->comps[compno].prec > 8 ? 255 : (1 << image->comps[compno].prec) - 1; image->comps[compno].x0 = int_ceildivpow2(image->comps[compno].x0 - int_ceildiv(image->x0, image->comps[compno].dx), image->comps[compno].factor); image->comps[compno].y0 = int_ceildivpow2(image->comps[compno].y0 - int_ceildiv(image->y0, image->comps[compno].dy), image->comps[compno].factor); - fprintf(fdest, "P5\n%d %d\n%d\n", wrr, hrr, max); - adjust = image->comps[compno].prec > 8 ? image->comps[compno].prec - 8 : 0; - - for (i = 0; i < wrr * hrr; i++) { + fprintf(fdest, "P5\n%d %d\n%d\n", wr, hr, max); + + if (image->comps[compno].prec > 8) { + adjustX = image->comps[0].prec - 8; + printf("PNM CONVERSION: Truncating component %d from %d bits to 8 bits\n",compno, image->comps[compno].prec); + } + else + adjustX = 0; + + for (i = 0; i < wr * hr; i++) { int l; unsigned char lc; - l = image->comps[compno].data[i / wrr * wr + i % wrr]; + l = image->comps[compno].data[i]; l += (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); - lc = (unsigned char) ((l >> adjust)+((l >> (adjust-1))%2)); + lc = (unsigned char) ((l >> adjustX)+((l >> (adjustX-1))%2)); fprintf(fdest, "%c", lc); } fclose(fdest); @@ -1081,8 +1418,9 @@ typedef struct tiff_infoheader{ }tiff_infoheader_t; int imagetotif(opj_image_t * image, const char *outfile) { - int width, height; - int bps,index; + int width, height, imgsize; + int bps,index,adjust = 0; + int last_i=0; TIFF *tif; tdata_t buf; tstrip_t strip; @@ -1106,7 +1444,8 @@ int imagetotif(opj_image_t * image, const char *outfile) { } width = image->comps[0].w; - height= image->comps[0].h; + height = image->comps[0].h; + imgsize = width * height ; bps = image->comps[0].prec; /* Set tags */ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); @@ -1119,43 +1458,166 @@ int imagetotif(opj_image_t * image, const char *outfile) { TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); /* Get a buffer for the data */ - buf = _TIFFmalloc(TIFFStripSize(tif)); - index=0; - strip_size=0; strip_size=TIFFStripSize(tif); + buf = _TIFFmalloc(strip_size); + index=0; + adjust = image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0; for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { unsigned char *dat8; - int i; - dat8 = buf; + int i, ssize; + ssize = TIFFStripSize(tif); + dat8 = (unsigned char*)buf; if (image->comps[0].prec == 8){ - for (i=0; icomps[0].data[index] ; // R - dat8[i+1] = image->comps[1].data[index] ; // G - dat8[i+2] = image->comps[2].data[index] ; // B - index++; + for (i=0; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r ; // R + dat8[i+1] = g ; // G + dat8[i+2] = b ; // B + index++; + last_i = i+3; + }else + break; + } + if(last_i < ssize){ + for (i=last_i; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r ; // R + if(i+1 comps[0].prec == 12){ - for (i=0; icomps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4); - dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[1].data[index]>>8)& 0x0f); - dat8[i+2] = (image->comps[1].data[index]); - dat8[i+3] = (image->comps[2].data[index]>>8)<<4 | (image->comps[2].data[index]>>4); - dat8[i+4] = (image->comps[2].data[index]<<4)|((image->comps[1].data[index+1]>>8)& 0x0f); - dat8[i+5] = (image->comps[0].data[index+1]); - dat8[i+6] = (image->comps[1].data[index+1]>>8)<<4 | (image->comps[1].data[index+1]>>4); - dat8[i+7] = (image->comps[1].data[index+1]<<4)|((image->comps[2].data[index+1]>>8)& 0x0f); - dat8[i+8] = (image->comps[2].data[index+1]); - index+=2; + for (i=0; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + r1 = image->comps[0].data[index+1]; + g1 = image->comps[1].data[index+1]; + b1 = image->comps[2].data[index+1]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + r1 += adjust; + g1 += adjust; + b1 += adjust; + } + dat8[i+0] = (r >> 4); + dat8[i+1] = ((r & 0x0f) << 4 )|((g >> 8)& 0x0f); + dat8[i+2] = g ; + dat8[i+3] = (b >> 4); + dat8[i+4] = ((b & 0x0f) << 4 )|((r1 >> 8)& 0x0f); + dat8[i+5] = r1; + dat8[i+6] = (g1 >> 4); + dat8[i+7] = ((g1 & 0x0f)<< 4 )|((b1 >> 8)& 0x0f); + dat8[i+8] = b1; + index+=2; + last_i = i+9; + }else + break; + } + if(last_i < ssize){ + for (i= last_i; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + r1 = image->comps[0].data[index+1]; + g1 = image->comps[1].data[index+1]; + b1 = image->comps[2].data[index+1]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + r1 += adjust; + g1 += adjust; + b1 += adjust; + } + dat8[i+0] = (r >> 4); + if(i+1 > 8)& 0x0f); else break; + if(i+2 > 4); else break; + if(i+4 > 8)& 0x0f);else break; + if(i+5 > 4); else break; + if(i+7 > 8)& 0x0f);else break; + if(i+8 comps[0].prec == 16){ - for (i=0; icomps[0].data[index];//LSB - dat8[i+1] = (image->comps[0].data[index]>> 8);//MSB - dat8[i+2] = image->comps[1].data[index]; - dat8[i+3] = (image->comps[1].data[index]>> 8); - dat8[i+4] = image->comps[2].data[index]; - dat8[i+5] = (image->comps[2].data[index]>> 8); - index++; + for (i=0 ; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r;//LSB + dat8[i+1] = (r >> 8);//MSB + dat8[i+2] = g; + dat8[i+3] = (g >> 8); + dat8[i+4] = b; + dat8[i+5] = (b >> 8); + index++; + last_i = i+6; + }else + break; + } + if(last_i < ssize){ + for (i=0 ; icomps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + g += adjust; + b += adjust; + } + dat8[i+0] = r;//LSB + if(i+1 > 8);else break;//MSB + if(i+2 > 8);else break; + if(i+4 > 8);else break; + index++; + }else + break; + } } }else{ fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec); @@ -1178,7 +1640,8 @@ int imagetotif(opj_image_t * image, const char *outfile) { } width = image->comps[0].w; - height= image->comps[0].h; + height = image->comps[0].h; + imgsize = width * height; bps = image->comps[0].prec; /* Set tags */ @@ -1192,34 +1655,59 @@ int imagetotif(opj_image_t * image, const char *outfile) { TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); /* Get a buffer for the data */ - buf = _TIFFmalloc(TIFFStripSize(tif)); - index = 0; - strip_size = 0; strip_size = TIFFStripSize(tif); + buf = _TIFFmalloc(strip_size); + index = 0; for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { unsigned char *dat8; int i; - dat8 = buf; + dat8 = (unsigned char*)buf; if (image->comps[0].prec == 8){ for (i=0; icomps[0].data[index] ; - index++; + if(index < imgsize){ + int r = 0; + r = image->comps[0].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + } + dat8[i+0] = r; + index++; + }else + break; } }else if (image->comps[0].prec == 12){ for (i = 0; icomps[0].data[index]>>8)<<4 | (image->comps[0].data[index]>>4); - dat8[i+1] = (image->comps[0].data[index]<<4)|((image->comps[0].data[index+1]>>8)& 0x0f); - dat8[i+2] = (image->comps[0].data[index+1]); - index+=2; + if(index < imgsize){ + int r = 0, r1 = 0; + r = image->comps[0].data[index]; + r1 = image->comps[0].data[index+1]; + if (image->comps[0].sgnd){ + r += adjust; + r1 += adjust; + } + dat8[i+0] = (r >> 4); + dat8[i+1] = ((r & 0x0f) << 4 )|((r1 >> 8)& 0x0f); + dat8[i+2] = r1 ; + index+=2; + }else + break; } }else if (image->comps[0].prec == 16){ for (i=0; icomps[0].data[index]; - dat8[i+1] = (image->comps[0].data[index]>> 8); - index++; + if(index < imgsize){ + int r = 0; + r = image->comps[0].data[index]; + if (image->comps[0].sgnd){ + r += adjust; + } + dat8[i+0] = r; + dat8[i+1] = r >> 8; + index++; + }else + break; } }else{ - fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec); + fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",image->comps[0].prec); fprintf(stderr,"Aborting\n"); return 1; } @@ -1228,14 +1716,14 @@ int imagetotif(opj_image_t * image, const char *outfile) { _TIFFfree(buf); TIFFClose(tif); }else{ - fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n"); + fprintf(stderr,"TIFF file creation. Bad color format. Only RGB & Grayscale has been implemented\n"); fprintf(stderr,"Aborting\n"); return 1; } return 0; } -opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) +opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) { int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; @@ -1248,6 +1736,7 @@ opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[3]; opj_image_t * image = NULL; + int imgsize = 0; tif = TIFFOpen(filename, "r"); @@ -1266,7 +1755,7 @@ opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &Info.tiPC); w= Info.tiWidth; h= Info.tiHeight; - + if (Info.tiPhoto == 2) { /* -->> -->> -->> RGB color @@ -1277,8 +1766,13 @@ opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) /* initialize image components*/ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); for(j = 0; j < numcomps; j++) { - cmptparm[j].prec = Info.tiBps; - cmptparm[j].bpp = Info.tiBps; + if (parameters->cp_cinema) { + cmptparm[j].prec = 12; + cmptparm[j].bpp = 12; + }else{ + cmptparm[j].prec = Info.tiBps; + cmptparm[j].bpp = Info.tiBps; + } cmptparm[j].sgnd = 0; cmptparm[j].dx = subsampling_dx; cmptparm[j].dy = subsampling_dy; @@ -1302,42 +1796,62 @@ opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) strip_size=0; strip_size=TIFFStripSize(tif); index = 0; + imgsize = image->comps[0].w * image->comps[0].h ; /* Read the Image components*/ for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { unsigned char *dat8; int i, ssize; ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size); - dat8 = buf; + dat8 = (unsigned char*)buf; if (Info.tiBps==12){ for (i=0; icomps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4); - image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; - image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4); - image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5]; - image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4); - image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8]; - index+=2; + if((index < imgsize)&(index+1 < imgsize)){ + image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4); + image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; + image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4); + image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5]; + image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4); + image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8]; + index+=2; + }else + break; } } else if( Info.tiBps==16){ for (i=0; icomps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; // R - image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; // G - image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; // B - index++; + if(index < imgsize){ + image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; // R + image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; // G + image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; // B + if(parameters->cp_cinema){/* Rounding to 12 bits*/ + image->comps[0].data[index] = (image->comps[0].data[index] + 0x08) >> 4 ; + image->comps[1].data[index] = (image->comps[1].data[index] + 0x08) >> 4 ; + image->comps[2].data[index] = (image->comps[2].data[index] + 0x08) >> 4 ; + } + index++; + }else + break; } } else if ( Info.tiBps==8){ for (i=0; icomps[0].data[index] = dat8[i+0]; // R - image->comps[1].data[index] = dat8[i+1]; // G - image->comps[2].data[index] = dat8[i+2]; // B - index++; + if(index < imgsize){ + image->comps[0].data[index] = dat8[i+0];// R + image->comps[1].data[index] = dat8[i+1];// G + image->comps[2].data[index] = dat8[i+2];// B + if(parameters->cp_cinema){/* Rounding to 12 bits*/ + image->comps[0].data[index] = image->comps[0].data[index] << 4 ; + image->comps[1].data[index] = image->comps[1].data[index] << 4 ; + image->comps[2].data[index] = image->comps[2].data[index] << 4 ; + } + index++; + }else + break; } } else{ - fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps); + fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps); fprintf(stderr,"Aborting\n"); return NULL; } @@ -1378,34 +1892,44 @@ opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) strip_size = 0; strip_size = TIFFStripSize(tif); index = 0; + imgsize = image->comps[0].w * image->comps[0].h ; /* Read the Image components*/ for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { unsigned char *dat8; int i, ssize; ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size); - dat8 = buf; + dat8 = (unsigned char*)buf; if (Info.tiBps==12){ for (i=0; icomps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4) ; - image->comps[0].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; - index+=2; + if(index < imgsize){ + image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4) ; + image->comps[0].data[index+1] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; + index+=2; + }else + break; } } else if( Info.tiBps==16){ for (i=0; icomps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; - index++; + if(index < imgsize){ + image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; + index++; + }else + break; } } else if ( Info.tiBps==8){ for (i=0; icomps[0].data[index] = dat8[i+0]; - index++; + if(index < imgsize){ + image->comps[0].data[index] = dat8[i+0]; + index++; + }else + break; } } else{ - fprintf(stderr,"Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps); + fprintf(stderr,"TIFF file creation. Bits=%d, Only 8,12,16 bits implemented\n",Info.tiBps); fprintf(stderr,"Aborting\n"); return NULL; } @@ -1414,9 +1938,582 @@ opj_image_t* tiftoimage(char *filename, opj_cparameters_t *parameters) _TIFFfree(buf); TIFFClose(tif); }else{ - fprintf(stderr,"False color format. Only RGB & Grayscale has been implemented\n"); + fprintf(stderr,"TIFF file creation. Bad color format. Only RGB & Grayscale has been implemented\n"); + fprintf(stderr,"Aborting\n"); + return NULL; + } + return image; +} + +/* -->> -->> -->> -->> + + RAW IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) { + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + + FILE *f = NULL; + int i, compno, numcomps, w, h; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t *cmptparm; + opj_image_t * image = NULL; + unsigned short ch; + + if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0) + { + fprintf(stderr,"\nError: invalid raw image parameters\n"); + fprintf(stderr,"Please use the Format option -F:\n"); + fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); + fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); fprintf(stderr,"Aborting\n"); return NULL; } + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !!\n", filename); + fprintf(stderr,"Aborting\n"); + return NULL; + } + numcomps = raw_cp->rawComp; + color_space = CLRSPC_SRGB; + w = raw_cp->rawWidth; + h = raw_cp->rawHeight; + cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t)); + + /* initialize image components */ + memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = raw_cp->rawBitDepth; + cmptparm[i].bpp = raw_cp->rawBitDepth; + cmptparm[i].sgnd = raw_cp->rawSigned; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(f); + return NULL; + } + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; + image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; + + if(raw_cp->rawBitDepth <= 8) + { + unsigned char value = 0; + for(compno = 0; compno < numcomps; compno++) { + for (i = 0; i < w * h; i++) { + if (!fread(&value, 1, 1, f)) { + fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + return NULL; + } + image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value; + } + } + } + else if(raw_cp->rawBitDepth <= 16) + { + unsigned short value; + for(compno = 0; compno < numcomps; compno++) { + for (i = 0; i < w * h; i++) { + unsigned char temp; + if (!fread(&temp, 1, 1, f)) { + fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + return NULL; + } + value = temp << 8; + if (!fread(&temp, 1, 1, f)) { + fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + return NULL; + } + value += temp; + image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value; + } + } + } + else { + fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n"); + return NULL; + } + + if (fread(&ch, 1, 1, f)) { + fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n"); + } + fclose(f); + return image; } + +int imagetoraw(opj_image_t * image, const char *outfile) +{ + FILE *rawFile = NULL; + unsigned int compno; + int w, h; + int line, row; + int *ptr; + + if((image->numcomps * image->x1 * image->y1) == 0) + { + fprintf(stderr,"\nError: invalid raw image parameters\n"); + return 1; + } + + rawFile = fopen(outfile, "wb"); + if (!rawFile) { + fprintf(stderr, "Failed to open %s for writing !!\n", outfile); + return 1; + } + + fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps); + + for(compno = 0; compno < image->numcomps; compno++) + { + fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w, + image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned"); + + w = image->comps[compno].w; + h = image->comps[compno].h; + + if(image->comps[compno].prec <= 8) + { + if(image->comps[compno].sgnd == 1) + { + signed char curr; + int mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + curr = (signed char) (*ptr & mask); + fwrite(&curr, sizeof(signed char), 1, rawFile); + ptr++; + } + } + } + else if(image->comps[compno].sgnd == 0) + { + unsigned char curr; + int mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + curr = (unsigned char) (*ptr & mask); + fwrite(&curr, sizeof(unsigned char), 1, rawFile); + ptr++; + } + } + } + } + else if(image->comps[compno].prec <= 16) + { + if(image->comps[compno].sgnd == 1) + { + signed short int curr; + int mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + unsigned char temp; + curr = (signed short int) (*ptr & mask); + temp = curr >> 8; + fwrite(&temp, 1, 1, rawFile); + temp = curr; + fwrite(&temp, 1, 1, rawFile); + ptr++; + } + } + } + else if(image->comps[compno].sgnd == 0) + { + unsigned short int curr; + int mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + unsigned char temp; + curr = (unsigned short int) (*ptr & mask); + temp = curr >> 8; + fwrite(&temp, 1, 1, rawFile); + temp = curr; + fwrite(&temp, 1, 1, rawFile); + ptr++; + } + } + } + } + else if (image->comps[compno].prec <= 32) + { + fprintf(stderr,"More than 16 bits per component no handled yet\n"); + return 1; + } + else + { + fprintf(stderr,"Error: invalid precision: %d\n", image->comps[compno].prec); + return 1; + } + } + fclose(rawFile); + return 0; +} + +opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params) +#ifdef WIN32 +{ + printf("Error. PNG format is not yet handled under windows\n"); + return NULL; +} +#else +{ + png_bytep row; + png_structp png; + png_infop info; + double gamma, display_exponent; + int bit_depth, interlace_type, compression_type, filter_type; + int unit, pass, nr_passes; + png_uint_32 resx, resy; + unsigned int i, max, src_w; + png_uint_32 width, height; + int color_type, has_alpha; + unsigned char *png_buf, *s; + FILE *reader; +/* j2k: */ + opj_image_t *image; + opj_image_cmptparm_t cmptparm[4]; + int sub_dx, sub_dy; + unsigned int nr_comp; + int *r, *g, *b, *a; + + if ((reader = fopen(read_idf, "rb")) == NULL) { + fprintf(stderr, "pngtoimage: can not open %s\n", read_idf); + return NULL; + } + nr_passes = 0; + png_buf = NULL; + +/* libpng-VERSION/example.c: + * PC : screen_gamma = 2.2; + * Mac: screen_gamma = 1.7 or 1.0; +*/ + display_exponent = 2.2; + + if ((png = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL)) == NULL) + goto fin; + if ((info = png_create_info_struct(png)) == NULL) + goto fin; + + if (setjmp(png_jmpbuf(png))) + goto fin; + + png_init_io(png, reader); + png_read_info(png, info); + + png_get_IHDR(png, info, &width, &height, + &bit_depth, &color_type, &interlace_type, + &compression_type, &filter_type); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png); + else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand(png); + + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_expand(png); + + if (bit_depth == 16) + png_set_strip_16(png); + +/* GRAY => RGB; GRAY_ALPHA => RGBA +*/ + if (color_type == PNG_COLOR_TYPE_GRAY + || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + png_set_gray_to_rgb(png); + color_type = + (color_type == PNG_COLOR_TYPE_GRAY ? PNG_COLOR_TYPE_RGB : + PNG_COLOR_TYPE_RGB_ALPHA); + } + if (!png_get_gAMA(png, info, &gamma)) + gamma = 0.45455; + + png_set_gamma(png, display_exponent, gamma); + + nr_passes = png_set_interlace_handling(png); + + png_read_update_info(png, info); + + png_get_pHYs(png, info, &resx, &resy, &unit); + + color_type = png_get_color_type(png, info); + + has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA); + + if (has_alpha) + nr_comp = 4; + else + nr_comp = 3; + + src_w = width * nr_comp; + png_buf = (unsigned char *) malloc(src_w * height); + + if (nr_passes == 0) + nr_passes = 1; + + for (pass = 0; pass < nr_passes; pass++) { + s = png_buf; + + for (i = 0; i < height; i++) { +/* libpng.3: + * If you want the "sparkle" effect, just call png_read_rows() as + * normal, with the third parameter NULL. +*/ + png_read_rows(png, &s, NULL, 1); + + s += src_w; + } + } + memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t)); + + sub_dx = params->subsampling_dx; + sub_dy = params->subsampling_dy; + + for (i = 0; i < nr_comp; ++i) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = sub_dx; + cmptparm[i].dy = sub_dy; + cmptparm[i].w = width; + cmptparm[i].h = height; + } + + image = opj_image_create(nr_comp, &cmptparm[0], CLRSPC_SRGB); + + if (image == NULL) + goto fin; + + image->x0 = params->image_offset_x0; + image->y0 = params->image_offset_y0; + image->x1 = + params->image_offset_x0 + (width - 1) * sub_dx + 1 + image->x0; + image->y1 = + params->image_offset_y0 + (height - 1) * sub_dy + 1 + image->y0; + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + a = image->comps[3].data; + s = png_buf; + + max = width * height; + + for (i = 0; i < max; ++i) { + *r++ = *s++; + *g++ = *s++; + *b++ = *s++; + + if (has_alpha) + *a++ = *s++; + } + + fin: + if (png) + png_destroy_read_struct(&png, &info, NULL); + if (png_buf) + free(png_buf); + + fclose(reader); + + return image; + +} /* pngtoimage() */ +#endif + +int imagetopng(opj_image_t * image, const char *write_idf) +#ifdef WIN32 +{ + printf("Error. PNG format is not yet handled under windows\n"); + return -1; +} +#else +{ + FILE *writer; + png_structp png_ptr; + png_infop info_ptr; + int *rs, *gs, *bs, *as; + unsigned char *row_buf, *d; + int fails, mono, graya, rgb, rgba; + int width, height, nr_colors, color_type; + int bit_depth, adjust, x, y; + png_color_8 sig_bit; + + writer = fopen(write_idf, "wb"); + + if (writer == NULL) + return 1; + + info_ptr = NULL; + fails = 1; + +/* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible with the one used at compile time, + * in case we are using dynamically linked libraries. REQUIRED. +*/ + png_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); +/*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */ + + if (png_ptr == NULL) + goto fin; + +/* Allocate/initialize the image information data. REQUIRED +*/ + info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr == NULL) + goto fin; + +/* Set error handling. REQUIRED if you are not supplying your own + * error handling functions in the png_create_write_struct() call. +*/ + if (setjmp(png_jmpbuf(png_ptr))) + goto fin; + +/* I/O initialization functions is REQUIRED +*/ + png_init_io(png_ptr, writer); + +/* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. + * REQUIRED +*/ + png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + + mono = graya = rgb = rgba = adjust = 0; + + nr_colors = image->numcomps; + width = image->comps[0].w; + height = image->comps[0].h; + rs = image->comps[0].data; + + if (nr_colors == 2) { + graya = 1; + color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + sig_bit.gray = image->comps[0].prec; + bit_depth = image->comps[0].prec; + as = image->comps[1].data; + } else if (nr_colors == 3) { + rgb = 1; + color_type = PNG_COLOR_TYPE_RGB; + sig_bit.red = image->comps[0].prec; + sig_bit.green = image->comps[1].prec; + sig_bit.blue = image->comps[2].prec; + bit_depth = image->comps[0].prec; + gs = image->comps[1].data; + bs = image->comps[2].data; + if (image->comps[0].sgnd) + adjust = 1 << (image->comps[0].prec - 1); + } else if (nr_colors == 4) { + rgb = rgba = 1; + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + sig_bit.red = image->comps[0].prec; + sig_bit.green = image->comps[1].prec; + sig_bit.blue = image->comps[2].prec; + sig_bit.alpha = image->comps[3].prec; + bit_depth = image->comps[0].prec; + gs = image->comps[1].data; + bs = image->comps[2].data; + as = image->comps[3].data; + if (image->comps[0].sgnd) + adjust = 1 << (image->comps[0].prec - 1); + } else { + mono = 1; + color_type = PNG_COLOR_TYPE_GRAY; + sig_bit.gray = image->comps[0].prec; + bit_depth = image->comps[0].prec; + } + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, + color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + +#ifdef HIDDEN_CODE +/* Optional gamma chunk is strongly suggested if you have any guess + * as to the correct gamma of the image. +*/ + + if (gamma > 0.0) { + png_set_gAMA(png_ptr, info_ptr, gamma); + } +#endif /* HIDDEN_CODE */ +#ifdef HIDDEN_CODE + if (have_bg) { + png_color_16 background; + + background.red = bg_red; + background.green = bg_green; + background.blue = bg_blue; + + png_set_bKGD(png_ptr, info_ptr, &background); + } +#endif /* HIDDEN_CODE */ + png_write_info(png_ptr, info_ptr); + + png_set_packing(png_ptr); + + row_buf = (unsigned char *) malloc(width * nr_colors); + + for (y = 0; y < height; ++y) { + d = row_buf; + + for (x = 0; x < width; ++x) { + if (mono) { + *d++ = (unsigned char) *rs++; + } + if (graya) { + *d++ = (unsigned char) *rs++; + *d++ = (unsigned char) *as++; + } else if (rgb) { + *d++ = (unsigned char) (*rs++ + adjust); + *d++ = (unsigned char) (*gs++ + adjust); + *d++ = (unsigned char) (*bs++ + adjust); + + if (rgba) + *d++ = (unsigned char) (*as++ + adjust); + } + } /* for(x) */ + + png_write_row(png_ptr, row_buf); + + } /* for(y) */ + + png_write_end(png_ptr, info_ptr); + + fails = 0; + + fin: + + if (png_ptr) { + png_destroy_write_struct(&png_ptr, &info_ptr); + } + fclose(writer); + + return fails; +} +#endif