• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 namespace fxcodec {
20 
21 static const OPJ_OFF_T kSkipError = static_cast<OPJ_OFF_T>(-1);
22 static const OPJ_SIZE_T kReadError = static_cast<OPJ_SIZE_T>(-1);
23 
24 static const uint8_t kStreamData[] = {
25     0x00, 0x01, 0x02, 0x03,
26     0x84, 0x85, 0x86, 0x87,  // Include some hi-bytes, too.
27 };
28 
TEST(fxcodec,DecodeDataNullDecodeData)29 TEST(fxcodec, DecodeDataNullDecodeData) {
30   uint8_t buffer[16];
31   DecodeData* ptr = nullptr;
32 
33   // Error codes, not segvs, should callers pass us a nullptr pointer.
34   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), ptr));
35   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, ptr));
36   EXPECT_FALSE(opj_seek_from_memory(1, ptr));
37 }
38 
TEST(fxcodec,DecodeDataNullStream)39 TEST(fxcodec, DecodeDataNullStream) {
40   DecodeData dd;
41   uint8_t buffer[16];
42 
43   // Reads of size 0 do nothing but return an error code.
44   fxcrt::Fill(buffer, 0xbd);
45   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
46   EXPECT_EQ(0xbd, buffer[0]);
47 
48   // Reads of nonzero size do nothing but return an error code.
49   fxcrt::Fill(buffer, 0xbd);
50   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
51   EXPECT_EQ(0xbd, buffer[0]);
52 
53   // Skips of size 0 always return an error code.
54   EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
55 
56   // Skips of nonzero size always return an error code.
57   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
58 
59   // Seeks to 0 offset return in error.
60   EXPECT_FALSE(opj_seek_from_memory(0, &dd));
61 
62   // Seeks to non-zero offsets return in error.
63   EXPECT_FALSE(opj_seek_from_memory(1, &dd));
64 }
65 
TEST(fxcodec,DecodeDataZeroSize)66 TEST(fxcodec, DecodeDataZeroSize) {
67   DecodeData dd(pdfium::make_span(kStreamData).first(0u));
68   uint8_t buffer[16];
69 
70   // Reads of size 0 do nothing but return an error code.
71   fxcrt::Fill(buffer, 0xbd);
72   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
73   EXPECT_EQ(0xbd, buffer[0]);
74 
75   // Reads of nonzero size do nothing but return an error code.
76   fxcrt::Fill(buffer, 0xbd);
77   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
78   EXPECT_EQ(0xbd, buffer[0]);
79 
80   // Skips of size 0 always return an error code.
81   EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
82 
83   // Skips of nonzero size always return an error code.
84   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
85 
86   // Seeks to 0 offset return in error.
87   EXPECT_FALSE(opj_seek_from_memory(0, &dd));
88 
89   // Seeks to non-zero offsets return in error.
90   EXPECT_FALSE(opj_seek_from_memory(1, &dd));
91 }
92 
TEST(fxcodec,DecodeDataReadInBounds)93 TEST(fxcodec, DecodeDataReadInBounds) {
94   uint8_t buffer[16];
95   {
96     DecodeData dd(kStreamData);
97 
98     // Exact sized read in a single call.
99     fxcrt::Fill(buffer, 0xbd);
100     EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer), &dd));
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   {
112     DecodeData dd(kStreamData);
113 
114     // Simple read.
115     fxcrt::Fill(buffer, 0xbd);
116     EXPECT_EQ(2u, opj_read_from_memory(buffer, 2, &dd));
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);
123     EXPECT_EQ(0u, opj_read_from_memory(buffer, 0, &dd));
124     EXPECT_EQ(0xbd, buffer[0]);
125 
126     // Read exactly up to end of data.
127     fxcrt::Fill(buffer, 0xbd);
128     EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
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);
139     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
140     EXPECT_EQ(0xbd, buffer[0]);
141   }
142 }
143 
TEST(fxcodec,DecodeDataReadBeyondBounds)144 TEST(fxcodec, DecodeDataReadBeyondBounds) {
145   uint8_t buffer[16];
146   {
147     DecodeData dd(kStreamData);
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   {
163     DecodeData dd(kStreamData);
164 
165     // Read well beyond bounds in a single step.
166     fxcrt::Fill(buffer, 0xbd);
167     EXPECT_EQ(8u, opj_read_from_memory(
168                       buffer, std::numeric_limits<OPJ_SIZE_T>::max(), &dd));
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   {
180     DecodeData dd(kStreamData);
181 
182     // Read of size 6 gets first 6 bytes.
183     // rest of buffer intact.
184     fxcrt::Fill(buffer, 0xbd);
185     EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
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);
196     EXPECT_EQ(2u, opj_read_from_memory(buffer, 6, &dd));
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);
203     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 6, &dd));
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.
TEST(fxcodec,DecodeDataSkip)210 TEST(fxcodec, DecodeDataSkip) {
211   uint8_t buffer[16];
212   {
213     DecodeData dd(kStreamData);
214 
215     // Skiping within buffer is allowed.
216     fxcrt::Fill(buffer, 0xbd);
217     EXPECT_EQ(1u, opj_skip_from_memory(1, &dd));
218     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
219     EXPECT_EQ(0x01, buffer[0]);
220     EXPECT_EQ(0xbd, buffer[1]);
221 
222     // Skiping 0 bytes changes nothing.
223     fxcrt::Fill(buffer, 0xbd);
224     EXPECT_EQ(0, opj_skip_from_memory(0, &dd));
225     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
231     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
232     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
233     EXPECT_EQ(0x87, buffer[0]);
234     EXPECT_EQ(0xbd, buffer[1]);
235 
236     // Next read fails.
237     fxcrt::Fill(buffer, 0xbd);
238     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
239     EXPECT_EQ(0xbd, buffer[0]);
240   }
241   {
242     DecodeData dd(kStreamData);
243 
244     // Skiping directly to EOS is allowed.
245     fxcrt::Fill(buffer, 0xbd);
246     EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
247 
248     // Next read fails.
249     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
250     EXPECT_EQ(0xbd, buffer[0]);
251   }
252   {
253     DecodeData dd(kStreamData);
254 
255     // Skipping beyond end of stream is allowed and returns full distance.
256     fxcrt::Fill(buffer, 0xbd);
257     EXPECT_EQ(9u, opj_skip_from_memory(9, &dd));
258 
259     // Next read fails.
260     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
261     EXPECT_EQ(0xbd, buffer[0]);
262   }
263   {
264     DecodeData dd(kStreamData);
265 
266     // Skipping way beyond EOS is allowd, doesn't wrap, and returns
267     // full distance.
268     fxcrt::Fill(buffer, 0xbd);
269     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
270     EXPECT_EQ(std::numeric_limits<OPJ_OFF_T>::max(),
271               opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
272 
273     // Next read fails. If it succeeds, it may mean we wrapped.
274     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
275     EXPECT_EQ(0xbd, buffer[0]);
276   }
277   {
278     DecodeData dd(kStreamData);
279 
280     // Negative skip within buffer not is allowed, position unchanged.
281     fxcrt::Fill(buffer, 0xbd);
282     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
283     EXPECT_EQ(kSkipError, opj_skip_from_memory(-2, &dd));
284 
285     // Next read succeeds as if nothing has happenned.
286     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
292     EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
293 
294     // Next read succeeds as if nothing has happenned.
295     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
296     EXPECT_EQ(0x85, buffer[0]);
297     EXPECT_EQ(0xbd, buffer[1]);
298   }
299   {
300     DecodeData dd(kStreamData);
301 
302     // Negative skip way before buffer is not allowed, doesn't wrap
303     fxcrt::Fill(buffer, 0xbd);
304     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
305     EXPECT_EQ(kSkipError,
306               opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
307 
308     // Next read succeeds. If it fails, it may mean we wrapped.
309     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
310     EXPECT_EQ(0x84, buffer[0]);
311     EXPECT_EQ(0xbd, buffer[1]);
312   }
313   {
314     DecodeData dd(kStreamData);
315 
316     // Negative skip after EOS isn't alowed, still EOS.
317     fxcrt::Fill(buffer, 0xbd);
318     EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
319     EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
320 
321     // Next read fails.
322     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
323     EXPECT_EQ(0xbd, buffer[0]);
324   }
325 }
326 
TEST(fxcodec,DecodeDataSeek)327 TEST(fxcodec, DecodeDataSeek) {
328   uint8_t buffer[16];
329   DecodeData dd(kStreamData);
330 
331   // Seeking within buffer is allowed and read succeeds
332   fxcrt::Fill(buffer, 0xbd);
333   EXPECT_TRUE(opj_seek_from_memory(1, &dd));
334   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
340   EXPECT_FALSE(opj_seek_from_memory(-1, &dd));
341   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
347   EXPECT_FALSE(
348       opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
349   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
355   EXPECT_TRUE(opj_seek_from_memory(8, &dd));
356   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
357   EXPECT_EQ(0xbd, buffer[0]);
358 
359   // Seeking back to zero offset is allowed and read succeeds.
360   fxcrt::Fill(buffer, 0xbd);
361   EXPECT_TRUE(opj_seek_from_memory(0, &dd));
362   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
368   EXPECT_TRUE(opj_seek_from_memory(16, &dd));
369   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
370   EXPECT_EQ(0xbd, buffer[0]);
371 
372   // Seeking within buffer after seek past EOF restores good state.
373   fxcrt::Fill(buffer, 0xbd);
374   EXPECT_TRUE(opj_seek_from_memory(4, &dd));
375   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
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);
381   EXPECT_TRUE(opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
382   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
383   EXPECT_EQ(0xbd, buffer[0]);
384 }
385 
TEST(fxcodec,YUV420ToRGB)386 TEST(fxcodec, YUV420ToRGB) {
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;
412   img.color_space = OPJ_CLRSPC_SYCC;
413   img.comps = FX_Alloc(opj_image_comp_t, 3);
414   const struct {
415     OPJ_UINT32 w;
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 
431     UNSAFE_TODO({
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;
438       CJPX_Decoder::Sycc420ToRgbForTesting(&img);
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       }
450       opj_image_data_free(img.comps[0].data);
451       opj_image_data_free(img.comps[1].data);
452       opj_image_data_free(img.comps[2].data);
453     });
454   }
455   FX_Free(img.comps);
456 }
457 
458 }  // namespace fxcodec
459