Home | History | Annotate | Download | only in PdfViewer
      1 /*
      2  * Copyright 2013 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 "SkBitmap.h"
      9 #include "SkColorPriv.h"
     10 #include "SkCommandLineFlags.h"
     11 #include "SkData.h"
     12 #include "SkForceLinking.h"
     13 #include "SkGraphics.h"
     14 #include "SkImageDecoder.h"
     15 #include "SkImageEncoder.h"
     16 #include "SkOSFile.h"
     17 #include "SkRandom.h"
     18 #include "SkStream.h"
     19 #include "SkTArray.h"
     20 #include "SkTemplates.h"
     21 
     22 __SK_FORCE_IMAGE_DECODER_LINKING;
     23 
     24 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.");
     25 
     26 struct Format {
     27     SkImageEncoder::Type    fType;
     28     SkImageDecoder::Format  fFormat;
     29     const char*             fSuffix;
     30 };
     31 
     32 /*
     33 static const Format gFormats[] = {
     34     { SkImageEncoder::kBMP_Type, SkImageDecoder::kBMP_Format, ".bmp" },
     35     { SkImageEncoder::kGIF_Type, SkImageDecoder::kGIF_Format, ".gif" },
     36     { SkImageEncoder::kICO_Type, SkImageDecoder::kICO_Format, ".ico" },
     37     { SkImageEncoder::kJPEG_Type, SkImageDecoder::kJPEG_Format, ".jpg" },
     38     { SkImageEncoder::kPNG_Type, SkImageDecoder::kPNG_Format, ".png" },
     39     { SkImageEncoder::kWBMP_Type, SkImageDecoder::kWBMP_Format, ".wbmp" },
     40     { SkImageEncoder::kWEBP_Type, SkImageDecoder::kWEBP_Format, ".webp" }
     41 };
     42 */
     43 
     44 static SkISize opaqueSize(const SkBitmap& bm) {
     45     int width = 1;
     46     int height = 1;
     47     for (int y = 0 ; y < bm.height(); y++) {
     48         for (int x = 0 ; x < bm.width(); x++) {
     49             SkColor color = bm.getColor(x, y);
     50             if (SkColorGetA(color) != 0) {
     51                 height = y + 1;
     52                 width = width > (x + 1) ? width : x + 1;
     53             }
     54         }
     55     }
     56 
     57     return SkISize::Make(width, height);
     58 }
     59 
     60 static void setup_bitmap(SkBitmap* bitmap, int width, int height) {
     61     bitmap->allocN32Pixels(width, height);
     62 }
     63 
     64 
     65 static bool write_bitmap(const char outName[], const SkBitmap& bm) {
     66     SkISize size = opaqueSize(bm);
     67     SkBitmap dst;
     68     setup_bitmap(&dst, size.width(), size.height());
     69 
     70     for (int y = 0 ; y < dst.height(); y++) {
     71         for (int x = 0 ; x < dst.width(); x++) {
     72             SkColor color = bm.getColor(x, y);
     73             if (SkColorGetA(color) != 0xff) {
     74                 int a = SkColorGetA(color);
     75                 int r = SkColorGetR(color);
     76                 int g = SkColorGetG(color);
     77                 int b = SkColorGetB(color);
     78                 if (a == 0) {
     79                     r = g = b = 0;
     80                 } else {
     81                     r = (r * a) / 255;
     82                     g = (g * a) / 255;
     83                     b = (b * a) / 255;
     84                     a = 255;
     85                 }
     86                 color = SkColorSetARGB((U8CPU)a, (U8CPU)r, (U8CPU)g, (U8CPU)b);
     87             }
     88             *dst.getAddr32(x, y) = color;
     89         }
     90     }
     91 
     92     return SkImageEncoder::EncodeFile(outName, dst, SkImageEncoder::kPNG_Type, 100);
     93 }
     94 
     95 static void decodeFileAndWrite(const char srcPath[]) {
     96     SkBitmap bitmap;
     97     SkFILEStream stream(srcPath);
     98     if (!stream.isValid()) {
     99         return;
    100     }
    101 
    102     SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
    103     if (NULL == codec) {
    104         return;
    105     }
    106 
    107     SkAutoTDelete<SkImageDecoder> ad(codec);
    108 
    109     stream.rewind();
    110 
    111     if (!codec->decode(&stream, &bitmap, kN32_SkColorType, SkImageDecoder::kDecodePixels_Mode)) {
    112         return;
    113     }
    114 
    115     write_bitmap(srcPath, bitmap);
    116 }
    117 
    118 /**
    119  *  Return true if the filename represents an image.
    120  */
    121 static bool is_image_file(const char* filename) {
    122     const char* gImageExtensions[] = {
    123         ".png", ".PNG", ".jpg", ".JPG", ".jpeg", ".JPEG", ".bmp", ".BMP",
    124         ".webp", ".WEBP", ".ico", ".ICO", ".wbmp", ".WBMP", ".gif", ".GIF"
    125     };
    126     for (size_t i = 0; i < SK_ARRAY_COUNT(gImageExtensions); ++i) {
    127         if (SkStrEndsWith(filename, gImageExtensions[i])) {
    128             return true;
    129         }
    130     }
    131     return false;
    132 }
    133 
    134 int tool_main(int argc, char** argv);
    135 int tool_main(int argc, char** argv) {
    136     SkCommandLineFlags::SetUsage("Decode files, and optionally write the results to files.");
    137     SkCommandLineFlags::Parse(argc, argv);
    138 
    139     if (FLAGS_readPath.count() < 1) {
    140         SkDebugf("Folder(s) or image(s) to decode are required.\n");
    141         return -1;
    142     }
    143 
    144 
    145     SkAutoGraphics ag;
    146 
    147     for (int i = 0; i < FLAGS_readPath.count(); i++) {
    148         const char* readPath = FLAGS_readPath[i];
    149         if (strlen(readPath) < 1) {
    150             break;
    151         }
    152         if (sk_isdir(readPath)) {
    153             const char* dir = readPath;
    154             SkOSFile::Iter iter(dir);
    155             SkString filename;
    156             while (iter.next(&filename)) {
    157                 if (!is_image_file(filename.c_str())) {
    158                     continue;
    159                 }
    160                 SkString fullname = SkOSPath::SkPathJoin(dir, filename.c_str());
    161                 decodeFileAndWrite(fullname.c_str());
    162             }
    163         } else if (sk_exists(readPath) && is_image_file(readPath)) {
    164             decodeFileAndWrite(readPath);
    165         }
    166     }
    167 
    168     return 0;
    169 }
    170 
    171 #if !defined SK_BUILD_FOR_IOS
    172 int main(int argc, char * const argv[]) {
    173     return tool_main(argc, (char**) argv);
    174 }
    175 #endif
    176