Home | History | Annotate | Download | only in codec
      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 "core/fxcodec/fx_codec.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "third_party/libopenjpeg20/opj_malloc.h"
     13 
     14 static const OPJ_OFF_T kSkipError = static_cast<OPJ_OFF_T>(-1);
     15 static const OPJ_SIZE_T kReadError = static_cast<OPJ_SIZE_T>(-1);
     16 
     17 static const uint8_t stream_data[] = {
     18     0x00, 0x01, 0x02, 0x03,
     19     0x84, 0x85, 0x86, 0x87,  // Include some hi-bytes, too.
     20 };
     21 
     22 union Float_t {
     23   Float_t(float num = 0.0f) : f(num) {}
     24 
     25   int32_t i;
     26   float f;
     27 };
     28 
     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 float startValue = 0.001f;
     34   const float endValue = 0.003f;
     35   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     std::tie(R, G, B) = AdobeCMYK_to_sRGB(f.f, f.f, f.f, f.f);
     40   }
     41   // Check various other 'special' numbers.
     42   std::tie(R, G, B) = AdobeCMYK_to_sRGB(0.0f, 0.25f, 0.5f, 1.0f);
     43 }
     44 
     45 TEST(fxcodec, DecodeDataNullDecodeData) {
     46   uint8_t 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(kSkipError, opj_skip_from_memory(1, ptr));
     52   EXPECT_FALSE(opj_seek_from_memory(1, ptr));
     53 }
     54 
     55 TEST(fxcodec, DecodeDataNullStream) {
     56   DecodeData dd(nullptr, 0);
     57   uint8_t buffer[16];
     58 
     59   // Reads of size 0 do nothing but return an error code.
     60   memset(buffer, 0xbd, sizeof(buffer));
     61   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
     62   EXPECT_EQ(0xbd, buffer[0]);
     63 
     64   // Reads of nonzero size do nothing but return an error code.
     65   memset(buffer, 0xbd, sizeof(buffer));
     66   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
     67   EXPECT_EQ(0xbd, buffer[0]);
     68 
     69   // Skips of size 0 always return an error code.
     70   EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
     71 
     72   // Skips of nonzero size always return an error code.
     73   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
     74 
     75   // Seeks to 0 offset return in error.
     76   EXPECT_FALSE(opj_seek_from_memory(0, &dd));
     77 
     78   // Seeks to non-zero offsets return in error.
     79   EXPECT_FALSE(opj_seek_from_memory(1, &dd));
     80 }
     81 
     82 TEST(fxcodec, DecodeDataZeroSize) {
     83   DecodeData dd(stream_data, 0);
     84   uint8_t buffer[16];
     85 
     86   // Reads of size 0 do nothing but return an error code.
     87   memset(buffer, 0xbd, sizeof(buffer));
     88   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
     89   EXPECT_EQ(0xbd, buffer[0]);
     90 
     91   // Reads of nonzero size do nothing but return an error code.
     92   memset(buffer, 0xbd, sizeof(buffer));
     93   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, sizeof(buffer), &dd));
     94   EXPECT_EQ(0xbd, buffer[0]);
     95 
     96   // Skips of size 0 always return an error code.
     97   EXPECT_EQ(kSkipError, opj_skip_from_memory(0, &dd));
     98 
     99   // Skips of nonzero size always return an error code.
    100   EXPECT_EQ(kSkipError, opj_skip_from_memory(1, &dd));
    101 
    102   // Seeks to 0 offset return in error.
    103   EXPECT_FALSE(opj_seek_from_memory(0, &dd));
    104 
    105   // Seeks to non-zero offsets return in error.
    106   EXPECT_FALSE(opj_seek_from_memory(1, &dd));
    107 }
    108 
    109 TEST(fxcodec, DecodeDataReadInBounds) {
    110   uint8_t buffer[16];
    111   {
    112     DecodeData dd(stream_data, sizeof(stream_data));
    113 
    114     // Exact sized read in a single call.
    115     memset(buffer, 0xbd, sizeof(buffer));
    116     EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer), &dd));
    117     EXPECT_EQ(0x00, buffer[0]);
    118     EXPECT_EQ(0x01, buffer[1]);
    119     EXPECT_EQ(0x02, buffer[2]);
    120     EXPECT_EQ(0x03, buffer[3]);
    121     EXPECT_EQ(0x84, buffer[4]);
    122     EXPECT_EQ(0x85, buffer[5]);
    123     EXPECT_EQ(0x86, buffer[6]);
    124     EXPECT_EQ(0x87, buffer[7]);
    125     EXPECT_EQ(0xbd, buffer[8]);
    126   }
    127   {
    128     DecodeData dd(stream_data, sizeof(stream_data));
    129 
    130     // Simple read.
    131     memset(buffer, 0xbd, sizeof(buffer));
    132     EXPECT_EQ(2u, opj_read_from_memory(buffer, 2, &dd));
    133     EXPECT_EQ(0x00, buffer[0]);
    134     EXPECT_EQ(0x01, buffer[1]);
    135     EXPECT_EQ(0xbd, buffer[2]);
    136 
    137     // Read of size 0 doesn't affect things.
    138     memset(buffer, 0xbd, sizeof(buffer));
    139     EXPECT_EQ(0u, opj_read_from_memory(buffer, 0, &dd));
    140     EXPECT_EQ(0xbd, buffer[0]);
    141 
    142     // Read exactly up to end of data.
    143     memset(buffer, 0xbd, sizeof(buffer));
    144     EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
    145     EXPECT_EQ(0x02, buffer[0]);
    146     EXPECT_EQ(0x03, buffer[1]);
    147     EXPECT_EQ(0x84, buffer[2]);
    148     EXPECT_EQ(0x85, buffer[3]);
    149     EXPECT_EQ(0x86, buffer[4]);
    150     EXPECT_EQ(0x87, buffer[5]);
    151     EXPECT_EQ(0xbd, buffer[6]);
    152 
    153     // Read of size 0 at EOF is still an error.
    154     memset(buffer, 0xbd, sizeof(buffer));
    155     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 0, &dd));
    156     EXPECT_EQ(0xbd, buffer[0]);
    157   }
    158 }
    159 
    160 TEST(fxcodec, DecodeDataReadBeyondBounds) {
    161   uint8_t buffer[16];
    162   {
    163     DecodeData dd(stream_data, sizeof(stream_data));
    164 
    165     // Read beyond bounds in a single step.
    166     memset(buffer, 0xbd, sizeof(buffer));
    167     EXPECT_EQ(8u, opj_read_from_memory(buffer, sizeof(buffer) + 1, &dd));
    168     EXPECT_EQ(0x00, buffer[0]);
    169     EXPECT_EQ(0x01, buffer[1]);
    170     EXPECT_EQ(0x02, buffer[2]);
    171     EXPECT_EQ(0x03, buffer[3]);
    172     EXPECT_EQ(0x84, buffer[4]);
    173     EXPECT_EQ(0x85, buffer[5]);
    174     EXPECT_EQ(0x86, buffer[6]);
    175     EXPECT_EQ(0x87, buffer[7]);
    176     EXPECT_EQ(0xbd, buffer[8]);
    177   }
    178   {
    179     DecodeData dd(stream_data, sizeof(stream_data));
    180 
    181     // Read well beyond bounds in a single step.
    182     memset(buffer, 0xbd, sizeof(buffer));
    183     EXPECT_EQ(8u, opj_read_from_memory(
    184                       buffer, std::numeric_limits<OPJ_SIZE_T>::max(), &dd));
    185     EXPECT_EQ(0x00, buffer[0]);
    186     EXPECT_EQ(0x01, buffer[1]);
    187     EXPECT_EQ(0x02, buffer[2]);
    188     EXPECT_EQ(0x03, buffer[3]);
    189     EXPECT_EQ(0x84, buffer[4]);
    190     EXPECT_EQ(0x85, buffer[5]);
    191     EXPECT_EQ(0x86, buffer[6]);
    192     EXPECT_EQ(0x87, buffer[7]);
    193     EXPECT_EQ(0xbd, buffer[8]);
    194   }
    195   {
    196     DecodeData dd(stream_data, sizeof(stream_data));
    197 
    198     // Read of size 6 gets first 6 bytes.
    199     // rest of buffer intact.
    200     memset(buffer, 0xbd, sizeof(buffer));
    201     EXPECT_EQ(6u, opj_read_from_memory(buffer, 6, &dd));
    202     EXPECT_EQ(0x00, buffer[0]);
    203     EXPECT_EQ(0x01, buffer[1]);
    204     EXPECT_EQ(0x02, buffer[2]);
    205     EXPECT_EQ(0x03, buffer[3]);
    206     EXPECT_EQ(0x84, buffer[4]);
    207     EXPECT_EQ(0x85, buffer[5]);
    208     EXPECT_EQ(0xbd, buffer[6]);
    209 
    210     // Read of size 6 gets remaining two bytes.
    211     memset(buffer, 0xbd, sizeof(buffer));
    212     EXPECT_EQ(2u, opj_read_from_memory(buffer, 6, &dd));
    213     EXPECT_EQ(0x86, buffer[0]);
    214     EXPECT_EQ(0x87, buffer[1]);
    215     EXPECT_EQ(0xbd, buffer[2]);
    216 
    217     // Read of 6 more gets nothing and leaves rest of buffer intact.
    218     memset(buffer, 0xbd, sizeof(buffer));
    219     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 6, &dd));
    220     EXPECT_EQ(0xbd, buffer[0]);
    221   }
    222 }
    223 
    224 // Note: Some care needs to be taken here because the skip/seek functions
    225 // take OPJ_OFF_T's as arguments, which are typically a signed type.
    226 TEST(fxcodec, DecodeDataSkip) {
    227   uint8_t buffer[16];
    228   {
    229     DecodeData dd(stream_data, sizeof(stream_data));
    230 
    231     // Skiping within buffer is allowed.
    232     memset(buffer, 0xbd, sizeof(buffer));
    233     EXPECT_EQ(1u, opj_skip_from_memory(1, &dd));
    234     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    235     EXPECT_EQ(0x01, buffer[0]);
    236     EXPECT_EQ(0xbd, buffer[1]);
    237 
    238     // Skiping 0 bytes changes nothing.
    239     memset(buffer, 0xbd, sizeof(buffer));
    240     EXPECT_EQ(0, opj_skip_from_memory(0, &dd));
    241     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    242     EXPECT_EQ(0x02, buffer[0]);
    243     EXPECT_EQ(0xbd, buffer[1]);
    244 
    245     // Skiping to EOS-1 is possible.
    246     memset(buffer, 0xbd, sizeof(buffer));
    247     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
    248     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    249     EXPECT_EQ(0x87, buffer[0]);
    250     EXPECT_EQ(0xbd, buffer[1]);
    251 
    252     // Next read fails.
    253     memset(buffer, 0xbd, sizeof(buffer));
    254     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    255     EXPECT_EQ(0xbd, buffer[0]);
    256   }
    257   {
    258     DecodeData dd(stream_data, sizeof(stream_data));
    259 
    260     // Skiping directly to EOS is allowed.
    261     memset(buffer, 0xbd, sizeof(buffer));
    262     EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
    263 
    264     // Next read fails.
    265     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    266     EXPECT_EQ(0xbd, buffer[0]);
    267   }
    268   {
    269     DecodeData dd(stream_data, sizeof(stream_data));
    270 
    271     // Skipping beyond end of stream is allowed and returns full distance.
    272     memset(buffer, 0xbd, sizeof(buffer));
    273     EXPECT_EQ(9u, opj_skip_from_memory(9, &dd));
    274 
    275     // Next read fails.
    276     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    277     EXPECT_EQ(0xbd, buffer[0]);
    278   }
    279   {
    280     DecodeData dd(stream_data, sizeof(stream_data));
    281 
    282     // Skipping way beyond EOS is allowd, doesn't wrap, and returns
    283     // full distance.
    284     memset(buffer, 0xbd, sizeof(buffer));
    285     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
    286     EXPECT_EQ(std::numeric_limits<OPJ_OFF_T>::max(),
    287               opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
    288 
    289     // Next read fails. If it succeeds, it may mean we wrapped.
    290     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    291     EXPECT_EQ(0xbd, buffer[0]);
    292   }
    293   {
    294     DecodeData dd(stream_data, sizeof(stream_data));
    295 
    296     // Negative skip within buffer not is allowed, position unchanged.
    297     memset(buffer, 0xbd, sizeof(buffer));
    298     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
    299     EXPECT_EQ(kSkipError, opj_skip_from_memory(-2, &dd));
    300 
    301     // Next read succeeds as if nothing has happenned.
    302     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    303     EXPECT_EQ(0x84, buffer[0]);
    304     EXPECT_EQ(0xbd, buffer[1]);
    305 
    306     // Negative skip before buffer is not allowed, position unchanged.
    307     memset(buffer, 0xbd, sizeof(buffer));
    308     EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
    309 
    310     // Next read succeeds as if nothing has happenned.
    311     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    312     EXPECT_EQ(0x85, buffer[0]);
    313     EXPECT_EQ(0xbd, buffer[1]);
    314   }
    315   {
    316     DecodeData dd(stream_data, sizeof(stream_data));
    317 
    318     // Negative skip way before buffer is not allowed, doesn't wrap
    319     memset(buffer, 0xbd, sizeof(buffer));
    320     EXPECT_EQ(4u, opj_skip_from_memory(4, &dd));
    321     EXPECT_EQ(kSkipError,
    322               opj_skip_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
    323 
    324     // Next read succeeds. If it fails, it may mean we wrapped.
    325     EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    326     EXPECT_EQ(0x84, buffer[0]);
    327     EXPECT_EQ(0xbd, buffer[1]);
    328   }
    329   {
    330     DecodeData dd(stream_data, sizeof(stream_data));
    331 
    332     // Negative skip after EOS isn't alowed, still EOS.
    333     memset(buffer, 0xbd, sizeof(buffer));
    334     EXPECT_EQ(8u, opj_skip_from_memory(8, &dd));
    335     EXPECT_EQ(kSkipError, opj_skip_from_memory(-4, &dd));
    336 
    337     // Next read fails.
    338     EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    339     EXPECT_EQ(0xbd, buffer[0]);
    340   }
    341 }
    342 
    343 TEST(fxcodec, DecodeDataSeek) {
    344   uint8_t buffer[16];
    345   DecodeData dd(stream_data, sizeof(stream_data));
    346 
    347   // Seeking within buffer is allowed and read succeeds
    348   memset(buffer, 0xbd, sizeof(buffer));
    349   EXPECT_TRUE(opj_seek_from_memory(1, &dd));
    350   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    351   EXPECT_EQ(0x01, buffer[0]);
    352   EXPECT_EQ(0xbd, buffer[1]);
    353 
    354   // Seeking before start returns error leaving position unchanged.
    355   memset(buffer, 0xbd, sizeof(buffer));
    356   EXPECT_FALSE(opj_seek_from_memory(-1, &dd));
    357   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    358   EXPECT_EQ(0x02, buffer[0]);
    359   EXPECT_EQ(0xbd, buffer[1]);
    360 
    361   // Seeking way before start returns error leaving position unchanged.
    362   memset(buffer, 0xbd, sizeof(buffer));
    363   EXPECT_FALSE(
    364       opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::min(), &dd));
    365   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    366   EXPECT_EQ(0x03, buffer[0]);
    367   EXPECT_EQ(0xbd, buffer[1]);
    368 
    369   // Seeking exactly to EOS is allowed but read fails.
    370   memset(buffer, 0xbd, sizeof(buffer));
    371   EXPECT_TRUE(opj_seek_from_memory(8, &dd));
    372   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    373   EXPECT_EQ(0xbd, buffer[0]);
    374 
    375   // Seeking back to zero offset is allowed and read succeeds.
    376   memset(buffer, 0xbd, sizeof(buffer));
    377   EXPECT_TRUE(opj_seek_from_memory(0, &dd));
    378   EXPECT_EQ(1u, opj_read_from_memory(buffer, 1, &dd));
    379   EXPECT_EQ(0x00, buffer[0]);
    380   EXPECT_EQ(0xbd, buffer[1]);
    381 
    382   // Seeking beyond end of stream is allowed but read fails.
    383   memset(buffer, 0xbd, sizeof(buffer));
    384   EXPECT_TRUE(opj_seek_from_memory(16, &dd));
    385   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    386   EXPECT_EQ(0xbd, buffer[0]);
    387 
    388   // Seeking within buffer after seek past EOF restores good state.
    389   memset(buffer, 0xbd, sizeof(buffer));
    390   EXPECT_TRUE(opj_seek_from_memory(4, &dd));
    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   // Seeking way beyond EOS is allowed, doesn't wrap, and read fails.
    396   memset(buffer, 0xbd, sizeof(buffer));
    397   EXPECT_TRUE(opj_seek_from_memory(std::numeric_limits<OPJ_OFF_T>::max(), &dd));
    398   EXPECT_EQ(kReadError, opj_read_from_memory(buffer, 1, &dd));
    399   EXPECT_EQ(0xbd, buffer[0]);
    400 }
    401 
    402 TEST(fxcodec, YUV420ToRGB) {
    403   opj_image_comp_t u;
    404   memset(&u, 0, sizeof(u));
    405   u.dx = 1;
    406   u.dy = 1;
    407   u.w = 16;
    408   u.h = 16;
    409   u.prec = 8;
    410   u.bpp = 8;
    411   opj_image_comp_t v;
    412   memset(&v, 0, sizeof(v));
    413   v.dx = 1;
    414   v.dy = 1;
    415   v.w = 16;
    416   v.h = 16;
    417   v.prec = 8;
    418   v.bpp = 8;
    419   opj_image_comp_t y;
    420   memset(&y, 0, sizeof(y));
    421   y.dx = 1;
    422   y.dy = 1;
    423   y.prec = 8;
    424   y.bpp = 8;
    425   opj_image_t img;
    426   memset(&img, 0, sizeof(img));
    427   img.numcomps = 3;
    428   img.color_space = OPJ_CLRSPC_SYCC;
    429   img.comps = FX_Alloc(opj_image_comp_t, 3);
    430   const struct {
    431     OPJ_UINT32 w;
    432     bool expected;
    433   } cases[] = {{0, false}, {1, false},  {30, false}, {31, true},
    434                {32, true}, {33, false}, {34, false}, {UINT_MAX, false}};
    435   for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); ++i) {
    436     y.w = cases[i].w;
    437     y.h = y.w;
    438     img.x1 = y.w;
    439     img.y1 = y.h;
    440     y.data = static_cast<OPJ_INT32*>(
    441         opj_image_data_alloc(y.w * y.h * sizeof(OPJ_INT32)));
    442     v.data = static_cast<OPJ_INT32*>(
    443         opj_image_data_alloc(v.w * v.h * sizeof(OPJ_INT32)));
    444     u.data = static_cast<OPJ_INT32*>(
    445         opj_image_data_alloc(u.w * u.h * sizeof(OPJ_INT32)));
    446     memset(y.data, 1, y.w * y.h * sizeof(OPJ_INT32));
    447     memset(u.data, 0, u.w * u.h * sizeof(OPJ_INT32));
    448     memset(v.data, 0, v.w * v.h * sizeof(OPJ_INT32));
    449     img.comps[0] = y;
    450     img.comps[1] = u;
    451     img.comps[2] = v;
    452     sycc420_to_rgb(&img);
    453     if (cases[i].expected) {
    454       EXPECT_EQ(img.comps[0].w, img.comps[1].w);
    455       EXPECT_EQ(img.comps[0].h, img.comps[1].h);
    456       EXPECT_EQ(img.comps[0].w, img.comps[2].w);
    457       EXPECT_EQ(img.comps[0].h, img.comps[2].h);
    458     } else {
    459       EXPECT_NE(img.comps[0].w, img.comps[1].w);
    460       EXPECT_NE(img.comps[0].h, img.comps[1].h);
    461       EXPECT_NE(img.comps[0].w, img.comps[2].w);
    462       EXPECT_NE(img.comps[0].h, img.comps[2].h);
    463     }
    464     opj_image_data_free(img.comps[0].data);
    465     opj_image_data_free(img.comps[1].data);
    466     opj_image_data_free(img.comps[2].data);
    467   }
    468   FX_Free(img.comps);
    469 }
    470