Fix issue 833.
[openjpeg.git] / src / bin / jp2 / convertbmp.c
index ca8b0a0419d3367837a9affadc1d07a300e6d982..ae83077caafce06d872fb498c766423c88fe77d6 100644 (file)
@@ -131,7 +131,7 @@ static void opj_applyLUT8u_8u32s_C1P3R(
        }
 }
 
-static void bmp24toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image)
+static void bmp24toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image)
 {
        int index;
        OPJ_UINT32 width, height;
@@ -175,13 +175,13 @@ static void bmp_mask_get_shift_and_prec(OPJ_UINT32 mask, OPJ_UINT32* shift, OPJ_
        *shift = l_shift; *prec = l_prec;
 }
 
-static void bmpmask32toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
+static void bmpmask32toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
 {
        int index;
        OPJ_UINT32 width, height;
        OPJ_UINT32 x, y;
        const OPJ_UINT8 *pSrc = NULL;
-       OPJ_BOOL hasAlpha = OPJ_FALSE;
+       OPJ_BOOL hasAlpha;
        OPJ_UINT32 redShift,   redPrec;
        OPJ_UINT32 greenShift, greenPrec;
        OPJ_UINT32 blueShift,  bluePrec;
@@ -233,13 +233,13 @@ static void bmpmask32toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride
        }
 }
 
-static void bmpmask16toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
+static void bmpmask16toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT32 redMask, OPJ_UINT32 greenMask, OPJ_UINT32 blueMask, OPJ_UINT32 alphaMask)
 {
        int index;
        OPJ_UINT32 width, height;
        OPJ_UINT32 x, y;
        const OPJ_UINT8 *pSrc = NULL;
-       OPJ_BOOL hasAlpha = OPJ_FALSE;
+       OPJ_BOOL hasAlpha;
        OPJ_UINT32 redShift,   redPrec;
        OPJ_UINT32 greenShift, greenPrec;
        OPJ_UINT32 blueShift,  bluePrec;
@@ -289,7 +289,7 @@ static void bmpmask16toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride
        }
 }
 
-static opj_image_t* bmp8toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT8 const* const* pLUT)
+static opj_image_t* bmp8toimage(const OPJ_UINT8* pData, OPJ_UINT32 stride, opj_image_t* image, OPJ_UINT8 const* const* pLUT)
 {
        OPJ_UINT32 width, height;
        const OPJ_UINT8 *pSrc = NULL;
@@ -302,9 +302,11 @@ static opj_image_t* bmp8toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 str
                opj_applyLUT8u_8u32s_C1R(pSrc, -(OPJ_INT32)stride, image->comps[0].data, (OPJ_INT32)width, pLUT[0], width, height);
        }
        else {
-               OPJ_INT32* pDst[] = { image->comps[0].data, image->comps[1].data, image->comps[2].data };
-               OPJ_INT32  pDstStride[] = { (OPJ_INT32)width, (OPJ_INT32)width, (OPJ_INT32)width };
+               OPJ_INT32* pDst[3];
+               OPJ_INT32  pDstStride[3];
                
+               pDst[0] = image->comps[0].data; pDst[1] = image->comps[1].data; pDst[2] = image->comps[2].data;
+               pDstStride[0] = (OPJ_INT32)width; pDstStride[1] = (OPJ_INT32)width; pDstStride[2] = (OPJ_INT32)width;
                opj_applyLUT8u_8u32s_C1P3R(pSrc, -(OPJ_INT32)stride, pDst, pDstStride, pLUT, width, height);
        }
        return image;
