1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// Copyright (c) Team CharLS.
// SPDX-License-Identifier: BSD-3-Clause
#include "bitstreamdamage.h"
#include "util.h"
#include <iostream>
#include <random>
#include <vector>
using charls::jpegls_decoder;
using charls::jpegls_errc;
using charls::jpegls_error;
using std::cout;
using std::error_code;
using std::mt19937;
using std::uniform_int_distribution;
using std::vector;
namespace {
void test_damaged_bit_stream1()
{
const vector<uint8_t> encoded_buffer{read_file("test/incorrect_images/InfiniteLoopFFMPEG.jls")};
vector<uint8_t> destination(size_t{256} * 256 * 2);
error_code error;
try
{
jpegls_decoder::decode(encoded_buffer, destination);
}
catch (const jpegls_error& e)
{
error = e.code();
}
assert::is_true(error == jpegls_errc::invalid_encoded_data);
}
void test_damaged_bit_stream2()
{
vector<uint8_t> encoded_buffer{read_file("test/tulips-gray-8bit-512-512-hp-encoder.jls")};
encoded_buffer.resize(900);
encoded_buffer.resize(40000, 3);
vector<uint8_t> destination(size_t{512} * 512);
error_code error;
try
{
jpegls_decoder::decode(encoded_buffer, destination);
}
catch (const jpegls_error& e)
{
error = e.code();
}
assert::is_true(error == jpegls_errc::invalid_encoded_data);
}
void test_damaged_bit_stream3()
{
vector<uint8_t> encoded_buffer{read_file("test/tulips-gray-8bit-512-512-hp-encoder.jls")};
encoded_buffer[300] = 0xFF;
encoded_buffer[301] = 0xFF;
vector<uint8_t> destination(size_t{512} * 512);
error_code error;
try
{
jpegls_decoder::decode(encoded_buffer, destination);
}
catch (const jpegls_error& e)
{
error = e.code();
}
assert::is_true(error == jpegls_errc::invalid_encoded_data);
}
void test_file_with_random_header_damage(const char* filename)
{
const vector<uint8_t> encoded_buffer_original{read_file(filename)};
mt19937 generator(102347325);
MSVC_WARNING_SUPPRESS_NEXT_LINE(26496) // cannot be marked as const as operator() is not always defined const.
uniform_int_distribution<uint32_t> distribution(0, 255);
vector<uint8_t> destination(size_t{512} * 512);
for (size_t i{}; i != 40; ++i)
{
vector<uint8_t> encoded_buffer(encoded_buffer_original);
vector<int> errors(10, 0);
for (int j{}; j != 20; ++j)
{
encoded_buffer[i] = static_cast<uint8_t>(distribution(generator));
encoded_buffer[i + 1] = static_cast<uint8_t>(distribution(generator));
encoded_buffer[i + 2] = static_cast<uint8_t>(distribution(generator));
encoded_buffer[i + 3] = static_cast<uint8_t>(distribution(generator));
error_code error;
try
{
jpegls_decoder::decode(encoded_buffer, destination);
}
catch (const jpegls_error& e)
{
error = e.code();
}
errors[static_cast<size_t>(error.value())]++;
}
cout << "With garbage input at index " << i << ": ";
for (size_t error{}; error != errors.size(); ++error)
{
if (errors[error] == 0)
continue;
cout << errors[error] << "x error (" << error << "); ";
}
cout << "\r\n";
}
}
void test_random_malformed_header()
{
test_file_with_random_header_damage("test/conformance/t8c0e0.jls");
test_file_with_random_header_damage("test/conformance/t8c1e0.jls");
test_file_with_random_header_damage("test/conformance/t8c2e0.jls");
}
} // namespace
void damaged_bit_stream_tests()
{
cout << "Test Damaged bit stream\r\n";
test_damaged_bit_stream1();
test_damaged_bit_stream2();
test_damaged_bit_stream3();
cout << "Begin random malformed bit stream tests:\n";
test_random_malformed_header();
cout << "End random malformed bit stream tests:\n";
}
|