diff --git a/tests/src/test_cases/test_draw_buf.c b/tests/src/test_cases/test_draw_buf.c index cc4ff2aab8..09cc38fec6 100644 --- a/tests/src/test_cases/test_draw_buf.c +++ b/tests/src/test_cases/test_draw_buf.c @@ -127,4 +127,146 @@ void test_draw_buf_xy_access(void) TEST_ASSERT_NULL(ret); } + +void test_draw_buf_premultiply(void) +{ + lv_draw_buf_t * draw_buf; + lv_result_t res; + int i; + /* Test ARGB8888 format */ + { + draw_buf = lv_draw_buf_create(2, 2, LV_COLOR_FORMAT_ARGB8888, 2 * 4); + + /* Fill with test data: white with 50% alpha */ + lv_color32_t * pixel = (lv_color32_t *)draw_buf->data; + for(i = 0; i < 4; i++) { + pixel[i] = (lv_color32_t) { + .alpha = 128, .red = 255, .green = 255, .blue = 255 + }; + } + + res = lv_draw_buf_premultiply(draw_buf); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + TEST_ASSERT(draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED); + + /* Verify premultiplied result: color should be 127 = (255 * 128) >> 8, alpha should be 128 */ + for(i = 0; i < 4; i++) { + TEST_ASSERT_EQUAL_UINT8(127, pixel[i].red); + TEST_ASSERT_EQUAL_UINT8(127, pixel[i].green); + TEST_ASSERT_EQUAL_UINT8(127, pixel[i].blue); + TEST_ASSERT_EQUAL_UINT8(128, pixel[i].alpha); /* Alpha should remain unchanged */ + } + + lv_draw_buf_destroy(draw_buf); + } + + /* Test XRGB8888 format */ + { + draw_buf = lv_draw_buf_create(2, 2, LV_COLOR_FORMAT_XRGB8888, 2 * 4); + + /* Fill with test data: white with 50% alpha */ + lv_color32_t * pixel = (lv_color32_t *)draw_buf->data; + for(i = 0; i < 4; i++) { + pixel[i] = (lv_color32_t) { + .alpha = 255, .red = 255, .green = 255, .blue = 255 + }; + } + + res = lv_draw_buf_premultiply(draw_buf); + TEST_ASSERT_EQUAL(LV_RESULT_INVALID, res); /* XRGB8888 is not supported */ + + lv_draw_buf_destroy(draw_buf); + } + + /* Test RGB565A8 format */ + { + draw_buf = lv_draw_buf_create(2, 2, LV_COLOR_FORMAT_RGB565A8, 2 * 2); + + /* Fill with test data */ + uint16_t * pixel = (uint16_t *)draw_buf->data; + lv_opa_t * alpha = (lv_opa_t *)(draw_buf->data + 2 * 2 * 2); /* RGB565 data size */ + for(i = 0; i < 4; i++) { + pixel[i] = lv_color_to_u16(lv_color_white()); /* White: 0xFFFF in RGB565 */ + alpha[i] = 128; /* 50% alpha */ + } + + res = lv_draw_buf_premultiply(draw_buf); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + TEST_ASSERT(draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED); + + /* Verify premultiplied result: white (0xFFFF) with 50% alpha should become gray */ + for(i = 0; i < 4; i++) { + /* RGB565: 5-6-5 bits, white premultiplied by 0.5 should be approximately half intensity */ + TEST_ASSERT_EQUAL_UINT16(0x7BEF, pixel[i]); /* Approximate half of white in RGB565 */ + } + + lv_draw_buf_destroy(draw_buf); + } + + /* Test ARGB8565 format */ + { + draw_buf = lv_draw_buf_create(2, 2, LV_COLOR_FORMAT_ARGB8565, 2 * 3); + + /* Fill with test data */ + uint8_t * pixel = draw_buf->data; + for(i = 0; i < 4; i++) { + uint16_t c = lv_color_to_u16(lv_color_white()); /* White: 0xFFFF */ + pixel[0] = c & 0xFF; /* Low byte of RGB565 */ + pixel[1] = (c >> 8) & 0xFF; /* High byte of RGB565 */ + pixel[2] = 128; /* Alpha */ + pixel += 3; + } + + res = lv_draw_buf_premultiply(draw_buf); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + TEST_ASSERT(draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED); + + /* Verify premultiplied result */ + pixel = draw_buf->data; + for(i = 0; i < 4; i++) { + uint16_t c = (pixel[1] << 8) | pixel[0]; /* Reconstruct RGB565 */ + /* White premultiplied by 0.5 should be approximately half intensity */ + TEST_ASSERT_EQUAL_UINT16(0x7BEF, c); /* Approximate half of white in RGB565 */ + TEST_ASSERT_EQUAL_UINT8(128, pixel[2]); /* Alpha should remain unchanged */ + pixel += 3; + } + + lv_draw_buf_destroy(draw_buf); + } + + /* Test indexed format (I1/I2/I4/I8) */ + lv_color_format_t color_formats[] = { + LV_COLOR_FORMAT_I1, + LV_COLOR_FORMAT_I2, + LV_COLOR_FORMAT_I4, + LV_COLOR_FORMAT_I8, + }; + + for(unsigned int fmt_i = 0; fmt_i < sizeof(color_formats) / sizeof(color_formats[0]); fmt_i++) { + draw_buf = lv_draw_buf_create(2, 2, color_formats[fmt_i], 0); + + /* Fill palette with test data */ + lv_color32_t * palette = (lv_color32_t *)draw_buf->data; + int palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(color_formats[fmt_i]); + for(i = 0; i < palette_size; i++) { + palette[i] = (lv_color32_t) { + .alpha = 128, .red = 255, .green = 255, .blue = 255 + }; + } + + res = lv_draw_buf_premultiply(draw_buf); + TEST_ASSERT_EQUAL(LV_RESULT_OK, res); + TEST_ASSERT(draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED); + + /* Verify palette was premultiplied */ + for(i = 0; i < palette_size; i++) { + TEST_ASSERT_EQUAL_UINT8(127, palette[i].red); + TEST_ASSERT_EQUAL_UINT8(127, palette[i].green); + TEST_ASSERT_EQUAL_UINT8(127, palette[i].blue); + TEST_ASSERT_EQUAL_UINT8(128, palette[i].alpha); + } + + lv_draw_buf_destroy(draw_buf); + } +} #endif