1 // Copyright 2014 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 <stdint.h>
6
7 #include <limits>
8
9 #include "core/fxcodec/jpx/cjpx_decoder.h"
10 #include "core/fxcodec/jpx/jpx_decode_utils.h"
11 #include "core/fxcrt/fx_memory.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/libopenjpeg20/opj_malloc.h"
14
15 namespace fxcodec {
16
17 static const OPJ_OFF_T kSkipError = static_cast<OPJ_OFF_T>(-1);
18 static const OPJ_SIZE_T kReadError = static_cast<OPJ_SIZE_T>(-1);
19
20 static const uint8_t stream_data[] = {
21 0x00, 0x01, 0x02, 0x03,
22 0x84, 0x85, 0x86, 0x87, // Include some hi-bytes, too.
23 };
24
TEST(fxcodec,DecodeDataNullDecodeData)25 TEST(fxcodec, DecodeDataNullDecodeData) {
26 uint8_t buffer[16];
27 DecodeData* ptr = nullptr;
28
29 // Error codes, not segvs, should callers pass us a nullptr pointer.
30 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), ptr));
31 EXPECT_EQ(kSkipError, opj_skip_from_memory(1, ptr));
32 EXPECT_FALSE(opj_seek_from_memory(1, ptr));
33 }
34
TEST(fxcodec,DecodeDataNullStream)35 TEST(fxcodec, DecodeDataNullStream) {
36 DecodeData dd(nullptr, 0);
37 uint8_t buffer[16];
38
39 // Reads of size 0 do nothing but return an error code.
40 memset(buffer, 0xbd, sizeof(buffer));
41 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
42 EXPECT_EQ(0xbd, buffer[0]);
43
44 // Reads of nonzero size do nothing but return an error code.
45 memset(buffer, 0xbd, sizeof(buffer));
46 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
47 EXPECT_EQ(0xbd, buffer[0]);
48
49 // Skips of size 0 always return an error code.
50 EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
51
52 // Skips of nonzero size always return an error code.
53 EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
54
55 // Seeks to 0 offset return in error.
56 EXPECT_FALSE(opj_seek_from_memory(0, &dd));
57
58 // Seeks to non-zero offsets return in error.
59 EXPECT_FALSE(opj_seek_from_memory(1, &dd));
60 }
61
TEST(fxcodec,DecodeDataZeroSize)62 TEST(fxcodec, DecodeDataZeroSize) {
63 DecodeData dd(stream_data, 0);
64 uint8_t buffer[16];
65
66 // Reads of size 0 do nothing but return an error code.
67 memset(buffer, 0xbd, sizeof(buffer));
68 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
69 EXPECT_EQ(0xbd, buffer[0]);
70
71 // Reads of nonzero size do nothing but return an error code.
72 memset(buffer, 0xbd, sizeof(buffer));
73 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
74 EXPECT_EQ(0xbd, buffer[0]);
75
76 // Skips of size 0 always return an error code.
77 EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
78
79 // Skips of nonzero size always return an error code.
80 EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
81
82 // Seeks to 0 offset return in error.
83 EXPECT_FALSE(opj_seek_from_memory(0, &dd));
84
85 // Seeks to non-zero offsets return in error.
86 EXPECT_FALSE(opj_seek_from_memory(1, &dd));
87 }
88
TEST(fxcodec,DecodeDataReadInBounds)89 TEST(fxcodec, DecodeDataReadInBounds) {
90 uint8_t buffer[16];
91 {
92 DecodeData dd(stream_data, sizeof(stream_data));
93
94 // Exact sized read in a single call.
95 memset(buffer, 0xbd, sizeof(buffer));
96 EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer), &dd));
97 EXPECT_EQ(0x00, buffer[0]);
98 EXPECT_EQ(0x01, buffer[1]);
99 EXPECT_EQ(0x02, buffer[2]);
100 EXPECT_EQ(0x03, buffer[3]);
101 EXPECT_EQ(0x84, buffer[4]);
102 EXPECT_EQ(0x85, buffer[5]);
103 EXPECT_EQ(0x86, buffer[6]);
104 EXPECT_EQ(0x87, buffer[7]);
105 EXPECT_EQ(0xbd, buffer[8]);
106 }
107 {
108 DecodeData dd(stream_data, sizeof(stream_data));
109
110 // Simple read.
111 memset(buffer, 0xbd, sizeof(buffer));
112 EXPECT_EQ(2u, opj_read_from_memory(buffer, 2, &dd));
113 EXPECT_EQ(0x00, buffer[0]);
114 EXPECT_EQ(0x01, buffer[1]);
115 EXPECT_EQ(0xbd, buffer[2]);
116
117 // Read of size 0 doesn't affect things.
118 memset(buffer, 0xbd, sizeof(buffer));
119 EXPECT_EQ(0u, opj_read_from_memory(buffer, 0, &dd));
120 EXPECT_EQ(0xbd, buffer[0]);
121
122 // Read exactly up to end of data.
123 memset(buffer, 0xbd, sizeof(buffer));
124 EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
125 EXPECT_EQ(0x02, buffer[0]);
126 EXPECT_EQ(0x03, buffer[1]);
127 EXPECT_EQ(0x84, buffer[2]);
128 EXPECT_EQ(0x85, buffer[3]);
129 EXPECT_EQ(0x86, buffer[4]);
130 EXPECT_EQ(0x87, buffer[5]);
131 EXPECT_EQ(0xbd, buffer[6]);
132
133 // Read of size 0 at EOF is still an error.
134 memset(buffer, 0xbd, sizeof(buffer));
135 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
136 EXPECT_EQ(0xbd, buffer[0]);
137 }
138 }
139
TEST(fxcodec,DecodeDataReadBeyondBounds)140 TEST(fxcodec, DecodeDataReadBeyondBounds) {
141 uint8_t buffer[16];
142 {
143 DecodeData dd(stream_data, sizeof(stream_data));
144
145 // Read beyond bounds in a single step.
146 memset(buffer, 0xbd, sizeof(buffer));
147 EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer) + 1, &dd));
148 EXPECT_EQ(0x00, buffer[0]);
149 EXPECT_EQ(0x01, buffer[1]);
150 EXPECT_EQ(0x02, buffer[2]);
151 EXPECT_EQ(0x03, buffer[3]);
152 EXPECT_EQ(0x84, buffer[4]);
153 EXPECT_EQ(0x85, buffer[5]);
154 EXPECT_EQ(0x86, buffer[6]);
155 EXPECT_EQ(0x87, buffer[7]);
156 EXPECT_EQ(0xbd, buffer[8]);
157 }
158 {
159 DecodeData dd(stream_data, sizeof(stream_data));
160
161 // Read well beyond bounds in a single step.
162 memset(buffer, 0xbd, sizeof(buffer));
163 EXPECT_EQ(8u, opj_read_from_memory(
164 buffer, std::numeric_limits<OPJ_SIZE_T>::max(), &dd));
165 EXPECT_EQ(0x00, buffer[0]);
166 EXPECT_EQ(0x01, buffer[1]);
167 EXPECT_EQ(0x02, buffer[2]);
168 EXPECT_EQ(0x03, buffer[3]);
169 EXPECT_EQ(0x84, buffer[4]);
170 EXPECT_EQ(0x85, buffer[5]);
171 EXPECT_EQ(0x86, buffer[6]);
172 EXPECT_EQ(0x87, buffer[7]);
173 EXPECT_EQ(0xbd, buffer[8]);
174 }
175 {
176 DecodeData dd(stream_data, sizeof(stream_data));
177
178 // Read of size 6 gets first 6 bytes.
179 // rest of buffer intact.
180 memset(buffer, 0xbd, sizeof(buffer));
181 EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
182 EXPECT_EQ(0x00, buffer[0]);
183 EXPECT_EQ(0x01, buffer[1]);
184 EXPECT_EQ(0x02, buffer[2]);
185 EXPECT_EQ(0x03, buffer[3]);
186 EXPECT_EQ(0x84, buffer[4]);
187 EXPECT_EQ(0x85, buffer[5]);
188 EXPECT_EQ(0xbd, buffer[6]);
189
190 // Read of size 6 gets remaining two bytes.
191 memset(buffer, 0xbd, sizeof(buffer));
192 EXPECT_EQ(2u, opj_read_from_memory(buffer, 6, &dd));
193 EXPECT_EQ(0x86, buffer[0]);
194 EXPECT_EQ(0x87, buffer[1]);
195 EXPECT_EQ(0xbd, buffer[2]);
196
197 // Read of 6 more gets nothing and leaves rest of buffer intact.
198 memset(buffer, 0xbd, sizeof(buffer));
199 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 6, &dd));
200 EXPECT_EQ(0xbd, buffer[0]);
201 }
202 }
203
204 // Note: Some care needs to be taken here because the skip/seek functions
205 // take OPJ_OFF_T's as arguments, which are typically a signed type.
TEST(fxcodec,DecodeDataSkip)206 TEST(fxcodec, DecodeDataSkip) {
207 uint8_t buffer[16];
208 {
209 DecodeData dd(stream_data, sizeof(stream_data));
210
211 // Skiping within buffer is allowed.
212 memset(buffer, 0xbd, sizeof(buffer));
213 EXPECT_EQ(1u, opj_skip_from_memory(1, &dd));
214 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
215 EXPECT_EQ(0x01, buffer[0]);
216 EXPECT_EQ(0xbd, buffer[1]);
217
218 // Skiping 0 bytes changes nothing.
219 memset(buffer, 0xbd, sizeof(buffer));
220 EXPECT_EQ(0, opj_skip_from_memory(0, &dd));
221 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
222 EXPECT_EQ(0x02, buffer[0]);
223 EXPECT_EQ(0xbd, buffer[1]);
224
225 // Skiping to EOS-1 is possible.
226 memset(buffer, 0xbd, sizeof(buffer));
227 EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
228 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
229 EXPECT_EQ(0x87, buffer[0]);
230 EXPECT_EQ(0xbd, buffer[1]);
231
232 // Next read fails.
233 memset(buffer, 0xbd, sizeof(buffer));
234 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
235 EXPECT_EQ(0xbd, buffer[0]);
236 }
237 {
238 DecodeData dd(stream_data, sizeof(stream_data));
239
240 // Skiping directly to EOS is allowed.
241 memset(buffer, 0xbd, sizeof(buffer));
242 EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
243
244 // Next read fails.
245 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
246 EXPECT_EQ(0xbd, buffer[0]);
247 }
248 {
249 DecodeData dd(stream_data, sizeof(stream_data));
250
251 // Skipping beyond end of stream is allowed and returns full distance.
252 memset(buffer, 0xbd, sizeof(buffer));
253 EXPECT_EQ(9u, opj_skip_from_memory(9, &dd));
254
255 // Next read fails.
256 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
257 EXPECT_EQ(0xbd, buffer[0]);
258 }
259 {
260 DecodeData dd(stream_data, sizeof(stream_data));
261
262 // Skipping way beyond EOS is allowd, doesn't wrap, and returns
263 // full distance.
264 memset(buffer, 0xbd, sizeof(buffer));
265 EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
266 EXPECT_EQ(std::numeric_limits<OPJ_OFF_T>::max(),
267 opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
268
269 // Next read fails. If it succeeds, it may mean we wrapped.
270 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
271 EXPECT_EQ(0xbd, buffer[0]);
272 }
273 {
274 DecodeData dd(stream_data, sizeof(stream_data));
275
276 // Negative skip within buffer not is allowed, position unchanged.
277 memset(buffer, 0xbd, sizeof(buffer));
278 EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
279 EXPECT_EQ(kSkipError, opj_skip_from_memory(-2, &dd));
280
281 // Next read succeeds as if nothing has happenned.
282 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
283 EXPECT_EQ(0x84, buffer[0]);
284 EXPECT_EQ(0xbd, buffer[1]);
285
286 // Negative skip before buffer is not allowed, position unchanged.
287 memset(buffer, 0xbd, sizeof(buffer));
288 EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
289
290 // Next read succeeds as if nothing has happenned.
291 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
292 EXPECT_EQ(0x85, buffer[0]);
293 EXPECT_EQ(0xbd, buffer[1]);
294 }
295 {
296 DecodeData dd(stream_data, sizeof(stream_data));
297
298 // Negative skip way before buffer is not allowed, doesn't wrap
299 memset(buffer, 0xbd, sizeof(buffer));
300 EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
301 EXPECT_EQ(kSkipError,
302 opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
303
304 // Next read succeeds. If it fails, it may mean we wrapped.
305 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
306 EXPECT_EQ(0x84, buffer[0]);
307 EXPECT_EQ(0xbd, buffer[1]);
308 }
309 {
310 DecodeData dd(stream_data, sizeof(stream_data));
311
312 // Negative skip after EOS isn't alowed, still EOS.
313 memset(buffer, 0xbd, sizeof(buffer));
314 EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
315 EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
316
317 // Next read fails.
318 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
319 EXPECT_EQ(0xbd, buffer[0]);
320 }
321 }
322
TEST(fxcodec,DecodeDataSeek)323 TEST(fxcodec, DecodeDataSeek) {
324 uint8_t buffer[16];
325 DecodeData dd(stream_data, sizeof(stream_data));
326
327 // Seeking within buffer is allowed and read succeeds
328 memset(buffer, 0xbd, sizeof(buffer));
329 EXPECT_TRUE(opj_seek_from_memory(1, &dd));
330 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
331 EXPECT_EQ(0x01, buffer[0]);
332 EXPECT_EQ(0xbd, buffer[1]);
333
334 // Seeking before start returns error leaving position unchanged.
335 memset(buffer, 0xbd, sizeof(buffer));
336 EXPECT_FALSE(opj_seek_from_memory(-1, &dd));
337 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
338 EXPECT_EQ(0x02, buffer[0]);
339 EXPECT_EQ(0xbd, buffer[1]);
340
341 // Seeking way before start returns error leaving position unchanged.
342 memset(buffer, 0xbd, sizeof(buffer));
343 EXPECT_FALSE(
344 opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
345 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
346 EXPECT_EQ(0x03, buffer[0]);
347 EXPECT_EQ(0xbd, buffer[1]);
348
349 // Seeking exactly to EOS is allowed but read fails.
350 memset(buffer, 0xbd, sizeof(buffer));
351 EXPECT_TRUE(opj_seek_from_memory(8, &dd));
352 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
353 EXPECT_EQ(0xbd, buffer[0]);
354
355 // Seeking back to zero offset is allowed and read succeeds.
356 memset(buffer, 0xbd, sizeof(buffer));
357 EXPECT_TRUE(opj_seek_from_memory(0, &dd));
358 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
359 EXPECT_EQ(0x00, buffer[0]);
360 EXPECT_EQ(0xbd, buffer[1]);
361
362 // Seeking beyond end of stream is allowed but read fails.
363 memset(buffer, 0xbd, sizeof(buffer));
364 EXPECT_TRUE(opj_seek_from_memory(16, &dd));
365 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
366 EXPECT_EQ(0xbd, buffer[0]);
367
368 // Seeking within buffer after seek past EOF restores good state.
369 memset(buffer, 0xbd, sizeof(buffer));
370 EXPECT_TRUE(opj_seek_from_memory(4, &dd));
371 EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
372 EXPECT_EQ(0x84, buffer[0]);
373 EXPECT_EQ(0xbd, buffer[1]);
374
375 // Seeking way beyond EOS is allowed, doesn't wrap, and read fails.
376 memset(buffer, 0xbd, sizeof(buffer));
377 EXPECT_TRUE(opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
378 EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
379 EXPECT_EQ(0xbd, buffer[0]);
380 }
381
TEST(fxcodec,YUV420ToRGB)382 TEST(fxcodec, YUV420ToRGB) {
383 opj_image_comp_t u;
384 memset(&u, 0, sizeof(u));
385 u.dx = 1;
386 u.dy = 1;
387 u.w = 16;
388 u.h = 16;
389 u.prec = 8;
390 u.bpp = 8;
391 opj_image_comp_t v;
392 memset(&v, 0, sizeof(v));
393 v.dx = 1;
394 v.dy = 1;
395 v.w = 16;
396 v.h = 16;
397 v.prec = 8;
398 v.bpp = 8;
399 opj_image_comp_t y;
400 memset(&y, 0, sizeof(y));
401 y.dx = 1;
402 y.dy = 1;
403 y.prec = 8;
404 y.bpp = 8;
405 opj_image_t img;
406 memset(&img, 0, sizeof(img));
407 img.numcomps = 3;
408 img.color_space = OPJ_CLRSPC_SYCC;
409 img.comps = FX_Alloc(opj_image_comp_t, 3);
410 const struct {
411 OPJ_UINT32 w;
412 bool expected;
413 } cases[] = {{0, false}, {1, false}, {30, false}, {31, true},
414 {32, true}, {33, false}, {34, false}, {UINT_MAX, false}};
415 for (const auto& testcase : cases) {
416 y.w = testcase.w;
417 y.h = y.w;
418 img.x1 = y.w;
419 img.y1 = y.h;
420 y.data = static_cast<OPJ_INT32*>(
421 opj_image_data_alloc(y.w * y.h * sizeof(OPJ_INT32)));
422 v.data = static_cast<OPJ_INT32*>(
423 opj_image_data_alloc(v.w * v.h * sizeof(OPJ_INT32)));
424 u.data = static_cast<OPJ_INT32*>(
425 opj_image_data_alloc(u.w * u.h * sizeof(OPJ_INT32)));
426 memset(y.data, 1, y.w * y.h * sizeof(OPJ_INT32));
427 memset(u.data, 0, u.w * u.h * sizeof(OPJ_INT32));
428 memset(v.data, 0, v.w * v.h * sizeof(OPJ_INT32));
429 img.comps[0] = y;
430 img.comps[1] = u;
431 img.comps[2] = v;
432 CJPX_Decoder::Sycc420ToRgbForTesting(&img);
433 if (testcase.expected) {
434 EXPECT_EQ(img.comps[0].w, img.comps[1].w);
435 EXPECT_EQ(img.comps[0].h, img.comps[1].h);
436 EXPECT_EQ(img.comps[0].w, img.comps[2].w);
437 EXPECT_EQ(img.comps[0].h, img.comps[2].h);
438 } else {
439 EXPECT_NE(img.comps[0].w, img.comps[1].w);
440 EXPECT_NE(img.comps[0].h, img.comps[1].h);
441 EXPECT_NE(img.comps[0].w, img.comps[2].w);
442 EXPECT_NE(img.comps[0].h, img.comps[2].h);
443 }
444 opj_image_data_free(img.comps[0].data);
445 opj_image_data_free(img.comps[1].data);
446 opj_image_data_free(img.comps[2].data);
447 }
448 FX_Free(img.comps);
449 }
450
451 } // namespace fxcodec
452