[trunk] fixed component precision upscaling in opj_decompress (fixes issue 458)
[openjpeg.git] / src / bin / jp2 / convert.c
index e946ca18f444daebe944eba9d671943e72fdee65..7f4593b0f14b0bf279c3ce5161c56bee8bd82099 100644 (file)
@@ -1,9 +1,15 @@
 /*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
+ * The copyright in this software is being made available under the 2-clauses 
+ * BSD License, included below. This software may be subject to other third 
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, 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) 2003-2007, Francois-Olivier Devaux 
+ * Copyright (c) 2003-2014, Antonin Descampe
  * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * Copyright (c) 2006-2007, Parvatha Elangovan
  * All rights reserved.
@@ -61,6 +67,92 @@ static int int_floorlog2(int a) {
     return l;
 }
 
+/* Component precision scaling */
+void clip_component(opj_image_comp_t* component, OPJ_UINT32 precision)
+{
+       OPJ_SIZE_T i;
+       OPJ_SIZE_T len;
+       OPJ_UINT32 umax = (OPJ_UINT32)((OPJ_INT32)-1);
+       
+       len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h;
+       if (precision < 32) {
+               umax = (1U << precision) - 1U;
+       }
+       
+       if (component->sgnd) {
+               OPJ_INT32* l_data = component->data;
+               OPJ_INT32 max = (OPJ_INT32)(umax / 2U);
+               OPJ_INT32 min = -max - 1;
+               for (i = 0; i < len; ++i) {
+                       if (l_data[i] > max) {
+                               l_data[i] = max;
+                       } else if (l_data[i] < min) {
+                               l_data[i] = min;
+                       }
+               }
+       } else {
+               OPJ_UINT32* l_data = (OPJ_UINT32*)component->data;
+               for (i = 0; i < len; ++i) {
+                       if (l_data[i] > umax) {
+                               l_data[i] = umax;
+                       }
+               }
+       }
+       component->prec = precision;
+}
+
+/* Component precision scaling */
+static void scale_component_up(opj_image_comp_t* component, OPJ_UINT32 precision)
+{
+       OPJ_SIZE_T i, len;
+       
+       len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h;
+       if (component->sgnd) {
+               OPJ_INT64  newMax = (1U << (precision - 1));
+               OPJ_INT64  oldMax = (1U << (component->prec - 1));
+               OPJ_INT32* l_data = component->data;
+               for (i = 0; i < len; ++i) {
+                       l_data[i] = (OPJ_INT32)(((OPJ_INT64)l_data[i] * newMax) / oldMax);
+               }
+       } else {
+               OPJ_UINT64  newMax = (1U << precision) - 1U;
+               OPJ_UINT64  oldMax = (1U << component->prec) - 1U;
+               OPJ_UINT32* l_data = (OPJ_UINT32*)component->data;
+               for (i = 0; i < len; ++i) {
+                       l_data[i] = (OPJ_UINT32)(((OPJ_UINT64)l_data[i] * newMax) / oldMax);
+               }
+       }
+       component->prec = precision;
+}
+void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision)
+{
+       int shift;
+       OPJ_SIZE_T i, len;
+       
+       if (component->prec == precision) {
+               return;
+       }
+       if (component->prec < precision) {
+               scale_component_up(component, precision);
+               return;
+       }
+       shift = (int)(component->prec - precision);
+       len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h;
+       if (component->sgnd) {
+               OPJ_INT32* l_data = component->data;
+               for (i = 0; i < len; ++i) {
+                       l_data[i] >>= shift;
+               }
+       } else {
+               OPJ_UINT32* l_data = (OPJ_UINT32*)component->data;
+               for (i = 0; i < len; ++i) {
+                       l_data[i] >>= shift;
+               }
+       }
+       component->prec = precision;
+}
+
+
 /* -->> -->> -->> -->>
 
   TGA IMAGE FORMAT
@@ -94,7 +186,7 @@ struct tga_header
 
 static unsigned short get_ushort(unsigned short val) {
 
-#ifdef WORDS_BIGENDIAN
+#ifdef OPJ_BIG_ENDIAN
     return( ((val & 0xff) << 8) + (val >> 8) );
 #else
     return( val );
@@ -181,9 +273,9 @@ static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel,
     return 1;
 }
 
-#if WORDS_BIGENDIAN == 1
+#ifdef OPJ_BIG_ENDIAN
 
-static inline int16_t swap16(int16_t x)
+static INLINE int16_t swap16(int16_t x)
 {
     return((((u_int16_t)x & 0x00ffU) <<  8) |
            (((u_int16_t)x & 0xff00U) >>  8));
@@ -228,7 +320,7 @@ static int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height,
     image_w = (unsigned short)width;
     image_h = (unsigned short) height;
 
-#if WORDS_BIGENDIAN == 0
+#ifndef OPJ_BIG_ENDIAN
     if(fwrite(&image_w, 2, 1, fp) != 1) goto fails;
     if(fwrite(&image_h, 2, 1, fp) != 1) goto fails;
 #else
@@ -523,700 +615,6 @@ fin:
        return fails;
 }
 
-/* -->> -->> -->> -->>
-
-  BMP IMAGE FORMAT
-
- <<-- <<-- <<-- <<-- */
-
-/* WORD defines a two byte word */
-typedef unsigned short int WORD;
-
-/* DWORD defines a four byte word */
-typedef unsigned 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;
-
-    unsigned int x, y;
-    int index;
-    int gray_scale = 1;
-    int has_color;
-    DWORD W, H;
-
-    IN = fopen(filename, "rb");
-    if (!IN)
-    {
-        fprintf(stderr, "Failed to open %s for reading !!\n", filename);
-        return NULL;
-    }
-
-    File_h.bfType = (WORD)getc(IN);
-    File_h.bfType = (WORD)((getc(IN) << 8) + File_h.bfType);
-
-    if (File_h.bfType != 19778)
-    {
-        fprintf(stderr,"Error, not a BMP file!\n");
-        fclose(IN);
-        return NULL;
-    }
-    /* FILE HEADER */
-    /* ------------- */
-    File_h.bfSize = (DWORD)getc(IN);
-    File_h.bfSize = (DWORD)(getc(IN) << 8) + File_h.bfSize;
-    File_h.bfSize = (DWORD)(getc(IN) << 16) + File_h.bfSize;
-    File_h.bfSize = (DWORD)(getc(IN) << 24) + File_h.bfSize;
-
-    File_h.bfReserved1 = (WORD)getc(IN);
-    File_h.bfReserved1 = (WORD)((getc(IN) << 8) + File_h.bfReserved1);
-
-    File_h.bfReserved2 = (WORD)getc(IN);
-    File_h.bfReserved2 = (WORD)((getc(IN) << 8) + File_h.bfReserved2);
-
-    File_h.bfOffBits = (DWORD)getc(IN);
-    File_h.bfOffBits = (DWORD)(getc(IN) << 8) + File_h.bfOffBits;
-    File_h.bfOffBits = (DWORD)(getc(IN) << 16) + File_h.bfOffBits;
-    File_h.bfOffBits = (DWORD)(getc(IN) << 24) + File_h.bfOffBits;
-
-    /* INFO HEADER */
-    /* ------------- */
-
-    Info_h.biSize = (DWORD)getc(IN);
-    Info_h.biSize = (DWORD)(getc(IN) << 8) + Info_h.biSize;
-    Info_h.biSize = (DWORD)(getc(IN) << 16) + Info_h.biSize;
-    Info_h.biSize = (DWORD)(getc(IN) << 24) + Info_h.biSize;
-
-    if(Info_h.biSize != 40)
-    {
-        fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize);
-        fclose(IN);
-        return NULL;
-    }
-    Info_h.biWidth = (DWORD)getc(IN);
-    Info_h.biWidth = (DWORD)(getc(IN) << 8) + Info_h.biWidth;
-    Info_h.biWidth = (DWORD)(getc(IN) << 16) + Info_h.biWidth;
-    Info_h.biWidth = (DWORD)(getc(IN) << 24) + Info_h.biWidth;
-    w = (int)Info_h.biWidth;
-
-    Info_h.biHeight = (DWORD)getc(IN);
-    Info_h.biHeight = (DWORD)(getc(IN) << 8) + Info_h.biHeight;
-    Info_h.biHeight = (DWORD)(getc(IN) << 16) + Info_h.biHeight;
-    Info_h.biHeight = (DWORD)(getc(IN) << 24) + Info_h.biHeight;
-    h = (int)Info_h.biHeight;
-
-    Info_h.biPlanes = (WORD)getc(IN);
-    Info_h.biPlanes = (WORD)((getc(IN) << 8) + Info_h.biPlanes);
-
-    Info_h.biBitCount = (WORD)getc(IN);
-    Info_h.biBitCount = (WORD)((getc(IN) << 8) + Info_h.biBitCount);
-
-    Info_h.biCompression = (DWORD)getc(IN);
-    Info_h.biCompression = (DWORD)(getc(IN) << 8) + Info_h.biCompression;
-    Info_h.biCompression = (DWORD)(getc(IN) << 16) + Info_h.biCompression;
-    Info_h.biCompression = (DWORD)(getc(IN) << 24) + Info_h.biCompression;
-
-    Info_h.biSizeImage = (DWORD)getc(IN);
-    Info_h.biSizeImage = (DWORD)(getc(IN) << 8) + Info_h.biSizeImage;
-    Info_h.biSizeImage = (DWORD)(getc(IN) << 16) + Info_h.biSizeImage;
-    Info_h.biSizeImage = (DWORD)(getc(IN) << 24) + Info_h.biSizeImage;
-
-    Info_h.biXpelsPerMeter = (DWORD)getc(IN);
-    Info_h.biXpelsPerMeter = (DWORD)(getc(IN) << 8) + Info_h.biXpelsPerMeter;
-    Info_h.biXpelsPerMeter = (DWORD)(getc(IN) << 16) + Info_h.biXpelsPerMeter;
-    Info_h.biXpelsPerMeter = (DWORD)(getc(IN) << 24) + Info_h.biXpelsPerMeter;
-
-    Info_h.biYpelsPerMeter = (DWORD)getc(IN);
-    Info_h.biYpelsPerMeter = (DWORD)(getc(IN) << 8) + Info_h.biYpelsPerMeter;
-    Info_h.biYpelsPerMeter = (DWORD)(getc(IN) << 16) + Info_h.biYpelsPerMeter;
-    Info_h.biYpelsPerMeter = (DWORD)(getc(IN) << 24) + Info_h.biYpelsPerMeter;
-
-    Info_h.biClrUsed = (DWORD)getc(IN);
-    Info_h.biClrUsed = (DWORD)(getc(IN) << 8) + Info_h.biClrUsed;
-    Info_h.biClrUsed = (DWORD)(getc(IN) << 16) + Info_h.biClrUsed;
-    Info_h.biClrUsed = (DWORD)(getc(IN) << 24) + Info_h.biClrUsed;
-
-    Info_h.biClrImportant = (DWORD)getc(IN);
-    Info_h.biClrImportant = (DWORD)(getc(IN) << 8) + Info_h.biClrImportant;
-    Info_h.biClrImportant = (DWORD)(getc(IN) << 16) + Info_h.biClrImportant;
-    Info_h.biClrImportant = (DWORD)(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 = OPJ_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 = (OPJ_UINT32)subsampling_dx;
-            cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
-            cmptparm[i].w = (OPJ_UINT32)w;
-            cmptparm[i].h = (OPJ_UINT32)h;
-        }
-        /* create the image */
-        image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
-        if(!image)
-        {
-            fclose(IN);
-            return NULL;
-        }
-
-        /* set image offset and reference grid */
-        image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
-        image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
-        image->x1 =    !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
-        image->y1 =    !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)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));
-
-        if ( fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN) != (3 * W + PAD) * H )
-        {
-            free(RGB);
-            opj_image_destroy(image);
-            fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
-            return NULL;
-        }
-
-        index = 0;
-
-        for(y = 0; y < H; y++)
-        {
-            unsigned char *scanline = RGB + (3 * (unsigned int)W + PAD) * ((unsigned int)H - 1 - (unsigned int)y);
-            for(x = 0; x < 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);
-    }/* if (Info_h.biBitCount == 24) */
-    else
-        if (Info_h.biBitCount == 8 && Info_h.biCompression == 0)/*RGB */
-        {
-            if(Info_h.biClrUsed == 0) Info_h.biClrUsed = 256;
-            else
-                if(Info_h.biClrUsed > 256) Info_h.biClrUsed = 256;
-
-            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));
-
-            has_color = 0;
-            for (j = 0; j < Info_h.biClrUsed; j++)
-            {
-                table_B[j] = (unsigned char)getc(IN);
-                table_G[j] = (unsigned char)getc(IN);
-                table_R[j] = (unsigned char)getc(IN);
-                getc(IN);
-                has_color +=
-                        !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
-            }
-            if(has_color) 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 ? OPJ_CLRSPC_GRAY : OPJ_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 = (OPJ_UINT32)subsampling_dx;
-                cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
-                cmptparm[i].w = (OPJ_UINT32)w;
-                cmptparm[i].h = (OPJ_UINT32)h;
-            }
-            /* create the image */
-            image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
-            if(!image)
-            {
-                fclose(IN);
-                free(table_R); free(table_G); free(table_B);
-                return NULL;
-            }
-
-            /* set image offset and reference grid */
-            image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
-            image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
-            image->x1 =        !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
-            image->y1 =        !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1;
-
-            /* set image data */
-
-            RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char));
-
-            if ( fread(RGB, sizeof(unsigned char), W * H, IN) != W * H )
-            {
-                free(table_R);
-                free(table_G);
-                free(table_B);
-                free(RGB);
-                opj_image_destroy(image);
-                fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
-                return NULL;
-            }
-            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);
-        }/* RGB8 */
-        else
-            if (Info_h.biBitCount == 8 && Info_h.biCompression == 1)/*RLE8*/
-            {
-                unsigned char *pix, *beyond;
-                int *gray, *red, *green, *blue;
-                unsigned int max;
-                int c, c1;
-                unsigned char uc;
-
-                if (Info_h.biClrUsed == 0)
-                    Info_h.biClrUsed = 256;
-                else if (Info_h.biClrUsed > 256)
-                    Info_h.biClrUsed = 256;
-
-                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));
-
-                has_color = 0;
-                for (j = 0; j < Info_h.biClrUsed; j++)
-                {
-                    table_B[j] = (unsigned char)getc(IN);
-                    table_G[j] = (unsigned char)getc(IN);
-                    table_R[j] = (unsigned char)getc(IN);
-                    getc(IN);
-                    has_color += !(table_R[j] == table_G[j] && table_R[j] == table_B[j]);
-                }
-
-                if (has_color)
-                    gray_scale = 0;
-
-                numcomps = gray_scale ? 1 : 3;
-                color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_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 = (OPJ_UINT32)subsampling_dx;
-                    cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
-                    cmptparm[i].w = (OPJ_UINT32)w;
-                    cmptparm[i].h = (OPJ_UINT32)h;
-                }
-                /* create the image */
-                image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
-                if (!image)
-                {
-                    fclose(IN);
-                    free(table_R);
-                    free(table_G);
-                    free(table_B);
-                    return NULL;
-                }
-
-                /* set image offset and reference grid */
-                image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
-                image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
-                image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
-                image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)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;
-                RGB = (unsigned char *) calloc(1, W * H * sizeof(unsigned char));
-                beyond = RGB + W * H;
-                pix = beyond - W;
-                x = y = 0;
-
-                while (y < H)
-                {
-                    c = getc(IN);
-
-                    if (c)
-                    {
-                        c1 = getc(IN);
-
-                        for (i = 0; i < c && x < W && pix < beyond; i++, x++, pix++)
-                            *pix = (unsigned char)c1;
-                    }
-                    else
-                    {
-                        c = getc(IN);
-
-                        if (c == 0x00) /* EOL */
-                        {
-                            x = 0;
-                            ++y;
-                            pix = RGB + x + (H - y - 1) * W;
-                        }
-                        else if (c == 0x01) /* EOP */
-                            break;
-                        else if (c == 0x02) /* MOVE by dxdy */
-                        {
-                            c = getc(IN);
-                            x += (unsigned int)c;
-                            c = getc(IN);
-                            y += (unsigned int)c;
-                            pix = RGB + (H - y - 1) * W + x;
-                        }
-                        else /* 03 .. 255 */
-                        {
-                            i = 0;
-                            for (; i < c && x < W && pix < beyond; i++, x++, pix++)
-                            {
-                                c1 = getc(IN);
-                                *pix = (unsigned char)c1;
-                            }
-                            if (c & 1) /* skip padding byte */
-                                getc(IN);
-                        }
-                    }
-                }/* while() */
-
-                if (gray_scale)
-                {
-                    gray = image->comps[0].data;
-                    pix = RGB;
-                    max = W * H;
-
-                    while (max--)
-                    {
-                        uc = *pix++;
-
-                        *gray++ = table_R[uc];
-                    }
-                }
-                else
-                {
-                    /*int *red, *green, *blue;*/
-
-                    red = image->comps[0].data;
-                    green = image->comps[1].data;
-                    blue = image->comps[2].data;
-                    pix = RGB;
-                    max = W * H;
-
-                    while (max--)
-                    {
-                        uc = *pix++;
-
-                        *red++ = table_R[uc];
-                        *green++ = table_G[uc];
-                        *blue++ = table_B[uc];
-                    }
-                }
-                free(RGB);
-                free(table_R);
-                free(table_G);
-                free(table_B);
-            }/* RLE8 */
-            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->comps[0].prec < 8) {
-        fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec);
-        return 1;
-    }
-    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 = (int)image->comps[0].w;
-        h = (int)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 = (int)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 = (int)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 = (int)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);
-            r = ((r >> adjustR)+((r >> (adjustR-1))%2));
-            if(r > 255) r = 255; else if(r < 0) r = 0;
-            rc = (unsigned char)r;
-
-            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);
-            g = ((g >> adjustG)+((g >> (adjustG-1))%2));
-            if(g > 255) g = 255; else if(g < 0) g = 0;
-            gc = (unsigned char)g;
-
-            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);
-            b = ((b >> adjustB)+((b >> (adjustB-1))%2));
-            if(b > 255) b = 255; else if(b < 0) b = 0;
-            bc = (unsigned char)b;
-
-            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 = (int)image->comps[0].w;
-        h = (int)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 = (int)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++) {
-            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);
-            r = ((r >> adjustR)+((r >> (adjustR-1))%2));
-            if(r > 255) r = 255; else if(r < 0) r = 0;
-
-            fprintf(fdest, "%c", (unsigned char)r);
-
-            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
@@ -1421,13 +819,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) {
 
 #define CLAMP(x,a,b) x < a ? a : (x > b ? b : x)
 
-#ifdef _MSC_VER
-#define STIN static __inline
-#else
-#define STIN static inline
-#endif
-
-STIN int clamp( const int value, const int prec, const int sgnd )
+static INLINE int clamp( const int value, const int prec, const int sgnd )
 {
   if( sgnd )
     {
@@ -1587,7 +979,6 @@ static char *skip_idf(char *start, char out_idf[256])
 
 static void read_pnm_header(FILE *reader, struct pnm_header *ph)
 {
-    char *s;
     int format, have_wh, end, ttype;
     char idf[256], type[256];
     char line[256];
@@ -1613,6 +1004,8 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
 
     while(fgets(line, 250, reader))
     {
+        char *s;
+
         if(*line == '#') continue;
 
         s = line;
@@ -1696,7 +1089,18 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
             have_wh = 1;
 
             if(format == 1 || format == 4) break;
-
+                                       
+            if(format == 2 || format == 3 || format == 5 || format == 6)
+            {
+                if (skip_int(s, &ph->maxval) != NULL) {
+                    if(ph->maxval > 65535) {
+                        return;
+                    }
+                    else {
+                        break;
+                    }
+                }
+            }
             continue;
         }
         if(format == 2 || format == 3 || format == 5 || format == 6)
@@ -1722,7 +1126,7 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
         }
         if(ph->depth < 1 || ph->depth > 4) return;
 
-        if(ph->width && ph->height && ph->depth & ph->maxval && ttype)
+        if(ph->width && ph->height && ph->depth && ph->maxval && ttype)
             ph->ok = 1;
     }
     else
@@ -1873,8 +1277,12 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) {
             {
                 for(compno = 0; compno < numcomps; compno++)
                 {
-                    if ( !fread(&c0, 1, 1, fp) )
-                        fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
+                if ( !fread(&c0, 1, 1, fp) )
+                  {
+                  fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
+                  opj_image_destroy(image);
+                  return NULL;
+                  }
                     if(one)
                     {
                         image->comps[compno].data[i] = c0;
@@ -2593,6 +2001,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
     int has_alpha = 0;
     unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
     unsigned int tiWidth, tiHeight;
+    OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
 
     tif = TIFFOpen(filename, "r");
 
@@ -2665,7 +2074,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
 */ 
     memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
 
-    if ((tiPhoto == PHOTOMETRIC_RGB) && (parameters->cp_cinema)) {
+    if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema)) {
         fprintf(stdout,"WARNING:\n"
                 "Input image bitdepth is %d bits\n"
                 "TIF conversion has automatically rescaled to 12-bits\n"
@@ -2681,7 +2090,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
         /*#define USETILEMODE*/
         for(j = 0; j < numcomps; j++)
         {
-            if(parameters->cp_cinema)
+            if(is_cinema)
             {
                 cmptparm[j].prec = 12;
                 cmptparm[j].bpp = 12;
@@ -2750,7 +2159,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
                         if(has_alpha)
                             image->comps[3].data[index] = ( dat8[i+7] << 8 ) | dat8[i+6];
 
-                        if(parameters->cp_cinema)
+                        if(is_cinema)
                         {
                             /* Rounding 16 to 12 bits
 */
@@ -2787,7 +2196,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
                                 image->comps[3].data[index] = dat8[i+3];
 #endif
 
-                            if(parameters->cp_cinema)
+                            if(is_cinema)
                             {
                                 /* Rounding 8 to 12 bits
 */
@@ -2812,7 +2221,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
 
                         for(i = 0; i < ssize; i += step)
                         {
-                            if((index < imgsize)&(index+1 < imgsize))
+                            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];
@@ -2955,9 +2364,11 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
     {
         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");
+        fprintf(stderr,"-F <width>,<height>,<ncomp>,<bitdepth>,{s,u}@<dx1>x<dy1>:...:<dxn>x<dyn>\n");
+        fprintf(stderr,"If subsampling is omitted, 1x1 is assumed for all components\n");
+        fprintf(stderr,"Example: -i image.raw -o image.j2k -F 512,512,3,8,u@1x1:2x2:2x2\n");
+        fprintf(stderr,"         for raw 512x512 image with 4:2:0 subsampling\n");
+        fprintf(stderr,"Aborting.\n");
         return NULL;
     }
 
@@ -2968,19 +2379,32 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
         return NULL;
     }
     numcomps = raw_cp->rawComp;
-    color_space = OPJ_CLRSPC_SRGB;
+
+    /* FIXME ADE at this point, tcp_mct has not been properly set in calling function */
+    if (numcomps == 0) {
+        color_space = OPJ_CLRSPC_GRAY;
+    } else if ((numcomps >= 3) && (parameters->tcp_mct == 0)) {
+        color_space = OPJ_CLRSPC_SYCC;
+    } else if ((numcomps >= 3) && (parameters->tcp_mct != 2)) {
+        color_space = OPJ_CLRSPC_SRGB;
+    } else {
+        color_space = OPJ_CLRSPC_UNKNOWN;
+    }
     w = raw_cp->rawWidth;
     h = raw_cp->rawHeight;
-    cmptparm = (opj_image_cmptparm_t*) malloc((size_t)numcomps * sizeof(opj_image_cmptparm_t));
-
+    cmptparm = (opj_image_cmptparm_t*) calloc((OPJ_UINT32)numcomps,sizeof(opj_image_cmptparm_t));
+    if (!cmptparm) {
+        fprintf(stderr, "Failed to allocate image components parameters !!\n");
+        fprintf(stderr,"Aborting\n");
+        return NULL;
+    }
     /* initialize image components */
-    memset(&cmptparm[0], 0, (size_t)numcomps * sizeof(opj_image_cmptparm_t));
     for(i = 0; i < numcomps; i++) {
         cmptparm[i].prec = (OPJ_UINT32)raw_cp->rawBitDepth;
         cmptparm[i].bpp = (OPJ_UINT32)raw_cp->rawBitDepth;
         cmptparm[i].sgnd = (OPJ_UINT32)raw_cp->rawSigned;
-        cmptparm[i].dx = (OPJ_UINT32)subsampling_dx;
-        cmptparm[i].dy = (OPJ_UINT32)subsampling_dy;
+        cmptparm[i].dx = (OPJ_UINT32)(subsampling_dx * raw_cp->rawComps[i].dx);
+        cmptparm[i].dy = (OPJ_UINT32)(subsampling_dy * raw_cp->rawComps[i].dy);
         cmptparm[i].w = (OPJ_UINT32)w;
         cmptparm[i].h = (OPJ_UINT32)h;
     }
@@ -3001,7 +2425,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
     {
         unsigned char value = 0;
         for(compno = 0; compno < numcomps; compno++) {
-            for (i = 0; i < w * h; i++) {
+            int nloop = (w*h)/(raw_cp->rawComps[compno].dx*raw_cp->rawComps[compno].dy);
+            for (i = 0; i < nloop; i++) {
                 if (!fread(&value, 1, 1, f)) {
                     fprintf(stderr,"Error reading raw file. End of file probably reached.\n");
                     return NULL;
@@ -3014,7 +2439,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p
     {
         unsigned short value;
         for(compno = 0; compno < numcomps; compno++) {
-            for (i = 0; i < w * h; i++) {
+            int nloop = (w*h)/(raw_cp->rawComps[compno].dx*raw_cp->rawComps[compno].dx);
+            for (i = 0; i < nloop; i++) {
                 unsigned char temp1;
                 unsigned char temp2;
                 if (!fread(&temp1, 1, 1, f)) {
@@ -3224,7 +2650,7 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
     opj_image_cmptparm_t cmptparm[4];
     int sub_dx, sub_dy;
     unsigned int nr_comp;
-    int *r, *g, *b, *a;
+    int *r, *g, *b, *a = NULL;
     unsigned char sigbuf[8];
 
     if((reader = fopen(read_idf, "rb")) == NULL)
@@ -3314,7 +2740,7 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
 
     png_read_image(png, rows);
 
-    memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
+    memset(cmptparm, 0, sizeof(cmptparm));
 
     sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy;
 
@@ -3342,7 +2768,10 @@ opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params)
     r = image->comps[0].data;
     g = image->comps[1].data;
     b = image->comps[2].data;
-    a = image->comps[3].data;
+    if(has_alpha) {
+        a = image->comps[3].data;
+        image->comps[3].alpha = 1;
+    }
 
     for(i = 0; i < height; ++i)
     {