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