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 "SkCodec.h"
      9 #include "Resources.h"
     10 #include "SkStream.h"
     11 #include "SkTemplates.h"
     12 #include "Test.h"
     13 
     14 static SkStreamAsset* resource(const char path[]) {
     15     SkString fullPath = GetResourcePath(path);
     16     return SkStream::NewFromFile(fullPath.c_str());
     17 }
     18 
     19 static void codec_yuv(skiatest::Reporter* reporter,
     20                   const char path[],
     21                   SkISize expectedSizes[3]) {
     22     SkAutoTDelete<SkStream> stream(resource(path));
     23     if (!stream) {
     24         INFOF(reporter, "Missing resource '%s'\n", path);
     25         return;
     26     }
     27     SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
     28     REPORTER_ASSERT(reporter, codec);
     29     if (!codec) {
     30         return;
     31     }
     32 
     33     // Test queryYUV8()
     34     SkCodec::YUVSizeInfo info;
     35     bool success = codec->queryYUV8(nullptr, nullptr);
     36     REPORTER_ASSERT(reporter, !success);
     37     success = codec->queryYUV8(&info, nullptr);
     38     REPORTER_ASSERT(reporter, (expectedSizes == nullptr) == !success);
     39     if (!success) {
     40         return;
     41     }
     42     REPORTER_ASSERT(reporter,
     43             0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
     44     REPORTER_ASSERT(reporter, info.fYWidthBytes == (uint32_t) SkAlign8(info.fYSize.width()));
     45     REPORTER_ASSERT(reporter, info.fUWidthBytes == (uint32_t) SkAlign8(info.fUSize.width()));
     46     REPORTER_ASSERT(reporter, info.fVWidthBytes == (uint32_t) SkAlign8(info.fVSize.width()));
     47     SkYUVColorSpace colorSpace;
     48     success = codec->queryYUV8(&info, &colorSpace);
     49     REPORTER_ASSERT(reporter,
     50             0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
     51     REPORTER_ASSERT(reporter, info.fYWidthBytes == (uint32_t) SkAlign8(info.fYSize.width()));
     52     REPORTER_ASSERT(reporter, info.fUWidthBytes == (uint32_t) SkAlign8(info.fUSize.width()));
     53     REPORTER_ASSERT(reporter, info.fVWidthBytes == (uint32_t) SkAlign8(info.fVSize.width()));
     54     REPORTER_ASSERT(reporter, kJPEG_SkYUVColorSpace == colorSpace);
     55 
     56     // Allocate the memory for the YUV decode
     57     size_t totalBytes = info.fYWidthBytes * info.fYSize.height() +
     58             info.fUWidthBytes * info.fUSize.height() +
     59             info.fVWidthBytes * info.fVSize.height();
     60     SkAutoMalloc storage(totalBytes);
     61     void* planes[3];
     62     planes[0] = storage.get();
     63     planes[1] = SkTAddOffset<void>(planes[0], info.fYWidthBytes * info.fYSize.height());
     64     planes[2] = SkTAddOffset<void>(planes[1], info.fUWidthBytes * info.fUSize.height());
     65 
     66     // Test getYUV8Planes()
     67     REPORTER_ASSERT(reporter, SkCodec::kInvalidInput ==
     68             codec->getYUV8Planes(info, nullptr));
     69     REPORTER_ASSERT(reporter, SkCodec::kSuccess ==
     70             codec->getYUV8Planes(info, planes));
     71 }
     72 
     73 DEF_TEST(Jpeg_YUV_Codec, r) {
     74     SkISize sizes[3];
     75 
     76     sizes[0].set(128, 128);
     77     sizes[1].set(64, 64);
     78     sizes[2].set(64, 64);
     79     codec_yuv(r, "color_wheel.jpg", sizes);
     80 
     81     // H2V2
     82     sizes[0].set(512, 512);
     83     sizes[1].set(256, 256);
     84     sizes[2].set(256, 256);
     85     codec_yuv(r, "mandrill_512_q075.jpg", sizes);
     86 
     87     // H1V1
     88     sizes[1].set(512, 512);
     89     sizes[2].set(512, 512);
     90     codec_yuv(r, "mandrill_h1v1.jpg", sizes);
     91 
     92     // H2V1
     93     sizes[1].set(256, 512);
     94     sizes[2].set(256, 512);
     95     codec_yuv(r, "mandrill_h2v1.jpg", sizes);
     96 
     97     // Non-power of two dimensions
     98     sizes[0].set(439, 154);
     99     sizes[1].set(220, 77);
    100     sizes[2].set(220, 77);
    101     codec_yuv(r, "cropped_mandrill.jpg", sizes);
    102 
    103     sizes[0].set(8, 8);
    104     sizes[1].set(4, 4);
    105     sizes[2].set(4, 4);
    106     codec_yuv(r, "randPixels.jpg", sizes);
    107 
    108     // Progressive images
    109     sizes[0].set(512, 512);
    110     sizes[1].set(512, 512);
    111     sizes[2].set(512, 512);
    112     codec_yuv(r, "brickwork-texture.jpg", sizes);
    113     codec_yuv(r, "brickwork_normal-map.jpg", sizes);
    114 
    115     // A CMYK encoded image should fail.
    116     codec_yuv(r, "CMYK.jpg", nullptr);
    117     // A grayscale encoded image should fail.
    118     codec_yuv(r, "grayscale.jpg", nullptr);
    119     // A PNG should fail.
    120     codec_yuv(r, "arrow.png", nullptr);
    121 }
    122