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 14static SkStreamAsset* resource(const char path[]) { 15 SkString fullPath = GetResourcePath(path); 16 return SkStream::NewFromFile(fullPath.c_str()); 17} 18 19static 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 73DEF_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