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::NewFromStream(stream.release())); 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, "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, "mandrill_512_q075.jpg", sizes); 91 92 // H1V1 93 sizes[1].set(512, 512); 94 sizes[2].set(512, 512); 95 codec_yuv(r, "mandrill_h1v1.jpg", sizes); 96 97 // H2V1 98 sizes[1].set(256, 512); 99 sizes[2].set(256, 512); 100 codec_yuv(r, "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, "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, "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, "brickwork-texture.jpg", sizes); 118 codec_yuv(r, "brickwork_normal-map.jpg", sizes); 119 120 // A CMYK encoded image should fail. 121 codec_yuv(r, "CMYK.jpg", nullptr); 122 // A grayscale encoded image should fail. 123 codec_yuv(r, "grayscale.jpg", nullptr); 124 // A PNG should fail. 125 codec_yuv(r, "arrow.png", nullptr); 126 } 127