• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
codec_yuv(skiatest::Reporter * reporter,const char path[],SkISize expectedSizes[3])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 
DEF_TEST(Jpeg_YUV_Codec,r)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