@@ -313,7 +315,7 @@ static opj_image_t* bmp8toimage(FILE *IN, const OPJ_UINT8* pData, OPJ_UINT32 str
 static OPJ_BOOL bmp_read_file_header(FILE* IN, OPJ_BITMAPFILEHEADER* header)
 {
        header->bfType  = (OPJ_UINT16)getc(IN);
-       header->bfType |= (OPJ_UINT16)((OPJ_UINT32)(getc(IN) << 8));
+       header->bfType |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
        
        if (header->bfType != 19778) {
                fprintf(stderr,"Error, not a BMP file!\n");
@@ -323,20 +325,20 @@ static OPJ_BOOL bmp_read_file_header(FILE* IN, OPJ_BITMAPFILEHEADER* header)
        /* FILE HEADER */
        /* ------------- */
        header->bfSize  = (OPJ_UINT32)getc(IN);
-       header->bfSize |= (OPJ_UINT32)(getc(IN) << 8);
-       header->bfSize |= (OPJ_UINT32)(getc(IN) << 16);
-       header->bfSize |= (OPJ_UINT32)(getc(IN) << 24);
+       header->bfSize |= (OPJ_UINT32)getc(IN) << 8;
+       header->bfSize |= (OPJ_UINT32)getc(IN) << 16;
+       header->bfSize |= (OPJ_UINT32)getc(IN) << 24;
        
        header->bfReserved1  = (OPJ_UINT16)getc(IN);
-       header->bfReserved1 |= (OPJ_UINT16)((OPJ_UINT32)(getc(IN) << 8));
+       header->bfReserved1 |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
        
        header->bfReserved2  = (OPJ_UINT16)getc(IN);
-       header->bfReserved2 |= (OPJ_UINT16)((OPJ_UINT32)(getc(IN) << 8));
+       header->bfReserved2 |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
        
        header->bfOffBits  = (OPJ_UINT32)getc(IN);
-       header->bfOffBits |= (OPJ_UINT32)(getc(IN) << 8);
-       header->bfOffBits |= (OPJ_UINT32)(getc(IN) << 16);
-       header->bfOffBits |= (OPJ_UINT32)(getc(IN) << 24);
+       header->bfOffBits |= (OPJ_UINT32)getc(IN) << 8;
+       header->bfOffBits |= (OPJ_UINT32)getc(IN) << 16;
+       header->bfOffBits |= (OPJ_UINT32)getc(IN) << 24;
        return OPJ_TRUE;
 }
 static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
@@ -345,9 +347,9 @@ static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
        /* INFO HEADER */
        /* ------------- */
        header->biSize  = (OPJ_UINT32)getc(IN);
-       header->biSize |= (OPJ_UINT32)(getc(IN) << 8);
-       header->biSize |= (OPJ_UINT32)(getc(IN) << 16);
-       header->biSize |= (OPJ_UINT32)(getc(IN) << 24);
+       header->biSize |= (OPJ_UINT32)getc(IN) << 8;
+       header->biSize |= (OPJ_UINT32)getc(IN) << 16;
+       header->biSize |= (OPJ_UINT32)getc(IN) << 24;
        
        switch (header->biSize) {
                case 12U:  /* BITMAPCOREHEADER */
@@ -363,125 +365,130 @@ static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
        }
        
        header->biWidth  = (OPJ_UINT32)getc(IN);
-       header->biWidth |= (OPJ_UINT32)(getc(IN) << 8);
-       header->biWidth |= (OPJ_UINT32)(getc(IN) << 16);
-       header->biWidth |= (OPJ_UINT32)(getc(IN) << 24);
+       header->biWidth |= (OPJ_UINT32)getc(IN) << 8;
+       header->biWidth |= (OPJ_UINT32)getc(IN) << 16;
+       header->biWidth |= (OPJ_UINT32)getc(IN) << 24;
        
        header->biHeight  = (OPJ_UINT32)getc(IN);
-       header->biHeight |= (OPJ_UINT32)(getc(IN) << 8);
-       header->biHeight |= (OPJ_UINT32)(getc(IN) << 16);
-       header->biHeight |= (OPJ_UINT32)(getc(IN) << 24);
+       header->biHeight |= (OPJ_UINT32)getc(IN) << 8;
+       header->biHeight |= (OPJ_UINT32)getc(IN) << 16;
+       header->biHeight |= (OPJ_UINT32)getc(IN) << 24;
        
        header->biPlanes  = (OPJ_UINT16)getc(IN);
-       header->biPlanes |= (OPJ_UINT16)((OPJ_UINT32)(getc(IN) << 8));
+       header->biPlanes |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
        
        header->biBitCount  = (OPJ_UINT16)getc(IN);
-       header->biBitCount |= (OPJ_UINT16)((OPJ_UINT32)(getc(IN) << 8));
+       header->biBitCount |= (OPJ_UINT16)((OPJ_UINT32)getc(IN) << 8);
        
        if(header->biSize >= 40U) {
                header->biCompression  = (OPJ_UINT32)getc(IN);
-               header->biCompression |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biCompression |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biCompression |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biCompression |= (OPJ_UINT32)getc(IN) << 8;
+               header->biCompression |= (OPJ_UINT32)getc(IN) << 16;
+               header->biCompression |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biSizeImage  = (OPJ_UINT32)getc(IN);
-               header->biSizeImage |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biSizeImage |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biSizeImage |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biSizeImage |= (OPJ_UINT32)getc(IN) << 8;
+               header->biSizeImage |= (OPJ_UINT32)getc(IN) << 16;
+               header->biSizeImage |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biXpelsPerMeter  = (OPJ_UINT32)getc(IN);
-               header->biXpelsPerMeter |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biXpelsPerMeter |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biXpelsPerMeter |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biXpelsPerMeter |= (OPJ_UINT32)getc(IN) << 8;
+               header->biXpelsPerMeter |= (OPJ_UINT32)getc(IN) << 16;
+               header->biXpelsPerMeter |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biYpelsPerMeter  = (OPJ_UINT32)getc(IN);
-               header->biYpelsPerMeter |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biYpelsPerMeter |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biYpelsPerMeter |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biYpelsPerMeter |= (OPJ_UINT32)getc(IN) << 8;
+               header->biYpelsPerMeter |= (OPJ_UINT32)getc(IN) << 16;
+               header->biYpelsPerMeter |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biClrUsed  = (OPJ_UINT32)getc(IN);
-               header->biClrUsed |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biClrUsed |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biClrUsed |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biClrUsed |= (OPJ_UINT32)getc(IN) << 8;
+               header->biClrUsed |= (OPJ_UINT32)getc(IN) << 16;
+               header->biClrUsed |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biClrImportant  = (OPJ_UINT32)getc(IN);
-               header->biClrImportant |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biClrImportant |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biClrImportant |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biClrImportant |= (OPJ_UINT32)getc(IN) << 8;
+               header->biClrImportant |= (OPJ_UINT32)getc(IN) << 16;
+               header->biClrImportant |= (OPJ_UINT32)getc(IN) << 24;
        }
        
        if(header->biSize >= 56U) {
                header->biRedMask  = (OPJ_UINT32)getc(IN);
-               header->biRedMask |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biRedMask |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biRedMask |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biRedMask |= (OPJ_UINT32)getc(IN) << 8;
+               header->biRedMask |= (OPJ_UINT32)getc(IN) << 16;
+               header->biRedMask |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biGreenMask  = (OPJ_UINT32)getc(IN);
-               header->biGreenMask |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biGreenMask |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biGreenMask |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biGreenMask |= (OPJ_UINT32)getc(IN) << 8;
+               header->biGreenMask |= (OPJ_UINT32)getc(IN) << 16;
+               header->biGreenMask |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biBlueMask  = (OPJ_UINT32)getc(IN);
-               header->biBlueMask |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biBlueMask |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biBlueMask |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biBlueMask |= (OPJ_UINT32)getc(IN) << 8;
+               header->biBlueMask |= (OPJ_UINT32)getc(IN) << 16;
+               header->biBlueMask |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biAlphaMask  = (OPJ_UINT32)getc(IN);
-               header->biAlphaMask |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biAlphaMask |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biAlphaMask |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 8;
+               header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 16;
+               header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 24;
        }
        
        if(header->biSize >= 108U) {
                header->biColorSpaceType  = (OPJ_UINT32)getc(IN);
-               header->biColorSpaceType |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biColorSpaceType |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biColorSpaceType |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biColorSpaceType |= (OPJ_UINT32)getc(IN) << 8;
+               header->biColorSpaceType |= (OPJ_UINT32)getc(IN) << 16;
+               header->biColorSpaceType |= (OPJ_UINT32)getc(IN) << 24;
                
-               fread(&(header->biColorSpaceEP), 1U, sizeof(header->biColorSpaceEP), IN);
+               if (fread(&(header->biColorSpaceEP), 1U, sizeof(header->biColorSpaceEP), IN) != sizeof(header->biColorSpaceEP)) {
+                       fprintf(stderr,"Error, can't  read BMP header\n");
+                       return OPJ_FALSE;
+               }
                
                header->biRedGamma  = (OPJ_UINT32)getc(IN);
-               header->biRedGamma |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biRedGamma |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biRedGamma |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biRedGamma |= (OPJ_UINT32)getc(IN) << 8;
+               header->biRedGamma |= (OPJ_UINT32)getc(IN) << 16;
+               header->biRedGamma |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biGreenGamma  = (OPJ_UINT32)getc(IN);
-               header->biGreenGamma |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biGreenGamma |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biGreenGamma |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biGreenGamma |= (OPJ_UINT32)getc(IN) << 8;
+               header->biGreenGamma |= (OPJ_UINT32)getc(IN) << 16;
+               header->biGreenGamma |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biBlueGamma  = (OPJ_UINT32)getc(IN);
-               header->biBlueGamma |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biBlueGamma |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biBlueGamma |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biBlueGamma |= (OPJ_UINT32)getc(IN) << 8;
+               header->biBlueGamma |= (OPJ_UINT32)getc(IN) << 16;
+               header->biBlueGamma |= (OPJ_UINT32)getc(IN) << 24;
        }
        
        if(header->biSize >= 124U) {
                header->biIntent  = (OPJ_UINT32)getc(IN);
-               header->biIntent |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biIntent |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biIntent |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biIntent |= (OPJ_UINT32)getc(IN) << 8;
+               header->biIntent |= (OPJ_UINT32)getc(IN) << 16;
+               header->biIntent |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biIccProfileData  = (OPJ_UINT32)getc(IN);
-               header->biIccProfileData |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biIccProfileData |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biIccProfileData |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biIccProfileData |= (OPJ_UINT32)getc(IN) << 8;
+               header->biIccProfileData |= (OPJ_UINT32)getc(IN) << 16;
+               header->biIccProfileData |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biIccProfileSize  = (OPJ_UINT32)getc(IN);
-               header->biIccProfileSize |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biIccProfileSize |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biIccProfileSize |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biIccProfileSize |= (OPJ_UINT32)getc(IN) << 8;
+               header->biIccProfileSize |= (OPJ_UINT32)getc(IN) << 16;
+               header->biIccProfileSize |= (OPJ_UINT32)getc(IN) << 24;
                
                header->biReserved  = (OPJ_UINT32)getc(IN);
-               header->biReserved |= (OPJ_UINT32)(getc(IN) << 8);
-               header->biReserved |= (OPJ_UINT32)(getc(IN) << 16);
-               header->biReserved |= (OPJ_UINT32)(getc(IN) << 24);
+               header->biReserved |= (OPJ_UINT32)getc(IN) << 8;
+               header->biReserved |= (OPJ_UINT32)getc(IN) << 16;
+               header->biReserved |= (OPJ_UINT32)getc(IN) << 24;
        }
        return OPJ_TRUE;
 }
 
 static OPJ_BOOL bmp_read_raw_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
 {
+       OPJ_ARG_NOT_USED(width);
+       
        if ( fread(pData, sizeof(OPJ_UINT8), stride * height, IN) != (stride * height) )
        {
                fprintf(stderr, "\nError: fread return a number of element different from the expected.\n");
@@ -565,7 +572,7 @@ static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride
                        OPJ_UINT8 c1 = (OPJ_UINT8)getc(IN);
                
                        for (j = 0; (j < c) && (x < width) && ((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
-                               *pix = (j&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+                               *pix = (OPJ_UINT8)((j&1) ? (c1 & 0x0fU) : ((c1>>4)&0x0fU));
                        }
                }
                else { /* absolute mode */
@@ -591,7 +598,7 @@ static OPJ_BOOL bmp_read_rle4_data(FILE* IN, OPJ_UINT8* pData, OPJ_UINT32 stride
                                        if((j&1) == 0) {
                                                        c1 = (OPJ_UINT8)getc(IN);
                                        }
-                                       *pix = (j&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+                                       *pix =  (OPJ_UINT8)((j&1) ? (c1 & 0x0fU) : ((c1>>4)&0x0fU));
                                }
                                if(((c&3) == 1) || ((c&3) == 2)) { /* skip padding byte */
                                                getc(IN);
@@ -606,7 +613,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
 {
        opj_image_cmptparm_t cmptparm[4];       /* maximum of 4 components */
        OPJ_UINT8 lut_R[256], lut_G[256], lut_B[256];
-       OPJ_UINT8 const* pLUT[] = { lut_R, lut_G, lut_B };
+       OPJ_UINT8 const* pLUT[3];
        opj_image_t * image = NULL;
        FILE *IN;
        OPJ_BITMAPFILEHEADER File_h;
@@ -616,6 +623,8 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
        OPJ_UINT8* pData = NULL;
        OPJ_UINT32 stride;
        
+       pLUT[0] = lut_R; pLUT[1] = lut_G; pLUT[2] = lut_B;
+       
        IN = fopen(filename, "rb");
        if (!IN)
        {
@@ -666,9 +675,27 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
                }
        }
        
-       stride = ((Info_h.biWidth * Info_h.biBitCount + 31U) / 32U) * 4U; // rows are aligned on 32bits
+       if (Info_h.biWidth == 0 || Info_h.biHeight == 0) {
+               fclose(IN);
+               return NULL;
+       }
+       
+       if (Info_h.biBitCount > (((OPJ_UINT32)-1) - 31) / Info_h.biWidth) {
+               fclose(IN);
+               return NULL;
+       }
+       stride = ((Info_h.biWidth * Info_h.biBitCount + 31U) / 32U) * 4U; /* rows are aligned on 32bits */
        if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /* RLE 4 gets decoded as 8 bits data for now... */
-               stride = ((Info_h.biWidth * 8U + 31U) / 32U) * 4U; // rows are aligned on 32bits
+               if (8 > (((OPJ_UINT32)-1) - 31) / Info_h.biWidth) {
+                       fclose(IN);
+                       return NULL;
+               }
+               stride = ((Info_h.biWidth * 8U + 31U) / 32U) * 4U;
+       }
+       
+       if (stride > ((OPJ_UINT32)-1) / sizeof(OPJ_UINT8) / Info_h.biHeight) {
+               fclose(IN);
+               return NULL;
        }
        pData = (OPJ_UINT8 *) calloc(1, stride * Info_h.biHeight * sizeof(OPJ_UINT8));
        if (pData == NULL) {
@@ -720,6 +747,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
        image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB);
        if(!image) {
                fclose(IN);
+               free(pData);
                return NULL;
        }
        if (numcmpts == 4U) {
@@ -734,25 +762,25 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
        
        /* Read the data */
        if (Info_h.biBitCount == 24 && Info_h.biCompression == 0) { /*RGB */
-               bmp24toimage(IN, pData, stride, image);
+               bmp24toimage(pData, stride, image);
        }
        else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { /* RGB 8bpp Indexed */
-               bmp8toimage(IN, pData, stride, image, pLUT);
+               bmp8toimage(pData, stride, image, pLUT);
        }
        else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { /*RLE8*/
-               bmp8toimage(IN, pData, stride, image, pLUT);
+               bmp8toimage(pData, stride, image, pLUT);
        }
        else if (Info_h.biBitCount == 4 && Info_h.biCompression == 2) { /*RLE4*/
-               bmp8toimage(IN, pData, stride, image, pLUT); /* RLE 4 gets decoded as 8 bits data for now */
+               bmp8toimage(pData, stride, image, pLUT); /* RLE 4 gets decoded as 8 bits data for now */
        }
        else if (Info_h.biBitCount == 32 && Info_h.biCompression == 0) { /* RGBX */
-               bmpmask32toimage(IN, pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, 0x00000000U);
+               bmpmask32toimage(pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU, 0x00000000U);
        }
        else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
-               bmpmask32toimage(IN, pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
+               bmpmask32toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
        }
        else if (Info_h.biBitCount == 16 && Info_h.biCompression == 0) { /* RGBX */
-               bmpmask16toimage(IN, pData, stride, image, 0x7C00U, 0x03E0U, 0x001FU, 0x0000U);
+               bmpmask16toimage(pData, stride, image, 0x7C00U, 0x03E0U, 0x001FU, 0x0000U);
        }
        else if (Info_h.biBitCount == 16 && Info_h.biCompression == 3) { /* bitmask */
                if ((Info_h.biRedMask == 0U) && (Info_h.biGreenMask == 0U) && (Info_h.biBlueMask == 0U)) {
@@ -760,7 +788,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
                        Info_h.biGreenMask = 0x07E0U;
                        Info_h.biBlueMask  = 0x001FU;
                }
-               bmpmask16toimage(IN, pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
+               bmpmask16toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask, Info_h.biBlueMask, Info_h.biAlphaMask);
        }
        else {
                opj_image_destroy(image);
@@ -881,7 +909,7 @@ int imagetobmp(opj_image_t * image, const char *outfile) {
             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 */
+                for (pad = ((3 * w) % 4) ? (4 - (3 * w) % 4) : 0; pad > 0; pad--)      /* ADD */
                     fprintf(fdest, "%c", 0);
             }
         }
@@ -893,6 +921,10 @@ int imagetobmp(opj_image_t * image, const char *outfile) {
         <<-- <<-- <<-- <<-- */
 
         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;
 
@@ -953,7 +985,7 @@ int imagetobmp(opj_image_t * image, const char *outfile) {
             fprintf(fdest, "%c", (OPJ_UINT8)r);
 
             if ((i + 1) % w == 0) {
-                for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--)      /* ADD */
+                for (pad = (w % 4) ? (4 - w % 4) : 0; pad > 0; pad--)  /* ADD */
                     fprintf(fdest, "%c", 0);
             }
         }