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