#include #include "nr-compose.h" #include "nr-compose-reference.h" #include #include #include #include static inline unsigned int DIV_ROUND(unsigned int v, unsigned int divisor) { return (v+divisor/2)/divisor; } static inline unsigned char NR_PREMUL_111(unsigned int c, unsigned int a) { return static_cast(DIV_ROUND(c*a, 255)); } template int IMGCMP(const unsigned char* a, const unsigned char* b, size_t n) { return memcmp(a, b, n); } template<> int IMGCMP(const unsigned char* a, const unsigned char* b, size_t n) { // If two pixels each have their alpha channel set to zero they're equivalent // Note that this doesn't work for premultiplied values, as their color values should // be zero when alpha is zero. int cr = 0; while(n && cr == 0) { if ( a[3] != 0 || b[3] != 0 ) { cr = memcmp(a, b, 4); } a+=4; b+=4; n-=4; } return cr; } class NrComposeTest : public CxxTest::TestSuite { private: int const w, h; unsigned char* const dst_rgba_n_org; unsigned char* const dst_rgba_p_org; unsigned char* const dst_rgb_org; unsigned char* const dst1_rgba; unsigned char* const dst2_rgba; unsigned char* const src_rgba_n; unsigned char* const src_rgba_p; unsigned char* const dst1_rgb; unsigned char* const dst2_rgb; unsigned char* const src_rgb; unsigned char* const mask; static unsigned int const alpha_vals[7]; static unsigned int const rgb_vals[3]; public: NrComposeTest() : w(13), h(5), dst_rgba_n_org(new unsigned char[w*h*4]), dst_rgba_p_org(new unsigned char[w*h*4]), dst_rgb_org(new unsigned char[w*h*3]), dst1_rgba(new unsigned char[w*h*4]), dst2_rgba(new unsigned char[w*h*4]), src_rgba_n(new unsigned char[w*h*4]), src_rgba_p(new unsigned char[w*h*4]), dst1_rgb(new unsigned char[w*h*3]), dst2_rgb(new unsigned char[w*h*3]), src_rgb(new unsigned char[w*h*3]), mask(new unsigned char[w*h]) { srand(23874683); // It shouldn't really matter what this is, as long as it's always the same (to be reproducible) for(int y=0; y(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_N_EMPTY_R8G8B8A8_P() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_P_EMPTY_R8G8B8A8_N() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_P_EMPTY_R8G8B8A8_P() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } void testnr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P() { for(size_t i=0; i(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } // FINAL DST SRC MASK void testnr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8() { memcpy(dst1_rgba, dst_rgba_n_org, w*h*4); memcpy(dst2_rgba, dst_rgba_n_org, w*h*4); nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8(dst1_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8_ref(dst2_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8() { memcpy(dst1_rgba, dst_rgba_n_org, w*h*4); memcpy(dst2_rgba, dst_rgba_n_org, w*h*4); nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8(dst1_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8_ref(dst2_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8() { memcpy(dst1_rgba, dst_rgba_p_org, w*h*4); memcpy(dst2_rgba, dst_rgba_p_org, w*h*4); nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8(dst1_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8_ref(dst2_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8() { memcpy(dst1_rgba, dst_rgba_p_org, w*h*4); memcpy(dst2_rgba, dst_rgba_p_org, w*h*4); nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8(dst1_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8_ref(dst2_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8() { memcpy(dst1_rgba, dst_rgba_n_org, w*h*4); memcpy(dst2_rgba, dst_rgba_n_org, w*h*4); nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8(dst1_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8_ref(dst2_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8() { memcpy(dst1_rgba, dst_rgba_n_org, w*h*4); memcpy(dst2_rgba, dst_rgba_n_org, w*h*4); nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8(dst1_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8_ref(dst2_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8() { memcpy(dst1_rgba, dst_rgba_p_org, w*h*4); memcpy(dst2_rgba, dst_rgba_p_org, w*h*4); nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8(dst1_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8_ref(dst2_rgba, w, h, w*4, src_rgba_n, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } void testnr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8() { memcpy(dst1_rgba, dst_rgba_p_org, w*h*4); memcpy(dst2_rgba, dst_rgba_p_org, w*h*4); nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8(dst1_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8_ref(dst2_rgba, w, h, w*4, src_rgba_p, w*4, mask, w); TS_ASSERT( IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } // FINAL DST MASK COLOR void testnr_R8G8B8A8_N_EMPTY_A8_RGBA32() { for(size_t j=0; j>24u)&0xff, (rgba>>16u)&0xff, (rgba>>8u)&0xff, rgba&0xff); memcpy(dst1_rgba, dst_rgba_n_org, w*h*4); memcpy(dst2_rgba, dst_rgba_n_org, w*h*4); nr_R8G8B8A8_N_EMPTY_A8_RGBA32(dst1_rgba, w, h, w*4, mask, w, rgba); nr_R8G8B8A8_N_EMPTY_A8_RGBA32_ref(dst2_rgba, w, h, w*4, mask, w, rgba); TSM_ASSERT(msg, IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } } void testnr_R8G8B8A8_P_EMPTY_A8_RGBA32() { for(size_t j=0; j>24u)&0xff, (rgba>>16u)&0xff, (rgba>>8u)&0xff, rgba&0xff); memcpy(dst1_rgba, dst_rgba_p_org, w*h*4); memcpy(dst2_rgba, dst_rgba_p_org, w*h*4); nr_R8G8B8A8_P_EMPTY_A8_RGBA32(dst1_rgba, w, h, w*4, mask, w, rgba); nr_R8G8B8A8_P_EMPTY_A8_RGBA32_ref(dst2_rgba, w, h, w*4, mask, w, rgba); TSM_ASSERT(msg, IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } } void testnr_R8G8B8_R8G8B8_A8_RGBA32() { for(size_t j=0; j>24u)&0xff, (rgba>>16u)&0xff, (rgba>>8u)&0xff, rgba&0xff); memcpy(dst1_rgb, dst_rgb_org, w*h*3); memcpy(dst2_rgb, dst_rgb_org, w*h*3); nr_R8G8B8_R8G8B8_A8_RGBA32(dst1_rgb, w, h, w*3, mask, w, rgba); nr_R8G8B8_R8G8B8_A8_RGBA32_ref(dst2_rgb, w, h, w*3, mask, w, rgba); TSM_ASSERT(msg, IMGCMP(dst1_rgb, dst2_rgb, w*h*3) == 0 ); } } } void testnr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32() { for(size_t j=0; j>24u)&0xff, (rgba>>16u)&0xff, (rgba>>8u)&0xff, rgba&0xff); memcpy(dst1_rgba, dst_rgba_n_org, w*h*4); memcpy(dst2_rgba, dst_rgba_n_org, w*h*4); nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32(dst1_rgba, w, h, w*4, mask, w, rgba); nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32_ref(dst2_rgba, w, h, w*4, mask, w, rgba); TSM_ASSERT(msg, IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } } void testnr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32() { for(size_t j=0; j>24u)&0xff, (rgba>>16u)&0xff, (rgba>>8u)&0xff, rgba&0xff); memcpy(dst1_rgba, dst_rgba_p_org, w*h*4); memcpy(dst2_rgba, dst_rgba_p_org, w*h*4); nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32(dst1_rgba, w, h, w*4, mask, w, rgba); nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32_ref(dst2_rgba, w, h, w*4, mask, w, rgba); TSM_ASSERT(msg, IMGCMP(dst1_rgba, dst2_rgba, w*h*4) == 0 ); } } } // RGB void testnr_R8G8B8_R8G8B8_R8G8B8A8_N() { for(size_t i=0; i(dst1_rgb, dst2_rgb, w*h*3) == 0 ); } } void testnr_R8G8B8_R8G8B8_R8G8B8A8_P() { for(size_t i=0; i(dst1_rgb, dst2_rgb, w*h*3) == 0 ); } } void testnr_R8G8B8_R8G8B8_R8G8B8A8_N_A8() { for(size_t i=0; i(dst1_rgb, dst2_rgb, w*h*3) == 0 ); } } void testnr_R8G8B8_R8G8B8_R8G8B8A8_P_A8() { for(size_t i=0; i(dst1_rgb, dst2_rgb, w*h*3) == 0 ); } } }; unsigned int const NrComposeTest::alpha_vals[7] = {0, 1, 127, 128, 129, 254, 255}; unsigned int const NrComposeTest::rgb_vals[3] = { ( 0u<<24u)+( 1u<<16u)+( 92u<<8u), (127u<<24u)+(128u<<16u)+(129u<<8u), (163u<<24u)+(254u<<16u)+(255u<<8u)}; /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :