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