diff --git a/libretro-common/formats/bmp/rbmp.c b/libretro-common/formats/bmp/rbmp.c index 08d97a80d5..543896b716 100644 --- a/libretro-common/formats/bmp/rbmp.c +++ b/libretro-common/formats/bmp/rbmp.c @@ -84,10 +84,7 @@ static int rbmp_get16le(rbmp_context *s) return rbmp_get8(s) + (rbmp_get8(s) << 8); } -static uint32_t rbmp_get32le(rbmp_context *s) -{ - return rbmp_get16le(s) + (rbmp_get16le(s) << 16); -} +#define RBMP_GET32LE(s) (rbmp_get16le(s) + (rbmp_get16le(s) << 16)) static unsigned char *rbmp_convert_format( unsigned char *data, @@ -266,11 +263,15 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, if (rbmp_get8(s) != 'B' || rbmp_get8(s) != 'M') return 0; - rbmp_get32le(s); /* discard filesize */ - rbmp_get16le(s); /* discard reserved */ - rbmp_get16le(s); /* discard reserved */ - offset = rbmp_get32le(s); - hsz = rbmp_get32le(s); + /* discard filesize */ + rbmp_get16le(s); + rbmp_get16le(s); + /* discard reserved */ + rbmp_get16le(s); + rbmp_get16le(s); + + offset = (uint32_t)RBMP_GET32LE(s); + hsz = (uint32_t)RBMP_GET32LE(s); /* BMP type not supported? */ if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) @@ -283,8 +284,8 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, } else { - s->img_x = rbmp_get32le(s); - s->img_y = rbmp_get32le(s); + s->img_x = (uint32_t)RBMP_GET32LE(s); + s->img_y = (uint32_t)RBMP_GET32LE(s); } /* Bad BMP? */ @@ -307,26 +308,40 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, } else { - int compress = rbmp_get32le(s); + int compress = (uint32_t)RBMP_GET32LE(s); /* BMP RLE type not supported? */ if (compress == 1 || compress == 2) return 0; - rbmp_get32le(s); /* discard sizeof */ - rbmp_get32le(s); /* discard hres */ - rbmp_get32le(s); /* discard vres */ - rbmp_get32le(s); /* discard colors used */ - rbmp_get32le(s); /* discard max important */ + /* discord sizeof */ + rbmp_get16le(s); + rbmp_get16le(s); + /* discard hres */ + rbmp_get16le(s); + rbmp_get16le(s); + /* discard vres */ + rbmp_get16le(s); + rbmp_get16le(s); + /* discard colors used */ + rbmp_get16le(s); + rbmp_get16le(s); + /* discard max important */ + rbmp_get16le(s); + rbmp_get16le(s); if (hsz == 40 || hsz == 56) { if (hsz == 56) { - rbmp_get32le(s); - rbmp_get32le(s); - rbmp_get32le(s); - rbmp_get32le(s); + rbmp_get16le(s); + rbmp_get16le(s); + rbmp_get16le(s); + rbmp_get16le(s); + rbmp_get16le(s); + rbmp_get16le(s); + rbmp_get16le(s); + rbmp_get16le(s); } if (bpp == 16 || bpp == 32) { @@ -350,9 +365,9 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, #endif break; case 3: - mr = rbmp_get32le(s); - mg = rbmp_get32le(s); - mb = rbmp_get32le(s); + mr = (uint32_t)RBMP_GET32LE(s); + mg = (uint32_t)RBMP_GET32LE(s); + mb = (uint32_t)RBMP_GET32LE(s); /* not documented, but generated by * Photoshop and handled by MS Paint */ /* Bad BMP ?*/ @@ -372,19 +387,33 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, } else { - mr = rbmp_get32le(s); - mg = rbmp_get32le(s); - mb = rbmp_get32le(s); - ma = rbmp_get32le(s); - rbmp_get32le(s); /* Discard color space */ + mr = (uint32_t)RBMP_GET32LE(s); + mg = (uint32_t)RBMP_GET32LE(s); + mb = (uint32_t)RBMP_GET32LE(s); + ma = (uint32_t)RBMP_GET32LE(s); + /* Discard color space */ + rbmp_get16le(s); + rbmp_get16le(s); for (i = 0; i < 12; ++i) - rbmp_get32le(s); /* Discard color space parameters */ + { + /* Discard color space parameters */ + rbmp_get16le(s); + rbmp_get16le(s); + } if (hsz == 124) { - rbmp_get32le(s); /* Discard rendering intent */ - rbmp_get32le(s); /* Discard offset of profile data */ - rbmp_get32le(s); /* Discard size of profile data */ - rbmp_get32le(s); /* Discard reserved */ + /* Discard rendering intent */ + rbmp_get16le(s); + rbmp_get16le(s); + /* Discard offset of profile data */ + rbmp_get16le(s); + rbmp_get16le(s); + /* Discard size of profile data */ + rbmp_get16le(s); + rbmp_get16le(s); + /* Discard reserved */ + rbmp_get16le(s); + rbmp_get16le(s); } } if (bpp < 16) @@ -572,24 +601,52 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, /* Need to apply alpha channel as well */ if (ma) { - for (i = 0; i < (int) s->img_x; ++i) + if (bpp == 16) { - uint32_t v = (bpp == 16 ? (uint32_t) rbmp_get16le(s) : rbmp_get32le(s)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & ma, ashift, acount)); + for (i = 0; i < (int) s->img_x; ++i) + { + uint32_t v = (uint32_t)rbmp_get16le(s); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & ma, ashift, acount)); + } + } + else + { + for (i = 0; i < (int) s->img_x; ++i) + { + uint32_t v = (uint32_t)RBMP_GET32LE(s); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & ma, ashift, acount)); + } } } else { - for (i = 0; i < (int) s->img_x; ++i) + if (bpp == 16) { - uint32_t v = (bpp == 16 ? (uint32_t) rbmp_get16le(s) : rbmp_get32le(s)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); - out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount)); - out[z++] = RBMP_BYTECAST(255); + for (i = 0; i < (int) s->img_x; ++i) + { + uint32_t v = (uint32_t)rbmp_get16le(s); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount)); + out[z++] = RBMP_BYTECAST(255); + } + } + else + { + for (i = 0; i < (int) s->img_x; ++i) + { + uint32_t v = (uint32_t)RBMP_GET32LE(s); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); + out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount)); + out[z++] = RBMP_BYTECAST(255); + } } } } @@ -609,7 +666,7 @@ static unsigned char *rbmp_bmp_load(rbmp_context *s, unsigned *x, unsigned *y, { for (i = 0; i < (int) s->img_x; ++i) { - uint32_t v = rbmp_get32le(s); + uint32_t v = (uint32_t)RBMP_GET32LE(s); out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mr, rshift, rcount)); out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mg, gshift, gcount)); out[z++] = RBMP_BYTECAST(rbmp_shiftsigned(v & mb, bshift, bcount));