1 // Copyright 2020 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "tests/block_utils.h"
16
17 #include <algorithm>
18 #include <cstdint>
19 #include <cstdio>
20 #include <cstring>
21
22 namespace libgav1 {
23 namespace test_utils {
24 namespace {
25
26 #define LIBGAV1_DEBUG_FORMAT_CODE "x"
27 template <typename Pixel>
PrintBlockDiff(const Pixel * block1,const Pixel * block2,int width,int height,int stride1,int stride2,const bool print_padding)28 void PrintBlockDiff(const Pixel* block1, const Pixel* block2, int width,
29 int height, int stride1, int stride2,
30 const bool print_padding) {
31 const int print_width = print_padding ? std::min(stride1, stride2) : width;
32 const int field_width = (sizeof(Pixel) == 1) ? 4 : 5;
33
34 for (int y = 0; y < height; ++y) {
35 printf("[%2d] ", y);
36 for (int x = 0; x < print_width; ++x) {
37 if (x >= width) {
38 if (block1[x] == block2[x]) {
39 printf("[%*" LIBGAV1_DEBUG_FORMAT_CODE "] ", field_width, block1[x]);
40 } else {
41 printf("[*%*" LIBGAV1_DEBUG_FORMAT_CODE "] ", field_width - 1,
42 block1[x]);
43 }
44 } else {
45 if (block1[x] == block2[x]) {
46 printf("%*" LIBGAV1_DEBUG_FORMAT_CODE " ", field_width, block1[x]);
47 } else {
48 printf("*%*" LIBGAV1_DEBUG_FORMAT_CODE " ", field_width - 1,
49 block1[x]);
50 }
51 }
52 }
53 printf("\n");
54 block1 += stride1;
55 block2 += stride2;
56 }
57 }
58
59 } // namespace
60
61 template <typename Pixel>
PrintBlock(const Pixel * block,int width,int height,int stride,const bool print_padding)62 void PrintBlock(const Pixel* block, int width, int height, int stride,
63 const bool print_padding /*= false*/) {
64 const int print_width = print_padding ? stride : width;
65 const int field_width = (sizeof(Pixel) == 1) ? 4 : 5;
66 for (int y = 0; y < height; ++y) {
67 printf("[%2d] ", y);
68 for (int x = 0; x < print_width; ++x) {
69 if (x >= width) {
70 printf("[%*" LIBGAV1_DEBUG_FORMAT_CODE "] ", field_width, block[x]);
71 } else {
72 printf("%*" LIBGAV1_DEBUG_FORMAT_CODE " ", field_width, block[x]);
73 }
74 }
75 printf("\n");
76 block += stride;
77 }
78 }
79 #undef LIBGAV1_DEBUG_FORMAT_CODE
80
81 template void PrintBlock(const uint8_t* block, int width, int height,
82 int stride, bool print_padding /*= false*/);
83 template void PrintBlock(const uint16_t* block, int width, int height,
84 int stride, bool print_padding /*= false*/);
85 template void PrintBlock(const int8_t* block, int width, int height, int stride,
86 bool print_padding /*= false*/);
87 template void PrintBlock(const int16_t* block, int width, int height,
88 int stride, bool print_padding /*= false*/);
89
90 template <typename Pixel>
CompareBlocks(const Pixel * block1,const Pixel * block2,int width,int height,int stride1,int stride2,const bool check_padding,const bool print_diff)91 bool CompareBlocks(const Pixel* block1, const Pixel* block2, int width,
92 int height, int stride1, int stride2,
93 const bool check_padding, const bool print_diff /*= true*/) {
94 bool ok = true;
95 const int check_width = check_padding ? std::min(stride1, stride2) : width;
96 for (int y = 0; y < height; ++y) {
97 const uint64_t row1 = static_cast<uint64_t>(y) * stride1;
98 const uint64_t row2 = static_cast<uint64_t>(y) * stride2;
99 ok = memcmp(block1 + row1, block2 + row2,
100 sizeof(block1[0]) * check_width) == 0;
101 if (!ok) break;
102 }
103 if (!ok && print_diff) {
104 printf("block1 (width: %d height: %d stride: %d):\n", width, height,
105 stride1);
106 PrintBlockDiff(block1, block2, width, height, stride1, stride2,
107 check_padding);
108 printf("\nblock2 (width: %d height: %d stride: %d):\n", width, height,
109 stride2);
110 PrintBlockDiff(block2, block1, width, height, stride2, stride1,
111 check_padding);
112 }
113 return ok;
114 }
115
116 template bool CompareBlocks(const uint8_t* block1, const uint8_t* block2,
117 int width, int height, int stride1, int stride2,
118 const bool check_padding,
119 const bool print_diff /*= true*/);
120 template bool CompareBlocks(const uint16_t* block1, const uint16_t* block2,
121 int width, int height, int stride1, int stride2,
122 const bool check_padding,
123 const bool print_diff /*= true*/);
124 template bool CompareBlocks(const int8_t* block1, const int8_t* block2,
125 int width, int height, int stride1, int stride2,
126 const bool check_padding,
127 const bool print_diff /*= true*/);
128 template bool CompareBlocks(const int16_t* block1, const int16_t* block2,
129 int width, int height, int stride1, int stride2,
130 const bool check_padding,
131 const bool print_diff /*= true*/);
132
133 } // namespace test_utils
134 } // namespace libgav1
135