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