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