blob: 45a0ff83aa2c6da0439d0991ad654e29e342de05 [file] [log] [blame]
Matt Sarett26b44df2017-05-02 16:04:56 -04001/*
2 * Copyright 2017 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 "Test.h"
10
11#include "SkBitmap.h"
Matt Sarettc367d032017-05-05 11:13:26 -040012#include "SkEncodedImageFormat.h"
Matt Sarettbe4c9b02017-05-08 12:11:44 -040013#include "SkImage.h"
Matt Sarett26b44df2017-05-02 16:04:56 -040014#include "SkJpegEncoder.h"
Matt Sarettc367d032017-05-05 11:13:26 -040015#include "SkPngEncoder.h"
Matt Sarett26b44df2017-05-02 16:04:56 -040016#include "SkStream.h"
17
Matt Sarettc367d032017-05-05 11:13:26 -040018static bool encode(SkEncodedImageFormat format, SkWStream* dst, const SkPixmap& src) {
19 switch (format) {
20 case SkEncodedImageFormat::kJPEG:
21 return SkJpegEncoder::Encode(dst, src, SkJpegEncoder::Options());
22 case SkEncodedImageFormat::kPNG:
23 return SkPngEncoder::Encode(dst, src, SkPngEncoder::Options());
24 default:
Matt Sarett41a8ec02017-05-05 15:07:41 -040025 return false;
Matt Sarettc367d032017-05-05 11:13:26 -040026 }
27}
28
29static std::unique_ptr<SkEncoder> make(SkEncodedImageFormat format, SkWStream* dst,
30 const SkPixmap& src) {
31 switch (format) {
32 case SkEncodedImageFormat::kJPEG:
33 return SkJpegEncoder::Make(dst, src, SkJpegEncoder::Options());
34 case SkEncodedImageFormat::kPNG:
35 return SkPngEncoder::Make(dst, src, SkPngEncoder::Options());
36 default:
37 return nullptr;
38 }
39}
40
41static void test_encode(skiatest::Reporter* r, SkEncodedImageFormat format) {
Matt Sarett26b44df2017-05-02 16:04:56 -040042 SkBitmap bitmap;
43 bool success = GetResourceAsBitmap("mandrill_128.png", &bitmap);
44 if (!success) {
45 return;
46 }
47
48 SkPixmap src;
49 success = bitmap.peekPixels(&src);
50 REPORTER_ASSERT(r, success);
51 if (!success) {
52 return;
53 }
54
55 SkDynamicMemoryWStream dst0, dst1, dst2, dst3;
Matt Sarettc367d032017-05-05 11:13:26 -040056 success = encode(format, &dst0, src);
Matt Sarett26b44df2017-05-02 16:04:56 -040057 REPORTER_ASSERT(r, success);
58
Matt Sarettc367d032017-05-05 11:13:26 -040059 auto encoder1 = make(format, &dst1, src);
Matt Sarett26b44df2017-05-02 16:04:56 -040060 for (int i = 0; i < src.height(); i++) {
61 success = encoder1->encodeRows(1);
62 REPORTER_ASSERT(r, success);
63 }
64
Matt Sarettc367d032017-05-05 11:13:26 -040065 auto encoder2 = make(format, &dst2, src);
Matt Sarett26b44df2017-05-02 16:04:56 -040066 for (int i = 0; i < src.height(); i+=3) {
67 success = encoder2->encodeRows(3);
68 REPORTER_ASSERT(r, success);
69 }
70
Matt Sarettc367d032017-05-05 11:13:26 -040071 auto encoder3 = make(format, &dst3, src);
Matt Sarett26b44df2017-05-02 16:04:56 -040072 success = encoder3->encodeRows(200);
73 REPORTER_ASSERT(r, success);
74
75 sk_sp<SkData> data0 = dst0.detachAsData();
76 sk_sp<SkData> data1 = dst1.detachAsData();
77 sk_sp<SkData> data2 = dst2.detachAsData();
78 sk_sp<SkData> data3 = dst3.detachAsData();
79 REPORTER_ASSERT(r, data0->equals(data1.get()));
80 REPORTER_ASSERT(r, data0->equals(data2.get()));
81 REPORTER_ASSERT(r, data0->equals(data3.get()));
82}
Matt Sarettc367d032017-05-05 11:13:26 -040083
Matt Sarettbe4c9b02017-05-08 12:11:44 -040084DEF_TEST(Encode, r) {
Matt Sarettc367d032017-05-05 11:13:26 -040085 test_encode(r, SkEncodedImageFormat::kJPEG);
86 test_encode(r, SkEncodedImageFormat::kPNG);
87}
Matt Sarettbe4c9b02017-05-08 12:11:44 -040088
89static inline bool equals(const SkBitmap& a, const SkBitmap& b) {
90 if (a.info() != b.info()) {
91 return false;
92 }
93
94 SkASSERT(kN32_SkColorType == a.colorType());
95 for (int y = 0; y < a.height(); y++) {
96 for (int x = 0; x < a.width(); x++) {
97 if (*a.getAddr32(x, y) != *b.getAddr32(x, y)) {
98 return false;
99 }
100 }
101 }
102
103 return true;
104}
105
106DEF_TEST(Encode_PngOptions, r) {
107 SkBitmap bitmap;
108 bool success = GetResourceAsBitmap("mandrill_128.png", &bitmap);
109 if (!success) {
110 return;
111 }
112
113 SkPixmap src;
114 success = bitmap.peekPixels(&src);
115 REPORTER_ASSERT(r, success);
116 if (!success) {
117 return;
118 }
119
120 SkDynamicMemoryWStream dst0, dst1, dst2;
121 SkPngEncoder::Options options;
122 success = SkPngEncoder::Encode(&dst0, src, options);
123 REPORTER_ASSERT(r, success);
124
125 options.fFilterFlags = SkPngEncoder::FilterFlag::kUp;
126 success = SkPngEncoder::Encode(&dst1, src, options);
127 REPORTER_ASSERT(r, success);
128
129 options.fZLibLevel = 3;
130 success = SkPngEncoder::Encode(&dst2, src, options);
131 REPORTER_ASSERT(r, success);
132
133 sk_sp<SkData> data0 = dst0.detachAsData();
134 sk_sp<SkData> data1 = dst1.detachAsData();
135 sk_sp<SkData> data2 = dst2.detachAsData();
136 REPORTER_ASSERT(r, data0->size() < data1->size());
137 REPORTER_ASSERT(r, data1->size() < data2->size());
138
139 SkBitmap bm0, bm1, bm2;
140 SkImage::MakeFromEncoded(data0)->asLegacyBitmap(&bm0, SkImage::kRO_LegacyBitmapMode);
141 SkImage::MakeFromEncoded(data1)->asLegacyBitmap(&bm1, SkImage::kRO_LegacyBitmapMode);
142 SkImage::MakeFromEncoded(data2)->asLegacyBitmap(&bm2, SkImage::kRO_LegacyBitmapMode);
143 REPORTER_ASSERT(r, equals(bm0, bm1));
144 REPORTER_ASSERT(r, equals(bm0, bm2));
145}