Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
lzw_decompressor_unittest.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "core/fxcodec/gif/lzw_decompressor.h"
6
7#include <stdint.h>
8#include <string.h>
9
10#include <array>
11#include <iterator>
12
13#include "core/fxcrt/compiler_specific.h"
14#include "core/fxcrt/data_vector.h"
15#include "core/fxcrt/stl_util.h"
16#include "testing/gmock/include/gmock/gmock.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19using ::testing::Each;
20using ::testing::ElementsAre;
21using ::testing::ElementsAreArray;
22
24 EXPECT_FALSE(LZWDecompressor::Create(0x10, 0x02));
25 EXPECT_FALSE(LZWDecompressor::Create(0x04, 0x0F));
26 EXPECT_FALSE(LZWDecompressor::Create(0x02, 0x02));
27}
28
30 uint8_t palette_exp = 0x1;
31 uint8_t code_exp = 0x2;
32 auto decompressor = LZWDecompressor::Create(palette_exp, code_exp);
33 ASSERT_NE(nullptr, decompressor);
34
35 // Check that 0 length extract does nothing
36 {
37 DataVector<uint8_t>* decompressed = decompressor->DecompressedForTest();
38 *decompressed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
39 *(decompressor->DecompressedNextForTest()) = decompressed->size();
40 uint8_t dest_buf[20];
41 fxcrt::Fill(dest_buf, 0xff);
42 EXPECT_EQ(0u, decompressor->ExtractDataForTest(
43 pdfium::make_span(dest_buf).first(0u)));
44 EXPECT_THAT(dest_buf, Each(static_cast<uint8_t>(-1)));
45 EXPECT_EQ(10u, *(decompressor->DecompressedNextForTest()));
46 for (size_t i = 0; i < *(decompressor->DecompressedNextForTest()); ++i) {
47 EXPECT_EQ(i, (*decompressed)[i]);
48 }
49 }
50
51 // Check that less than decompressed size only gets the expected number
52 {
53 DataVector<uint8_t>* decompressed = decompressor->DecompressedForTest();
54 *decompressed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
55 *(decompressor->DecompressedNextForTest()) = decompressed->size();
56 std::array<uint8_t, 20> dest_buf;
57 fxcrt::Fill(dest_buf, 0xff);
58 EXPECT_EQ(5u, decompressor->ExtractDataForTest(
59 pdfium::make_span(dest_buf).first(5u)));
60 size_t i = 0;
61 for (; i < 5; ++i) {
62 EXPECT_EQ(9 - i, dest_buf[i]);
63 }
64 EXPECT_THAT(pdfium::span(dest_buf).first(5), ElementsAre(9, 8, 7, 6, 5));
65 EXPECT_THAT(pdfium::span(dest_buf).subspan(5),
66 Each(static_cast<uint8_t>(-1)));
67 EXPECT_EQ(5u, *(decompressor->DecompressedNextForTest()));
68 for (i = 0; i < *(decompressor->DecompressedNextForTest()); ++i) {
69 EXPECT_EQ(i, (*decompressed)[i]);
70 }
71 }
72
73 // Check that greater than decompressed size depletes the decompressor
74 {
75 DataVector<uint8_t>* decompressed = decompressor->DecompressedForTest();
76 *decompressed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
77 *(decompressor->DecompressedNextForTest()) = decompressed->size();
78 uint8_t dest_buf[20];
79 fxcrt::Fill(dest_buf, 0xff);
80 EXPECT_EQ(10u, decompressor->ExtractDataForTest(dest_buf));
81 EXPECT_THAT(pdfium::span(dest_buf).first(10),
82 ElementsAre(9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
83 EXPECT_THAT(pdfium::span(dest_buf).subspan(10),
84 Each(static_cast<uint8_t>(-1)));
85 EXPECT_EQ(0u, *(decompressor->DecompressedNextForTest()));
86 }
87}
88
90 uint8_t palette_exp = 0x0;
91 uint8_t code_exp = 0x2;
92 auto decompressor = LZWDecompressor::Create(palette_exp, code_exp);
93 ASSERT_NE(nullptr, decompressor);
94
95 uint8_t image_data[10];
96 uint8_t output_data[10];
97 uint32_t output_size = std::size(output_data);
98
99 decompressor->SetSource(pdfium::span<uint8_t>());
101 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
102
103 decompressor->SetSource(image_data);
105 UNSAFE_TODO(decompressor->Decode(nullptr, &output_size)));
107 UNSAFE_TODO(decompressor->Decode(output_data, nullptr)));
108
109 output_size = 0;
111 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
112}
113
115 uint8_t palette_exp = 0x0;
116 uint8_t code_exp = 0x2;
117 auto decompressor = LZWDecompressor::Create(palette_exp, code_exp);
118 ASSERT_NE(nullptr, decompressor);
119
120 uint8_t image_data[] = {0x44, 0x01};
121 uint8_t expected_data[] = {0x00};
122 uint8_t output_data[std::size(expected_data)] = {};
123 uint32_t output_size = std::size(output_data);
124
125 decompressor->SetSource(image_data);
127 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
128
129 EXPECT_EQ(std::size(output_data), output_size);
130 EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data)));
131}
132
134 uint8_t palette_exp = 0x0;
135 uint8_t code_exp = 0x2;
136 auto decompressor = LZWDecompressor::Create(palette_exp, code_exp);
137 ASSERT_NE(nullptr, decompressor);
138
139 static constexpr uint8_t kImageData[] = {0x84, 0x8F, 0xA9, 0xCB,
140 0xED, 0x0F, 0x63, 0x2B};
141 static constexpr uint8_t kExpectedData[] = {
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00};
151 uint8_t output_data[std::size(kExpectedData)] = {};
152 uint32_t output_size = std::size(output_data);
153
154 decompressor->SetSource(kImageData);
156 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
157
158 EXPECT_EQ(std::size(output_data), output_size);
159 EXPECT_TRUE(0 == memcmp(kExpectedData, output_data, sizeof(kExpectedData)));
160}
161
163 uint8_t palette_exp = 0x1;
164 uint8_t code_exp = 0x2;
165 auto decompressor = LZWDecompressor::Create(palette_exp, code_exp);
166 ASSERT_NE(nullptr, decompressor);
167
168 static constexpr uint8_t kImageData[] = {
169 0x8C, 0x2D, 0x99, 0x87, 0x2A, 0x1C, 0xDC, 0x33, 0xA0, 0x02, 0x75,
170 0xEC, 0x95, 0xFA, 0xA8, 0xDE, 0x60, 0x8C, 0x04, 0x91, 0x4C, 0x01};
171 static constexpr uint8_t kExpectedData[] = {
172 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
173 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
174 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
175 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
176 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
177 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
178 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
179 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
180 0x01, 0x01, 0x01, 0x01};
181 uint8_t output_data[std::size(kExpectedData)] = {};
182 uint32_t output_size = std::size(output_data);
183
184 decompressor->SetSource(kImageData);
186 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
187
188 EXPECT_EQ(std::size(output_data), output_size);
189 EXPECT_TRUE(0 == memcmp(kExpectedData, output_data, sizeof(kExpectedData)));
190}
191
193 auto decompressor = LZWDecompressor::Create(/*color_exp=*/0, /*code_exp=*/2);
194 ASSERT_NE(nullptr, decompressor);
195
196 static constexpr uint8_t kImageData[] = {0x84, 0x6f, 0x05};
197 decompressor->SetSource(kImageData);
198
199 static constexpr uint8_t kExpectedScanline[] = {0x00, 0x00, 0x00, 0x00};
200 uint8_t output_data[std::size(kExpectedScanline)];
201 fxcrt::Fill(output_data, 0xff);
202 uint32_t output_size = std::size(output_data);
204 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
205 EXPECT_EQ(std::size(kExpectedScanline), output_size);
206 EXPECT_THAT(output_data, ElementsAreArray(kExpectedScanline));
207
208 fxcrt::Fill(output_data, 0xff);
209 output_size = std::size(output_data);
211 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
212 EXPECT_EQ(std::size(kExpectedScanline), output_size);
213 EXPECT_THAT(output_data, ElementsAreArray(kExpectedScanline));
214}
215
217 uint8_t palette_exp = 0x2; // Image uses 10 colours, so the palette exp
218 // should be 3, 2^(3+1) = 16 colours.
219 uint8_t code_exp = 0x4;
220 auto decompressor = LZWDecompressor::Create(palette_exp, code_exp);
221 ASSERT_NE(nullptr, decompressor);
222
223 static constexpr uint8_t kImageData[] = {
224 0x30, 0xC9, 0x49, 0x81, 0xBD, 0x78, 0xE8, 0xCD, 0x89, 0xFF,
225 0x60, 0x20, 0x8E, 0xE4, 0x61, 0x9E, 0xA8, 0xA1, 0xAE, 0x2C,
226 0xE2, 0xBE, 0xB0, 0x20, 0xCF, 0x74, 0x61, 0xDF, 0x78, 0x04};
227
228 uint8_t output_data[100] = {}; // The uncompressed data is for a 10x10 image
229 uint32_t output_size = std::size(output_data);
230
231 decompressor->SetSource(kImageData);
233 UNSAFE_TODO(decompressor->Decode(output_data, &output_size)));
234}
#define UNSAFE_TODO(...)
fxcodec::LZWDecompressor LZWDecompressor
TEST(LZWDecompressor, CreateBadParams)