diff options
Diffstat (limited to 'tests/openjpeg/codec/convert.c')
-rw-r--r-- | tests/openjpeg/codec/convert.c | 2686 |
1 files changed, 2686 insertions, 0 deletions
diff --git a/tests/openjpeg/codec/convert.c b/tests/openjpeg/codec/convert.c new file mode 100644 index 00000000..25e715bf --- /dev/null +++ b/tests/openjpeg/codec/convert.c @@ -0,0 +1,2686 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * 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 + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "opj_config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef HAVE_LIBTIFF +#ifdef _WIN32 +#include "../libs/libtiff/tiffio.h" +#else +#include <tiffio.h> +#endif /* _WIN32 */ +#endif /* HAVE_LIBTIFF */ + +#ifdef HAVE_LIBPNG +#ifdef _WIN32 +#include "../libs/png/png.h" +#else +#include <png.h> +#endif /* _WIN32 */ +#endif /* HAVE_LIBPNG */ + +#include "../libopenjpeg/openjpeg.h" +#include "convert.h" + +/* + * Get logarithm of an integer and round downwards. + * + * log2(a) + */ +static int int_floorlog2(int a) { + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} + +/* + * Divide an integer by a power of 2 and round upwards. + * + * a divided by 2^b + */ +static int int_ceildivpow2(int a, int b) { + return (a + (1 << b) - 1) >> b; +} + +/* + * Divide an integer and round upwards. + * + * a divided by b + */ +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 +{ + unsigned char id_length; /* Image id field length */ + unsigned char colour_map_type; /* Colour map type */ + unsigned char image_type; /* Image type */ + /* + ** Colour map specification + */ + unsigned short colour_map_index; /* First entry index */ + unsigned short colour_map_length; /* Colour map length */ + unsigned char colour_map_entry_size; /* Colour map entry size */ + /* + ** Image specification + */ + unsigned short x_origin; /* x origin of image */ + unsigned short y_origin; /* u origin of image */ + unsigned short image_width; /* Image width */ + unsigned short image_height; /* Image height */ + unsigned char pixel_depth; /* Pixel depth */ + unsigned char image_desc; /* Image descriptor */ +} tga_header; +#pragma pack(pop) // Return to normal structure packing alignment. + +int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, + unsigned int *width, unsigned int *height, int *flip_image) +{ + int palette_size; + tga_header tga ; + + if (!bits_per_pixel || !width || !height || !flip_image) + return 0; + + // Read TGA header + fread((unsigned char*)&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) + { + unsigned char *id = (unsigned char *) 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((unsigned char*)&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; + unsigned int image_width, image_height, pixel_bit_depth; + unsigned int 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;x<image_width;x++) + { + unsigned char r,g,b; + fread(&b, 1, 1, f); + fread(&g, 1, 1, f); + fread(&r, 1, 1, f); + + image->comps[0].data[index]=r; + image->comps[1].data[index]=g; + image->comps[2].data[index]=b; + index++; + } + } + else if (numcomps==4) + { + for (x=0;x<image_width;x++) + { + unsigned char r,g,b,a; + fread(&b, 1, 1, f); + fread(&g, 1, 1, f); + fread(&r, 1, 1, f); + fread(&a, 1, 1, f); + + image->comps[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; + int i; + unsigned int alpha_channel; + float r,g,b,a; + unsigned char 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<<image->comps[0].prec)-1); + + for (y=0; y < height; y++) { + unsigned int 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 = (unsigned char)(b*scale); + fwrite(&value,1,1,fdest); + + value = (unsigned char)(g*scale); + fwrite(&value,1,1,fdest); + + value = (unsigned char)(r*scale); + fwrite(&value,1,1,fdest); + + if (write_alpha) { + a = (float)(image->comps[alpha_channel].data[index]); + value = (unsigned char)(a*scale); + fwrite(&value,1,1,fdest); + } + } + } + + return 0; +} + +/* -->> -->> -->> -->> + + BMP IMAGE FORMAT + + <<-- <<-- <<-- <<-- */ + +/* WORD defines a two byte word */ +typedef unsigned short int WORD; + +/* DWORD defines a four byte word */ +typedef unsigned long int DWORD; + +typedef struct { + WORD bfType; /* 'BM' for Bitmap (19776) */ + DWORD bfSize; /* Size of the file */ + WORD bfReserved1; /* Reserved : 0 */ + WORD bfReserved2; /* Reserved : 0 */ + DWORD bfOffBits; /* Offset */ +} BITMAPFILEHEADER_t; + +typedef struct { + DWORD biSize; /* Size of the structure in bytes */ + DWORD biWidth; /* Width of the image in pixels */ + DWORD biHeight; /* Heigth of the image in pixels */ + WORD biPlanes; /* 1 */ + WORD biBitCount; /* Number of color bits by pixels */ + DWORD biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */ + DWORD biSizeImage; /* Size of the image in bytes */ + DWORD biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */ + DWORD biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */ + DWORD biClrUsed; /* Number of color used in the image (0: ALL) */ + DWORD biClrImportant; /* Number of important color (0: ALL) */ +} BITMAPINFOHEADER_t; + +opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) { + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + + int i, numcomps, w, h; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ + opj_image_t * image = NULL; + + FILE *IN; + BITMAPFILEHEADER_t File_h; + BITMAPINFOHEADER_t Info_h; + unsigned char *RGB; + unsigned char *table_R, *table_G, *table_B; + unsigned int j, PAD = 0; + + int x, y, index; + int gray_scale = 1, not_end_file = 1; + + unsigned int line = 0, col = 0; + unsigned char v, v2; + DWORD W, H; + + IN = fopen(filename, "rb"); + if (!IN) { + fprintf(stderr, "Failed to open %s for reading !!\n", filename); + return 0; + } + + File_h.bfType = getc(IN); + File_h.bfType = (getc(IN) << 8) + File_h.bfType; + + if (File_h.bfType != 19778) { + fprintf(stderr,"Error, not a BMP file!\n"); + return 0; + } else { + /* FILE HEADER */ + /* ------------- */ + File_h.bfSize = getc(IN); + File_h.bfSize = (getc(IN) << 8) + File_h.bfSize; + File_h.bfSize = (getc(IN) << 16) + File_h.bfSize; + File_h.bfSize = (getc(IN) << 24) + File_h.bfSize; + + File_h.bfReserved1 = getc(IN); + File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1; + + File_h.bfReserved2 = getc(IN); + File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2; + + File_h.bfOffBits = getc(IN); + File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits; + File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits; + File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits; + + /* INFO HEADER */ + /* ------------- */ + + Info_h.biSize = getc(IN); + Info_h.biSize = (getc(IN) << 8) + Info_h.biSize; + Info_h.biSize = (getc(IN) << 16) + Info_h.biSize; + Info_h.biSize = (getc(IN) << 24) + Info_h.biSize; + + Info_h.biWidth = getc(IN); + Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth; + Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth; + Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth; + w = Info_h.biWidth; + + Info_h.biHeight = getc(IN); + Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight; + Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight; + Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight; + h = Info_h.biHeight; + + Info_h.biPlanes = getc(IN); + Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes; + + Info_h.biBitCount = getc(IN); + Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount; + + Info_h.biCompression = getc(IN); + Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression; + Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression; + Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression; + + Info_h.biSizeImage = getc(IN); + Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage; + Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage; + Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage; + + Info_h.biXpelsPerMeter = getc(IN); + Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter; + + Info_h.biYpelsPerMeter = getc(IN); + Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter; + + Info_h.biClrUsed = getc(IN); + Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed; + Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed; + Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed; + + Info_h.biClrImportant = getc(IN); + Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant; + Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant; + Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant; + + /* Read the data and store them in the OUT file */ + + if (Info_h.biBitCount == 24) { + numcomps = 3; + color_space = CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + 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 = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(IN); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + + /* PAD = 4 - (3 * W) % 4; */ + /* PAD = (PAD == 4) ? 0 : PAD; */ + PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; + + RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char)); + + fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN); + + index = 0; + + for(y = 0; y < (int)H; y++) { + unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y); + for(x = 0; x < (int)W; x++) { + unsigned char *pixel = &scanline[3 * x]; + image->comps[0].data[index] = pixel[2]; /* R */ + image->comps[1].data[index] = pixel[1]; /* G */ + image->comps[2].data[index] = pixel[0]; /* B */ + index++; + } + } + + free(RGB); + + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + + for (j = 0; j < Info_h.biClrUsed; j++) { + table_B[j] = getc(IN); + table_G[j] = getc(IN); + table_R[j] = getc(IN); + getc(IN); + if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j]) + gray_scale = 0; + } + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + if (Info_h.biWidth % 2) + W++; + + numcomps = gray_scale ? 1 : 3; + color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + 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 = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(IN); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ + + RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); + + fread(RGB, sizeof(unsigned char), W * H, IN); + if (gray_scale) { + index = 0; + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) { + image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]; + index++; + } + } + + } else { + index = 0; + for (j = 0; j < W * H; j++) { + if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) { + unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]; + image->comps[0].data[index] = table_R[pixel_index]; + image->comps[1].data[index] = table_G[pixel_index]; + image->comps[2].data[index] = table_B[pixel_index]; + index++; + } + } + } + free(RGB); + free(table_R); + free(table_G); + free(table_B); + } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + + for (j = 0; j < Info_h.biClrUsed; j++) { + table_B[j] = getc(IN); + table_G[j] = getc(IN); + table_R[j] = getc(IN); + getc(IN); + if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j]) + gray_scale = 0; + } + + numcomps = gray_scale ? 1 : 3; + color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + 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 = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if(!image) { + fclose(IN); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; + image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + + /* set image data */ + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, File_h.bfOffBits, SEEK_SET); + + RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char)); + + while (not_end_file) { + v = getc(IN); + if (v) { + v2 = getc(IN); + for (i = 0; i < (int) v; i++) { + RGB[line * Info_h.biWidth + col] = v2; + col++; + } + } else { + v = getc(IN); + switch (v) { + case 0: + col = 0; + line++; + break; + case 1: + line++; + not_end_file = 0; + break; + case 2: + fprintf(stderr,"No Delta supported\n"); + opj_image_destroy(image); + fclose(IN); + return NULL; + default: + for (i = 0; i < v; i++) { + v2 = getc(IN); + RGB[line * Info_h.biWidth + col] = v2; + col++; + } + if (v % 2) + v2 = getc(IN); + break; + } + } + } + if (gray_scale) { + index = 0; + for (line = 0; line < Info_h.biHeight; line++) { + for (col = 0; col < Info_h.biWidth; col++) { + image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]]; + index++; + } + } + } else { + index = 0; + for (line = 0; line < Info_h.biHeight; line++) { + for (col = 0; col < Info_h.biWidth; col++) { + unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]; + image->comps[0].data[index] = table_R[pixel_index]; + image->comps[1].data[index] = table_G[pixel_index]; + image->comps[2].data[index] = table_B[pixel_index]; + index++; + } + } + } + free(RGB); + free(table_R); + free(table_G); + free(table_B); + } else { + fprintf(stderr, + "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount); + } + fclose(IN); + } + + return image; +} + +int imagetobmp(opj_image_t * image, const char *outfile) { + 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 + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec) { + + /* -->> -->> -->> -->> + 24 bits color + <<-- <<-- <<-- <<-- */ + + fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return 1; + } + + w = image->comps[0].w; + h = image->comps[0].h; + + fprintf(fdest, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", + (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) ((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 * 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); + + 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) % w == 0) { + for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(fdest, "%c", 0); + } + } + fclose(fdest); + } else { /* Gray-scale */ + + /* -->> -->> -->> -->> + 8 bits non code (Gray scale) + <<-- <<-- <<-- <<-- */ + + fdest = fopen(outfile, "wb"); + w = image->comps[0].w; + h = image->comps[0].h; + + fprintf(fdest, "BM"); + + /* FILE HEADER */ + /* ------------- */ + 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, + ((54 + 1024) >> 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) ((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) (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); + }else + adjustR = 0; + + for (i = 0; i < 256; i++) { + fprintf(fdest, "%c%c%c%c", i, i, i, 0); + } + + 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); + } + } + fclose(fdest); + } + + return 0; +} + +/* -->> -->> -->> -->> + +PGX IMAGE FORMAT + +<<-- <<-- <<-- <<-- */ + + +unsigned char readuchar(FILE * f) +{ + unsigned char c1; + fread(&c1, 1, 1, f); + return c1; +} + +unsigned short readushort(FILE * f, int bigendian) +{ + unsigned char c1, c2; + fread(&c1, 1, 1, f); + fread(&c2, 1, 1, f); + if (bigendian) + return (c1 << 8) + c2; + else + return (c2 << 8) + c1; +} + +unsigned int readuint(FILE * f, int bigendian) +{ + unsigned char c1, c2, c3, c4; + fread(&c1, 1, 1, f); + fread(&c2, 1, 1, f); + fread(&c3, 1, 1, f); + fread(&c4, 1, 1, f); + if (bigendian) + return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4; + else + return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1; +} + +opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) { + FILE *f = NULL; + int w, h, prec; + int i, numcomps, max; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm; /* maximum of 1 component */ + opj_image_t * image = NULL; + + char endian1,endian2,sign; + char signtmp[32]; + + char temp[32]; + int bigendian; + opj_image_comp_t *comp = NULL; + + numcomps = 1; + color_space = CLRSPC_GRAY; + + memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t)); + + max = 0; + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !\n", filename); + return NULL; + } + + fseek(f, 0, SEEK_SET); + fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h); + + i=0; + sign='+'; + while (signtmp[i]!='\0') { + if (signtmp[i]=='-') sign='-'; + i++; + } + + fgetc(f); + if (endian1=='M' && endian2=='L') { + bigendian = 1; + } else if (endian2=='M' && endian1=='L') { + bigendian = 0; + } else { + fprintf(stderr, "Bad pgx header, please check input file\n"); + return NULL; + } + + /* initialize image component */ + + cmptparm.x0 = parameters->image_offset_x0; + cmptparm.y0 = parameters->image_offset_y0; + cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1; + cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1; + + if (sign == '-') { + cmptparm.sgnd = 1; + } else { + cmptparm.sgnd = 0; + } + cmptparm.prec = prec; + cmptparm.bpp = prec; + cmptparm.dx = parameters->subsampling_dx; + cmptparm.dy = parameters->subsampling_dy; + + /* create the image */ + image = opj_image_create(numcomps, &cmptparm, color_space); + if(!image) { + fclose(f); + return N |