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