blob: 574e2e0bdc2b675d9fc8e3239faf934a2f450eba [file] [log] [blame]
Hal Canary5b39dc82019-04-17 13:29:46 -04001// Copyright 2019 Google LLC.
2// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
Mike Kleinc0bd9f92019-04-23 12:05:21 -05004#include "include/codec/SkCodec.h"
5#include "include/core/SkBitmap.h"
6#include "include/encode/SkPngEncoder.h"
7#include "src/core/SkOSFile.h"
Hal Canary5b39dc82019-04-17 13:29:46 -04008
Hal Canarya06f9d02019-12-03 14:27:04 -05009static bool update(SkBitmap* maxBitmap, SkBitmap* minBitmap, const SkBitmap& bm) {
Hal Canary5b39dc82019-04-17 13:29:46 -040010 SkASSERT(!bm.drawsNothing());
11 SkASSERT(4 == bm.bytesPerPixel());
12 if (maxBitmap->drawsNothing()) {
13 maxBitmap->allocPixels(bm.info());
14 maxBitmap->eraseColor(0x00000000);
15 minBitmap->allocPixels(bm.info());
16 minBitmap->eraseColor(0xFFFFFFFF);
17 }
Hal Canarya06f9d02019-12-03 14:27:04 -050018 if (maxBitmap->dimensions() != bm.dimensions()) {
19 return false;
20 }
Hal Canary5b39dc82019-04-17 13:29:46 -040021 SkASSERT_RELEASE(maxBitmap->info() == bm.info());
22 const SkPixmap& pmin = minBitmap->pixmap();
23 const SkPixmap& pmax = maxBitmap->pixmap();
24 const SkPixmap& pm = bm.pixmap();
25 for (int y = 0; y < pm.height(); ++y) {
26 for (int x = 0; x < pm.width(); ++x) {
27 uint32_t* minPtr = pmin.writable_addr32(x, y);
28 uint32_t* maxPtr = pmax.writable_addr32(x, y);
29 uint8_t minColor[4], maxColor[4], color[4];
30 memcpy(minColor, minPtr, 4);
31 memcpy(maxColor, maxPtr, 4);
32 memcpy(color, pm.addr32(x, y), 4);
33 for (unsigned i = 0; i < 4; ++i) {
34 minColor[i] = std::min(minColor[i], color[i]);
35 maxColor[i] = std::max(maxColor[i], color[i]);
36 }
37 memcpy(minPtr, minColor, 4);
38 memcpy(maxPtr, maxColor, 4);
39 }
40 }
Hal Canarya06f9d02019-12-03 14:27:04 -050041 return true;
Hal Canary5b39dc82019-04-17 13:29:46 -040042}
43
44static SkBitmap decode_to_srgb_8888_unpremul(const char* path) {
45 SkBitmap dst;
46 if (auto codec = SkCodec::MakeFromData(SkData::MakeFromFileName(path))) {
47 SkISize size = codec->getInfo().dimensions();
48 SkASSERT(!size.isEmpty());
49 dst.allocPixels(SkImageInfo::Make(
50 size.width(), size.height(), kRGBA_8888_SkColorType,
51 kUnpremul_SkAlphaType, SkColorSpace::MakeSRGB()));
52 if (SkCodec::kSuccess != codec->getPixels(dst.pixmap())) {
53 dst.reset();
54 }
55 }
56 return dst;
57}
58
59bool encode_png(const char* path, const SkPixmap& pixmap) {
60 if (!pixmap.addr()) {
61 return false;
62 }
63 SkPngEncoder::Options encOpts;
64 encOpts.fZLibLevel = 9; // slow encode;
65 SkFILEWStream o(path);
66 return o.isValid() && SkPngEncoder::Encode(&o, pixmap, encOpts);
67}
68
69int main(int argc, char** argv) {
70 SkASSERT_RELEASE(argc > 2);
71 const char* src_dir = argv[1];
72 const char* dst_dir = argv[2];
73 SkBitmap maxBitmap, minBitmap;
74 SkOSFile::Iter iter(src_dir);
75 SkString name;
76 while (iter.next(&name)) {
77 name.prependf("%s/", src_dir);
78 SkBitmap bm = decode_to_srgb_8888_unpremul(name.c_str());
Hal Canarya06f9d02019-12-03 14:27:04 -050079 if (bm.drawsNothing()) {
80 SkDebugf("'%s' failed to decode.\n", name.c_str());
81 continue;
82 }
83 if (!update(&maxBitmap, &minBitmap, bm)) {
84 SkDebugf("'%s' has unmatched dimensions.\n", name.c_str());
85 continue;
Hal Canary5b39dc82019-04-17 13:29:46 -040086 }
87 }
88 SkASSERT_RELEASE(sk_mkdir(dst_dir));
Hal Canarya06f9d02019-12-03 14:27:04 -050089 if ((maxBitmap.drawsNothing()) || (maxBitmap.drawsNothing())) {
90 SkDebugf("Failure: '%s' '%s'\n", src_dir, dst_dir);
91 return 1;
92 }
Hal Canary5b39dc82019-04-17 13:29:46 -040093 encode_png(SkStringPrintf("%s/min.png", dst_dir).c_str(), minBitmap.pixmap());
94 encode_png(SkStringPrintf("%s/max.png", dst_dir).c_str(), maxBitmap.pixmap());
Hal Canarya06f9d02019-12-03 14:27:04 -050095 return 0;
Hal Canary5b39dc82019-04-17 13:29:46 -040096}