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