diff options
| -rw-r--r-- | doc/Manual/en/BH_Bitmap.pod | 14 | ||||
| -rw-r--r-- | doc/Manual/ru/BH_Bitmap.pod | 14 | ||||
| -rw-r--r-- | include/BH/Bitmap.h | 43 | ||||
| -rw-r--r-- | src/Bitmap.c | 299 |
4 files changed, 222 insertions, 148 deletions
diff --git a/doc/Manual/en/BH_Bitmap.pod b/doc/Manual/en/BH_Bitmap.pod index f5a450f..9ce6897 100644 --- a/doc/Manual/en/BH_Bitmap.pod +++ b/doc/Manual/en/BH_Bitmap.pod @@ -70,6 +70,10 @@ Currently, the following pixel formats are supported: 64-bit RGB with alpha represented in uint64_t value. The layout is: 0xAAAARRRRGGGGBBBB +=item B<BH_BITMAP_RGBA5551>, B<BH_BITMAP_BGRA5551>, B<BH_BITMAP_ARGB1555>, B<BH_BITMAP_ABGR1555> + +16-bit RGB + =item B<BH_BITMAP_RGB565>, B<BH_BITMAP_BGR565> 16-bit RGB @@ -116,7 +120,8 @@ premultiplied form. int format, int flags, void *data, - BH_Color *palette); + BH_Color *palette, + int *result); Creates the bitmap with the specified I<width>, I<height> and pixel I<format>. @@ -134,6 +139,8 @@ The optional I<data> parameter specifies pointer to the existing data. The optional I<palette> parameter specifies pointer to the existing palette. +The optional parameter I<result> returns 0 or an error code. + This function returns a pointer to a new BH_Bitmap object or NULL. @@ -198,7 +205,8 @@ The I<x> and I<y> parameters specify a position on the bitmap. uint32_t y, uint32_t width, uint32_t height, - int shallow); + int shallow, + int *result); Creates a copy of the bitmap region by the given position and size. @@ -210,6 +218,8 @@ The I<shallow> parameter specifies whether the new bitmap is a shallow copy (or a view) of the existing bitmap or a deep copy. For the shallow copy to work, the region should be within the existing bitmap. +The optional parameter I<result> returns 0 or an error code. + This function returns a pointer to a new BH_Bitmap object or NULL. diff --git a/doc/Manual/ru/BH_Bitmap.pod b/doc/Manual/ru/BH_Bitmap.pod index 4188691..d8c3483 100644 --- a/doc/Manual/ru/BH_Bitmap.pod +++ b/doc/Manual/ru/BH_Bitmap.pod @@ -71,6 +71,10 @@ BH_Bitmap - доступ к растровому изображению/карт 64-разрядный RGB с прозрачностью, представленный в виде uint64_t. Формат: 0xAAAARRRRGGGGBBBB +=item B<BH_BITMAP_RGBA5551>, B<BH_BITMAP_BGRA5551>, B<BH_BITMAP_ARGB1555>, B<BH_BITMAP_ABGR1555> + +16-разрядный RGB + =item B<BH_BITMAP_RGB565>, B<BH_BITMAP_BGR565> 16-разрядный RGB @@ -117,7 +121,8 @@ BH_Bitmap - доступ к растровому изображению/карт int format, int flags, void *data, - BH_Color *palette); + BH_Color *palette, + int *result); Создает растровое изображение с указанной шириной, высотой и пиксельным форматом. @@ -140,6 +145,8 @@ BH_Bitmap - доступ к растровому изображению/карт Необязательный параметр I<palette> указывает на существующую палитру. +Опциональный параметр I<result> возвращает 0 или код ошибки. + Эта функция возвращает указатель на новый объект BH_Bitmap или значение NULL. @@ -204,7 +211,8 @@ void BH_BitmapSetIndex(BH_Bitmap *bitmap, uint32_t y, uint32_t width, uint32_t height, - int shallow); + int shallow, + int *result); Создает копию области растрового изображения с заданным положением и размером. @@ -217,6 +225,8 @@ void BH_BitmapSetIndex(BH_Bitmap *bitmap, его глубокой копией. Для работы с поверхностной копией область должна находиться в пределах существующего растрового изображения. +Опциональный параметр I<result> возвращает 0 или код ошибки. + Эта функция возвращает указатель на новый объект BH_Bitmap или NULL. diff --git a/include/BH/Bitmap.h b/include/BH/Bitmap.h index 32d23a8..b5327ba 100644 --- a/include/BH/Bitmap.h +++ b/include/BH/Bitmap.h @@ -25,22 +25,27 @@ typedef struct BH_Bitmap BH_Bitmap; #define BH_BITMAP_RGBA64 0x000A #define BH_BITMAP_RGB565 0x000B #define BH_BITMAP_BGR565 0x000C -#define BH_BITMAP_RGB888 0x000D -#define BH_BITMAP_BGR888 0x000E -#define BH_BITMAP_RGBA8888 0x000F -#define BH_BITMAP_BGRA8888 0x0010 -#define BH_BITMAP_ARGB8888 0x0011 -#define BH_BITMAP_ABGR8888 0x0012 -#define BH_BITMAP_RGB161616 0x0013 -#define BH_BITMAP_BGR161616 0x0014 -#define BH_BITMAP_RGBA16161616 0x0015 -#define BH_BITMAP_BGRA16161616 0x0016 -#define BH_BITMAP_ARGB16161616 0x0017 -#define BH_BITMAP_ABGR16161616 0x0018 -#define BH_BITMAP_RGBA1010102 0x0019 -#define BH_BITMAP_BGRA1010102 0x001A -#define BH_BITMAP_ARGB2101010 0x001B -#define BH_BITMAP_ABGR2101010 0x001C +#define BH_BITMAP_RGBA5551 0x000D +#define BH_BITMAP_BGRA5551 0x000E +#define BH_BITMAP_ARGB1555 0x000F +#define BH_BITMAP_ABGR5551 0x0010 +#define BH_BITMAP_RGB888 0x0011 +#define BH_BITMAP_BGR888 0x0012 +#define BH_BITMAP_RGBA8888 0x0013 +#define BH_BITMAP_BGRA8888 0x0014 +#define BH_BITMAP_ARGB8888 0x0015 +#define BH_BITMAP_ABGR8888 0x0016 +#define BH_BITMAP_RGB161616 0x0017 +#define BH_BITMAP_BGR161616 0x0018 +#define BH_BITMAP_RGBA16161616 0x0019 +#define BH_BITMAP_BGRA16161616 0x001A +#define BH_BITMAP_ARGB16161616 0x001B +#define BH_BITMAP_ABGR16161616 0x001C +#define BH_BITMAP_RGBA1010102 0x001D +#define BH_BITMAP_BGRA1010102 0x001E +#define BH_BITMAP_ARGB2101010 0x001F +#define BH_BITMAP_ABGR2101010 0x0020 + #define BH_BITMAP_FLAG_ALIGN32 0x0001 #define BH_BITMAP_FLAG_EXT_DATA 0x0002 @@ -52,7 +57,8 @@ BH_Bitmap *BH_BitmapNew(uint32_t width, int format, int flags, void *data, - BH_Color *palette); + BH_Color *palette, + int *result); void BH_BitmapFree(BH_Bitmap *bitmap); @@ -86,7 +92,8 @@ BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap, uint32_t y, uint32_t width, uint32_t height, - int shallow); + int shallow, + int *result); void *BH_BitmapScanline(const BH_Bitmap *bitmap, diff --git a/src/Bitmap.c b/src/Bitmap.c index e5eecd6..50246d6 100644 --- a/src/Bitmap.c +++ b/src/Bitmap.c @@ -1,3 +1,4 @@ +#include "BH/Common.h" #include <BH/Bitmap.h> #include <stdlib.h> #include <string.h> @@ -27,44 +28,93 @@ typedef struct FormatInfo { int type; - int channels; + size_t channels; uint16_t masks[4]; uint8_t shifts[8]; - int size; + size_t size; } FormatInfo; +struct BH_Bitmap +{ + uint32_t width; + uint32_t height; + int format; + const FormatInfo *formatInfo; + int flags; + size_t stride; + uint8_t *data; + BH_Color *palette; +}; + const static struct FormatInfo formats[] = { - {TYPE_INDEX1, 7, {0x0001}, {7, 6, 5, 4, 3, 2, 1, 0}, 0}, /* BH_BITMAP_INDEX1 */ - {TYPE_INDEX1, 7, {0x0001}, {0, 1, 2, 3, 4, 5, 6, 7}, 0}, /* BH_BITMAP_INDEX1_LSB */ - {TYPE_INDEX2, 3, {0x0003}, {3, 2, 1, 0}, 0}, /* BH_BITMAP_INDEX2 */ - {TYPE_INDEX2, 3, {0x0003}, {0, 1, 2, 3}, 0}, /* BH_BITMAP_INDEX2_LSB */ - {TYPE_INDEX4, 1, {0x000F}, {1, 0}, 0}, /* BH_BITMAP_INDEX4 */ - {TYPE_INDEX4, 1, {0x000F}, {0, 1}, 0}, /* BH_BITMAP_INDEX4_LSB */ - {TYPE_INDEX8, 0, {0x00FF}, {0}, 1}, /* BH_BITMAP_INDEX8 */ - {TYPE_PACKED8, 1, {0x00FF}, {0}, 1}, /* BH_BITMAP_GRAY8 */ - {TYPE_PACKED16, 1, {0xFFFF}, {0}, 2}, /* BH_BITMAP_GRAY16 */ - {TYPE_PACKED32, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {16, 8, 0, 24}, 4}, /* BH_BITMAP_RGBA32 */ - {TYPE_PACKED64, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {32, 16, 0, 48}, 8}, /* BH_BITMAP_RGBA64 */ - {TYPE_PACKED16, 3, {0x001F, 0x003F, 0x001F}, {11, 5, 0}, 2}, /* BH_BITMAP_RGB565 */ - {TYPE_PACKED16, 3, {0x001F, 0x003F, 0x001F}, {0, 5, 11}, 2}, /* BH_BITMAP_BGR565 */ - {TYPE_ARRAY8, 3, {0x00FF, 0x00FF, 0x00FF}, {0, 1, 2}, 3}, /* BH_BITMAP_RGB888 */ - {TYPE_ARRAY8, 3, {0x00FF, 0x00FF, 0x00FF}, {2, 1, 0}, 3}, /* BH_BITMAP_BGR888 */ - {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {0, 1, 2, 3}, 4}, /* BH_BITMAP_RGBA8888 */ - {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {2, 1, 0, 3}, 4}, /* BH_BITMAP_BGRA8888 */ - {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {1, 2, 3, 0}, 4}, /* BH_BITMAP_ARGB8888 */ - {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {3, 2, 1, 0}, 4}, /* BH_BITMAP_ABGR8888 */ - {TYPE_ARRAY16, 3, {0xFFFF, 0xFFFF, 0xFFFF}, {0, 1, 2}, 6}, /* BH_BITMAP_RGB161616 */ - {TYPE_ARRAY16, 3, {0xFFFF, 0xFFFF, 0xFFFF}, {2, 1, 0}, 6}, /* BH_BITMAP_BGR161616 */ - {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {0, 1, 2, 3}, 8}, /* BH_BITMAP_RGBA16161616 */ - {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {2, 1, 0, 3}, 8}, /* BH_BITMAP_BGRA16161616 */ - {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {1, 2, 3, 0}, 8}, /* BH_BITMAP_ARGB16161616 */ - {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {3, 2, 1, 0}, 8}, /* BH_BITMAP_ABGR16161616 */ - {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {22, 12, 2, 0}, 4}, /* BH_BITMAP_RGBA1010102 */ - {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {2, 12, 22, 0}, 4}, /* BH_BITMAP_BGRA1010102 */ - {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {20, 10, 0, 30}, 4}, /* BH_BITMAP_ARGB2101010 */ - {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {0, 10, 20, 30}, 4}, /* BH_BITMAP_ABGR2101010 */ + /* BH_BITMAP_INDEX1 */ + {TYPE_INDEX1, 7, {0x0001}, {7, 6, 5, 4, 3, 2, 1, 0}, 0}, + /* BH_BITMAP_INDEX1_LSB */ + {TYPE_INDEX1, 7, {0x0001}, {0, 1, 2, 3, 4, 5, 6, 7}, 0}, + /* BH_BITMAP_INDEX2 */ + {TYPE_INDEX2, 3, {0x0003}, {3, 2, 1, 0}, 0}, + /* BH_BITMAP_INDEX2_LSB */ + {TYPE_INDEX2, 3, {0x0003}, {0, 1, 2, 3}, 0}, + /* BH_BITMAP_INDEX4 */ + {TYPE_INDEX4, 1, {0x000F}, {1, 0}, 0}, + /* BH_BITMAP_INDEX4_LSB */ + {TYPE_INDEX4, 1, {0x000F}, {0, 1}, 0}, + /* BH_BITMAP_INDEX8 */ + {TYPE_INDEX8, 0, {0x00FF}, {0}, 1}, + /* BH_BITMAP_GRAY8 */ + {TYPE_PACKED8, 1, {0x00FF}, {0}, 1}, + /* BH_BITMAP_GRAY16 */ + {TYPE_PACKED16, 1, {0xFFFF}, {0}, 2}, + /* BH_BITMAP_RGBA32 */ + {TYPE_PACKED32, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {16, 8, 0, 24}, 4}, + /* BH_BITMAP_RGBA64 */ + {TYPE_PACKED64, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {32, 16, 0, 48}, 8}, + /* BH_BITMAP_RGB565 */ + {TYPE_PACKED16, 3, {0x001F, 0x003F, 0x001F}, {11, 5, 0}, 2}, + /* BH_BITMAP_BGR565 */ + {TYPE_PACKED16, 3, {0x001F, 0x003F, 0x001F}, {0, 5, 11}, 2}, + /* BH_BITMAP_RGBA5551 */ + {TYPE_PACKED16, 4, {0x001F, 0x001F, 0x001F, 0x0001}, {11, 6, 1, 0}, 2}, + /* BH_BITMAP_BGRA5551 */ + {TYPE_PACKED16, 4, {0x001F, 0x001F, 0x001F, 0x0001}, {1, 6, 11, 0}, 2}, + /* BH_BITMAP_ARGB1555 */ + {TYPE_PACKED16, 4, {0x001F, 0x001F, 0x001F, 0x0001}, {10, 5, 0, 15}, 2}, + /* BH_BITMAP_ABGR1555 */ + {TYPE_PACKED16, 4, {0x001F, 0x001F, 0x001F, 0x0001}, {0, 5, 10, 15}, 2}, + /* BH_BITMAP_RGB888 */ + {TYPE_ARRAY8, 3, {0x00FF, 0x00FF, 0x00FF}, {0, 1, 2}, 3}, + /* BH_BITMAP_BGR888 */ + {TYPE_ARRAY8, 3, {0x00FF, 0x00FF, 0x00FF}, {2, 1, 0}, 3}, + /* BH_BITMAP_RGBA8888 */ + {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {0, 1, 2, 3}, 4}, + /* BH_BITMAP_BGRA8888 */ + {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {2, 1, 0, 3}, 4}, + /* BH_BITMAP_ARGB8888 */ + {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {1, 2, 3, 0}, 4}, + /* BH_BITMAP_ABGR8888 */ + {TYPE_ARRAY8, 4, {0x00FF, 0x00FF, 0x00FF, 0x00FF}, {3, 2, 1, 0}, 4}, + /* BH_BITMAP_RGB161616 */ + {TYPE_ARRAY16, 3, {0xFFFF, 0xFFFF, 0xFFFF}, {0, 1, 2}, 6}, + /* BH_BITMAP_BGR161616 */ + {TYPE_ARRAY16, 3, {0xFFFF, 0xFFFF, 0xFFFF}, {2, 1, 0}, 6}, + /* BH_BITMAP_RGBA16161616 */ + {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {0, 1, 2, 3}, 8}, + /* BH_BITMAP_BGRA16161616 */ + {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {2, 1, 0, 3}, 8}, + /* BH_BITMAP_ARGB16161616 */ + {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {1, 2, 3, 0}, 8}, + /* BH_BITMAP_ABGR16161616 */ + {TYPE_ARRAY16, 4, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, {3, 2, 1, 0}, 8}, + /* BH_BITMAP_RGBA1010102 */ + {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {22, 12, 2, 0}, 4}, + /* BH_BITMAP_BGRA1010102 */ + {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {2, 12, 22, 0}, 4}, + /* BH_BITMAP_ARGB2101010 */ + {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {20, 10, 0, 30}, 4}, + /* BH_BITMAP_ABGR2101010 */ + {TYPE_PACKED32, 4, {0x03FF, 0x03FF, 0x03FF, 0x0003}, {0, 10, 20, 30}, 4}, }; @@ -129,7 +179,6 @@ static size_t bestPaletteIndex(BH_Color *color, static void readPacked(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { uint64_t raw; @@ -154,7 +203,6 @@ static void readPacked(const FormatInfo *formatInfo, static void writePacked(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { uint64_t raw; @@ -180,7 +228,6 @@ static void writePacked(const FormatInfo *formatInfo, static void readArray8(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { switch (formatInfo->channels) @@ -195,7 +242,6 @@ static void readArray8(const FormatInfo *formatInfo, static void writeArray8(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { switch (formatInfo->channels) @@ -210,7 +256,6 @@ static void writeArray8(const FormatInfo *formatInfo, static void readArray16(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { value->type = BH_COLOR_TYPE_RGBA; @@ -226,7 +271,6 @@ static void readArray16(const FormatInfo *formatInfo, static void writeArray16(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { switch (formatInfo->channels) @@ -241,26 +285,24 @@ static void writeArray16(const FormatInfo *formatInfo, static void readArray(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { switch (formatInfo->type) { - case TYPE_ARRAY8: readArray8(formatInfo, data, x, value); break; - case TYPE_ARRAY16: readArray16(formatInfo, data, x, value); break; + case TYPE_ARRAY8: readArray8(formatInfo, data, value); break; + case TYPE_ARRAY16: readArray16(formatInfo, data, value); break; } } static void writeArray(const FormatInfo *formatInfo, void *data, - int x, BH_Color *value) { switch (formatInfo->type) { - case TYPE_ARRAY8: writeArray8(formatInfo, data, x, value); break; - case TYPE_ARRAY16: writeArray16(formatInfo, data, x, value); break; + case TYPE_ARRAY8: writeArray8(formatInfo, data, value); break; + case TYPE_ARRAY16: writeArray16(formatInfo, data, value); break; } } @@ -285,16 +327,16 @@ static void writeIndex(const FormatInfo *formatInfo, } -void readData(const FormatInfo *formatInfo, - void *data, - int x, - BH_Color *value, - const BH_Color *palette) +static void readData(const FormatInfo *formatInfo, + void *data, + int x, + BH_Color *value, + const BH_Color *palette) { switch (formatInfo->type & 0x0F00) { case TYPE_PACKED: - readPacked(formatInfo, data, x, value); + readPacked(formatInfo, data, value); value->type = BH_COLOR_TYPE_RGBA; break; @@ -303,24 +345,24 @@ void readData(const FormatInfo *formatInfo, break; case TYPE_ARRAY: - readArray(formatInfo, data, x, value); + readArray(formatInfo, data, value); value->type = BH_COLOR_TYPE_RGBA; break; } } -void writeData(const FormatInfo *formatInfo, - void *data, - int x, - BH_Color *value, - const BH_Color *palette) +static void writeData(const FormatInfo *formatInfo, + void *data, + int x, + BH_Color *value, + const BH_Color *palette) { switch (formatInfo->type & 0x0F00) { case TYPE_PACKED: BH_ColorToRGBA(value, value); - writePacked(formatInfo, data, x, value); + writePacked(formatInfo, data, value); break; case TYPE_INDEX: @@ -329,25 +371,12 @@ void writeData(const FormatInfo *formatInfo, case TYPE_ARRAY: BH_ColorToRGBA(value, value); - writeArray(formatInfo, data, x, value); + writeArray(formatInfo, data, value); break; } } -struct BH_Bitmap -{ - uint32_t width; - uint32_t height; - int format; - const FormatInfo *formatInfo; - int flags; - size_t stride; - uint8_t *data; - BH_Color *palette; -}; - - static void *rowAt(const FormatInfo *formatInfo, void *data, uint32_t x) @@ -365,8 +394,6 @@ static void *rowAt(const FormatInfo *formatInfo, static size_t calculateStride(const FormatInfo *formatInfo, uint32_t width) { - size_t step; - switch (formatInfo->type) { case TYPE_INDEX1: return (width + 7) / 8; @@ -409,28 +436,31 @@ static size_t calculateTrailer(const FormatInfo *formatInfo) } -/* Public functions */ BH_Bitmap *BH_BitmapNew(uint32_t width, uint32_t height, int format, int flags, void *data, - BH_Color *palette) + BH_Color *palette, + int *result) { - BH_Bitmap *result; const FormatInfo *formatInfo; - int needPalette; - size_t header, body, allocSize, stride, step; - - /* Basic sanity check */ - if (width == 0 || width >= 0x7FFFFFFF || - height == 0 || height >= 0x7FFFFFFF) - return NULL; + size_t header, body, allocSize, stride; + int needPalette, code; + BH_Bitmap *bitmap; - /* Get format information */ + bitmap = NULL; + code = BH_OK; formatInfo = formats + (format & 0x0FFF); - if ((format & 0x0FFF) > sizeof(formats) / sizeof(FormatInfo)) - return NULL; + + /* Basic checks and format validation */ + if (width == 0 || width >= 0x7FFFFFFF || + height == 0 || height >= 0x7FFFFFFF || + (format & 0x0FFF) > sizeof(formats) / sizeof(FormatInfo)) + { + code = BH_INVALID; + goto done; + } /* Unset internal flags */ flags &= ~BH_BITMAP_FLAG_EXT_DATA; @@ -442,26 +472,33 @@ BH_Bitmap *BH_BitmapNew(uint32_t width, /* Check stride overflow */ if (!stride) - return NULL; + { + code = BH_ERROR; + goto done; + } if (flags & BH_BITMAP_FLAG_ALIGN32) { if (BH_CHECK_UADD_WRAP(stride, sizeof(uint32_t) - 1, size_t)) - return NULL; + { + code = BH_ERROR; + goto done; + } stride = (stride + sizeof(uint32_t) - 1) & ~(sizeof(uint32_t) - 1); } - header = sizeof(*result); + header = sizeof(*bitmap); header = (header + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t) - 1); allocSize = calculateTrailer(formatInfo); 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; + if (BH_CHECK_UMUL_WRAP(stride, height, size_t) || + BH_CHECK_UADD_WRAP(body, sizeof(uint32_t) - 1, size_t)) + { + code = BH_ERROR; + goto done; + } body = (body + (sizeof(uint32_t) - 1)) & ~(sizeof(uint32_t) - 1); /* Adjust body and trailer size if ext data or palette is provided */ @@ -477,35 +514,42 @@ BH_Bitmap *BH_BitmapNew(uint32_t width, 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; + if (BH_CHECK_UADD_WRAP(allocSize, header, size_t) || + BH_CHECK_UADD_WRAP(allocSize + header, body, size_t)) + { + code = BH_ERROR; + goto done; + } + allocSize += header + body; /* Allocate and setup bitmap data */ - result = malloc(allocSize); - if (!result) - return NULL; + bitmap = malloc(allocSize); + if (!bitmap) + { + code = BH_OOM; + goto done; + } if (!data) - data = (uint8_t *)result + header; + data = (uint8_t *)bitmap + header; if (!palette && needPalette) - palette = (BH_Color *)((uint8_t *)result + header + body); + palette = (BH_Color *)((uint8_t *)bitmap + header + body); + + bitmap->width = width; + bitmap->height = height; + bitmap->format = format; + bitmap->formatInfo = formatInfo; + bitmap->flags = flags; + bitmap->stride = stride; + bitmap->data = data; + bitmap->palette = palette; - result->width = width; - result->height = height; - result->format = format; - result->formatInfo = formatInfo; - result->flags = flags; - result->stride = stride; - result->data = data; - result->palette = palette; +done: + if (result) + *result = code; - return result; + return bitmap; } @@ -544,9 +588,10 @@ BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap, uint32_t y, uint32_t width, uint32_t height, - int shallow) + int shallow, + int *result) { - BH_Bitmap *result; + BH_Bitmap *resultBitmap; uint32_t i, j; /* Sanity checks */ @@ -559,20 +604,22 @@ BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap, /* Shallow copy can't go out of bounds of the source bitmap */ if (shallow) { - result = BH_BitmapNew(width, height, bitmap->format, bitmap->flags, - BH_BitmapAt(bitmap, x, y), bitmap->palette); - result->stride = bitmap->stride; - return result; + resultBitmap = BH_BitmapNew(width, height, bitmap->format, bitmap->flags, + BH_BitmapAt(bitmap, x, y), bitmap->palette, + result); + resultBitmap->stride = bitmap->stride; + return resultBitmap; } /* Deep copy of the bitmap */ - result = BH_BitmapNew(width, height, bitmap->format, bitmap->flags, NULL, NULL); - if (!result) + resultBitmap = BH_BitmapNew(width, height, bitmap->format, bitmap->flags, + NULL, NULL, result); + if (!resultBitmap) return NULL; /* Copy the palette if neccesery */ - if (result->palette) - memcpy(result->palette, bitmap->palette, sizeof(uint32_t) * 256); + if (resultBitmap->palette) + memcpy(resultBitmap->palette, bitmap->palette, sizeof(uint32_t) * 256); for (j = 0; j < height; ++j) { @@ -580,11 +627,11 @@ BH_Bitmap *BH_BitmapCopy(BH_Bitmap *bitmap, { BH_Color color; BH_BitmapColor(bitmap, i + x, j + y, &color); - BH_BitmapSetColor(result, i, j, &color); + BH_BitmapSetColor(resultBitmap, i, j, &color); } } - return result; + return resultBitmap; } |
