blob: e31fb783d6a87deaa6f42e883e3bc2f70a3cc376 [file] [log] [blame]
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -07001// Copyright 2017 PDFium Authors. All rights reserved.
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/cfx_lzwdecompressor.h"
6
7#include "core/fxcrt/fx_memory.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10TEST(CFX_LZWDecompressor, CreateBadParams) {
11 EXPECT_EQ(nullptr, CFX_LZWDecompressor::Create(0x10, 0x02));
12 EXPECT_EQ(nullptr, CFX_LZWDecompressor::Create(0x04, 0x0F));
13 EXPECT_EQ(nullptr, CFX_LZWDecompressor::Create(0x02, 0x02));
14}
15
16TEST(CFX_LZWDecompressor, ExtractData) {
17 uint8_t palette_exp = 0x1;
18 uint8_t code_exp = 0x2;
19 auto decompressor = CFX_LZWDecompressor::Create(palette_exp, code_exp);
20 ASSERT_NE(nullptr, decompressor);
21
22 // Check that 0 length extract does nothing
23 {
24 std::vector<uint8_t>* decompressed = decompressor->DecompressedForTest();
25 *decompressed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
26 *(decompressor->DecompressedNextForTest()) = decompressed->size();
Haibo Huang49cc9302020-04-27 16:14:24 -070027 uint8_t dest_buf[20];
28 memset(dest_buf, static_cast<uint8_t>(-1), sizeof(dest_buf));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070029
Haibo Huang49cc9302020-04-27 16:14:24 -070030 EXPECT_EQ(0u, decompressor->ExtractDataForTest(dest_buf, 0));
31 for (size_t i = 0; i < FX_ArraySize(dest_buf); ++i)
32 EXPECT_EQ(static_cast<uint8_t>(-1), dest_buf[i]);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070033
34 EXPECT_EQ(10u, *(decompressor->DecompressedNextForTest()));
35 for (size_t i = 0; i < *(decompressor->DecompressedNextForTest()); ++i)
Haibo Huang49cc9302020-04-27 16:14:24 -070036 EXPECT_EQ(i, (*decompressed)[i]);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070037 }
38
39 // Check that less than decompressed size only gets the expected number
40 {
41 std::vector<uint8_t>* decompressed = decompressor->DecompressedForTest();
42 *decompressed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
43 *(decompressor->DecompressedNextForTest()) = decompressed->size();
Haibo Huang49cc9302020-04-27 16:14:24 -070044 uint8_t dest_buf[20];
45 memset(dest_buf, static_cast<uint8_t>(-1), sizeof(dest_buf));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070046
Haibo Huang49cc9302020-04-27 16:14:24 -070047 EXPECT_EQ(5u, decompressor->ExtractDataForTest(dest_buf, 5));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070048 size_t i = 0;
49 for (; i < 5; ++i)
Haibo Huang49cc9302020-04-27 16:14:24 -070050 EXPECT_EQ(9 - i, dest_buf[i]);
51 for (; i < FX_ArraySize(dest_buf); ++i)
52 EXPECT_EQ(static_cast<uint8_t>(-1), dest_buf[i]);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070053
54 EXPECT_EQ(5u, *(decompressor->DecompressedNextForTest()));
55 for (i = 0; i < *(decompressor->DecompressedNextForTest()); ++i)
Haibo Huang49cc9302020-04-27 16:14:24 -070056 EXPECT_EQ(i, (*decompressed)[i]);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070057 }
58
59 // Check that greater than decompressed size depletes the decompressor
60 {
61 std::vector<uint8_t>* decompressed = decompressor->DecompressedForTest();
62 *decompressed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
63 *(decompressor->DecompressedNextForTest()) = decompressed->size();
Haibo Huang49cc9302020-04-27 16:14:24 -070064 uint8_t dest_buf[20];
65 memset(dest_buf, static_cast<uint8_t>(-1), sizeof(dest_buf));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070066
Haibo Huang49cc9302020-04-27 16:14:24 -070067 EXPECT_EQ(10u, decompressor->ExtractDataForTest(dest_buf,
68 FX_ArraySize(dest_buf)));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070069 size_t i = 0;
70 for (; i < 10; ++i)
Haibo Huang49cc9302020-04-27 16:14:24 -070071 EXPECT_EQ(9 - i, dest_buf[i]);
72 for (; i < FX_ArraySize(dest_buf); ++i)
73 EXPECT_EQ(static_cast<uint8_t>(-1), dest_buf[i]);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070074
75 EXPECT_EQ(0u, *(decompressor->DecompressedNextForTest()));
76 }
77}
78
79TEST(CFX_LZWDecompressor, DecodeBadParams) {
80 uint8_t palette_exp = 0x0;
81 uint8_t code_exp = 0x2;
82 auto decompressor = CFX_LZWDecompressor::Create(palette_exp, code_exp);
83 ASSERT_NE(nullptr, decompressor);
84
85 uint8_t image_data[10];
86 uint32_t image_size = FX_ArraySize(image_data);
87
88 uint8_t output_data[10];
89 uint32_t output_size = FX_ArraySize(output_data);
90
91 EXPECT_EQ(
92 CFX_GifDecodeStatus::Error,
93 decompressor->Decode(nullptr, image_size, output_data, &output_size));
94 EXPECT_EQ(CFX_GifDecodeStatus::Error,
95 decompressor->Decode(image_data, 0, output_data, &output_size));
96 EXPECT_EQ(
97 CFX_GifDecodeStatus::Error,
98 decompressor->Decode(image_data, image_size, nullptr, &output_size));
99 EXPECT_EQ(CFX_GifDecodeStatus::Error,
100 decompressor->Decode(image_data, image_size, output_data, nullptr));
101
102 output_size = 0;
103 EXPECT_EQ(
104 CFX_GifDecodeStatus::InsufficientDestSize,
105 decompressor->Decode(image_data, image_size, output_data, &output_size));
106}
107
108TEST(CFX_LZWDecompressor, Decode1x1SingleColour) {
109 uint8_t palette_exp = 0x0;
110 uint8_t code_exp = 0x2;
111 auto decompressor = CFX_LZWDecompressor::Create(palette_exp, code_exp);
112 ASSERT_NE(nullptr, decompressor);
113
114 uint8_t image_data[] = {0x44, 0x01};
115 uint32_t image_size = FX_ArraySize(image_data);
116
117 uint8_t expected_data[] = {0x00};
118 uint8_t output_data[FX_ArraySize(expected_data)];
119 memset(output_data, 0, sizeof(output_data));
120 uint32_t output_size = FX_ArraySize(output_data);
121
122 EXPECT_EQ(
123 CFX_GifDecodeStatus::Success,
124 decompressor->Decode(image_data, image_size, output_data, &output_size));
125
126 EXPECT_EQ(FX_ArraySize(output_data), output_size);
127 EXPECT_TRUE(0 == memcmp(expected_data, output_data, sizeof(expected_data)));
128}
129
130TEST(CFX_LZWDecompressor, Decode10x10SingleColour) {
131 uint8_t palette_exp = 0x0;
132 uint8_t code_exp = 0x2;
133 auto decompressor = CFX_LZWDecompressor::Create(palette_exp, code_exp);
134 ASSERT_NE(nullptr, decompressor);
135
Haibo Huang49cc9302020-04-27 16:14:24 -0700136 static constexpr uint8_t kImageData[] = {0x84, 0x8F, 0xA9, 0xCB,
137 0xED, 0x0F, 0x63, 0x2B};
138 uint32_t image_size = FX_ArraySize(kImageData);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700139
Haibo Huang49cc9302020-04-27 16:14:24 -0700140 static constexpr uint8_t kExpectedData[] = {
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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};
150 uint8_t output_data[FX_ArraySize(kExpectedData)];
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700151 memset(output_data, 0, sizeof(output_data));
152 uint32_t output_size = FX_ArraySize(output_data);
153
154 EXPECT_EQ(
155 CFX_GifDecodeStatus::Success,
Haibo Huang49cc9302020-04-27 16:14:24 -0700156 decompressor->Decode(kImageData, image_size, output_data, &output_size));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700157
158 EXPECT_EQ(FX_ArraySize(output_data), output_size);
Haibo Huang49cc9302020-04-27 16:14:24 -0700159 EXPECT_TRUE(0 == memcmp(kExpectedData, output_data, sizeof(kExpectedData)));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700160}
161
162TEST(CFX_LZWDecompressor, Decode10x10MultipleColour) {
163 uint8_t palette_exp = 0x1;
164 uint8_t code_exp = 0x2;
165 auto decompressor = CFX_LZWDecompressor::Create(palette_exp, code_exp);
166 ASSERT_NE(nullptr, decompressor);
167
Haibo Huang49cc9302020-04-27 16:14:24 -0700168 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 uint32_t image_size = FX_ArraySize(kImageData);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700172
Haibo Huang49cc9302020-04-27 16:14:24 -0700173 static constexpr uint8_t kExpectedData[] = {
174 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
175 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
176 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
177 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
178 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
179 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
180 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
181 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
182 0x01, 0x01, 0x01, 0x01};
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700183
Haibo Huang49cc9302020-04-27 16:14:24 -0700184 uint8_t output_data[FX_ArraySize(kExpectedData)];
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700185 memset(output_data, 0, sizeof(output_data));
186 uint32_t output_size = FX_ArraySize(output_data);
187
188 EXPECT_EQ(
189 CFX_GifDecodeStatus::Success,
Haibo Huang49cc9302020-04-27 16:14:24 -0700190 decompressor->Decode(kImageData, image_size, output_data, &output_size));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700191
192 EXPECT_EQ(FX_ArraySize(output_data), output_size);
Haibo Huang49cc9302020-04-27 16:14:24 -0700193 EXPECT_TRUE(0 == memcmp(kExpectedData, output_data, sizeof(kExpectedData)));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700194}
195
196TEST(CFX_LZWDecompressor, HandleColourCodeOutOfPalette) {
197 uint8_t palette_exp = 0x2; // Image uses 10 colours, so the palette exp
198 // should be 3, 2^(3+1) = 16 colours.
199 uint8_t code_exp = 0x4;
200 auto decompressor = CFX_LZWDecompressor::Create(palette_exp, code_exp);
201 ASSERT_NE(nullptr, decompressor);
202
Haibo Huang49cc9302020-04-27 16:14:24 -0700203 static constexpr uint8_t kImageData[] = {
204 0x30, 0xC9, 0x49, 0x81, 0xBD, 0x78, 0xE8, 0xCD, 0x89, 0xFF,
205 0x60, 0x20, 0x8E, 0xE4, 0x61, 0x9E, 0xA8, 0xA1, 0xAE, 0x2C,
206 0xE2, 0xBE, 0xB0, 0x20, 0xCF, 0x74, 0x61, 0xDF, 0x78, 0x04};
207 uint32_t image_size = FX_ArraySize(kImageData);
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700208
209 uint8_t output_data[100]; // The uncompressed data is for a 10x10 image
210 memset(output_data, 0, sizeof(output_data));
211 uint32_t output_size = FX_ArraySize(output_data);
212
213 EXPECT_EQ(
214 CFX_GifDecodeStatus::Error,
Haibo Huang49cc9302020-04-27 16:14:24 -0700215 decompressor->Decode(kImageData, image_size, output_data, &output_size));
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700216}