• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/codec/codec_int.h"
10 #include "testing/fx_string_testhelpers.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 static const OPJ_OFF_T kSkipError = static_cast<OPJ_OFF_T>(-1);
14 static const OPJ_SIZE_T kReadError = static_cast<OPJ_SIZE_T>(-1);
15 static const OPJ_SIZE_T kWriteError = static_cast<OPJ_SIZE_T>(-1);
16 
17 static unsigned char stream_data[] = {
18     0x00, 0x01, 0x02, 0x03,
19     0x84, 0x85, 0x86, 0x87,  // Include some hi-bytes, too.
20 };
21 
22 union Float_t {
Float_t(float num=0.0f)23   Float_t(float num = 0.0f) : f(num) {}
24 
25   int32_t i;
26   FX_FLOAT f;
27 };
28 
TEST(fxcodec,CMYK_Rounding)29 TEST(fxcodec, CMYK_Rounding) {
30   // Testing all floats from 0.0 to 1.0 takes about 35 seconds in release
31   // builds and much longer in debug builds, so just test the known-dangerous
32   // range.
33   const FX_FLOAT startValue = 0.001f;
34   const FX_FLOAT endValue = 0.003f;
35   FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
36   // Iterate through floats by incrementing the representation, as discussed in
37   // https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/
38   for (Float_t f = startValue; f.f < endValue; f.i++) {
39     AdobeCMYK_to_sRGB(f.f, f.f, f.f, f.f, R, G, B);
40   }
41   // Check various other 'special' numbers.
42   AdobeCMYK_to_sRGB(0.0f, 0.25f, 0.5f, 1.0f, R, G, B);
43 }
44 
TEST(fxcodec,DecodeDataNullDecodeData)45 TEST(fxcodec, DecodeDataNullDecodeData) {
46   unsigned char buffer[16];
47   DecodeData* ptr = nullptr;
48 
49   // Error codes, not segvs, should callers pass us a nullptr pointer.
50   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), ptr));
51   EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, sizeof(buffer), ptr));
52   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, ptr));
53   EXPECT_FALSE(opj_seek_from_memory(1, ptr));
54 }
55 
TEST(fxcodec,DecodeDataNullStream)56 TEST(fxcodec, DecodeDataNullStream) {
57   DecodeData dd(nullptr, 0);
58   unsigned char buffer[16];
59 
60   // Reads of size 0 do nothing but return an error code.
61   memset(buffer, 0xbd, sizeof(buffer));
62   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
63   EXPECT_EQ(0xbd, buffer[0]);
64 
65   // Reads of nonzero size do nothing but return an error code.
66   memset(buffer, 0xbd, sizeof(buffer));
67   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
68   EXPECT_EQ(0xbd, buffer[0]);
69 
70   // writes of size 0 do nothing but return an error code.
71   EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, 0, &dd));
72 
73   // writes of nonzero size do nothing but return an error code.
74   EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, sizeof(buffer), &dd));
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,DecodeDataZeroSize)89 TEST(fxcodec, DecodeDataZeroSize) {
90   DecodeData dd(stream_data, 0);
91   unsigned char buffer[16];
92 
93   // Reads of size 0 do nothing but return an error code.
94   memset(buffer, 0xbd, sizeof(buffer));
95   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
96   EXPECT_EQ(0xbd, buffer[0]);
97 
98   // Reads of nonzero size do nothing but return an error code.
99   memset(buffer, 0xbd, sizeof(buffer));
100   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
101   EXPECT_EQ(0xbd, buffer[0]);
102 
103   // writes of size 0 do nothing but return an error code.
104   EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, 0, &dd));
105 
106   // writes of nonzero size do nothing but return an error code.
107   EXPECT_EQ(kWriteError, opj_write_from_memory(buffer, sizeof(buffer), &dd));
108 
109   // Skips of size 0 always return an error code.
110   EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
111 
112   // Skips of nonzero size always return an error code.
113   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
114 
115   // Seeks to 0 offset return in error.
116   EXPECT_FALSE(opj_seek_from_memory(0, &dd));
117 
118   // Seeks to non-zero offsets return in error.
119   EXPECT_FALSE(opj_seek_from_memory(1, &dd));
120 }
121 
TEST(fxcodec,DecodeDataReadInBounds)122 TEST(fxcodec, DecodeDataReadInBounds) {
123   unsigned char buffer[16];
124   {
125     DecodeData dd(stream_data, sizeof(stream_data));
126 
127     // Exact sized read in a single call.
128     memset(buffer, 0xbd, sizeof(buffer));
129     EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer), &dd));
130     EXPECT_EQ(0x00, buffer[0]);
131     EXPECT_EQ(0x01, buffer[1]);
132     EXPECT_EQ(0x02, buffer[2]);
133     EXPECT_EQ(0x03, buffer[3]);
134     EXPECT_EQ(0x84, buffer[4]);
135     EXPECT_EQ(0x85, buffer[5]);
136     EXPECT_EQ(0x86, buffer[6]);
137     EXPECT_EQ(0x87, buffer[7]);
138     EXPECT_EQ(0xbd, buffer[8]);
139   }
140   {
141     DecodeData dd(stream_data, sizeof(stream_data));
142 
143     // Simple read.
144     memset(buffer, 0xbd, sizeof(buffer));
145     EXPECT_EQ(2u, opj_read_from_memory(buffer, 2, &dd));
146     EXPECT_EQ(0x00, buffer[0]);
147     EXPECT_EQ(0x01, buffer[1]);
148     EXPECT_EQ(0xbd, buffer[2]);
149 
150     // Read of size 0 doesn't affect things.
151     memset(buffer, 0xbd, sizeof(buffer));
152     EXPECT_EQ(0u, opj_read_from_memory(buffer, 0, &dd));
153     EXPECT_EQ(0xbd, buffer[0]);
154 
155     // Read exactly up to end of data.
156     memset(buffer, 0xbd, sizeof(buffer));
157     EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
158     EXPECT_EQ(0x02, buffer[0]);
159     EXPECT_EQ(0x03, buffer[1]);
160     EXPECT_EQ(0x84, buffer[2]);
161     EXPECT_EQ(0x85, buffer[3]);
162     EXPECT_EQ(0x86, buffer[4]);
163     EXPECT_EQ(0x87, buffer[5]);
164     EXPECT_EQ(0xbd, buffer[6]);
165 
166     // Read of size 0 at EOF is still an error.
167     memset(buffer, 0xbd, sizeof(buffer));
168     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
169     EXPECT_EQ(0xbd, buffer[0]);
170   }
171 }
172 
TEST(fxcodec,DecodeDataReadBeyondBounds)173 TEST(fxcodec, DecodeDataReadBeyondBounds) {
174   unsigned char buffer[16];
175   {
176     DecodeData dd(stream_data, sizeof(stream_data));
177 
178     // Read beyond bounds in a single step.
179     memset(buffer, 0xbd, sizeof(buffer));
180     EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer) + 1, &dd));
181     EXPECT_EQ(0x00, buffer[0]);
182     EXPECT_EQ(0x01, buffer[1]);
183     EXPECT_EQ(0x02, buffer[2]);
184     EXPECT_EQ(0x03, buffer[3]);
185     EXPECT_EQ(0x84, buffer[4]);
186     EXPECT_EQ(0x85, buffer[5]);
187     EXPECT_EQ(0x86, buffer[6]);
188     EXPECT_EQ(0x87, buffer[7]);
189     EXPECT_EQ(0xbd, buffer[8]);
190   }
191   {
192     DecodeData dd(stream_data, sizeof(stream_data));
193 
194     // Read well beyond bounds in a single step.
195     memset(buffer, 0xbd, sizeof(buffer));
196     EXPECT_EQ(8u, opj_read_from_memory(
197                       buffer, std::numeric_limits<OPJ_SIZE_T>::max(), &dd));
198     EXPECT_EQ(0x00, buffer[0]);
199     EXPECT_EQ(0x01, buffer[1]);
200     EXPECT_EQ(0x02, buffer[2]);
201     EXPECT_EQ(0x03, buffer[3]);
202     EXPECT_EQ(0x84, buffer[4]);
203     EXPECT_EQ(0x85, buffer[5]);
204     EXPECT_EQ(0x86, buffer[6]);
205     EXPECT_EQ(0x87, buffer[7]);
206     EXPECT_EQ(0xbd, buffer[8]);
207   }
208   {
209     DecodeData dd(stream_data, sizeof(stream_data));
210 
211     // Read of size 6 gets first 6 bytes.
212     // rest of buffer intact.
213     memset(buffer, 0xbd, sizeof(buffer));
214     EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
215     EXPECT_EQ(0x00, buffer[0]);
216     EXPECT_EQ(0x01, buffer[1]);
217     EXPECT_EQ(0x02, buffer[2]);
218     EXPECT_EQ(0x03, buffer[3]);
219     EXPECT_EQ(0x84, buffer[4]);
220     EXPECT_EQ(0x85, buffer[5]);
221     EXPECT_EQ(0xbd, buffer[6]);
222 
223     // Read of size 6 gets remaining two bytes.
224     memset(buffer, 0xbd, sizeof(buffer));
225     EXPECT_EQ(2u, opj_read_from_memory(buffer, 6, &dd));
226     EXPECT_EQ(0x86, buffer[0]);
227     EXPECT_EQ(0x87, buffer[1]);
228     EXPECT_EQ(0xbd, buffer[2]);
229 
230     // Read of 6 more gets nothing and leaves rest of buffer intact.
231     memset(buffer, 0xbd, sizeof(buffer));
232     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 6, &dd));
233     EXPECT_EQ(0xbd, buffer[0]);
234   }
235 }
236 
TEST(fxcodec,DecodeDataWriteInBounds)237 TEST(fxcodec, DecodeDataWriteInBounds) {
238   unsigned char stream[16];
239   static unsigned char buffer_data[] = {
240       0x00, 0x01, 0x02, 0x03, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84,
241   };
242   {
243     // Pretend the stream can only hold 4 bytes.
244     DecodeData dd(stream, 4);
245 
246     memset(stream, 0xbd, sizeof(stream));
247     EXPECT_EQ(4u, opj_write_from_memory(buffer_data, 4, &dd));
248     EXPECT_EQ(0x00, stream[0]);
249     EXPECT_EQ(0x01, stream[1]);
250     EXPECT_EQ(0x02, stream[2]);
251     EXPECT_EQ(0x03, stream[3]);
252     EXPECT_EQ(0xbd, stream[4]);
253   }
254   {
255     // Pretend the stream can only hold 4 bytes.
256     DecodeData dd(stream, 4);
257 
258     memset(stream, 0xbd, sizeof(stream));
259     EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 2, &dd));
260     EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 2, &dd));
261     EXPECT_EQ(0x00, stream[0]);
262     EXPECT_EQ(0x01, stream[1]);
263     EXPECT_EQ(0x00, stream[2]);
264     EXPECT_EQ(0x01, stream[3]);
265     EXPECT_EQ(0xbd, stream[4]);
266   }
267 }
268 
TEST(fxcodec,DecodeDataWriteBeyondBounds)269 TEST(fxcodec, DecodeDataWriteBeyondBounds) {
270   unsigned char stream[16];
271   static unsigned char buffer_data[] = {
272       0x10, 0x11, 0x12, 0x13, 0x94, 0x95, 0x96, 0x97,
273   };
274   {
275     // Pretend the stream can only hold 4 bytes.
276     DecodeData dd(stream, 4);
277 
278     // Write ending past EOF transfers up til EOF.
279     memset(stream, 0xbd, sizeof(stream));
280     EXPECT_EQ(4u, opj_write_from_memory(buffer_data, 5, &dd));
281     EXPECT_EQ(0x10, stream[0]);
282     EXPECT_EQ(0x11, stream[1]);
283     EXPECT_EQ(0x12, stream[2]);
284     EXPECT_EQ(0x13, stream[3]);
285     EXPECT_EQ(0xbd, stream[4]);
286 
287     // Subsequent writes fail.
288     memset(stream, 0xbd, sizeof(stream));
289     EXPECT_EQ(kWriteError, opj_write_from_memory(buffer_data, 5, &dd));
290     EXPECT_EQ(0xbd, stream[0]);
291   }
292   {
293     // Pretend the stream can only hold 4 bytes.
294     DecodeData dd(stream, 4);
295 
296     // Write ending past EOF (two steps) transfers up til EOF.
297     memset(stream, 0xbd, sizeof(stream));
298     EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 2, &dd));
299     EXPECT_EQ(2u, opj_write_from_memory(buffer_data, 4, &dd));
300     EXPECT_EQ(0x10, stream[0]);
301     EXPECT_EQ(0x11, stream[1]);
302     EXPECT_EQ(0x10, stream[2]);
303     EXPECT_EQ(0x11, stream[3]);
304     EXPECT_EQ(0xbd, stream[4]);
305 
306     // Subsequent writes fail.
307     memset(stream, 0xbd, sizeof(stream));
308     EXPECT_EQ(kWriteError, opj_write_from_memory(buffer_data, 5, &dd));
309     EXPECT_EQ(0xbd, stream[0]);
310   }
311 }
312 
313 // Note: Some care needs to be taken here because the skip/seek functions
314 // take OPJ_OFF_T's as arguments, which are typically a signed type.
TEST(fxcodec,DecodeDataSkip)315 TEST(fxcodec, DecodeDataSkip) {
316   unsigned char buffer[16];
317   {
318     DecodeData dd(stream_data, sizeof(stream_data));
319 
320     // Skiping within buffer is allowed.
321     memset(buffer, 0xbd, sizeof(buffer));
322     EXPECT_EQ(1u, opj_skip_from_memory(1, &dd));
323     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
324     EXPECT_EQ(0x01, buffer[0]);
325     EXPECT_EQ(0xbd, buffer[1]);
326 
327     // Skiping 0 bytes changes nothing.
328     memset(buffer, 0xbd, sizeof(buffer));
329     EXPECT_EQ(0, opj_skip_from_memory(0, &dd));
330     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
331     EXPECT_EQ(0x02, buffer[0]);
332     EXPECT_EQ(0xbd, buffer[1]);
333 
334     // Skiping to EOS-1 is possible.
335     memset(buffer, 0xbd, sizeof(buffer));
336     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
337     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
338     EXPECT_EQ(0x87, buffer[0]);
339     EXPECT_EQ(0xbd, buffer[1]);
340 
341     // Next read fails.
342     memset(buffer, 0xbd, sizeof(buffer));
343     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
344     EXPECT_EQ(0xbd, buffer[0]);
345   }
346   {
347     DecodeData dd(stream_data, sizeof(stream_data));
348 
349     // Skiping directly to EOS is allowed.
350     memset(buffer, 0xbd, sizeof(buffer));
351     EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
352 
353     // Next read fails.
354     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
355     EXPECT_EQ(0xbd, buffer[0]);
356   }
357   {
358     DecodeData dd(stream_data, sizeof(stream_data));
359 
360     // Skipping beyond end of stream is allowed and returns full distance.
361     memset(buffer, 0xbd, sizeof(buffer));
362     EXPECT_EQ(9u, opj_skip_from_memory(9, &dd));
363 
364     // Next read fails.
365     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
366     EXPECT_EQ(0xbd, buffer[0]);
367   }
368   {
369     DecodeData dd(stream_data, sizeof(stream_data));
370 
371     // Skipping way beyond EOS is allowd, doesn't wrap, and returns
372     // full distance.
373     memset(buffer, 0xbd, sizeof(buffer));
374     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
375     EXPECT_EQ(std::numeric_limits<OPJ_OFF_T>::max(),
376               opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
377 
378     // Next read fails. If it succeeds, it may mean we wrapped.
379     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
380     EXPECT_EQ(0xbd, buffer[0]);
381   }
382   {
383     DecodeData dd(stream_data, sizeof(stream_data));
384 
385     // Negative skip within buffer not is allowed, position unchanged.
386     memset(buffer, 0xbd, sizeof(buffer));
387     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
388     EXPECT_EQ(kSkipError, opj_skip_from_memory(-2, &dd));
389 
390     // Next read succeeds as if nothing has happenned.
391     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
392     EXPECT_EQ(0x84, buffer[0]);
393     EXPECT_EQ(0xbd, buffer[1]);
394 
395     // Negative skip before buffer is not allowed, position unchanged.
396     memset(buffer, 0xbd, sizeof(buffer));
397     EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
398 
399     // Next read succeeds as if nothing has happenned.
400     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
401     EXPECT_EQ(0x85, buffer[0]);
402     EXPECT_EQ(0xbd, buffer[1]);
403   }
404   {
405     DecodeData dd(stream_data, sizeof(stream_data));
406 
407     // Negative skip way before buffer is not allowed, doesn't wrap
408     memset(buffer, 0xbd, sizeof(buffer));
409     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
410     EXPECT_EQ(kSkipError,
411               opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
412 
413     // Next read succeeds. If it fails, it may mean we wrapped.
414     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
415     EXPECT_EQ(0x84, buffer[0]);
416     EXPECT_EQ(0xbd, buffer[1]);
417   }
418   {
419     DecodeData dd(stream_data, sizeof(stream_data));
420 
421     // Negative skip after EOS isn't alowed, still EOS.
422     memset(buffer, 0xbd, sizeof(buffer));
423     EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
424     EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
425 
426     // Next read fails.
427     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
428     EXPECT_EQ(0xbd, buffer[0]);
429   }
430 }
431 
TEST(fxcodec,DecodeDataSeek)432 TEST(fxcodec, DecodeDataSeek) {
433   unsigned char buffer[16];
434   DecodeData dd(stream_data, sizeof(stream_data));
435 
436   // Seeking within buffer is allowed and read succeeds
437   memset(buffer, 0xbd, sizeof(buffer));
438   EXPECT_TRUE(opj_seek_from_memory(1, &dd));
439   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
440   EXPECT_EQ(0x01, buffer[0]);
441   EXPECT_EQ(0xbd, buffer[1]);
442 
443   // Seeking before start returns error leaving position unchanged.
444   memset(buffer, 0xbd, sizeof(buffer));
445   EXPECT_FALSE(opj_seek_from_memory(-1, &dd));
446   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
447   EXPECT_EQ(0x02, buffer[0]);
448   EXPECT_EQ(0xbd, buffer[1]);
449 
450   // Seeking way before start returns error leaving position unchanged.
451   memset(buffer, 0xbd, sizeof(buffer));
452   EXPECT_FALSE(
453       opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
454   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
455   EXPECT_EQ(0x03, buffer[0]);
456   EXPECT_EQ(0xbd, buffer[1]);
457 
458   // Seeking exactly to EOS is allowed but read fails.
459   memset(buffer, 0xbd, sizeof(buffer));
460   EXPECT_TRUE(opj_seek_from_memory(8, &dd));
461   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
462   EXPECT_EQ(0xbd, buffer[0]);
463 
464   // Seeking back to zero offset is allowed and read succeeds.
465   memset(buffer, 0xbd, sizeof(buffer));
466   EXPECT_TRUE(opj_seek_from_memory(0, &dd));
467   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
468   EXPECT_EQ(0x00, buffer[0]);
469   EXPECT_EQ(0xbd, buffer[1]);
470 
471   // Seeking beyond end of stream is allowed but read fails.
472   memset(buffer, 0xbd, sizeof(buffer));
473   EXPECT_TRUE(opj_seek_from_memory(16, &dd));
474   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
475   EXPECT_EQ(0xbd, buffer[0]);
476 
477   // Seeking within buffer after seek past EOF restores good state.
478   memset(buffer, 0xbd, sizeof(buffer));
479   EXPECT_TRUE(opj_seek_from_memory(4, &dd));
480   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
481   EXPECT_EQ(0x84, buffer[0]);
482   EXPECT_EQ(0xbd, buffer[1]);
483 
484   // Seeking way beyond EOS is allowed, doesn't wrap, and read fails.
485   memset(buffer, 0xbd, sizeof(buffer));
486   EXPECT_TRUE(opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
487   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
488   EXPECT_EQ(0xbd, buffer[0]);
489 }
490 
TEST(fxcodec,YUV420ToRGB)491 TEST(fxcodec, YUV420ToRGB) {
492   opj_image_comp_t u;
493   memset(&u, 0, sizeof(u));
494   u.dx = 1;
495   u.dy = 1;
496   u.w = 16;
497   u.h = 16;
498   u.prec = 8;
499   u.bpp = 8;
500   opj_image_comp_t v;
501   memset(&v, 0, sizeof(v));
502   v.dx = 1;
503   v.dy = 1;
504   v.w = 16;
505   v.h = 16;
506   v.prec = 8;
507   v.bpp = 8;
508   opj_image_comp_t y;
509   memset(&y, 0, sizeof(y));
510   y.dx = 1;
511   y.dy = 1;
512   y.prec = 8;
513   y.bpp = 8;
514   opj_image_t img;
515   memset(&img, 0, sizeof(img));
516   img.numcomps = 3;
517   img.color_space = OPJ_CLRSPC_SYCC;
518   img.comps = FX_Alloc(opj_image_comp_t, 3);
519   const struct {
520     OPJ_UINT32 w;
521     bool expected;
522   } cases[] = {{0, false}, {1, false},  {30, false}, {31, true},
523                {32, true}, {33, false}, {34, false}, {UINT_MAX, false}};
524   for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); ++i) {
525     y.w = cases[i].w;
526     y.h = y.w;
527     img.x1 = y.w;
528     img.y1 = y.h;
529     y.data = FX_Alloc(OPJ_INT32, y.w * y.h);
530     memset(y.data, 1, y.w * y.h * sizeof(OPJ_INT32));
531     u.data = FX_Alloc(OPJ_INT32, u.w * u.h);
532     memset(u.data, 0, u.w * u.h * sizeof(OPJ_INT32));
533     v.data = FX_Alloc(OPJ_INT32, v.w * v.h);
534     memset(v.data, 0, v.w * v.h * sizeof(OPJ_INT32));
535     img.comps[0] = y;
536     img.comps[1] = u;
537     img.comps[2] = v;
538     sycc420_to_rgb(&img);
539     if (cases[i].expected) {
540       EXPECT_EQ(img.comps[0].w, img.comps[1].w);
541       EXPECT_EQ(img.comps[0].h, img.comps[1].h);
542       EXPECT_EQ(img.comps[0].w, img.comps[2].w);
543       EXPECT_EQ(img.comps[0].h, img.comps[2].h);
544     } else {
545       EXPECT_NE(img.comps[0].w, img.comps[1].w);
546       EXPECT_NE(img.comps[0].h, img.comps[1].h);
547       EXPECT_NE(img.comps[0].w, img.comps[2].w);
548       EXPECT_NE(img.comps[0].h, img.comps[2].h);
549     }
550     FX_Free(img.comps[0].data);
551     FX_Free(img.comps[1].data);
552     FX_Free(img.comps[2].data);
553   }
554   FX_Free(img.comps);
555 }
556