blob: d3b916784372fdeab18d8883fbd82d0d9edf5ad7 [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
8#include "SkCodec.h"
9#include "Resources.h"
10#include "SkStream.h"
11#include "SkTemplates.h"
msarett4984c3c2016-03-10 05:44:43 -080012#include "SkYUVSizeInfo.h"
msarett829caa22016-02-11 14:17:17 -080013#include "Test.h"
14
msarett829caa22016-02-11 14:17:17 -080015static void codec_yuv(skiatest::Reporter* reporter,
16 const char path[],
17 SkISize expectedSizes[3]) {
bungemanf93d7112016-09-16 06:24:20 -070018 SkAutoTDelete<SkStream> stream(GetResourceAsStream(path));
msarett829caa22016-02-11 14:17:17 -080019 if (!stream) {
msarett829caa22016-02-11 14:17:17 -080020 return;
21 }
mtklein18300a32016-03-16 13:53:35 -070022 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.release()));
msarett829caa22016-02-11 14:17:17 -080023 REPORTER_ASSERT(reporter, codec);
24 if (!codec) {
25 return;
26 }
27
28 // Test queryYUV8()
msarett4984c3c2016-03-10 05:44:43 -080029 SkYUVSizeInfo info;
msarett829caa22016-02-11 14:17:17 -080030 bool success = codec->queryYUV8(nullptr, nullptr);
31 REPORTER_ASSERT(reporter, !success);
32 success = codec->queryYUV8(&info, nullptr);
33 REPORTER_ASSERT(reporter, (expectedSizes == nullptr) == !success);
34 if (!success) {
35 return;
36 }
37 REPORTER_ASSERT(reporter,
38 0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
msarett4984c3c2016-03-10 05:44:43 -080039 REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kY] ==
40 (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kY].width()));
41 REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kU] ==
42 (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kU].width()));
43 REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kV] ==
44 (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kV].width()));
msarett829caa22016-02-11 14:17:17 -080045 SkYUVColorSpace colorSpace;
46 success = codec->queryYUV8(&info, &colorSpace);
47 REPORTER_ASSERT(reporter,
48 0 == memcmp((const void*) &info, (const void*) expectedSizes, 3 * sizeof(SkISize)));
msarett4984c3c2016-03-10 05:44:43 -080049 REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kY] ==
50 (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kY].width()));
51 REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kU] ==
52 (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kU].width()));
53 REPORTER_ASSERT(reporter, info.fWidthBytes[SkYUVSizeInfo::kV] ==
54 (uint32_t) SkAlign8(info.fSizes[SkYUVSizeInfo::kV].width()));
msarett829caa22016-02-11 14:17:17 -080055 REPORTER_ASSERT(reporter, kJPEG_SkYUVColorSpace == colorSpace);
56
57 // Allocate the memory for the YUV decode
msarett4984c3c2016-03-10 05:44:43 -080058 size_t totalBytes =
59 info.fWidthBytes[SkYUVSizeInfo::kY] * info.fSizes[SkYUVSizeInfo::kY].height() +
60 info.fWidthBytes[SkYUVSizeInfo::kU] * info.fSizes[SkYUVSizeInfo::kU].height() +
61 info.fWidthBytes[SkYUVSizeInfo::kV] * info.fSizes[SkYUVSizeInfo::kV].height();
msarett829caa22016-02-11 14:17:17 -080062 SkAutoMalloc storage(totalBytes);
63 void* planes[3];
64 planes[0] = storage.get();
msarett4984c3c2016-03-10 05:44:43 -080065 planes[1] = SkTAddOffset<void>(planes[0],
66 info.fWidthBytes[SkYUVSizeInfo::kY] * info.fSizes[SkYUVSizeInfo::kY].height());
67 planes[2] = SkTAddOffset<void>(planes[1],
68 info.fWidthBytes[SkYUVSizeInfo::kU] * info.fSizes[SkYUVSizeInfo::kU].height());
msarett829caa22016-02-11 14:17:17 -080069
70 // Test getYUV8Planes()
71 REPORTER_ASSERT(reporter, SkCodec::kInvalidInput ==
72 codec->getYUV8Planes(info, nullptr));
73 REPORTER_ASSERT(reporter, SkCodec::kSuccess ==
74 codec->getYUV8Planes(info, planes));
75}
76
77DEF_TEST(Jpeg_YUV_Codec, r) {
78 SkISize sizes[3];
79
80 sizes[0].set(128, 128);
81 sizes[1].set(64, 64);
82 sizes[2].set(64, 64);
83 codec_yuv(r, "color_wheel.jpg", sizes);
84
85 // H2V2
86 sizes[0].set(512, 512);
87 sizes[1].set(256, 256);
88 sizes[2].set(256, 256);
89 codec_yuv(r, "mandrill_512_q075.jpg", sizes);
90
91 // H1V1
92 sizes[1].set(512, 512);
93 sizes[2].set(512, 512);
94 codec_yuv(r, "mandrill_h1v1.jpg", sizes);
95
96 // H2V1
97 sizes[1].set(256, 512);
98 sizes[2].set(256, 512);
99 codec_yuv(r, "mandrill_h2v1.jpg", sizes);
100
101 // Non-power of two dimensions
102 sizes[0].set(439, 154);
103 sizes[1].set(220, 77);
104 sizes[2].set(220, 77);
105 codec_yuv(r, "cropped_mandrill.jpg", sizes);
106
107 sizes[0].set(8, 8);
108 sizes[1].set(4, 4);
109 sizes[2].set(4, 4);
110 codec_yuv(r, "randPixels.jpg", sizes);
111
112 // Progressive images
113 sizes[0].set(512, 512);
114 sizes[1].set(512, 512);
115 sizes[2].set(512, 512);
116 codec_yuv(r, "brickwork-texture.jpg", sizes);
117 codec_yuv(r, "brickwork_normal-map.jpg", sizes);
118
119 // A CMYK encoded image should fail.
120 codec_yuv(r, "CMYK.jpg", nullptr);
121 // A grayscale encoded image should fail.
122 codec_yuv(r, "grayscale.jpg", nullptr);
123 // A PNG should fail.
124 codec_yuv(r, "arrow.png", nullptr);
125}