Add input checks, fix overflow/wrap related bugs
This commit is contained in:
@@ -113,8 +113,8 @@ I<BH_BITMAP_RGBA32> pixel format.
|
|||||||
|
|
||||||
=head2 BH_BitmapNew
|
=head2 BH_BitmapNew
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapNew(int width,
|
BH_Bitmap *BH_BitmapNew(uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int format,
|
int format,
|
||||||
int flags,
|
int flags,
|
||||||
void *data,
|
void *data,
|
||||||
@@ -149,8 +149,8 @@ Destroys the bitmap object.
|
|||||||
=head2 BH_BitmapColor
|
=head2 BH_BitmapColor
|
||||||
|
|
||||||
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
BH_Color *value);
|
BH_Color *value);
|
||||||
|
|
||||||
Reads color value of the pixel at specified position.
|
Reads color value of the pixel at specified position.
|
||||||
@@ -161,8 +161,8 @@ The I<x> and I<y> parameters specify a position on the bitmap.
|
|||||||
=head2 BH_BitmapSetColor
|
=head2 BH_BitmapSetColor
|
||||||
|
|
||||||
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
const BH_Color *value);
|
const BH_Color *value);
|
||||||
|
|
||||||
Writes color value of the pixel at specified position.
|
Writes color value of the pixel at specified position.
|
||||||
@@ -173,8 +173,8 @@ The I<x> and I<y> parameters specify a position on the bitmap.
|
|||||||
=head2 BH_BitmapIndex
|
=head2 BH_BitmapIndex
|
||||||
|
|
||||||
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
Returns the index value at the specified position.
|
Returns the index value at the specified position.
|
||||||
|
|
||||||
@@ -184,8 +184,8 @@ The I<x> and I<y> parameters specify a position on the bitmap.
|
|||||||
=head2 BH_BitmapSetIndex
|
=head2 BH_BitmapSetIndex
|
||||||
|
|
||||||
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
uint8_t index);
|
uint8_t index);
|
||||||
|
|
||||||
Sets the index value at the specified position.
|
Sets the index value at the specified position.
|
||||||
@@ -196,10 +196,10 @@ The I<x> and I<y> parameters specify a position on the bitmap.
|
|||||||
=head2 BH_BitmapCopy
|
=head2 BH_BitmapCopy
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
int width,
|
uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int shallow);
|
int shallow);
|
||||||
|
|
||||||
Creates a copy of the bitmap region by the given position and size.
|
Creates a copy of the bitmap region by the given position and size.
|
||||||
@@ -218,7 +218,7 @@ This function returns a pointer to a new BH_Bitmap object or NULL.
|
|||||||
=head2 BH_BitmapScanline
|
=head2 BH_BitmapScanline
|
||||||
|
|
||||||
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
Returns address of the scanline in the bitmap.
|
Returns address of the scanline in the bitmap.
|
||||||
|
|
||||||
@@ -226,22 +226,22 @@ Returns address of the scanline in the bitmap.
|
|||||||
=head2 BH_BitmapAt
|
=head2 BH_BitmapAt
|
||||||
|
|
||||||
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
Returns address of the pixel in the bitmap.
|
Returns address of the pixel in the bitmap.
|
||||||
|
|
||||||
|
|
||||||
=head2 BH_BitmapWidth
|
=head2 BH_BitmapWidth
|
||||||
|
|
||||||
int BH_BitmapWidth(BH_Bitmap *bitmap);
|
uint32_t BH_BitmapWidth(BH_Bitmap *bitmap);
|
||||||
|
|
||||||
Returns width of the bitmap.
|
Returns width of the bitmap.
|
||||||
|
|
||||||
|
|
||||||
=head2 BH_BitmapHeight
|
=head2 BH_BitmapHeight
|
||||||
|
|
||||||
int BH_BitmapHeight(BH_Bitmap *bitmap);
|
uint32_t BH_BitmapHeight(BH_Bitmap *bitmap);
|
||||||
|
|
||||||
Returns height of the bitmap.
|
Returns height of the bitmap.
|
||||||
|
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ I<BH_BITMAP_INDEX4> и I<BH_BITMAP_INDEX8>.
|
|||||||
|
|
||||||
=head2 BH_BitmapNew
|
=head2 BH_BitmapNew
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapNew(int width,
|
BH_Bitmap *BH_BitmapNew(uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int format,
|
int format,
|
||||||
int flags,
|
int flags,
|
||||||
void *data,
|
void *data,
|
||||||
@@ -155,8 +155,8 @@ I<BH_BITMAP_INDEX4> и I<BH_BITMAP_INDEX8>.
|
|||||||
=head2 BH_BitmapColor
|
=head2 BH_BitmapColor
|
||||||
|
|
||||||
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
BH_Color *value);
|
BH_Color *value);
|
||||||
|
|
||||||
Считывает значение цвета пикселя в указанной позиции.
|
Считывает значение цвета пикселя в указанной позиции.
|
||||||
@@ -167,8 +167,8 @@ I<BH_BITMAP_INDEX4> и I<BH_BITMAP_INDEX8>.
|
|||||||
=head2 BH_BitmapSetColor
|
=head2 BH_BitmapSetColor
|
||||||
|
|
||||||
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
const BH_Color *value);
|
const BH_Color *value);
|
||||||
|
|
||||||
Записывает значение цвета пикселя в указанной позиции.
|
Записывает значение цвета пикселя в указанной позиции.
|
||||||
@@ -179,8 +179,8 @@ I<BH_BITMAP_INDEX4> и I<BH_BITMAP_INDEX8>.
|
|||||||
=head2 BH_BitmapIndex
|
=head2 BH_BitmapIndex
|
||||||
|
|
||||||
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
Возвращает значение индекса в указанной позиции.
|
Возвращает значение индекса в указанной позиции.
|
||||||
|
|
||||||
@@ -190,8 +190,8 @@ I<BH_BITMAP_INDEX4> и I<BH_BITMAP_INDEX8>.
|
|||||||
=head2 BH_BitmapSetIndex
|
=head2 BH_BitmapSetIndex
|
||||||
|
|
||||||
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
uint8_t index);
|
uint8_t index);
|
||||||
|
|
||||||
Устанавливает значение индекса в указанной позиции.
|
Устанавливает значение индекса в указанной позиции.
|
||||||
@@ -202,10 +202,10 @@ void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
|||||||
=head2 BH_BitmapCopy
|
=head2 BH_BitmapCopy
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
int width,
|
uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int shallow);
|
int shallow);
|
||||||
|
|
||||||
Создает копию области растрового изображения с заданным положением и размером.
|
Создает копию области растрового изображения с заданным положением и размером.
|
||||||
@@ -225,7 +225,7 @@ void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
|||||||
=head2 BH_BitmapScanline
|
=head2 BH_BitmapScanline
|
||||||
|
|
||||||
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
Возвращает адрес строки сканирования в растровом изображении.
|
Возвращает адрес строки сканирования в растровом изображении.
|
||||||
|
|
||||||
@@ -233,22 +233,22 @@ void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
|||||||
=head2 BH_BitmapAt
|
=head2 BH_BitmapAt
|
||||||
|
|
||||||
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
Возвращает адрес пикселя в растровом изображении.
|
Возвращает адрес пикселя в растровом изображении.
|
||||||
|
|
||||||
|
|
||||||
=head2 BH_BitmapWidth
|
=head2 BH_BitmapWidth
|
||||||
|
|
||||||
int BH_BitmapWidth(BH_Bitmap *bitmap);
|
uint32_t BH_BitmapWidth(BH_Bitmap *bitmap);
|
||||||
|
|
||||||
Возвращает ширину растрового изображения.
|
Возвращает ширину растрового изображения.
|
||||||
|
|
||||||
|
|
||||||
=head2 BH_BitmapHeight
|
=head2 BH_BitmapHeight
|
||||||
|
|
||||||
int BH_BitmapHeight(BH_Bitmap *bitmap);
|
uint32_t BH_BitmapHeight(BH_Bitmap *bitmap);
|
||||||
|
|
||||||
Возвращает высоту растрового изображения.
|
Возвращает высоту растрового изображения.
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ typedef struct BH_Bitmap BH_Bitmap;
|
|||||||
#define BH_BITMAP_FLAG_EXT_PALETTE 0x0004
|
#define BH_BITMAP_FLAG_EXT_PALETTE 0x0004
|
||||||
|
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapNew(int width,
|
BH_Bitmap *BH_BitmapNew(uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int format,
|
int format,
|
||||||
int flags,
|
int flags,
|
||||||
void *data,
|
void *data,
|
||||||
@@ -47,49 +47,49 @@ void BH_BitmapFree(BH_Bitmap *bitmap);
|
|||||||
|
|
||||||
|
|
||||||
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
BH_Color *value);
|
BH_Color *value);
|
||||||
|
|
||||||
|
|
||||||
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
const BH_Color *value);
|
const BH_Color *value);
|
||||||
|
|
||||||
|
|
||||||
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
|
|
||||||
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
uint8_t index);
|
uint8_t index);
|
||||||
|
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
int width,
|
uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int shallow);
|
int shallow);
|
||||||
|
|
||||||
|
|
||||||
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
|
|
||||||
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y);
|
uint32_t y);
|
||||||
|
|
||||||
|
|
||||||
int BH_BitmapWidth(BH_Bitmap *bitmap);
|
uint32_t BH_BitmapWidth(BH_Bitmap *bitmap);
|
||||||
|
|
||||||
|
|
||||||
int BH_BitmapHeight(BH_Bitmap *bitmap);
|
uint32_t BH_BitmapHeight(BH_Bitmap *bitmap);
|
||||||
|
|
||||||
|
|
||||||
int BH_BitmapFormat(BH_Bitmap *bitmap);
|
int BH_BitmapFormat(BH_Bitmap *bitmap);
|
||||||
|
|||||||
126
src/Bitmap.c
126
src/Bitmap.c
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
struct BH_Bitmap
|
struct BH_Bitmap
|
||||||
{
|
{
|
||||||
int width;
|
uint32_t width;
|
||||||
int height;
|
uint32_t height;
|
||||||
int format;
|
int format;
|
||||||
int flags;
|
int flags;
|
||||||
size_t step;
|
size_t step;
|
||||||
@@ -131,7 +131,7 @@ static size_t calculateStep(int format)
|
|||||||
|
|
||||||
static uint8_t bitmapIndex(void *data,
|
static uint8_t bitmapIndex(void *data,
|
||||||
int format,
|
int format,
|
||||||
int x)
|
uint32_t x)
|
||||||
{
|
{
|
||||||
int isLSB;
|
int isLSB;
|
||||||
uint8_t octet;
|
uint8_t octet;
|
||||||
@@ -161,7 +161,7 @@ static uint8_t bitmapIndex(void *data,
|
|||||||
|
|
||||||
static void setBitmapIndex(void *data,
|
static void setBitmapIndex(void *data,
|
||||||
int format,
|
int format,
|
||||||
int x,
|
uint32_t x,
|
||||||
uint8_t index)
|
uint8_t index)
|
||||||
{
|
{
|
||||||
int isLSB;
|
int isLSB;
|
||||||
@@ -199,7 +199,7 @@ static void bitmapColor(void *data,
|
|||||||
void *palette,
|
void *palette,
|
||||||
int format,
|
int format,
|
||||||
BH_Color *value,
|
BH_Color *value,
|
||||||
int x)
|
uint32_t x)
|
||||||
{
|
{
|
||||||
switch (format & 0x0FFF)
|
switch (format & 0x0FFF)
|
||||||
{
|
{
|
||||||
@@ -423,7 +423,7 @@ static void setBitmapColor(void *data,
|
|||||||
void *palette,
|
void *palette,
|
||||||
int format,
|
int format,
|
||||||
const BH_Color *value,
|
const BH_Color *value,
|
||||||
int x)
|
uint32_t x)
|
||||||
{
|
{
|
||||||
switch (format & 0x0FFF)
|
switch (format & 0x0FFF)
|
||||||
{
|
{
|
||||||
@@ -611,7 +611,7 @@ static void setBitmapColor(void *data,
|
|||||||
static void *rowAt(void *data,
|
static void *rowAt(void *data,
|
||||||
int format,
|
int format,
|
||||||
int step,
|
int step,
|
||||||
int x)
|
uint32_t x)
|
||||||
{
|
{
|
||||||
switch (format & 0x0FFF)
|
switch (format & 0x0FFF)
|
||||||
{
|
{
|
||||||
@@ -631,16 +631,22 @@ static void *rowAt(void *data,
|
|||||||
|
|
||||||
|
|
||||||
static size_t calculateStride(int format,
|
static size_t calculateStride(int format,
|
||||||
int width)
|
uint32_t width)
|
||||||
{
|
{
|
||||||
|
size_t step;
|
||||||
|
|
||||||
switch (format & 0x0FFF)
|
switch (format & 0x0FFF)
|
||||||
{
|
{
|
||||||
case BH_BITMAP_INDEX1: return (width + 7) / 8;
|
case BH_BITMAP_INDEX1: return (width + 7) / 8;
|
||||||
case BH_BITMAP_INDEX2: return (width + 3) / 4;
|
case BH_BITMAP_INDEX2: return (width + 3) / 4;
|
||||||
case BH_BITMAP_INDEX4: return (width + 1) / 2;
|
case BH_BITMAP_INDEX4: return (width + 1) / 2;
|
||||||
case BH_BITMAP_INDEX8: return width * calculateStep(format);
|
|
||||||
}
|
}
|
||||||
return width * calculateStep(format);
|
|
||||||
|
step = calculateStep(format);
|
||||||
|
if (BH_CHECK_UMUL_WRAP(step, width, size_t))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return step * width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -673,8 +679,8 @@ static size_t calculateTrailer(int format)
|
|||||||
|
|
||||||
|
|
||||||
/* Public functions */
|
/* Public functions */
|
||||||
BH_Bitmap *BH_BitmapNew(int width,
|
BH_Bitmap *BH_BitmapNew(uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int format,
|
int format,
|
||||||
int flags,
|
int flags,
|
||||||
void *data,
|
void *data,
|
||||||
@@ -682,7 +688,12 @@ BH_Bitmap *BH_BitmapNew(int width,
|
|||||||
{
|
{
|
||||||
BH_Bitmap *result;
|
BH_Bitmap *result;
|
||||||
int needPalette;
|
int needPalette;
|
||||||
size_t header, body, trailer, stride, step;
|
size_t header, body, allocSize, stride, step;
|
||||||
|
|
||||||
|
/* Basic sanity check */
|
||||||
|
if (width == 0 || width >= 0x7FFFFFFF ||
|
||||||
|
height == 0 || height >= 0x7FFFFFFF)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Unset internal flags */
|
/* Unset internal flags */
|
||||||
flags &= ~BH_BITMAP_FLAG_EXT_DATA;
|
flags &= ~BH_BITMAP_FLAG_EXT_DATA;
|
||||||
@@ -693,19 +704,35 @@ BH_Bitmap *BH_BitmapNew(int width,
|
|||||||
stride = calculateStride(format, width);
|
stride = calculateStride(format, width);
|
||||||
needPalette = isPaletteNeeded(format);
|
needPalette = isPaletteNeeded(format);
|
||||||
|
|
||||||
|
/* Check stride overflow */
|
||||||
|
if (!stride)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (flags & BH_BITMAP_FLAG_ALIGN32)
|
if (flags & BH_BITMAP_FLAG_ALIGN32)
|
||||||
|
{
|
||||||
|
if (BH_CHECK_UADD_WRAP(stride, sizeof(uint32_t) - 1, size_t))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
stride = (stride + sizeof(uint32_t) - 1) & ~(sizeof(uint32_t) - 1);
|
stride = (stride + sizeof(uint32_t) - 1) & ~(sizeof(uint32_t) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
header = sizeof(*result);
|
header = sizeof(*result);
|
||||||
header = (header + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t) - 1);
|
header = (header + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t) - 1);
|
||||||
body = (stride * height + (sizeof(uint32_t) - 1)) & ~(sizeof(uint32_t) - 1);
|
allocSize = calculateTrailer(format);
|
||||||
trailer = calculateTrailer(format);
|
|
||||||
|
body = stride * height;
|
||||||
|
if (BH_CHECK_UMUL_WRAP(stride, height, size_t))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (BH_CHECK_UADD_WRAP(body, sizeof(uint32_t) - 1, size_t))
|
||||||
|
return NULL;
|
||||||
|
body = (body + (sizeof(uint32_t) - 1)) & ~(sizeof(uint32_t) - 1);
|
||||||
|
|
||||||
/* Adjust body and trailer size if ext data or palette is provided */
|
/* Adjust body and trailer size if ext data or palette is provided */
|
||||||
if (palette)
|
if (palette)
|
||||||
{
|
{
|
||||||
flags |= BH_BITMAP_FLAG_EXT_PALETTE;
|
flags |= BH_BITMAP_FLAG_EXT_PALETTE;
|
||||||
trailer = 0;
|
allocSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
@@ -714,8 +741,16 @@ BH_Bitmap *BH_BitmapNew(int width,
|
|||||||
body = 0;
|
body = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BH_CHECK_UADD_WRAP(allocSize, header, size_t))
|
||||||
|
return NULL;
|
||||||
|
allocSize += header;
|
||||||
|
|
||||||
|
if (BH_CHECK_UADD_WRAP(allocSize, body, size_t))
|
||||||
|
return NULL;
|
||||||
|
allocSize += body;
|
||||||
|
|
||||||
/* Allocate and setup bitmap data */
|
/* Allocate and setup bitmap data */
|
||||||
result = malloc(header + body + trailer);
|
result = malloc(allocSize);
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -745,16 +780,16 @@ void BH_BitmapFree(BH_Bitmap *bitmap)
|
|||||||
|
|
||||||
|
|
||||||
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
void BH_BitmapColor(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
BH_Color *value)
|
BH_Color *value)
|
||||||
{
|
{
|
||||||
bitmapColor(BH_BitmapAt(bitmap, x, y), bitmap->palette, bitmap->format, value, x);
|
bitmapColor(BH_BitmapAt(bitmap, x, y), bitmap->palette, bitmap->format, value, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
const BH_Color *value)
|
const BH_Color *value)
|
||||||
{
|
{
|
||||||
setBitmapColor(BH_BitmapAt(bitmap, x, y), bitmap->palette, bitmap->format, value, x);
|
setBitmapColor(BH_BitmapAt(bitmap, x, y), bitmap->palette, bitmap->format, value, x);
|
||||||
@@ -762,33 +797,28 @@ void BH_BitmapSetColor(BH_Bitmap *bitmap,
|
|||||||
|
|
||||||
|
|
||||||
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
int width,
|
uint32_t width,
|
||||||
int height,
|
uint32_t height,
|
||||||
int shallow)
|
int shallow)
|
||||||
{
|
{
|
||||||
BH_Bitmap *result;
|
BH_Bitmap *result;
|
||||||
int i, j;
|
uint32_t i, j;
|
||||||
|
|
||||||
/* Check for bogus width and height */
|
/* Sanity checks */
|
||||||
if (width < 0 || height < 0)
|
if (!width || !height || x >= bitmap->width || y >= bitmap->height)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (width < bitmap->width - x || height < bitmap->height - y)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Shallow copy can't go out of bounds of the source bitmap */
|
/* Shallow copy can't go out of bounds of the source bitmap */
|
||||||
if (shallow)
|
if (shallow)
|
||||||
{
|
{
|
||||||
if (x < 0 || x > bitmap->width || y < 0 || y > bitmap->height)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (width < 0 || width > bitmap->width - x ||
|
|
||||||
height < 0 || height > bitmap->height - y)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
result = BH_BitmapNew(width, height, bitmap->format, bitmap->flags,
|
result = BH_BitmapNew(width, height, bitmap->format, bitmap->flags,
|
||||||
BH_BitmapAt(bitmap, x, y), bitmap->palette);
|
BH_BitmapAt(bitmap, x, y), bitmap->palette);
|
||||||
result->stride = bitmap->stride;
|
result->stride = bitmap->stride;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,13 +836,7 @@ BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
|||||||
for (i = 0; i < width; ++i)
|
for (i = 0; i < width; ++i)
|
||||||
{
|
{
|
||||||
BH_Color color;
|
BH_Color color;
|
||||||
memset(&color, 0, sizeof(color));
|
|
||||||
|
|
||||||
|
|
||||||
if (i + x >= 0 && i + x < bitmap->width &&
|
|
||||||
j + y >= 0 && j + y < bitmap->height)
|
|
||||||
BH_BitmapColor(bitmap, i + x, j + y, &color);
|
BH_BitmapColor(bitmap, i + x, j + y, &color);
|
||||||
|
|
||||||
BH_BitmapSetColor(result, i, j, &color);
|
BH_BitmapSetColor(result, i, j, &color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -822,16 +846,16 @@ BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap,
|
|||||||
|
|
||||||
|
|
||||||
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
uint8_t BH_BitmapIndex(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y)
|
uint32_t y)
|
||||||
{
|
{
|
||||||
return bitmapIndex(BH_BitmapAt(bitmap, x, y), bitmap->format, x);
|
return bitmapIndex(BH_BitmapAt(bitmap, x, y), bitmap->format, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y,
|
uint32_t y,
|
||||||
uint8_t index)
|
uint8_t index)
|
||||||
{
|
{
|
||||||
setBitmapIndex(BH_BitmapAt(bitmap, x, y), bitmap->format, x, index);
|
setBitmapIndex(BH_BitmapAt(bitmap, x, y), bitmap->format, x, index);
|
||||||
@@ -839,27 +863,27 @@ void BH_BitmapSetIndex(BH_Bitmap *bitmap,
|
|||||||
|
|
||||||
|
|
||||||
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
void *BH_BitmapScanline(const BH_Bitmap *bitmap,
|
||||||
int y)
|
uint32_t y)
|
||||||
{
|
{
|
||||||
return bitmap->data + y * bitmap->stride;
|
return bitmap->data + y * bitmap->stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
void *BH_BitmapAt(const BH_Bitmap *bitmap,
|
||||||
int x,
|
uint32_t x,
|
||||||
int y)
|
uint32_t y)
|
||||||
{
|
{
|
||||||
return rowAt(BH_BitmapScanline(bitmap, y), bitmap->format, bitmap->step, x);
|
return rowAt(BH_BitmapScanline(bitmap, y), bitmap->format, bitmap->step, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BH_BitmapWidth(BH_Bitmap *bitmap)
|
uint32_t BH_BitmapWidth(BH_Bitmap *bitmap)
|
||||||
{
|
{
|
||||||
return bitmap->width;
|
return bitmap->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BH_BitmapHeight(BH_Bitmap *bitmap)
|
uint32_t BH_BitmapHeight(BH_Bitmap *bitmap)
|
||||||
{
|
{
|
||||||
return bitmap->height;
|
return bitmap->height;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user