mirror of https://github.com/mgba-emu/mgba.git
Util: Start mImage/mColor APIs and tests
This commit is contained in:
parent
646a0e9b33
commit
e79ae2860b
|
@ -22,9 +22,9 @@ typedef uint32_t color_t;
|
||||||
#define M_G5(X) (((X) >> 5) & 0x1F)
|
#define M_G5(X) (((X) >> 5) & 0x1F)
|
||||||
#define M_B5(X) (((X) >> 10) & 0x1F)
|
#define M_B5(X) (((X) >> 10) & 0x1F)
|
||||||
|
|
||||||
#define M_R8(X) (((((X) << 3) & 0xF8) * 0x21) >> 2)
|
#define M_R8(X) ((M_R5(X) * 0x21) >> 2)
|
||||||
#define M_G8(X) (((((X) >> 2) & 0xF8) * 0x21) >> 2)
|
#define M_G8(X) ((M_G5(X) * 0x21) >> 2)
|
||||||
#define M_B8(X) (((((X) >> 7) & 0xF8) * 0x21) >> 2)
|
#define M_B8(X) ((M_B5(X) * 0x21) >> 2)
|
||||||
|
|
||||||
#define M_RGB5_TO_BGR8(X) ((M_R5(X) << 3) | (M_G5(X) << 11) | (M_B5(X) << 19))
|
#define M_RGB5_TO_BGR8(X) ((M_R5(X) << 3) | (M_G5(X) << 11) | (M_B5(X) << 19))
|
||||||
#define M_RGB5_TO_RGB8(X) ((M_R5(X) << 19) | (M_G5(X) << 11) | (M_B5(X) << 3))
|
#define M_RGB5_TO_RGB8(X) ((M_R5(X) << 19) | (M_G5(X) << 11) | (M_B5(X) << 3))
|
||||||
|
@ -81,7 +81,54 @@ enum mColorFormat {
|
||||||
mCOLOR_ANY = -1
|
mCOLOR_ANY = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mImage {
|
||||||
|
void* data;
|
||||||
|
unsigned width;
|
||||||
|
unsigned height;
|
||||||
|
unsigned stride;
|
||||||
|
unsigned depth;
|
||||||
|
enum mColorFormat format;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t mImageGetPixel(const struct mImage* image, unsigned x, unsigned y);
|
||||||
|
uint32_t mImageGetPixelRaw(const struct mImage* image, unsigned x, unsigned y);
|
||||||
|
void mImageSetPixel(struct mImage* image, unsigned x, unsigned y, uint32_t color);
|
||||||
|
void mImageSetPixelRaw(struct mImage* image, unsigned x, unsigned y, uint32_t color);
|
||||||
|
|
||||||
|
uint32_t mColorConvert(uint32_t color, enum mColorFormat from, enum mColorFormat to);
|
||||||
|
|
||||||
#ifndef PYCPARSE
|
#ifndef PYCPARSE
|
||||||
|
static inline unsigned mColorFormatBytes(enum mColorFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case mCOLOR_XBGR8:
|
||||||
|
case mCOLOR_XRGB8:
|
||||||
|
case mCOLOR_BGRX8:
|
||||||
|
case mCOLOR_RGBX8:
|
||||||
|
case mCOLOR_ABGR8:
|
||||||
|
case mCOLOR_ARGB8:
|
||||||
|
case mCOLOR_BGRA8:
|
||||||
|
case mCOLOR_RGBA8:
|
||||||
|
return 4;
|
||||||
|
case mCOLOR_RGB5:
|
||||||
|
case mCOLOR_BGR5:
|
||||||
|
case mCOLOR_RGB565:
|
||||||
|
case mCOLOR_BGR565:
|
||||||
|
case mCOLOR_ARGB5:
|
||||||
|
case mCOLOR_ABGR5:
|
||||||
|
case mCOLOR_RGBA5:
|
||||||
|
case mCOLOR_BGRA5:
|
||||||
|
return 2;
|
||||||
|
case mCOLOR_RGB8:
|
||||||
|
case mCOLOR_BGR8:
|
||||||
|
return 3;
|
||||||
|
case mCOLOR_L8:
|
||||||
|
return 1;
|
||||||
|
case mCOLOR_ANY:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline color_t mColorFrom555(uint16_t value) {
|
static inline color_t mColorFrom555(uint16_t value) {
|
||||||
#ifdef COLOR_16_BIT
|
#ifdef COLOR_16_BIT
|
||||||
#ifdef COLOR_5_6_5
|
#ifdef COLOR_5_6_5
|
||||||
|
|
|
@ -16,6 +16,7 @@ set(SOURCE_FILES
|
||||||
convolve.c
|
convolve.c
|
||||||
elf-read.c
|
elf-read.c
|
||||||
geometry.c
|
geometry.c
|
||||||
|
image.c
|
||||||
image/export.c
|
image/export.c
|
||||||
image/png-io.c
|
image/png-io.c
|
||||||
patch.c
|
patch.c
|
||||||
|
@ -34,7 +35,9 @@ set(GUI_FILES
|
||||||
gui/menu.c)
|
gui/menu.c)
|
||||||
|
|
||||||
set(TEST_FILES
|
set(TEST_FILES
|
||||||
|
test/color.c
|
||||||
test/geometry.c
|
test/geometry.c
|
||||||
|
test/image.c
|
||||||
test/sfo.c
|
test/sfo.c
|
||||||
test/string-parser.c
|
test/string-parser.c
|
||||||
test/string-utf8.c
|
test/string-utf8.c
|
||||||
|
|
|
@ -0,0 +1,269 @@
|
||||||
|
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include <mgba-util/image.h>
|
||||||
|
|
||||||
|
#define PIXEL(IM, X, Y) \
|
||||||
|
(void*) (((IM)->stride * (Y) + (X)) * (IM)->depth + (uintptr_t) (IM)->data)
|
||||||
|
|
||||||
|
uint32_t mImageGetPixelRaw(const struct mImage* image, unsigned x, unsigned y) {
|
||||||
|
if (x >= image->width || y >= image->height) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const void* pixel = PIXEL(image, x, y);
|
||||||
|
uint32_t color;
|
||||||
|
switch (image->depth) {
|
||||||
|
case 1:
|
||||||
|
color = *(const uint8_t*) pixel;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = *(const uint16_t*) pixel;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
color = *(const uint32_t*) pixel;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
color = ((const uint8_t*) pixel)[0] << 16;
|
||||||
|
color |= ((const uint8_t*) pixel)[1] << 8;
|
||||||
|
color |= ((const uint8_t*) pixel)[2];
|
||||||
|
#else
|
||||||
|
color = ((const uint8_t*) pixel)[0];
|
||||||
|
color |= ((const uint8_t*) pixel)[1] << 8;
|
||||||
|
color |= ((const uint8_t*) pixel)[2] << 16;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mImageGetPixel(const struct mImage* image, unsigned x, unsigned y) {
|
||||||
|
return mColorConvert(mImageGetPixelRaw(image, x, y), image->format, mCOLOR_ARGB8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mImageSetPixelRaw(struct mImage* image, unsigned x, unsigned y, uint32_t color) {
|
||||||
|
if (x >= image->width || y >= image->height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void* pixel = PIXEL(image, x, y);
|
||||||
|
switch (image->depth) {
|
||||||
|
case 1:
|
||||||
|
*(uint8_t*) pixel = color;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(uint16_t*) pixel = color;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(uint32_t*) pixel = color;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
((uint8_t*) pixel)[0] = color >> 16;
|
||||||
|
((uint8_t*) pixel)[1] = color >> 8;
|
||||||
|
((uint8_t*) pixel)[2] = color;
|
||||||
|
#else
|
||||||
|
((uint8_t*) pixel)[0] = color;
|
||||||
|
((uint8_t*) pixel)[1] = color >> 8;
|
||||||
|
((uint8_t*) pixel)[2] = color >> 16;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mImageSetPixel(struct mImage* image, unsigned x, unsigned y, uint32_t color) {
|
||||||
|
mImageSetPixelRaw(image, x, y, mColorConvert(color, mCOLOR_ARGB8, image->format));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mColorConvert(uint32_t color, enum mColorFormat from, enum mColorFormat to) {
|
||||||
|
if (from == to) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r;
|
||||||
|
int g;
|
||||||
|
int b;
|
||||||
|
int a = 0xFF;
|
||||||
|
|
||||||
|
switch (from) {
|
||||||
|
case mCOLOR_ARGB8:
|
||||||
|
a = color >> 24;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_XRGB8:
|
||||||
|
case mCOLOR_RGB8:
|
||||||
|
r = (color >> 16) & 0xFF;
|
||||||
|
g = (color >> 8) & 0xFF;
|
||||||
|
b = color & 0xFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_ABGR8:
|
||||||
|
a = color >> 24;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_XBGR8:
|
||||||
|
case mCOLOR_BGR8:
|
||||||
|
b = (color >> 16) & 0xFF;
|
||||||
|
g = (color >> 8) & 0xFF;
|
||||||
|
r = color & 0xFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_RGBA8:
|
||||||
|
a = color & 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_RGBX8:
|
||||||
|
r = (color >> 24) & 0xFF;
|
||||||
|
g = (color >> 16) & 0xFF;
|
||||||
|
b = (color >> 8) & 0xFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_BGRA8:
|
||||||
|
a = color & 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_BGRX8:
|
||||||
|
b = (color >> 24) & 0xFF;
|
||||||
|
g = (color >> 16) & 0xFF;
|
||||||
|
r = (color >> 8) & 0xFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_ARGB5:
|
||||||
|
a = (color >> 15) * 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_RGB5:
|
||||||
|
r = (((color >> 10) & 0x1F) * 0x21) >> 2;
|
||||||
|
g = (((color >> 5) & 0x1F) * 0x21) >> 2;
|
||||||
|
b = ((color & 0x1F) * 0x21) >> 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_ABGR5:
|
||||||
|
a = (color >> 15) * 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_BGR5:
|
||||||
|
b = (((color >> 10) & 0x1F) * 0x21) >> 2;
|
||||||
|
g = (((color >> 5) & 0x1F) * 0x21) >> 2;
|
||||||
|
r = ((color & 0x1F) * 0x21) >> 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_RGBA5:
|
||||||
|
a = (color & 1) * 0xFF;
|
||||||
|
r = (((color >> 11) & 0x1F) * 0x21) >> 2;
|
||||||
|
g = (((color >> 6) & 0x1F) * 0x21) >> 2;
|
||||||
|
b = (((color >> 1) & 0x1F) * 0x21) >> 2;
|
||||||
|
break;
|
||||||
|
case mCOLOR_BGRA5:
|
||||||
|
a = (color & 1) * 0xFF;
|
||||||
|
b = (((color >> 11) & 0x1F) * 0x21) >> 2;
|
||||||
|
g = (((color >> 6) & 0x1F) * 0x21) >> 2;
|
||||||
|
r = (((color >> 1) & 0x1F) * 0x21) >> 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_RGB565:
|
||||||
|
r = (((color >> 10) & 0x1F) * 0x21) >> 2;
|
||||||
|
g = (((color >> 5) & 0x3F) * 0x41) >> 4;
|
||||||
|
b = ((color & 0x1F) * 0x21) >> 2;
|
||||||
|
break;
|
||||||
|
case mCOLOR_BGR565:
|
||||||
|
b = (((color >> 10) & 0x1F) * 0x21) >> 2;
|
||||||
|
g = (((color >> 5) & 0x3F) * 0x41) >> 4;
|
||||||
|
r = ((color & 0x1F) * 0x21) >> 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_L8:
|
||||||
|
r = color;
|
||||||
|
g = color;
|
||||||
|
b = color;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mCOLOR_ANY:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = 0;
|
||||||
|
switch (to) {
|
||||||
|
case mCOLOR_XRGB8:
|
||||||
|
a = 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_ARGB8:
|
||||||
|
color |= a << 24;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_RGB8:
|
||||||
|
color |= r << 16;
|
||||||
|
color |= g << 8;
|
||||||
|
color |= b;
|
||||||
|
break;
|
||||||
|
case mCOLOR_XBGR8:
|
||||||
|
a = 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_ABGR8:
|
||||||
|
color |= a << 24;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_BGR8:
|
||||||
|
color |= b << 16;
|
||||||
|
color |= g << 8;
|
||||||
|
color |= r;
|
||||||
|
break;
|
||||||
|
case mCOLOR_RGBX8:
|
||||||
|
a = 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_RGBA8:
|
||||||
|
color |= a;
|
||||||
|
color |= r << 24;
|
||||||
|
color |= g << 16;
|
||||||
|
color |= b << 8;
|
||||||
|
break;
|
||||||
|
case mCOLOR_BGRX8:
|
||||||
|
a = 0xFF;
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_BGRA8:
|
||||||
|
color |= a;
|
||||||
|
color |= b << 24;
|
||||||
|
color |= g << 16;
|
||||||
|
color |= r << 8;
|
||||||
|
break;
|
||||||
|
case mCOLOR_ARGB5:
|
||||||
|
color |= (!!a << 15);
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_RGB5:
|
||||||
|
color |= (r >> 3) << 10;
|
||||||
|
color |= (g >> 3) << 5;
|
||||||
|
color |= b >> 3;
|
||||||
|
break;
|
||||||
|
case mCOLOR_ABGR5:
|
||||||
|
color |= (!!a << 15);
|
||||||
|
// Fall through
|
||||||
|
case mCOLOR_BGR5:
|
||||||
|
color |= (b >> 3) << 10;
|
||||||
|
color |= (g >> 3) << 5;
|
||||||
|
color |= r >> 3;
|
||||||
|
break;
|
||||||
|
case mCOLOR_RGBA5:
|
||||||
|
color |= !!a;
|
||||||
|
color |= (r >> 3) << 11;
|
||||||
|
color |= (g >> 3) << 6;
|
||||||
|
color |= (b >> 3) << 1;
|
||||||
|
break;
|
||||||
|
case mCOLOR_BGRA5:
|
||||||
|
color |= !!a;
|
||||||
|
color |= (b >> 3) << 11;
|
||||||
|
color |= (g >> 3) << 6;
|
||||||
|
color |= (r >> 3) << 1;
|
||||||
|
break;
|
||||||
|
case mCOLOR_RGB565:
|
||||||
|
color |= (r >> 3) << 11;
|
||||||
|
color |= (g >> 2) << 5;
|
||||||
|
color |= b >> 3;
|
||||||
|
break;
|
||||||
|
case mCOLOR_BGR565:
|
||||||
|
color |= (b >> 3) << 11;
|
||||||
|
color |= (g >> 2) << 5;
|
||||||
|
color |= r >> 3;
|
||||||
|
break;
|
||||||
|
case mCOLOR_L8:
|
||||||
|
// sRGB primaries in fixed point, roughly fudged to saturate to 0xFFFF
|
||||||
|
color = (55 * r + 184 * g + 18 * b) >> 8;
|
||||||
|
break;
|
||||||
|
case mCOLOR_ANY:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "util/test/suite.h"
|
||||||
|
|
||||||
|
#include <mgba-util/image.h>
|
||||||
|
|
||||||
|
M_TEST_DEFINE(channelSwap32) {
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ARGB8, mCOLOR_ABGR8), 0xFFCCBBAA);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ABGR8, mCOLOR_ARGB8), 0xFFCCBBAA);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_XRGB8, mCOLOR_XBGR8), 0xFFCCBBAA);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_XBGR8, mCOLOR_XRGB8), 0xFFCCBBAA);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCC, mCOLOR_RGB8, mCOLOR_BGR8), 0xCCBBAA);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCC, mCOLOR_BGR8, mCOLOR_RGB8), 0xCCBBAA);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ARGB8, mCOLOR_RGBA8), 0xAABBCCFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ABGR8, mCOLOR_BGRA8), 0xAABBCCFF);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCCFF, mCOLOR_RGBA8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCCFF, mCOLOR_BGRA8, mCOLOR_ABGR8), 0xFFAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ARGB8, mCOLOR_BGRA8), 0xCCBBAAFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ABGR8, mCOLOR_RGBA8), 0xCCBBAAFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_RGBA8, mCOLOR_ABGR8), 0xCCBBAAFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_BGRA8, mCOLOR_ARGB8), 0xCCBBAAFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(channelSwap16) {
|
||||||
|
assert_int_equal(mColorConvert(0xFFE0, mCOLOR_ARGB5, mCOLOR_ABGR5), 0x83FF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFE0, mCOLOR_ABGR5, mCOLOR_ARGB5), 0x83FF);
|
||||||
|
assert_int_equal(mColorConvert(0x7FE0, mCOLOR_RGB5, mCOLOR_BGR5), 0x03FF);
|
||||||
|
assert_int_equal(mColorConvert(0x7FE0, mCOLOR_BGR5, mCOLOR_RGB5), 0x03FF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFE0, mCOLOR_RGB565, mCOLOR_BGR565), 0x07FF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFE0, mCOLOR_BGR565, mCOLOR_RGB565), 0x07FF);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFE0, mCOLOR_ARGB5, mCOLOR_RGBA5), 0xFFC1);
|
||||||
|
assert_int_equal(mColorConvert(0xFFE0, mCOLOR_RGBA5, mCOLOR_ARGB5), 0x7FF0);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(convertQuantizeOpaque) {
|
||||||
|
assert_int_equal(mColorConvert(0xA0B0C0, mCOLOR_XRGB8, mCOLOR_RGB5), (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA1B1C1, mCOLOR_XRGB8, mCOLOR_RGB5), (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA2B2C2, mCOLOR_XRGB8, mCOLOR_RGB5), (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA4B4C4, mCOLOR_XRGB8, mCOLOR_RGB5), (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA8B8C8, mCOLOR_XRGB8, mCOLOR_RGB5), (0xA << 11) | (0x1B << 6) | (0x1C << 1) | 1);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xA0B0C0, mCOLOR_XRGB8, mCOLOR_BGR5), (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA1B1C1, mCOLOR_XRGB8, mCOLOR_BGR5), (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA2B2C2, mCOLOR_XRGB8, mCOLOR_BGR5), (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA4B4C4, mCOLOR_XRGB8, mCOLOR_BGR5), (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA8B8C8, mCOLOR_XRGB8, mCOLOR_BGR5), (0xC << 11) | (0x1B << 6) | (0x1A << 1) | 1);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xA0B0C0, mCOLOR_XRGB8, mCOLOR_RGB565), (0xA << 12) | (0xB << 7) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA1B1C1, mCOLOR_XRGB8, mCOLOR_RGB565), (0xA << 12) | (0xB << 7) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA2B2C2, mCOLOR_XRGB8, mCOLOR_RGB565), (0xA << 12) | (0xB << 7) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA4B4C4, mCOLOR_XRGB8, mCOLOR_RGB565), (0xA << 12) | (0xB << 7) | (0x1C << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA8B8C8, mCOLOR_XRGB8, mCOLOR_RGB565), (0xA << 12) | (0x1B << 7) | (0x2C << 1) | 1);
|
||||||
|
assert_int_equal(mColorConvert(0xACBCCC, mCOLOR_XRGB8, mCOLOR_RGB565), (0xA << 12) | (0x1B << 7) | (0x3C << 1) | 1);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xA0B0C0, mCOLOR_XRGB8, mCOLOR_BGR565), (0xC << 12) | (0xB << 7) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA1B1C1, mCOLOR_XRGB8, mCOLOR_BGR565), (0xC << 12) | (0xB << 7) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA2B2C2, mCOLOR_XRGB8, mCOLOR_BGR565), (0xC << 12) | (0xB << 7) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA4B4C4, mCOLOR_XRGB8, mCOLOR_BGR565), (0xC << 12) | (0xB << 7) | (0x1A << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xA8B8C8, mCOLOR_XRGB8, mCOLOR_BGR565), (0xC << 12) | (0x1B << 7) | (0x2A << 1) | 1);
|
||||||
|
assert_int_equal(mColorConvert(0xACBCCC, mCOLOR_XRGB8, mCOLOR_BGR565), (0xC << 12) | (0x1B << 7) | (0x3A << 1) | 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(convertQuantizeTransparent) {
|
||||||
|
assert_int_equal(mColorConvert(0xFFA0B0C0, mCOLOR_ARGB8, mCOLOR_ARGB5), 0x8000 | (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0x00A0B0C0, mCOLOR_ARGB8, mCOLOR_ARGB5), (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xFEA0B0C0, mCOLOR_ARGB8, mCOLOR_ARGB5), 0x8000 | (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
assert_int_equal(mColorConvert(0x01A0B0C0, mCOLOR_ARGB8, mCOLOR_ARGB5), 0x8000 | (0xA << 11) | (0xB << 6) | (0xC << 1));
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFA0B0C0, mCOLOR_ARGB8, mCOLOR_ABGR5), 0x8000 | (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0x00A0B0C0, mCOLOR_ARGB8, mCOLOR_ABGR5), (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0xFEA0B0C0, mCOLOR_ARGB8, mCOLOR_ABGR5), 0x8000 | (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
assert_int_equal(mColorConvert(0x01A0B0C0, mCOLOR_ARGB8, mCOLOR_ABGR5), 0x8000 | (0xC << 11) | (0xB << 6) | (0xA << 1));
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFA0B0C0, mCOLOR_ARGB8, mCOLOR_RGBA5), 1 | (0xA << 12) | (0xB << 7) | (0xC << 2));
|
||||||
|
assert_int_equal(mColorConvert(0x00A0B0C0, mCOLOR_ARGB8, mCOLOR_RGBA5), (0xA << 12) | (0xB << 7) | (0xC << 2));
|
||||||
|
assert_int_equal(mColorConvert(0xFEA0B0C0, mCOLOR_ARGB8, mCOLOR_RGBA5), 1 | (0xA << 12) | (0xB << 7) | (0xC << 2));
|
||||||
|
assert_int_equal(mColorConvert(0x01A0B0C0, mCOLOR_ARGB8, mCOLOR_RGBA5), 1 | (0xA << 12) | (0xB << 7) | (0xC << 2));
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFA0B0C0, mCOLOR_ARGB8, mCOLOR_BGRA5), 1 | (0xC << 12) | (0xB << 7) | (0xA << 2));
|
||||||
|
assert_int_equal(mColorConvert(0x00A0B0C0, mCOLOR_ARGB8, mCOLOR_BGRA5), (0xC << 12) | (0xB << 7) | (0xA << 2));
|
||||||
|
assert_int_equal(mColorConvert(0xFEA0B0C0, mCOLOR_ARGB8, mCOLOR_BGRA5), 1 | (0xC << 12) | (0xB << 7) | (0xA << 2));
|
||||||
|
assert_int_equal(mColorConvert(0x01A0B0C0, mCOLOR_ARGB8, mCOLOR_BGRA5), 1 | (0xC << 12) | (0xB << 7) | (0xA << 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(convertToOpaque) {
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ARGB8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xFEAABBCC, mCOLOR_ARGB8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x01AABBCC, mCOLOR_ARGB8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x00AABBCC, mCOLOR_ARGB8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_ARGB8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xFEAABBCC, mCOLOR_ARGB8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x01AABBCC, mCOLOR_ARGB8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x00AABBCC, mCOLOR_ARGB8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCCFF, mCOLOR_RGBA8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCCFE, mCOLOR_RGBA8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCC01, mCOLOR_RGBA8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCC00, mCOLOR_RGBA8, mCOLOR_XRGB8), 0xFFAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCCFF, mCOLOR_RGBA8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCCFE, mCOLOR_RGBA8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCC01, mCOLOR_RGBA8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xAABBCC00, mCOLOR_RGBA8, mCOLOR_RGB8), 0xAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0x7FFF, mCOLOR_ARGB5, mCOLOR_RGB5), 0x7FFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFFF, mCOLOR_ARGB5, mCOLOR_RGB5), 0x7FFF);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFFE, mCOLOR_RGBA5, mCOLOR_RGB5), 0x7FFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFFF, mCOLOR_RGBA5, mCOLOR_RGB5), 0x7FFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(convertToAlpha) {
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_XRGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xFEAABBCC, mCOLOR_XRGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x01AABBCC, mCOLOR_XRGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x00AABBCC, mCOLOR_XRGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0xFFAABBCC, mCOLOR_RGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0xFEAABBCC, mCOLOR_RGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x01AABBCC, mCOLOR_RGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
assert_int_equal(mColorConvert(0x00AABBCC, mCOLOR_RGB8, mCOLOR_ARGB8), 0xFFAABBCC);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0x7FFF, mCOLOR_RGB5, mCOLOR_ARGB5), 0xFFFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFFF, mCOLOR_RGB5, mCOLOR_ARGB5), 0xFFFF);
|
||||||
|
|
||||||
|
assert_int_equal(mColorConvert(0x7FFF, mCOLOR_RGB5, mCOLOR_RGBA5), 0xFFFF);
|
||||||
|
assert_int_equal(mColorConvert(0xFFFF, mCOLOR_RGB5, mCOLOR_RGBA5), 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(convertFromGray) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 256; ++i) {
|
||||||
|
assert_int_equal(mColorConvert(i, mCOLOR_L8, mCOLOR_RGB8), (i << 16) | (i << 8) | i);
|
||||||
|
assert_int_equal(mColorConvert(i, mCOLOR_L8, mCOLOR_ARGB8), 0xFF000000 | (i << 16) | (i << 8) | i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(convertToGray) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 256; ++i) {
|
||||||
|
assert_int_equal(mColorConvert((i << 16) | (i << 8) | i, mCOLOR_RGB8, mCOLOR_L8), i);
|
||||||
|
assert_int_equal(mColorConvert((i << 16) | (i << 8) | i, mCOLOR_ARGB8, mCOLOR_L8), i);
|
||||||
|
assert_int_equal(mColorConvert(0xFF000000 | (i << 16) | (i << 8) | i, mCOLOR_ARGB8, mCOLOR_L8), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_SUITE_DEFINE(Color,
|
||||||
|
cmocka_unit_test(channelSwap32),
|
||||||
|
cmocka_unit_test(channelSwap16),
|
||||||
|
cmocka_unit_test(convertQuantizeOpaque),
|
||||||
|
cmocka_unit_test(convertQuantizeTransparent),
|
||||||
|
cmocka_unit_test(convertToOpaque),
|
||||||
|
cmocka_unit_test(convertToAlpha),
|
||||||
|
cmocka_unit_test(convertFromGray),
|
||||||
|
cmocka_unit_test(convertToGray),
|
||||||
|
)
|
|
@ -0,0 +1,450 @@
|
||||||
|
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "util/test/suite.h"
|
||||||
|
|
||||||
|
#include <mgba-util/image.h>
|
||||||
|
|
||||||
|
M_TEST_DEFINE(pitchRead) {
|
||||||
|
static uint8_t buffer[12] = {
|
||||||
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mImage image = {
|
||||||
|
.data = buffer,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.width = 12;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
for (i = 0; i < 12; ++i) {
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.width = 6;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), (i * 2) << 8 | (i * 2 + 1));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), (i * 2 + 1) << 8 | (i * 2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.width = 4;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), (i * 3) << 16 | (i * 3 + 1) << 8 | (i * 3 + 2));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), (i * 3 + 2) << 16 | (i * 3 + 1) << 8 | (i * 3));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 4;
|
||||||
|
image.width = 3;
|
||||||
|
image.format = mCOLOR_ARGB8;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), (i * 4) << 24 | (i * 4 + 1) << 16 | (i * 4 + 2) << 8 | (i * 4 + 3));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, i, 0), (i * 4 + 3) << 24 | (i * 4 + 2) << 16 | (i * 4 + 1) << 8 | (i * 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(strideRead) {
|
||||||
|
static uint8_t buffer[12] = {
|
||||||
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mImage image = {
|
||||||
|
.data = buffer,
|
||||||
|
.width = 1
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 12;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
for (i = 0; i < 12; ++i) {
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.stride = 2;
|
||||||
|
image.height = 6;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 6;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 2) << 8 | (i * 2 + 1));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 2 + 1) << 8 | (i * 2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.stride = 2;
|
||||||
|
image.height = 3;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 4) << 8 | (i * 4 + 1));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 4 + 1) << 8 | (i * 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 4;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 3) << 16 | (i * 3 + 1) << 8 | (i * 3 + 2));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 3 + 2) << 16 | (i * 3 + 1) << 8 | (i * 3));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.stride = 2;
|
||||||
|
image.height = 2;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 6) << 16 | (i * 6 + 1) << 8 | (i * 6 + 2));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 6 + 2) << 16 | (i * 6 + 1) << 8 | (i * 6));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
image.depth = 4;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 3;
|
||||||
|
image.format = mCOLOR_ARGB8;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 4) << 24 | (i * 4 + 1) << 16 | (i * 4 + 2) << 8 | (i * 4 + 3));
|
||||||
|
#else
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, i), (i * 4 + 3) << 24 | (i * 4 + 2) << 16 | (i * 4 + 1) << 8 | (i * 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(oobRead) {
|
||||||
|
static uint8_t buffer[8] = {
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mImage image = {
|
||||||
|
.data = buffer,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1,
|
||||||
|
.stride = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 0), 0xFF);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 0), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 1), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 1), 0);
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 0), 0xFFFF);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 0), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 1), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 1), 0);
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 0), 0xFFFFFF);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 0), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 1), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 1), 0);
|
||||||
|
|
||||||
|
image.depth = 4;
|
||||||
|
image.format = mCOLOR_ARGB8;
|
||||||
|
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 0), 0xFFFFFFFF);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 0), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 0, 1), 0);
|
||||||
|
assert_int_equal(mImageGetPixelRaw(&image, 1, 1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(pitchWrite) {
|
||||||
|
static const uint8_t baseline[12] = {
|
||||||
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t buffer[12];
|
||||||
|
|
||||||
|
struct mImage image = {
|
||||||
|
.data = buffer,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.width = 12;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 12; ++i) {
|
||||||
|
mImageSetPixelRaw(&image, i, 0, i);
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(baseline));
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.width = 6;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, i, 0, (i * 2) << 8 | (i * 2 + 1));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, i, 0, (i * 2 + 1) << 8 | (i * 2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(baseline));
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.width = 4;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, i, 0, (i * 3) << 16 | (i * 3 + 1) << 8 | (i * 3 + 2));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, i, 0, (i * 3 + 2) << 16 | (i * 3 + 1) << 8 | (i * 3));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(baseline));
|
||||||
|
|
||||||
|
image.depth = 4;
|
||||||
|
image.width = 3;
|
||||||
|
image.format = mCOLOR_ARGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, i, 0, (i * 4) << 24 | (i * 4 + 1) << 16 | (i * 4 + 2) << 8 | (i * 4 + 3));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, i, 0, (i * 4 + 3) << 24 | (i * 4 + 2) << 16 | (i * 4 + 1) << 8 | (i * 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(baseline));
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(strideWrite) {
|
||||||
|
static const uint8_t baseline[12] = {
|
||||||
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB
|
||||||
|
};
|
||||||
|
static const uint8_t baseline2x1[12] = {
|
||||||
|
0x0, 0x0, 0x2, 0x0, 0x4, 0x0, 0x6, 0x0, 0x8, 0x0, 0xA, 0x0
|
||||||
|
};
|
||||||
|
static const uint8_t baseline2x2[12] = {
|
||||||
|
0x0, 0x1, 0x0, 0x0, 0x4, 0x5, 0x0, 0x0, 0x8, 0x9, 0x0, 0x0
|
||||||
|
};
|
||||||
|
static const uint8_t baseline3x2[12] = {
|
||||||
|
0x0, 0x1, 0x2, 0x0, 0x0, 0x0, 0x6, 0x7, 0x8, 0x0, 0x0, 0x0
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t buffer[12];
|
||||||
|
|
||||||
|
struct mImage image = {
|
||||||
|
.data = buffer,
|
||||||
|
.width = 1
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 12;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 12; ++i) {
|
||||||
|
mImageSetPixelRaw(&image, 0, i, i);
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.stride = 2;
|
||||||
|
image.height = 6;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
mImageSetPixelRaw(&image, 0, i, i * 2);
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline2x1, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 6;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 6; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 2) << 8 | (i * 2 + 1));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 2 + 1) << 8 | (i * 2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.stride = 2;
|
||||||
|
image.height = 3;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 4) << 8 | (i * 4 + 1));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 4 + 1) << 8 | (i * 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline2x2, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 4;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 3) << 16 | (i * 3 + 1) << 8 | (i * 3 + 2));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 3 + 2) << 16 | (i * 3 + 1) << 8 | (i * 3));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.stride = 2;
|
||||||
|
image.height = 2;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 6) << 16 | (i * 6 + 1) << 8 | (i * 6 + 2));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 6 + 2) << 16 | (i * 6 + 1) << 8 | (i * 6));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline3x2, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 4;
|
||||||
|
image.stride = 1;
|
||||||
|
image.height = 3;
|
||||||
|
image.format = mCOLOR_ARGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 4) << 24 | (i * 4 + 1) << 16 | (i * 4 + 2) << 8 | (i * 4 + 3));
|
||||||
|
#else
|
||||||
|
mImageSetPixelRaw(&image, 0, i, (i * 4 + 3) << 24 | (i * 4 + 2) << 16 | (i * 4 + 1) << 8 | (i * 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert_memory_equal(baseline, buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(oobWrite) {
|
||||||
|
static uint8_t buffer[8];
|
||||||
|
|
||||||
|
struct mImage image = {
|
||||||
|
.data = buffer,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1,
|
||||||
|
.stride = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
image.depth = 1;
|
||||||
|
image.format = mCOLOR_L8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
mImageSetPixelRaw(&image, 0, 0, 0xFF);
|
||||||
|
mImageSetPixelRaw(&image, 1, 0, 0);
|
||||||
|
mImageSetPixelRaw(&image, 0, 1, 0);
|
||||||
|
mImageSetPixelRaw(&image, 1, 1, 0);
|
||||||
|
assert_memory_equal(buffer, (&(uint8_t[8]) { 0xFF }), sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 2;
|
||||||
|
image.format = mCOLOR_RGB5;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
mImageSetPixelRaw(&image, 0, 0, 0xFFFF);
|
||||||
|
mImageSetPixelRaw(&image, 1, 0, 0);
|
||||||
|
mImageSetPixelRaw(&image, 0, 1, 0);
|
||||||
|
mImageSetPixelRaw(&image, 1, 1, 0);
|
||||||
|
assert_memory_equal(buffer, (&(uint8_t[8]) { 0xFF, 0xFF }), sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 3;
|
||||||
|
image.format = mCOLOR_RGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
mImageSetPixelRaw(&image, 0, 0, 0xFFFFFF);
|
||||||
|
mImageSetPixelRaw(&image, 1, 0, 0);
|
||||||
|
mImageSetPixelRaw(&image, 0, 1, 0);
|
||||||
|
mImageSetPixelRaw(&image, 1, 1, 0);
|
||||||
|
assert_memory_equal(buffer, (&(uint8_t[8]) { 0xFF, 0xFF, 0xFF }), sizeof(buffer));
|
||||||
|
|
||||||
|
image.depth = 4;
|
||||||
|
image.format = mCOLOR_ARGB8;
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
mImageSetPixelRaw(&image, 0, 0, 0xFFFFFFFF);
|
||||||
|
mImageSetPixelRaw(&image, 1, 0, 0);
|
||||||
|
mImageSetPixelRaw(&image, 0, 1, 0);
|
||||||
|
mImageSetPixelRaw(&image, 1, 1, 0);
|
||||||
|
assert_memory_equal(buffer, (&(uint8_t[8]) { 0xFF, 0xFF, 0xFF, 0xFF }), sizeof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_SUITE_DEFINE(Image,
|
||||||
|
cmocka_unit_test(pitchRead),
|
||||||
|
cmocka_unit_test(strideRead),
|
||||||
|
cmocka_unit_test(oobRead),
|
||||||
|
cmocka_unit_test(pitchWrite),
|
||||||
|
cmocka_unit_test(strideWrite),
|
||||||
|
cmocka_unit_test(oobWrite),
|
||||||
|
)
|
Loading…
Reference in New Issue