History

avcodec/tests/mjpegenc_huffman: Also test length counts

This is better than just testing that the tree is not overdetermined.

Andreas Rheinhardt committed 1 year ago

Commit c8ce9de1 parent 76842431 file · +37 −11Browse files

Showing the changes to libavcodec (1 of 1 file). Show all

Unified · Split

libavcodec/tests/mjpegenc_huffman.c+37−11
@@ -31,15 +31,16 @@ · 30 unmodified lines
31#include "libavcodec/mjpegenc_huffman.c"31#include "libavcodec/mjpegenc_huffman.c"
32 32
33// Validate the computed lengths satisfy the JPEG restrictions and is optimal.33// Validate the computed lengths satisfy the JPEG restrictions and is optimal.
34static int check_lengths(int L, int expected_length,34static int check_lengths(int L, const int *probs, int nprobs,
35 const int *probs, int nprobs)35 int expected_length, const uint8_t expected_len_counts[/* L + 1 */])
36{36{
37 HuffTable lengths[256];37 HuffTable lengths[256];
38 PTable val_counts[256];38 PTable val_counts[256];
39 uint8_t len_counts[17] = { 0 };
39 int actual_length = 0, i, j, k, prob, length;40 int actual_length = 0, i, j, k, prob, length;
40 int ret = 0;41 int ret = 0;
41 double cantor_measure = 0;
42 av_assert0(nprobs <= 256);42 av_assert0(nprobs <= 256);
43 av_assert0(L < FF_ARRAY_ELEMS(len_counts));
43 44
44 for (i = 0; i < nprobs; i++) {45 for (i = 0; i < nprobs; i++) {
45 val_counts[i] = (PTable){.value = i, .prob = probs[i]};46 val_counts[i] = (PTable){.value = i, .prob = probs[i]};
@@ -47,6 +48,26 @@ static int check_lengths(int L, int expected_length, · 1 unmodified line
47 48
48 mjpegenc_huffman_compute_bits(val_counts, lengths, nprobs, L);49 mjpegenc_huffman_compute_bits(val_counts, lengths, nprobs, L);
49 50
51 for (int i = 0; i < nprobs; ++i) {
52 if (lengths[i].length > L) {
53 fprintf(stderr,
54 "Len %d of element %d of Huffman table with %d elements exceeds max length %d\n",
55 lengths[i].length, i, nprobs, L);
56 return 1;
57 }
58 len_counts[lengths[i].length]++;
59 }
60 // Test that the lengths can be made part of a complete, prefix-free tree:
61 unsigned code = 0;
62 for (int i = 1; i <= L; ++i) {
63 code <<= 1;
64 code += len_counts[i];
65 }
66 if (code > 1U << L) {
67 fprintf(stderr, "Huffman tree overdetermined/invalid\n");
68 ret = 1;
69 }
70
50 for (i = 0; i < nprobs; i++) {71 for (i = 0; i < nprobs; i++) {
51 // Find the value's prob and length72 // Find the value's prob and length
52 for (j = 0; j < nprobs; j++)73 for (j = 0; j < nprobs; j++)
@@ -59,22 +80,18 @@ static int check_lengths(int L, int expected_length, · 6 unmodified lines
59 80
60 if (prob) {81 if (prob) {
61 actual_length += prob * length;82 actual_length += prob * length;
62 cantor_measure += 1. / (1 << length);
63 }83 }
64 84
65 if (length > L || length < 1) return 1;85 if (length > L || length < 1) return 1;
66 }86 }
67 // Check that the codes can be prefix-free.
68 if (cantor_measure > 1) ret = 1;
69 // Check that the total length is optimal87 // Check that the total length is optimal
70 if (actual_length != expected_length) ret = 1;88 if (actual_length != expected_length) ret = 1;
71 89
72 if (ret == 1) {90 if (ret == 1) {
73 fprintf(stderr,91 fprintf(stderr,
74 "Cantor measure: %f\n"
75 "Actual length: %d\n"92 "Actual length: %d\n"
76 "Expected length: %d\n",93 "Expected length: %d\n",
77 cantor_measure, actual_length, expected_length);94 actual_length, expected_length);
78 }95 }
79 96
80 return ret;97 return ret;
@@ -83,6 +100,9 @@ static int check_lengths(int L, int expected_length, · 2 unmodified lines
83static const int probs_zeroes[] = {100static const int probs_zeroes[] = {
84 6, 6, 0, 0, 0101 6, 6, 0, 0, 0
85};102};
103static const uint8_t len_counts_zeroes[] = {
104 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
105};
86 106
87static const int probs_skewed[] = {107static const int probs_skewed[] = {
88 2, 0, 0, 0, 0, 1, 0, 0, 20, 0, 2, 0, 10, 5, 1, 1, 9, 1, 1, 6, 0, 5, 0, 1, 0, 7, 6,108 2, 0, 0, 0, 0, 1, 0, 0, 20, 0, 2, 0, 10, 5, 1, 1, 9, 1, 1, 6, 0, 5, 0, 1, 0, 7, 6,
@@ -96,6 +116,9 @@ static const int probs_skewed[] = { · 7 unmodified lines
96 0, 3, 0, 0, 28, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 23, 0, 0, 0, 0,116 0, 3, 0, 0, 28, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 23, 0, 0, 0, 0,
97 0, 21, 1, 0, 3, 24, 2, 0, 0, 7, 0, 0, 1, 5, 1, 2, 0, 5117 0, 21, 1, 0, 3, 24, 2, 0, 0, 7, 0, 0, 1, 5, 1, 2, 0, 5
98};118};
119static const uint8_t len_counts_skewed[] = {
120 0, 1, 0, 0, 1, 2, 7, 11, 18, 31, 28, 40, 0, 1, 0, 0, 116,
121};
99 122
100static const int probs_sat[] = {123static const int probs_sat[] = {
101 74, 8, 14, 7, 9345, 40, 0, 2014, 2, 1, 115, 0, 2, 1, 194, 388, 20, 0, 0, 2, 1, 121,124 74, 8, 14, 7, 9345, 40, 0, 2014, 2, 1, 115, 0, 2, 1, 194, 388, 20, 0, 0, 2, 1, 121,
@@ -110,6 +133,9 @@ static const int probs_sat[] = { · 8 unmodified lines
110 0, 1085, 0, 0, 0, 3, 489, 36, 1, 0, 1, 9420, 294, 28, 0, 57, 5, 0, 9, 2, 0, 1, 2,133 0, 1085, 0, 0, 0, 3, 489, 36, 1, 0, 1, 9420, 294, 28, 0, 57, 5, 0, 9, 2, 0, 1, 2,
111 2, 0, 0, 9, 2, 29, 2, 2, 7, 0, 5, 490, 0, 7, 5, 0, 1, 8, 0, 0, 23255, 0, 1134 2, 0, 0, 9, 2, 29, 2, 2, 7, 0, 5, 490, 0, 7, 5, 0, 1, 8, 0, 0, 23255, 0, 1
112};135};
136static const uint8_t len_counts_sat[] = {
137 0, 1, 0, 2, 1, 2, 2, 5, 5, 7, 7, 8, 17, 23, 16, 24, 136,
138};
113 139
114// Test the example given on @see140// Test the example given on @see
115// http://guru.multimedia.cx/small-tasks-for-ffmpeg/141// http://guru.multimedia.cx/small-tasks-for-ffmpeg/
@@ -154,13 +180,13 @@ int main(int argc, char **argv) · 38 unmodified lines
154 }180 }
155 181
156 // Check handling of zero probabilities182 // Check handling of zero probabilities
157 if (check_lengths(16, 18, probs_zeroes, FF_ARRAY_ELEMS(probs_zeroes)))183 if (check_lengths(16, probs_zeroes, FF_ARRAY_ELEMS(probs_zeroes), 18, len_counts_zeroes))
158 ret = 1;184 ret = 1;
159 // Check skewed distribution over 256 without saturated lengths185 // Check skewed distribution over 256 without saturated lengths
160 if (check_lengths(16, 41282, probs_skewed, FF_ARRAY_ELEMS(probs_skewed)))186 if (check_lengths(16, probs_skewed, FF_ARRAY_ELEMS(probs_skewed), 41282, len_counts_skewed))
161 ret = 1;187 ret = 1;
162 // Check skewed distribution over 256 with saturated lengths188 // Check skewed distribution over 256 with saturated lengths
163 if (check_lengths(16, 669904, probs_sat, FF_ARRAY_ELEMS(probs_sat)))189 if (check_lengths(16, probs_sat, FF_ARRAY_ELEMS(probs_sat), 669904, len_counts_sat))
164 ret = 1;190 ret = 1;
165 191
166 return ret;192 return ret;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t