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 "SkYUVASizeInfo.h"
14 #include "Test.h"
15
codec_yuv(skiatest::Reporter * reporter,const char path[],SkISize expectedSizes[4])16 static void codec_yuv(skiatest::Reporter* reporter,
17 const char path[],
18 SkISize expectedSizes[4]) {
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 SkYUVASizeInfo info;
31
32 {
33 bool success = codec->queryYUV8(nullptr, nullptr);
34 REPORTER_ASSERT(reporter, !success);
35 success = codec->queryYUV8(&info, nullptr);
36 REPORTER_ASSERT(reporter, (expectedSizes == nullptr) == !success);
37 if (!success) {
38 return;
39 }
40
41 for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
42 REPORTER_ASSERT(reporter, info.fSizes[i] == expectedSizes[i]);
43 REPORTER_ASSERT(reporter,
44 info.fWidthBytes[i] == (uint32_t) SkAlign8(info.fSizes[i].width()));
45 }
46 }
47
48 {
49 SkYUVColorSpace colorSpace;
50 bool success = codec->queryYUV8(&info, &colorSpace);
51 REPORTER_ASSERT(reporter, (expectedSizes == nullptr) == !success);
52 if (!success) {
53 return;
54 }
55
56 for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
57 REPORTER_ASSERT(reporter, info.fSizes[i] == expectedSizes[i]);
58 REPORTER_ASSERT(reporter,
59 info.fWidthBytes[i] == (uint32_t) SkAlign8(info.fSizes[i].width()));
60 }
61 REPORTER_ASSERT(reporter, kJPEG_SkYUVColorSpace == colorSpace);
62 }
63
64 // Allocate the memory for the YUV decode
65 size_t totalBytes = info.computeTotalBytes();
66
67 SkAutoMalloc storage(totalBytes);
68 void* planes[SkYUVASizeInfo::kMaxCount];
69
70 info.computePlanes(storage.get(), planes);
71
72 // Test getYUV8Planes()
73 REPORTER_ASSERT(reporter, SkCodec::kInvalidInput == codec->getYUV8Planes(info, nullptr));
74 REPORTER_ASSERT(reporter, SkCodec::kSuccess == codec->getYUV8Planes(info, planes));
75 }
76
DEF_TEST(Jpeg_YUV_Codec,r)77 DEF_TEST(Jpeg_YUV_Codec, r) {
78 SkISize sizes[4];
79
80 sizes[0].set(128, 128);
81 sizes[1].set(64, 64);
82 sizes[2].set(64, 64);
83 sizes[3].set(0, 0);
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