Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "Resources.h"
      9 #include "SkAutoMalloc.h"
     10 #include "SkCodec.h"
     11 #include "SkStream.h"
     12 #include "SkTemplates.h"
     13 #include "SkYUVSizeInfo.h"
     14 #include "Test.h"
     15 
     16 static void codec_yuv(skiatest::Reporter* reporter,
     17                   const char path[],
     18                   SkISize expectedSizes[3]) {
     19     std::unique_ptr<SkStream> stream(GetResourceAsStream(path));
     20     if (!stream) {
     21         return;
     22     }
     23     std::unique_ptr<SkCodec> codec(SkCodec::MakeFromStream(std::move(stream)));
     24     REPORTER_ASSERT(reporter, codec);
     25     if (!codec) {
     26         return;
     27     }
     28 
     29     // Test queryYUV8()
     30     SkYUVSizeInfo info;
     31     bool success = codec->queryYUV8(nullptr, nullptr);
     32     REPORTER_ASSERT(reporter, !success);
     33     success = codec->queryYUV8(&info, nullptr);
     34     REPORTER_ASSERT(reporter, (expectedSizes == nullptr) == !success);
     35     if (!success) {
     36         return;
     37     }
     38     REPORTER_ASSERT(reporter,
     39             0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
     40     REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kY] ==
     41             (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kY].width()));
     42     REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kU] ==
     43             (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kU].width()));
     44     REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kV] ==
     45             (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kV].width()));
     46     SkYUVColorSpace colorSpace;
     47     success = codec->queryYUV8(&info, &colorSpace);
     48     REPORTER_ASSERT(reporter,
     49             0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
     50     REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kY] ==
     51             (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kY].width()));
     52     REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kU] ==
     53             (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kU].width()));
     54     REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kV] ==
     55             (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kV].width()));
     56     REPORTER_ASSERT(reporter, kJPEG_SkYUVColorSpace == colorSpace);
     57 
     58     // Allocate the memory for the YUV decode
     59     size_t totalBytes =
     60             info.fWidthBytes[SkYUVSizeInfo::kY] * info.fSizes[SkYUVSizeInfo::kY].height() +
     61             info.fWidthBytes[SkYUVSizeInfo::kU] * info.fSizes[SkYUVSizeInfo::kU].height() +
     62             info.fWidthBytes[SkYUVSizeInfo::kV] * info.fSizes[SkYUVSizeInfo::kV].height();
     63     SkAutoMalloc storage(totalBytes);
     64     void* planes[3];
     65     planes[0] = storage.get();
     66     planes[1] = SkTAddOffset<void>(planes[0],
     67             info.fWidthBytes[SkYUVSizeInfo::kY] * info.fSizes[SkYUVSizeInfo::kY].height());
     68     planes[2] = SkTAddOffset<void>(planes[1],
     69             info.fWidthBytes[SkYUVSizeInfo::kU] * info.fSizes[SkYUVSizeInfo::kU].height());
     70 
     71     // Test getYUV8Planes()
     72     REPORTER_ASSERT(reporter, SkCodec::kInvalidInput ==
     73             codec->getYUV8Planes(info, nullptr));
     74     REPORTER_ASSERT(reporter, SkCodec::kSuccess ==
     75             codec->getYUV8Planes(info, planes));
     76 }
     77 
     78 DEF_TEST(Jpeg_YUV_Codec, r) {
     79     SkISize sizes[3];
     80 
     81     sizes[0].set(128, 128);
     82     sizes[1].set(64, 64);
     83     sizes[2].set(64, 64);
     84     codec_yuv(r, "images/color_wheel.jpg", sizes);
     85 
     86     // H2V2
     87     sizes[0].set(512, 512);
     88     sizes[1].set(256, 256);
     89     sizes[2].set(256, 256);
     90     codec_yuv(r, "images/mandrill_512_q075.jpg", sizes);
     91 
     92     // H1V1
     93     sizes[1].set(512, 512);
     94     sizes[2].set(512, 512);
     95     codec_yuv(r, "images/mandrill_h1v1.jpg", sizes);
     96 
     97     // H2V1
     98     sizes[1].set(256, 512);
     99     sizes[2].set(256, 512);
    100     codec_yuv(r, "images/mandrill_h2v1.jpg", sizes);
    101 
    102     // Non-power of two dimensions
    103     sizes[0].set(439, 154);
    104     sizes[1].set(220, 77);
    105     sizes[2].set(220, 77);
    106     codec_yuv(r, "images/cropped_mandrill.jpg", sizes);
    107 
    108     sizes[0].set(8, 8);
    109     sizes[1].set(4, 4);
    110     sizes[2].set(4, 4);
    111     codec_yuv(r, "images/randPixels.jpg", sizes);
    112 
    113     // Progressive images
    114     sizes[0].set(512, 512);
    115     sizes[1].set(512, 512);
    116     sizes[2].set(512, 512);
    117     codec_yuv(r, "images/brickwork-texture.jpg", sizes);
    118     codec_yuv(r, "images/brickwork_normal-map.jpg", sizes);
    119 
    120     // A CMYK encoded image should fail.
    121     codec_yuv(r, "images/CMYK.jpg", nullptr);
    122     // A grayscale encoded image should fail.
    123     codec_yuv(r, "images/grayscale.jpg", nullptr);
    124     // A PNG should fail.
    125     codec_yuv(r, "images/arrow.png", nullptr);
    126 }
    127