15149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com/* 25149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com * Copyright 2013 Google Inc. 35149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com * 45149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com * Use of this source code is governed by a BSD-style license that can be 55149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com * found in the LICENSE file. 65149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com */ 75149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 85149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkBitmap.h" 95149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkColorPriv.h" 105149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkCommandLineFlags.h" 115149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkData.h" 125149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkForceLinking.h" 135149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkGraphics.h" 145149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkImageDecoder.h" 155149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkImageEncoder.h" 165149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkOSFile.h" 175149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkRandom.h" 185149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkStream.h" 195149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkTArray.h" 205149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#include "SkTemplates.h" 215149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 225149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com__SK_FORCE_IMAGE_DECODER_LINKING; 235149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 245149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comDEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required."); 255149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 265149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comstruct Format { 275149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkImageEncoder::Type fType; 285149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkImageDecoder::Format fFormat; 295149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com const char* fSuffix; 305149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com}; 315149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 320724e1fc2d3227bded0fe9bf07f467f2ba80fa30mtklein@google.com/* 335149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comstatic const Format gFormats[] = { 345149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kBMP_Type, SkImageDecoder::kBMP_Format, ".bmp" }, 355149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kGIF_Type, SkImageDecoder::kGIF_Format, ".gif" }, 365149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kICO_Type, SkImageDecoder::kICO_Format, ".ico" }, 375149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kJPEG_Type, SkImageDecoder::kJPEG_Format, ".jpg" }, 385149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kPNG_Type, SkImageDecoder::kPNG_Format, ".png" }, 395149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kWBMP_Type, SkImageDecoder::kWBMP_Format, ".wbmp" }, 405149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com { SkImageEncoder::kWEBP_Type, SkImageDecoder::kWEBP_Format, ".webp" } 415149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com}; 420724e1fc2d3227bded0fe9bf07f467f2ba80fa30mtklein@google.com*/ 435149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 4433f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.comstatic SkISize opaqueSize(const SkBitmap& bm) { 455149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com int width = 1; 465149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com int height = 1; 475149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com for (int y = 0 ; y < bm.height(); y++) { 4845be4eb90426e17bde8f36478cc02f076fdc87d9edisonn@google.com for (int x = 0 ; x < bm.width(); x++) { 495149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkColor color = bm.getColor(x, y); 505149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (SkColorGetA(color) != 0) { 515149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com height = y + 1; 525149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com width = width > (x + 1) ? width : x + 1; 535149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 545149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 555149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 565149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 575149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return SkISize::Make(width, height); 585149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 595149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 605149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comstatic void setup_bitmap(SkBitmap* bitmap, int width, int height) { 616c22573edb234ad14df947278cfed010669a39a7reed bitmap->allocN32Pixels(width, height); 625149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 635149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 645149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 655149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comstatic bool write_bitmap(const char outName[], const SkBitmap& bm) { 665149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkISize size = opaqueSize(bm); 675149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkBitmap dst; 685149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com setup_bitmap(&dst, size.width(), size.height()); 695149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 705149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com for (int y = 0 ; y < dst.height(); y++) { 715149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com for (int x = 0 ; x < dst.width(); x++) { 725149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkColor color = bm.getColor(x, y); 735149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (SkColorGetA(color) != 0xff) { 745149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com int a = SkColorGetA(color); 755149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com int r = SkColorGetR(color); 765149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com int g = SkColorGetG(color); 775149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com int b = SkColorGetB(color); 785149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (a == 0) { 795149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com r = g = b = 0; 805149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } else { 815149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com r = (r * a) / 255; 825149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com g = (g * a) / 255; 835149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com b = (b * a) / 255; 845149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com a = 255; 855149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 865149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com color = SkColorSetARGB((U8CPU)a, (U8CPU)r, (U8CPU)g, (U8CPU)b); 875149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 885149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com *dst.getAddr32(x, y) = color; 895149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 905149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 915149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 925149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return SkImageEncoder::EncodeFile(outName, dst, SkImageEncoder::kPNG_Type, 100); 935149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 945149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 955149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comstatic void decodeFileAndWrite(const char srcPath[]) { 965149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkBitmap bitmap; 975149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkFILEStream stream(srcPath); 985149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (!stream.isValid()) { 995149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return; 1005149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1015149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1025149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkImageDecoder* codec = SkImageDecoder::Factory(&stream); 1035149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (NULL == codec) { 1045149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return; 1055149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1065149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1075149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkAutoTDelete<SkImageDecoder> ad(codec); 1085149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1095149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com stream.rewind(); 1105149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 111bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed if (!codec->decode(&stream, &bitmap, kN32_SkColorType, SkImageDecoder::kDecodePixels_Mode)) { 1125149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return; 1135149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1145149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1155149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com write_bitmap(srcPath, bitmap); 1165149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 1175149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1185149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com/** 1195149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com * Return true if the filename represents an image. 1205149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com */ 1215149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comstatic bool is_image_file(const char* filename) { 1225149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com const char* gImageExtensions[] = { 1235149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com ".png", ".PNG", ".jpg", ".JPG", ".jpeg", ".JPEG", ".bmp", ".BMP", 1245149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com ".webp", ".WEBP", ".ico", ".ICO", ".wbmp", ".WBMP", ".gif", ".GIF" 1255149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com }; 1265149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gImageExtensions); ++i) { 1275149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (SkStrEndsWith(filename, gImageExtensions[i])) { 1285149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return true; 1295149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1305149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1315149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return false; 1325149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 1335149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1345149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comint tool_main(int argc, char** argv); 1355149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comint tool_main(int argc, char** argv) { 1365149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkCommandLineFlags::SetUsage("Decode files, and optionally write the results to files."); 1375149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkCommandLineFlags::Parse(argc, argv); 1385149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1395149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (FLAGS_readPath.count() < 1) { 1405149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkDebugf("Folder(s) or image(s) to decode are required.\n"); 1415149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return -1; 1425149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1435149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1445149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1455149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkAutoGraphics ag; 1465149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1475149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com for (int i = 0; i < FLAGS_readPath.count(); i++) { 1485149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com const char* readPath = FLAGS_readPath[i]; 1495149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (strlen(readPath) < 1) { 1505149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com break; 1515149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1525149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (sk_isdir(readPath)) { 1535149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com const char* dir = readPath; 1545149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkOSFile::Iter iter(dir); 1555149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com SkString filename; 1565149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com while (iter.next(&filename)) { 1575149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com if (!is_image_file(filename.c_str())) { 1585149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com continue; 1595149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 160a8e2e1504b9af6ba791637f228debaa23953064atfarina SkString fullname = SkOSPath::Join(dir, filename.c_str()); 1615149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com decodeFileAndWrite(fullname.c_str()); 1625149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1635149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } else if (sk_exists(readPath) && is_image_file(readPath)) { 1645149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com decodeFileAndWrite(readPath); 1655149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1665149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com } 1675149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1685149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return 0; 1695149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 1705149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com 1715149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#if !defined SK_BUILD_FOR_IOS 1725149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.comint main(int argc, char * const argv[]) { 1735149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com return tool_main(argc, (char**) argv); 1745149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com} 1755149bd954b301abb3cb1e6332c5c84a8d3b99681edisonn@google.com#endif 176