#include /* {{{ TEST: merge2h */ struct tests_merge2h { uint8_t row[8]; /* last element is invalid because we do not know the next data */ uint16_t exp_0[7]; uint8_t exp_1[7]; }; static struct tests_merge2h const TESTS_MERGE2H[] = { { .row = { 1, 2, 5, 255, 255, 254, 0, 0 }, .exp_0 = { 3, 7, 260, 510, 509, 254, 0 }, .exp_1 = { 2, 4, 130, 255, 255, 127, 0 }, }, { .row = { 1, 1, 5, 255, 255, 254, 0, 0 }, .exp_0 = { 2, 6, 260, 510, 509, 254, 0 }, .exp_1 = { 1, 3, 130, 255, 255, 127, 0 }, }, { .row = { 0, 0, 0, 0, 254, 0, 0, 0 }, .exp_0 = { 0, 0, 0, 254, 254, 0, 0 }, .exp_1 = { 0, 0, 0, 127, 127, 0, 0 }, }, }; static void _noinline_ test_merge2h(void) { for (size_t i = 0; i < ARRAY_SIZE(TESTS_MERGE2H); ++i) { struct tests_merge2h const *test = &(TESTS_MERGE2H[i]); uint8x8_t row = vld1_u8(test->row); uint16x8_t res_0 = merge2h(row); uint8x8_t res_1 = merge2h_r(row); uint16_t tmp_0[8]; uint8_t tmp_1[8]; vst1q_u16(tmp_0, res_0); vst1_u8 (tmp_1, res_1); if (memcmp(tmp_0, test->exp_0, sizeof test->exp_0) != 0) BUG(); if (memcmp(tmp_1, test->exp_1, sizeof test->exp_1) != 0) BUG(); } } /* }}} TEST: merge2h */ /* {{{ TEST: merge4d */ struct tests_merge4d { uint8_t prev[8]; uint8_t row[8]; uint8_t next[8]; /* last element is invalid because we do not know the next data */ uint8_t exp[7]; }; static struct tests_merge4d const TESTS_MERGE4D[] = { { .prev = { 1, 2, 255, 255, 255, 255, 3, 0 }, .row = { 1, 1, 5, 255, 255, 254, 0, 4 }, .next = { 0, 0, 253, 255, 0, 255, 0, 0 }, .exp = { 1, 2, 192, 255, 191, 191, 2 }, }, { .prev = { 1, 2, 255, 255, 255, 255, 0, 0 }, .row = { 1, 2, 5, 255, 255, 254, 0, 0 }, .next = { 0, 0, 253, 255, 0, 255, 0, 0 }, .exp = { 1, 2, 192, 255, 191, 191, 0 }, }, }; static void _noinline_ test_merge4d(void) { for (size_t i = 0; i < ARRAY_SIZE(TESTS_MERGE4D); ++i) { struct tests_merge4d const *test = &(TESTS_MERGE4D[i]); uint8x8_t prev = vld1_u8(test->prev); uint8x8_t row = vld1_u8(test->row); uint8x8_t next = vld1_u8(test->next); uint16_t vert_sum[8]; for (size_t j = 0; j < ARRAY_SIZE(vert_sum); ++j) vert_sum[j] = test->prev[j] + test->next[j]; uint16x8_t vert = vld1q_u16(vert_sum); /* total sum */ uint16x8_t res_0 = merge4d(row, vert); /* average */ uint8x8_t res_1 = merge4d_r(row, vert); uint16x8_t res_2 = merge4dv(row, prev, next); uint8x8_t res_3 = merge4dv_r(row, prev, next); uint16_t sum_t[7]; uint16_t tmp_0[8]; uint8_t tmp_1[8]; uint16_t tmp_2[8]; uint8_t tmp_3[8]; for (size_t j = 0; j < ARRAY_SIZE(sum_t); ++j) sum_t[j] = test->row[j] + test->row[j+1] + vert_sum[j]; vst1q_u16(tmp_0, res_0); vst1_u8 (tmp_1, res_1); vst1q_u16(tmp_2, res_2); vst1_u8 (tmp_3, res_3); if (memcmp(tmp_0, sum_t, sizeof sum_t) != 0) BUG(); if (memcmp(tmp_2, sum_t, sizeof sum_t) != 0) BUG(); if (memcmp(tmp_1, test->exp, sizeof test->exp) != 0) BUG(); if (memcmp(tmp_3, test->exp, sizeof test->exp) != 0) BUG(); } } /* }}} TEST: merge4d */ /* {{{ TEST: merge4q */ struct tests_merge4q { uint8_t prev[8]; uint8_t next[8]; uint8_t exp[7]; }; static struct tests_merge4q const TESTS_MERGE4Q[] = { { .prev = { 1, 2, 255, 255, 255, 255, 3, 0 }, .exp = { 1, 128, 255, 191, 191, 128, 1 }, .next = { 0, 0, 253, 255, 0, 255, 0, 0 }, }, { .prev = { 0, 0, 0, 0, 254, 0, 0, 0 }, .exp = { 0, 0, 0, 127, 127, 0, 0 }, .next = { 0, 0, 0, 0, 254, 0, 0, 0 }, }, }; static void _noinline_ test_merge4q(void) { for (size_t i = 0; i < ARRAY_SIZE(TESTS_MERGE4Q); ++i) { struct tests_merge4q const *test = &(TESTS_MERGE4Q[i]); uint8x8_t prev = vld1_u8(test->prev); uint8x8_t next = vld1_u8(test->next); uint16x8_t res_0 = merge4q(prev, next); uint8x8_t res_1 = merge4q_r(prev, next); uint16_t sum[7]; uint16_t tmp_0[8]; uint8_t tmp_1[8]; vst1q_u16(tmp_0, res_0); vst1_u8 (tmp_1, res_1); for (size_t j = 0; j < ARRAY_SIZE(sum); ++j) sum[j] = (test->prev[j] + test->prev[j+1] + test->next[j] + test->next[j+1]); if (memcmp(tmp_0, sum, sizeof sum) != 0) BUG(); if (memcmp(tmp_1, test->exp, sizeof test->exp) != 0) BUG(); } } /* }}} TEST: merge4q */ struct tests_combine_pixels { uint8_t even[8]; uint8_t odd[8]; uint8_t exp[16]; }; static struct tests_combine_pixels const TESTS_COMBINE_PIXELS[] = { { .even = { 0, 2, 4, 6, 8, 10, 12, 14 }, .odd = { 1, 3, 5, 7, 9, 11, 13, 15 }, .exp = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } }, }; static void _noinline_ test_combine_pixels(void) { for (size_t i = 0; i < ARRAY_SIZE(TESTS_COMBINE_PIXELS); ++i) { struct tests_combine_pixels const *test = &(TESTS_COMBINE_PIXELS[i]); uint8x8_t even = vld1_u8(test->even); uint8x8_t odd = vld1_u8(test->odd); uint8x16_t res = combine_pixels(even, odd); uint8_t tmp[16]; vst1q_u8(tmp, res); if (memcmp(tmp, test->exp, sizeof test->exp) != 0) BUG(); } } #if 0 struct tests_convert_pixels { uint8_t g_prev[8]; uint8_t r_prev[8]; uint8_t b[8]; uint8_t g_b[8]; uint8_t g_r[8]; uint8_t r[8]; uint8_t b_next[8]; uint8_t g_next[8]; }; static struct tests_convert_pixels const TESTS_CONVERT_PIXELS[] = { { .g_prev = { 1, 1, 0, 0, 0, 0, 0, 0 }, .r_prev = { 2, 2, 0, 0, 0, 0, 0, 0 }, .b = { 3, 3, 0, 0, 0, 0, 0, 0 }, .g_b = { 1, 1, 0, 0, 0, 0, 0, 0 }, .g_r = { 1, 1, 0, 0, 0, 0, 0, 0 }, .r = { 1, 1, 0, 0, 0, 0, 0, 0 }, .b_next = { 1, 1, 0, 0, 0, 0, 0, 0 }, .g_next = { 2, 2, 0, 0, 0, 0, 0, 0 }, }, }; static void _noinline_ test_convert_pixels(void) { for (size_t i = 0; i < ARRAY_SIZE(TESTS_CONVERT_PIXELS); ++i) { struct tests_convert_pixels const *test = &(TESTS_CONVERT_PIXELS[i]); uint8x16x4_t row0; uint8x16x4_t row1; convert_pixel uint8x8_t even = vld1_u8(test->even); uint8x8_t odd = vld1_u8(test->odd); uint8x16_t res = convert_pixels(even, odd); uint8_t tmp[16]; vst1q_u8(tmp, res); if (memcmp(tmp, test->exp, sizeof test->exp) != 0) BUG(); } } #endif static void run_tests(void) { test_merge2h(); test_merge4d(); test_merge4q(); test_combine_pixels(); }