1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker
11*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <stddef.h>
13*fb1b10abSAndroid Build Coastguard Worker #include <stdio.h>
14*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
15*fb1b10abSAndroid Build Coastguard Worker #include <string.h>
16*fb1b10abSAndroid Build Coastguard Worker #include <sys/types.h>
17*fb1b10abSAndroid Build Coastguard Worker
18*fb1b10abSAndroid Build Coastguard Worker #include "gtest/gtest.h"
19*fb1b10abSAndroid Build Coastguard Worker
20*fb1b10abSAndroid Build Coastguard Worker #include "test/acm_random.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "vp8/decoder/dboolhuff.h"
22*fb1b10abSAndroid Build Coastguard Worker #include "vp8/encoder/boolhuff.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_integer.h"
24*fb1b10abSAndroid Build Coastguard Worker
25*fb1b10abSAndroid Build Coastguard Worker namespace {
26*fb1b10abSAndroid Build Coastguard Worker const int num_tests = 10;
27*fb1b10abSAndroid Build Coastguard Worker
28*fb1b10abSAndroid Build Coastguard Worker // In a real use the 'decrypt_state' parameter will be a pointer to a struct
29*fb1b10abSAndroid Build Coastguard Worker // with whatever internal state the decryptor uses. For testing we'll just
30*fb1b10abSAndroid Build Coastguard Worker // xor with a constant key, and decrypt_state will point to the start of
31*fb1b10abSAndroid Build Coastguard Worker // the original buffer.
32*fb1b10abSAndroid Build Coastguard Worker const uint8_t secret_key[16] = {
33*fb1b10abSAndroid Build Coastguard Worker 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
34*fb1b10abSAndroid Build Coastguard Worker 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0
35*fb1b10abSAndroid Build Coastguard Worker };
36*fb1b10abSAndroid Build Coastguard Worker
encrypt_buffer(uint8_t * buffer,size_t size)37*fb1b10abSAndroid Build Coastguard Worker void encrypt_buffer(uint8_t *buffer, size_t size) {
38*fb1b10abSAndroid Build Coastguard Worker for (size_t i = 0; i < size; ++i) {
39*fb1b10abSAndroid Build Coastguard Worker buffer[i] ^= secret_key[i & 15];
40*fb1b10abSAndroid Build Coastguard Worker }
41*fb1b10abSAndroid Build Coastguard Worker }
42*fb1b10abSAndroid Build Coastguard Worker
test_decrypt_cb(void * decrypt_state,const uint8_t * input,uint8_t * output,int count)43*fb1b10abSAndroid Build Coastguard Worker void test_decrypt_cb(void *decrypt_state, const uint8_t *input, uint8_t *output,
44*fb1b10abSAndroid Build Coastguard Worker int count) {
45*fb1b10abSAndroid Build Coastguard Worker const size_t offset = input - reinterpret_cast<uint8_t *>(decrypt_state);
46*fb1b10abSAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
47*fb1b10abSAndroid Build Coastguard Worker output[i] = input[i] ^ secret_key[(offset + i) & 15];
48*fb1b10abSAndroid Build Coastguard Worker }
49*fb1b10abSAndroid Build Coastguard Worker }
50*fb1b10abSAndroid Build Coastguard Worker
51*fb1b10abSAndroid Build Coastguard Worker } // namespace
52*fb1b10abSAndroid Build Coastguard Worker
53*fb1b10abSAndroid Build Coastguard Worker using libvpx_test::ACMRandom;
54*fb1b10abSAndroid Build Coastguard Worker
TEST(VP8,TestBitIO)55*fb1b10abSAndroid Build Coastguard Worker TEST(VP8, TestBitIO) {
56*fb1b10abSAndroid Build Coastguard Worker ACMRandom rnd(ACMRandom::DeterministicSeed());
57*fb1b10abSAndroid Build Coastguard Worker for (int n = 0; n < num_tests; ++n) {
58*fb1b10abSAndroid Build Coastguard Worker for (int method = 0; method <= 7; ++method) { // we generate various proba
59*fb1b10abSAndroid Build Coastguard Worker const int kBitsToTest = 1000;
60*fb1b10abSAndroid Build Coastguard Worker uint8_t probas[kBitsToTest];
61*fb1b10abSAndroid Build Coastguard Worker
62*fb1b10abSAndroid Build Coastguard Worker for (int i = 0; i < kBitsToTest; ++i) {
63*fb1b10abSAndroid Build Coastguard Worker const int parity = i & 1;
64*fb1b10abSAndroid Build Coastguard Worker /* clang-format off */
65*fb1b10abSAndroid Build Coastguard Worker probas[i] =
66*fb1b10abSAndroid Build Coastguard Worker (method == 0) ? 0 : (method == 1) ? 255 :
67*fb1b10abSAndroid Build Coastguard Worker (method == 2) ? 128 :
68*fb1b10abSAndroid Build Coastguard Worker (method == 3) ? rnd.Rand8() :
69*fb1b10abSAndroid Build Coastguard Worker (method == 4) ? (parity ? 0 : 255) :
70*fb1b10abSAndroid Build Coastguard Worker // alternate between low and high proba:
71*fb1b10abSAndroid Build Coastguard Worker (method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) :
72*fb1b10abSAndroid Build Coastguard Worker (method == 6) ?
73*fb1b10abSAndroid Build Coastguard Worker (parity ? rnd(64) : 255 - rnd(64)) :
74*fb1b10abSAndroid Build Coastguard Worker (parity ? rnd(32) : 255 - rnd(32));
75*fb1b10abSAndroid Build Coastguard Worker /* clang-format on */
76*fb1b10abSAndroid Build Coastguard Worker }
77*fb1b10abSAndroid Build Coastguard Worker for (int bit_method = 0; bit_method <= 3; ++bit_method) {
78*fb1b10abSAndroid Build Coastguard Worker const int random_seed = 6432;
79*fb1b10abSAndroid Build Coastguard Worker const int kBufferSize = 10000;
80*fb1b10abSAndroid Build Coastguard Worker ACMRandom bit_rnd(random_seed);
81*fb1b10abSAndroid Build Coastguard Worker BOOL_CODER bw;
82*fb1b10abSAndroid Build Coastguard Worker uint8_t bw_buffer[kBufferSize];
83*fb1b10abSAndroid Build Coastguard Worker vp8_start_encode(&bw, bw_buffer, bw_buffer + kBufferSize);
84*fb1b10abSAndroid Build Coastguard Worker
85*fb1b10abSAndroid Build Coastguard Worker int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0;
86*fb1b10abSAndroid Build Coastguard Worker for (int i = 0; i < kBitsToTest; ++i) {
87*fb1b10abSAndroid Build Coastguard Worker if (bit_method == 2) {
88*fb1b10abSAndroid Build Coastguard Worker bit = (i & 1);
89*fb1b10abSAndroid Build Coastguard Worker } else if (bit_method == 3) {
90*fb1b10abSAndroid Build Coastguard Worker bit = bit_rnd(2);
91*fb1b10abSAndroid Build Coastguard Worker }
92*fb1b10abSAndroid Build Coastguard Worker vp8_encode_bool(&bw, bit, static_cast<int>(probas[i]));
93*fb1b10abSAndroid Build Coastguard Worker }
94*fb1b10abSAndroid Build Coastguard Worker
95*fb1b10abSAndroid Build Coastguard Worker vp8_stop_encode(&bw);
96*fb1b10abSAndroid Build Coastguard Worker // vp8dx_bool_decoder_fill() may read into uninitialized data that
97*fb1b10abSAndroid Build Coastguard Worker // isn't used meaningfully, but may trigger an MSan warning.
98*fb1b10abSAndroid Build Coastguard Worker memset(bw_buffer + bw.pos, 0, sizeof(VP8_BD_VALUE) - 1);
99*fb1b10abSAndroid Build Coastguard Worker
100*fb1b10abSAndroid Build Coastguard Worker BOOL_DECODER br;
101*fb1b10abSAndroid Build Coastguard Worker encrypt_buffer(bw_buffer, kBufferSize);
102*fb1b10abSAndroid Build Coastguard Worker vp8dx_start_decode(&br, bw_buffer, kBufferSize, test_decrypt_cb,
103*fb1b10abSAndroid Build Coastguard Worker reinterpret_cast<void *>(bw_buffer));
104*fb1b10abSAndroid Build Coastguard Worker bit_rnd.Reset(random_seed);
105*fb1b10abSAndroid Build Coastguard Worker for (int i = 0; i < kBitsToTest; ++i) {
106*fb1b10abSAndroid Build Coastguard Worker if (bit_method == 2) {
107*fb1b10abSAndroid Build Coastguard Worker bit = (i & 1);
108*fb1b10abSAndroid Build Coastguard Worker } else if (bit_method == 3) {
109*fb1b10abSAndroid Build Coastguard Worker bit = bit_rnd(2);
110*fb1b10abSAndroid Build Coastguard Worker }
111*fb1b10abSAndroid Build Coastguard Worker GTEST_ASSERT_EQ(vp8dx_decode_bool(&br, probas[i]), bit)
112*fb1b10abSAndroid Build Coastguard Worker << "pos: " << i << " / " << kBitsToTest
113*fb1b10abSAndroid Build Coastguard Worker << " bit_method: " << bit_method << " method: " << method;
114*fb1b10abSAndroid Build Coastguard Worker }
115*fb1b10abSAndroid Build Coastguard Worker }
116*fb1b10abSAndroid Build Coastguard Worker }
117*fb1b10abSAndroid Build Coastguard Worker }
118*fb1b10abSAndroid Build Coastguard Worker }
119