xref: /aosp_15_r20/external/pdfium/core/fxcodec/jpx/jpx_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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