TestSwizzle.cpp (26833B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "gtest/gtest.h" 8 #include "mozilla/ArrayUtils.h" 9 #include "mozilla/gfx/Swizzle.h" 10 #include "Orientation.h" 11 12 using namespace mozilla; 13 using namespace mozilla::gfx; 14 using namespace mozilla::image; 15 16 TEST(Moz2D, PremultiplyData) 17 { 18 const uint8_t in_bgra[5 * 4] = { 19 255, 255, 0, 255, // verify 255 alpha leaves RGB unchanged 20 0, 0, 255, 255, 21 0, 255, 255, 0, // verify 0 alpha zeroes out RGB 22 0, 0, 0, 0, 23 255, 0, 0, 128, // verify that 255 RGB maps to alpha 24 }; 25 uint8_t out[5 * 4]; 26 const uint8_t check_bgra[5 * 4] = { 27 255, 255, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 128, 28 }; 29 // check swizzled output 30 const uint8_t check_rgba[5 * 4] = { 31 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 32 }; 33 const uint8_t check_argb[5 * 4] = { 34 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 128, 35 }; 36 37 PremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 38 sizeof(in_bgra), SurfaceFormat::B8G8R8A8, IntSize(5, 1)); 39 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 40 41 PremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 42 sizeof(in_bgra), SurfaceFormat::R8G8B8A8, IntSize(5, 1)); 43 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 44 45 PremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 46 sizeof(in_bgra), SurfaceFormat::A8R8G8B8, IntSize(5, 1)); 47 EXPECT_TRUE(ArrayEqual(out, check_argb)); 48 } 49 50 TEST(Moz2D, PremultiplyRow) 51 { 52 const uint8_t in_bgra[5 * 4] = { 53 255, 255, 0, 255, // verify 255 alpha leaves RGB unchanged 54 0, 0, 255, 255, 55 0, 255, 255, 0, // verify 0 alpha zeroes out RGB 56 0, 0, 0, 0, 57 255, 0, 0, 128, // verify that 255 RGB maps to alpha 58 }; 59 uint8_t out[5 * 4]; 60 const uint8_t check_bgra[5 * 4] = { 61 255, 255, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 128, 62 }; 63 // check swizzled output 64 const uint8_t check_rgba[5 * 4] = { 65 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 66 }; 67 const uint8_t check_argb[5 * 4] = { 68 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 128, 69 }; 70 71 SwizzleRowFn func = 72 PremultiplyRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8A8); 73 func(in_bgra, out, 5); 74 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 75 76 func = PremultiplyRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::R8G8B8A8); 77 func(in_bgra, out, 5); 78 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 79 80 func = PremultiplyRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::A8R8G8B8); 81 func(in_bgra, out, 5); 82 EXPECT_TRUE(ArrayEqual(out, check_argb)); 83 } 84 85 TEST(Moz2D, PremultiplyYFlipData) 86 { 87 const uint8_t stride = 2 * 4; 88 const uint8_t in_bgra[6 * 4] = { 89 255, 255, 0, 255, // row 1: verify 255 alpha leaves RGB unchanged 90 0, 0, 255, 255, 91 0, 255, 255, 0, // row 2: verify 0 alpha zeroes out RGB 92 0, 0, 0, 0, 93 255, 0, 0, 128, // row 3: verify that 255 RGB maps to alpha 94 255, 255, 255, 128, 95 }; 96 const uint8_t in_bgra_2[4 * 4] = { 97 255, 255, 0, 255, // row 1: verify 255 alpha leaves RGB unchanged 98 0, 0, 255, 255, 99 0, 255, 255, 0, // row 2: verify 0 alpha zeroes out RGB 100 0, 0, 0, 0, 101 }; 102 const uint8_t in_bgra_3[2 * 4] = { 103 255, 0, 0, 128, // row 1: verify that 255 RGB maps to alpha 104 255, 255, 255, 128, 105 }; 106 uint8_t out[6 * 4]; 107 uint8_t out_2[4 * 4]; 108 uint8_t out_3[2 * 4]; 109 const uint8_t check_bgra[6 * 4] = { 110 128, 0, 0, 128, 128, 128, 128, 128, 0, 0, 0, 0, 111 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 255, 255, 112 }; 113 const uint8_t check_bgra_2[4 * 4] = { 114 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 255, 255, 115 }; 116 const uint8_t check_bgra_3[2 * 4] = { 117 128, 0, 0, 128, 128, 128, 128, 128, 118 }; 119 // check swizzled output 120 const uint8_t check_rgba[6 * 4] = { 121 0, 0, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 122 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 123 }; 124 125 // Premultiply. 126 PremultiplyYFlipData(in_bgra, stride, SurfaceFormat::B8G8R8A8, out, stride, 127 SurfaceFormat::B8G8R8A8, IntSize(2, 3)); 128 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 129 130 // Premultiply in-place with middle row. 131 memcpy(out, in_bgra, sizeof(out)); 132 PremultiplyYFlipData(out, stride, SurfaceFormat::B8G8R8A8, out, stride, 133 SurfaceFormat::B8G8R8A8, IntSize(2, 3)); 134 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 135 136 // Premultiply in-place without middle row. 137 memcpy(out_2, in_bgra_2, sizeof(out_2)); 138 PremultiplyYFlipData(out_2, stride, SurfaceFormat::B8G8R8A8, out_2, stride, 139 SurfaceFormat::B8G8R8A8, IntSize(2, 2)); 140 EXPECT_TRUE(ArrayEqual(out_2, check_bgra_2)); 141 142 // Premultiply in-place only middle row. 143 memcpy(out_3, in_bgra_3, sizeof(out_3)); 144 PremultiplyYFlipData(out_3, stride, SurfaceFormat::B8G8R8A8, out_3, stride, 145 SurfaceFormat::B8G8R8A8, IntSize(2, 1)); 146 EXPECT_TRUE(ArrayEqual(out_3, check_bgra_3)); 147 148 // Premultiply and swizzle with middle row. 149 PremultiplyYFlipData(in_bgra, stride, SurfaceFormat::B8G8R8A8, out, stride, 150 SurfaceFormat::R8G8B8A8, IntSize(2, 3)); 151 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 152 } 153 154 TEST(Moz2D, UnpremultiplyData) 155 { 156 const uint8_t in_bgra[5 * 4] = { 157 255, 255, 0, 255, // verify 255 alpha leaves RGB unchanged 158 0, 0, 255, 255, 0, 0, 0, 0, // verify 0 alpha leaves RGB at 0 159 0, 0, 0, 64, // verify 0 RGB stays 0 with non-zero alpha 160 128, 0, 0, 128, // verify that RGB == alpha maps to 255 161 162 }; 163 uint8_t out[5 * 4]; 164 const uint8_t check_bgra[5 * 4] = { 165 255, 255, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 64, 255, 0, 0, 128, 166 }; 167 // check swizzled output 168 const uint8_t check_rgba[5 * 4] = { 169 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 255, 128, 170 }; 171 const uint8_t check_argb[5 * 4] = { 172 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 255, 173 }; 174 175 UnpremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 176 sizeof(in_bgra), SurfaceFormat::B8G8R8A8, IntSize(5, 1)); 177 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 178 179 UnpremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 180 sizeof(in_bgra), SurfaceFormat::R8G8B8A8, IntSize(5, 1)); 181 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 182 183 UnpremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 184 sizeof(in_bgra), SurfaceFormat::A8R8G8B8, IntSize(5, 1)); 185 EXPECT_TRUE(ArrayEqual(out, check_argb)); 186 } 187 188 TEST(Moz2D, UnpremultiplyRow) 189 { 190 const uint8_t in_bgra[5 * 4] = { 191 255, 255, 0, 255, // verify 255 alpha leaves RGB unchanged 192 0, 0, 255, 255, 0, 0, 0, 0, // verify 0 alpha leaves RGB at 0 193 0, 0, 0, 64, // verify 0 RGB stays 0 with non-zero alpha 194 128, 0, 0, 128, // verify that RGB == alpha maps to 255 195 196 }; 197 uint8_t out[5 * 4]; 198 const uint8_t check_bgra[5 * 4] = { 199 255, 255, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 64, 255, 0, 0, 128, 200 }; 201 // check swizzled output 202 const uint8_t check_rgba[5 * 4] = { 203 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 255, 128, 204 }; 205 const uint8_t check_argb[5 * 4] = { 206 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 255, 207 }; 208 209 SwizzleRowFn func = 210 UnpremultiplyRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8A8); 211 func(in_bgra, out, 5); 212 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 213 214 func = UnpremultiplyRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::R8G8B8A8); 215 func(in_bgra, out, 5); 216 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 217 218 func = UnpremultiplyRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::A8R8G8B8); 219 func(in_bgra, out, 5); 220 EXPECT_TRUE(ArrayEqual(out, check_argb)); 221 } 222 223 TEST(Moz2D, SwizzleData) 224 { 225 const uint8_t in_bgra[5 * 4] = { 226 253, 254, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 1, 2, 3, 64, 127, 0, 9, 128, 227 228 }; 229 uint8_t out[5 * 4]; 230 // check copy 231 const uint8_t check_bgra[5 * 4] = { 232 253, 254, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 1, 2, 3, 64, 127, 0, 9, 128, 233 }; 234 // check swaps 235 const uint8_t check_rgba[5 * 4] = { 236 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 0, 0, 3, 2, 1, 64, 9, 0, 127, 128, 237 }; 238 const uint8_t check_argb[5 * 4] = { 239 255, 0, 254, 253, 255, 255, 0, 0, 0, 0, 0, 0, 64, 3, 2, 1, 128, 9, 0, 127, 240 }; 241 // check opaquifying 242 const uint8_t check_rgbx[5 * 4] = { 243 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 244 0, 255, 3, 2, 1, 255, 9, 0, 127, 255, 245 }; 246 // check packing 247 uint8_t out24[5 * 3]; 248 const uint8_t check_bgr[5 * 3] = {253, 254, 0, 0, 0, 255, 0, 0, 249 0, 1, 2, 3, 127, 0, 9}; 250 const uint8_t check_rgb[5 * 3] = { 251 0, 254, 253, 255, 0, 0, 0, 0, 0, 3, 2, 1, 9, 0, 127, 252 }; 253 uint8_t out8[5]; 254 const uint8_t check_a[5] = {255, 255, 0, 64, 128}; 255 uint16_t out16[5]; 256 #define PACK_RGB565(b, g, r) \ 257 (((b & 0xF8) >> 3) | ((g & 0xFC) << 3) | ((r & 0xF8) << 8)) 258 const uint16_t check_16[5] = { 259 PACK_RGB565(253, 254, 0), PACK_RGB565(0, 0, 255), PACK_RGB565(0, 0, 0), 260 PACK_RGB565(1, 2, 3), PACK_RGB565(127, 0, 9), 261 }; 262 263 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 264 sizeof(out), SurfaceFormat::B8G8R8A8, IntSize(5, 1)); 265 EXPECT_TRUE(ArrayEqual(out, check_bgra)); 266 267 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 268 sizeof(out), SurfaceFormat::R8G8B8A8, IntSize(5, 1)); 269 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 270 271 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 272 sizeof(out), SurfaceFormat::A8R8G8B8, IntSize(5, 1)); 273 EXPECT_TRUE(ArrayEqual(out, check_argb)); 274 275 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out, 276 sizeof(out), SurfaceFormat::R8G8B8X8, IntSize(5, 1)); 277 EXPECT_TRUE(ArrayEqual(out, check_rgbx)); 278 279 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out24, 280 sizeof(out24), SurfaceFormat::B8G8R8, IntSize(5, 1)); 281 EXPECT_TRUE(ArrayEqual(out24, check_bgr)); 282 283 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out24, 284 sizeof(out24), SurfaceFormat::R8G8B8, IntSize(5, 1)); 285 EXPECT_TRUE(ArrayEqual(out24, check_rgb)); 286 287 SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8, out8, 288 sizeof(out8), SurfaceFormat::A8, IntSize(5, 1)); 289 EXPECT_TRUE(ArrayEqual(out8, check_a)); 290 291 const uint8_t* uint32_argb; 292 293 #if MOZ_BIG_ENDIAN() 294 EXPECT_EQ(SurfaceFormat::A8R8G8B8_UINT32, SurfaceFormat::A8R8G8B8); 295 uint32_argb = check_argb; 296 #else 297 EXPECT_EQ(SurfaceFormat::A8R8G8B8_UINT32, SurfaceFormat::B8G8R8A8); 298 uint32_argb = check_bgra; 299 #endif 300 301 SwizzleData(uint32_argb, sizeof(in_bgra), SurfaceFormat::A8R8G8B8_UINT32, 302 reinterpret_cast<uint8_t*>(out16), sizeof(out16), 303 SurfaceFormat::R5G6B5_UINT16, IntSize(5, 1)); 304 EXPECT_TRUE(ArrayEqual(out16, check_16)); 305 } 306 307 TEST(Moz2D, SwizzleYFlipData) 308 { 309 const uint8_t stride = 2 * 4; 310 const uint8_t in_bgra[6 * 4] = { 311 255, 255, 0, 255, // row 1 312 0, 0, 255, 255, 0, 255, 255, 0, // row 2 313 0, 0, 0, 0, 255, 0, 0, 128, // row 3 314 255, 255, 255, 128, 315 }; 316 const uint8_t in_bgra_2[4 * 4] = { 317 255, 255, 0, 255, // row 1 318 0, 0, 255, 255, 0, 255, 255, 0, // row 2 319 0, 0, 0, 0, 320 }; 321 const uint8_t in_bgra_3[2 * 4] = { 322 255, 0, 0, 128, // row 1 323 255, 255, 255, 128, 324 }; 325 uint8_t out[6 * 4]; 326 uint8_t out_2[4 * 4]; 327 uint8_t out_3[2 * 4]; 328 const uint8_t check_rgba[6 * 4] = { 329 0, 0, 255, 128, 255, 255, 255, 128, 255, 255, 0, 0, 330 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 331 }; 332 const uint8_t check_rgba_2[4 * 4] = { 333 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 334 }; 335 const uint8_t check_rgba_3[2 * 4] = { 336 0, 0, 255, 128, 255, 255, 255, 128, 337 }; 338 339 // Swizzle. 340 SwizzleYFlipData(in_bgra, stride, SurfaceFormat::B8G8R8A8, out, stride, 341 SurfaceFormat::R8G8B8A8, IntSize(2, 3)); 342 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 343 344 // Swizzle in-place with middle row. 345 memcpy(out, in_bgra, sizeof(out)); 346 SwizzleYFlipData(out, stride, SurfaceFormat::B8G8R8A8, out, stride, 347 SurfaceFormat::R8G8B8A8, IntSize(2, 3)); 348 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 349 350 // Swizzle in-place without middle row. 351 memcpy(out_2, in_bgra_2, sizeof(out_2)); 352 SwizzleYFlipData(out_2, stride, SurfaceFormat::B8G8R8A8, out_2, stride, 353 SurfaceFormat::R8G8B8A8, IntSize(2, 2)); 354 EXPECT_TRUE(ArrayEqual(out_2, check_rgba_2)); 355 356 // Swizzle in-place only middle row. 357 memcpy(out_3, in_bgra_3, sizeof(out_3)); 358 SwizzleYFlipData(out_3, stride, SurfaceFormat::B8G8R8A8, out_3, stride, 359 SurfaceFormat::R8G8B8A8, IntSize(2, 1)); 360 EXPECT_TRUE(ArrayEqual(out_3, check_rgba_3)); 361 } 362 363 TEST(Moz2D, SwizzleRow) 364 { 365 const uint8_t in_bgra[5 * 4] = { 366 253, 254, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0, 1, 2, 3, 64, 127, 0, 9, 128, 367 368 }; 369 uint8_t out[5 * 4]; 370 // check swaps 371 const uint8_t check_rgba[5 * 4] = { 372 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 0, 0, 3, 2, 1, 64, 9, 0, 127, 128, 373 }; 374 // check opaquifying 375 const uint8_t check_rgbx[5 * 4] = { 376 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 377 0, 255, 3, 2, 1, 255, 9, 0, 127, 255, 378 }; 379 // check packing 380 uint8_t out24[5 * 3]; 381 const uint8_t check_bgr[5 * 3] = {253, 254, 0, 0, 0, 255, 0, 0, 382 0, 1, 2, 3, 127, 0, 9}; 383 const uint8_t check_rgb[5 * 3] = { 384 0, 254, 253, 255, 0, 0, 0, 0, 0, 3, 2, 1, 9, 0, 127, 385 }; 386 // check unpacking 387 uint8_t out_unpack[16 * 4]; 388 const uint8_t in_rgb[16 * 3] = { 389 0, 254, 253, 255, 0, 0, 0, 0, 0, 3, 2, 1, 9, 0, 127, 4, 390 5, 6, 9, 8, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 391 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 392 }; 393 const uint8_t check_unpack_rgbx[16 * 4] = { 394 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 0, 255, 3, 2, 1, 255, 395 9, 0, 127, 255, 4, 5, 6, 255, 9, 8, 7, 255, 10, 11, 12, 255, 396 13, 14, 15, 255, 16, 17, 18, 255, 19, 20, 21, 255, 22, 23, 24, 255, 397 25, 26, 27, 255, 28, 29, 30, 255, 31, 32, 33, 255, 34, 35, 36, 255, 398 }; 399 const uint8_t check_unpack_bgrx[16 * 4] = { 400 253, 254, 0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 1, 2, 3, 255, 401 127, 0, 9, 255, 6, 5, 4, 255, 7, 8, 9, 255, 12, 11, 10, 255, 402 15, 14, 13, 255, 18, 17, 16, 255, 21, 20, 19, 255, 24, 23, 22, 255, 403 27, 26, 25, 255, 30, 29, 28, 255, 33, 32, 31, 255, 36, 35, 34, 255, 404 }; 405 const uint8_t check_unpack_xrgb[16 * 4] = { 406 255, 0, 254, 253, 255, 255, 0, 0, 255, 0, 0, 0, 255, 3, 2, 1, 407 255, 9, 0, 127, 255, 4, 5, 6, 255, 9, 8, 7, 255, 10, 11, 12, 408 255, 13, 14, 15, 255, 16, 17, 18, 255, 19, 20, 21, 255, 22, 23, 24, 409 255, 25, 26, 27, 255, 28, 29, 30, 255, 31, 32, 33, 255, 34, 35, 36, 410 }; 411 412 SwizzleRowFn func = 413 SwizzleRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::R8G8B8A8); 414 func(in_bgra, out, 5); 415 EXPECT_TRUE(ArrayEqual(out, check_rgba)); 416 417 func = SwizzleRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::R8G8B8X8); 418 func(in_bgra, out, 5); 419 EXPECT_TRUE(ArrayEqual(out, check_rgbx)); 420 421 func = SwizzleRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8A8); 422 func(in_bgra, out, 5); 423 EXPECT_TRUE(ArrayEqual(out, in_bgra)); 424 425 func = SwizzleRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::B8G8R8); 426 func(in_bgra, out24, 5); 427 EXPECT_TRUE(ArrayEqual(out24, check_bgr)); 428 429 func = SwizzleRow(SurfaceFormat::B8G8R8A8, SurfaceFormat::R8G8B8); 430 func(in_bgra, out24, 5); 431 EXPECT_TRUE(ArrayEqual(out24, check_rgb)); 432 433 func = SwizzleRow(SurfaceFormat::R8G8B8, SurfaceFormat::B8G8R8X8); 434 func(in_rgb, out_unpack, 16); 435 EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_bgrx)); 436 437 memset(out_unpack, 0xE5, sizeof(out_unpack)); 438 memcpy(out_unpack, in_rgb, sizeof(in_rgb)); 439 func(out_unpack, out_unpack, 16); 440 EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_bgrx)); 441 442 func = SwizzleRow(SurfaceFormat::R8G8B8, SurfaceFormat::R8G8B8X8); 443 func(in_rgb, out_unpack, 16); 444 EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_rgbx)); 445 446 memset(out_unpack, 0xE5, sizeof(out_unpack)); 447 memcpy(out_unpack, in_rgb, sizeof(in_rgb)); 448 func(out_unpack, out_unpack, 16); 449 EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_rgbx)); 450 451 func = SwizzleRow(SurfaceFormat::R8G8B8, SurfaceFormat::X8R8G8B8); 452 func(in_rgb, out_unpack, 16); 453 EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_xrgb)); 454 455 memset(out_unpack, 0xE5, sizeof(out_unpack)); 456 memcpy(out_unpack, in_rgb, sizeof(in_rgb)); 457 func(out_unpack, out_unpack, 16); 458 EXPECT_TRUE(ArrayEqual(out_unpack, check_unpack_xrgb)); 459 } 460 461 TEST(Moz2D, ReorientRow) 462 { 463 // Input is a 3x4 image. 464 const uint8_t in_row0[3 * 4] = { 465 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 466 }; 467 const uint8_t in_row1[3 * 4] = { 468 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 469 }; 470 const uint8_t in_row2[3 * 4] = { 471 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 472 }; 473 const uint8_t in_row3[3 * 4] = { 474 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 475 }; 476 477 // Output is either a 3x4 image or 4x3 image. 478 uint8_t out[3 * 4 * 4]; 479 IntSize outSize(3, 4); 480 IntSize outSizeSwap(4, 3); 481 int32_t outStride = 3 * 4; 482 int32_t outStrideSwap = 4 * 4; 483 IntRect dirty; 484 485 auto func = ReorientRow(Orientation()); 486 dirty = func(in_row0, 0, out, outSize, outStride); 487 EXPECT_EQ(dirty, IntRect(0, 0, 3, 1)); 488 dirty = func(in_row1, 1, out, outSize, outStride); 489 EXPECT_EQ(dirty, IntRect(0, 1, 3, 1)); 490 dirty = func(in_row2, 2, out, outSize, outStride); 491 EXPECT_EQ(dirty, IntRect(0, 2, 3, 1)); 492 dirty = func(in_row3, 3, out, outSize, outStride); 493 EXPECT_EQ(dirty, IntRect(0, 3, 3, 1)); 494 495 // clang-format off 496 const uint8_t check_identity[3 * 4 * 4] = { 497 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 498 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 499 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 500 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 501 }; 502 // clang-format on 503 EXPECT_TRUE(ArrayEqual(out, check_identity)); 504 505 func = ReorientRow(Orientation(Angle::D90)); 506 dirty = func(in_row0, 0, out, outSizeSwap, outStrideSwap); 507 EXPECT_EQ(dirty, IntRect(3, 0, 1, 3)); 508 dirty = func(in_row1, 1, out, outSizeSwap, outStrideSwap); 509 EXPECT_EQ(dirty, IntRect(2, 0, 1, 3)); 510 dirty = func(in_row2, 2, out, outSizeSwap, outStrideSwap); 511 EXPECT_EQ(dirty, IntRect(1, 0, 1, 3)); 512 dirty = func(in_row3, 3, out, outSizeSwap, outStrideSwap); 513 EXPECT_EQ(dirty, IntRect(0, 0, 1, 3)); 514 515 // clang-format off 516 const uint8_t check_d90[3 * 4 * 4] = { 517 36, 37, 38, 39, 24, 25, 26, 27, 12, 13, 14, 15, 0, 1, 2, 3, 518 40, 41, 42, 43, 28, 29, 30, 31, 16, 17, 18, 19, 4, 5, 6, 7, 519 44, 45, 46, 47, 32, 33, 34, 35, 20, 21, 22, 23, 8, 9, 10, 11, 520 }; 521 // clang-format on 522 EXPECT_TRUE(ArrayEqual(out, check_d90)); 523 524 func = ReorientRow(Orientation(Angle::D180)); 525 dirty = func(in_row0, 0, out, outSize, outStride); 526 EXPECT_EQ(dirty, IntRect(0, 3, 3, 1)); 527 dirty = func(in_row1, 1, out, outSize, outStride); 528 EXPECT_EQ(dirty, IntRect(0, 2, 3, 1)); 529 dirty = func(in_row2, 2, out, outSize, outStride); 530 EXPECT_EQ(dirty, IntRect(0, 1, 3, 1)); 531 dirty = func(in_row3, 3, out, outSize, outStride); 532 EXPECT_EQ(dirty, IntRect(0, 0, 3, 1)); 533 534 // clang-format off 535 const uint8_t check_d180[3 * 4 * 4] = { 536 44, 45, 46, 47, 40, 41, 42, 43, 36, 37, 38, 39, 537 32, 33, 34, 35, 28, 29, 30, 31, 24, 25, 26, 27, 538 20, 21, 22, 23, 16, 17, 18, 19, 12, 13, 14, 15, 539 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 540 }; 541 // clang-format on 542 EXPECT_TRUE(ArrayEqual(out, check_d180)); 543 544 func = ReorientRow(Orientation(Angle::D270)); 545 dirty = func(in_row0, 0, out, outSizeSwap, outStrideSwap); 546 EXPECT_EQ(dirty, IntRect(0, 0, 1, 3)); 547 dirty = func(in_row1, 1, out, outSizeSwap, outStrideSwap); 548 EXPECT_EQ(dirty, IntRect(1, 0, 1, 3)); 549 dirty = func(in_row2, 2, out, outSizeSwap, outStrideSwap); 550 EXPECT_EQ(dirty, IntRect(2, 0, 1, 3)); 551 dirty = func(in_row3, 3, out, outSizeSwap, outStrideSwap); 552 EXPECT_EQ(dirty, IntRect(3, 0, 1, 3)); 553 554 // clang-format off 555 const uint8_t check_d270[3 * 4 * 4] = { 556 8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 557 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 558 0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 559 }; 560 // clang-format on 561 EXPECT_TRUE(ArrayEqual(out, check_d270)); 562 563 func = ReorientRow(Orientation(Angle::D0, Flip::Horizontal)); 564 dirty = func(in_row0, 0, out, outSize, outStride); 565 EXPECT_EQ(dirty, IntRect(0, 0, 3, 1)); 566 dirty = func(in_row1, 1, out, outSize, outStride); 567 EXPECT_EQ(dirty, IntRect(0, 1, 3, 1)); 568 dirty = func(in_row2, 2, out, outSize, outStride); 569 EXPECT_EQ(dirty, IntRect(0, 2, 3, 1)); 570 dirty = func(in_row3, 3, out, outSize, outStride); 571 EXPECT_EQ(dirty, IntRect(0, 3, 3, 1)); 572 573 // clang-format off 574 const uint8_t check_d0_flip[3 * 4 * 4] = { 575 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, 576 20, 21, 22, 23, 16, 17, 18, 19, 12, 13, 14, 15, 577 32, 33, 34, 35, 28, 29, 30, 31, 24, 25, 26, 27, 578 44, 45, 46, 47, 40, 41, 42, 43, 36, 37, 38, 39, 579 }; 580 // clang-format on 581 EXPECT_TRUE(ArrayEqual(out, check_d0_flip)); 582 583 func = ReorientRow(Orientation(Angle::D90, Flip::Horizontal)); 584 dirty = func(in_row0, 0, out, outSizeSwap, outStrideSwap); 585 EXPECT_EQ(dirty, IntRect(0, 0, 1, 3)); 586 dirty = func(in_row1, 1, out, outSizeSwap, outStrideSwap); 587 EXPECT_EQ(dirty, IntRect(1, 0, 1, 3)); 588 dirty = func(in_row2, 2, out, outSizeSwap, outStrideSwap); 589 EXPECT_EQ(dirty, IntRect(2, 0, 1, 3)); 590 dirty = func(in_row3, 3, out, outSizeSwap, outStrideSwap); 591 EXPECT_EQ(dirty, IntRect(3, 0, 1, 3)); 592 593 // clang-format off 594 const uint8_t check_d90_flip[3 * 4 * 4] = { 595 0, 1, 2, 3, 12, 13, 14, 15, 24, 25, 26, 27, 36, 37, 38, 39, 596 4, 5, 6, 7, 16, 17, 18, 19, 28, 29, 30, 31, 40, 41, 42, 43, 597 8, 9, 10, 11, 20, 21, 22, 23, 32, 33, 34, 35, 44, 45, 46, 47, 598 }; 599 // clang-format on 600 EXPECT_TRUE(ArrayEqual(out, check_d90_flip)); 601 602 func = ReorientRow(Orientation(Angle::D180, Flip::Horizontal)); 603 dirty = func(in_row0, 0, out, outSize, outStride); 604 EXPECT_EQ(dirty, IntRect(0, 3, 3, 1)); 605 dirty = func(in_row1, 1, out, outSize, outStride); 606 EXPECT_EQ(dirty, IntRect(0, 2, 3, 1)); 607 dirty = func(in_row2, 2, out, outSize, outStride); 608 EXPECT_EQ(dirty, IntRect(0, 1, 3, 1)); 609 dirty = func(in_row3, 3, out, outSize, outStride); 610 EXPECT_EQ(dirty, IntRect(0, 0, 3, 1)); 611 612 // clang-format off 613 const uint8_t check_d180_flip[3 * 4 * 4] = { 614 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 615 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 616 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 617 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 618 }; 619 // clang-format on 620 EXPECT_TRUE(ArrayEqual(out, check_d180_flip)); 621 622 func = ReorientRow(Orientation(Angle::D270, Flip::Horizontal)); 623 dirty = func(in_row0, 0, out, outSizeSwap, outStrideSwap); 624 EXPECT_EQ(dirty, IntRect(3, 0, 1, 3)); 625 dirty = func(in_row1, 1, out, outSizeSwap, outStrideSwap); 626 EXPECT_EQ(dirty, IntRect(2, 0, 1, 3)); 627 dirty = func(in_row2, 2, out, outSizeSwap, outStrideSwap); 628 EXPECT_EQ(dirty, IntRect(1, 0, 1, 3)); 629 dirty = func(in_row3, 3, out, outSizeSwap, outStrideSwap); 630 EXPECT_EQ(dirty, IntRect(0, 0, 1, 3)); 631 632 // clang-format off 633 const uint8_t check_d270_flip[3 * 4 * 4] = { 634 44, 45, 46, 47, 32, 33, 34, 35, 20, 21, 22, 23, 8, 9, 10, 11, 635 40, 41, 42, 43, 28, 29, 30, 31, 16, 17, 18, 19, 4, 5, 6, 7, 636 36, 37, 38, 39, 24, 25, 26, 27, 12, 13, 14, 15, 0, 1, 2, 3, 637 }; 638 // clang-format on 639 EXPECT_TRUE(ArrayEqual(out, check_d270_flip)); 640 641 func = ReorientRow( 642 Orientation(Angle::D0, Flip::Horizontal, /* aFlipFirst */ true)); 643 dirty = func(in_row0, 0, out, outSize, outStride); 644 EXPECT_EQ(dirty, IntRect(0, 0, 3, 1)); 645 dirty = func(in_row1, 1, out, outSize, outStride); 646 EXPECT_EQ(dirty, IntRect(0, 1, 3, 1)); 647 dirty = func(in_row2, 2, out, outSize, outStride); 648 EXPECT_EQ(dirty, IntRect(0, 2, 3, 1)); 649 dirty = func(in_row3, 3, out, outSize, outStride); 650 EXPECT_EQ(dirty, IntRect(0, 3, 3, 1)); 651 652 // No rotation, so flipping before and after are the same. 653 EXPECT_TRUE(ArrayEqual(out, check_d0_flip)); 654 655 func = ReorientRow( 656 Orientation(Angle::D90, Flip::Horizontal, /* aFlipFirst */ true)); 657 dirty = func(in_row0, 0, out, outSizeSwap, outStrideSwap); 658 EXPECT_EQ(dirty, IntRect(3, 0, 1, 3)); 659 dirty = func(in_row1, 1, out, outSizeSwap, outStrideSwap); 660 EXPECT_EQ(dirty, IntRect(2, 0, 1, 3)); 661 dirty = func(in_row2, 2, out, outSizeSwap, outStrideSwap); 662 EXPECT_EQ(dirty, IntRect(1, 0, 1, 3)); 663 dirty = func(in_row3, 3, out, outSizeSwap, outStrideSwap); 664 EXPECT_EQ(dirty, IntRect(0, 0, 1, 3)); 665 666 // Flip, rotate 90 degrees is the same as rotate 270 degrees, flip. 667 EXPECT_TRUE(ArrayEqual(out, check_d270_flip)); 668 669 func = ReorientRow( 670 Orientation(Angle::D180, Flip::Horizontal, /* aFlipFirst */ true)); 671 dirty = func(in_row0, 0, out, outSize, outStride); 672 EXPECT_EQ(dirty, IntRect(0, 3, 3, 1)); 673 dirty = func(in_row1, 1, out, outSize, outStride); 674 EXPECT_EQ(dirty, IntRect(0, 2, 3, 1)); 675 dirty = func(in_row2, 2, out, outSize, outStride); 676 EXPECT_EQ(dirty, IntRect(0, 1, 3, 1)); 677 dirty = func(in_row3, 3, out, outSize, outStride); 678 EXPECT_EQ(dirty, IntRect(0, 0, 3, 1)); 679 680 // Flip, rotate 180 degrees is the same as rotate 180 degrees, flip. 681 EXPECT_TRUE(ArrayEqual(out, check_d180_flip)); 682 683 func = ReorientRow( 684 Orientation(Angle::D270, Flip::Horizontal, /* aFlipFirst */ true)); 685 dirty = func(in_row0, 0, out, outSizeSwap, outStrideSwap); 686 EXPECT_EQ(dirty, IntRect(0, 0, 1, 3)); 687 dirty = func(in_row1, 1, out, outSizeSwap, outStrideSwap); 688 EXPECT_EQ(dirty, IntRect(1, 0, 1, 3)); 689 dirty = func(in_row2, 2, out, outSizeSwap, outStrideSwap); 690 EXPECT_EQ(dirty, IntRect(2, 0, 1, 3)); 691 dirty = func(in_row3, 3, out, outSizeSwap, outStrideSwap); 692 EXPECT_EQ(dirty, IntRect(3, 0, 1, 3)); 693 694 // Flip, rotate 270 degrees is the same as rotate 90 degrees, flip. 695 EXPECT_TRUE(ArrayEqual(out, check_d90_flip)); 696 }