blob: 0c31c0929ac209749989199e52bcd73e76cf78d7 [file] [log] [blame]
msarett829caa22016-02-11 14:17:17 -08001/*
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
Kevin Lubickc456b732017-01-11 17:21:57 +00008#include "Resources.h"
Hal Canary95e3c052017-01-11 12:44:43 -05009#include "SkAutoMalloc.h"
10#include "SkCodec.h"
msarett829caa22016-02-11 14:17:17 -080011#include "SkStream.h"
12#include "SkTemplates.h"
msarett4984c3c2016-03-10 05:44:43 -080013#include "SkYUVSizeInfo.h"
msarett829caa22016-02-11 14:17:17 -080014#include "Test.h"
15
msarett829caa22016-02-11 14:17:17 -080016static void codec_yuv(skiatest::Reporter* reporter,
17 const char path[],
18 SkISize expectedSizes[3]) {
Ben Wagner145dbcd2016-11-03 14:40:50 -040019 std::unique_ptr<SkStream> stream(GetResourceAsStream(path));
msarett829caa22016-02-11 14:17:17 -080020 if (!stream) {
msarett829caa22016-02-11 14:17:17 -080021 return;
22 }
Ben Wagner145dbcd2016-11-03 14:40:50 -040023 std::unique_ptr<SkCodec> codec(SkCodec::NewFromStream(stream.release()));
msarett829caa22016-02-11 14:17:17 -080024 REPORTER_ASSERT(reporter, codec);
25 if (!codec) {
26 return;
27 }
28
29 // Test queryYUV8()
msarett4984c3c2016-03-10 05:44:43 -080030 SkYUVSizeInfo info;
msarett829caa22016-02-11 14:17:17 -080031 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)));
msarett4984c3c2016-03-10 05:44:43 -080040 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()));
msarett829caa22016-02-11 14:17:17 -080046 SkYUVColorSpace colorSpace;
47 success = codec->queryYUV8(&info, &colorSpace);
48 REPORTER_ASSERT(reporter,
49 0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
msarett4984c3c2016-03-10 05:44:43 -080050 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()));
msarett829caa22016-02-11 14:17:17 -080056 REPORTER_ASSERT(reporter, kJPEG_SkYUVColorSpace == colorSpace);
57
58 // Allocate the memory for the YUV decode
msarett4984c3c2016-03-10 05:44:43 -080059 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();
msarett829caa22016-02-11 14:17:17 -080063 SkAutoMalloc storage(totalBytes);
64 void* planes[3];
65 planes[0] = storage.get();
msarett4984c3c2016-03-10 05:44:43 -080066 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());
msarett829caa22016-02-11 14:17:17 -080070
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
78DEF_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}