• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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 "SkDebugCanvas.h"
9 #include "SkDevice.h"
10 #include "SkGraphics.h"
11 #include "SkImageDecoder.h"
12 #include "SkImageEncoder.h"
13 #include "SkOSFile.h"
14 #include "SkPicture.h"
15 #include "SkPicturePlayback.h"
16 #include "SkPictureRecord.h"
17 #include "SkStream.h"
18 #include "picture_utils.h"
19 #include "path_utils.h"
20 
usage()21 static void usage() {
22     SkDebugf("Usage: filter -i inFile [-o outFile] [--input-dir path] [--output-dir path]\n");
23     SkDebugf("                        [-h|--help]\n\n");
24     SkDebugf("    -i inFile  : file to file.\n");
25     SkDebugf("    -o outFile : result of filtering.\n");
26     SkDebugf("    --input-dir : process all files in dir with .skp extension.\n");
27     SkDebugf("    --output-dir : results of filtering the input dir.\n");
28     SkDebugf("    -h|--help  : Show this help message.\n");
29 }
30 
31 // Is the supplied paint simply a color?
is_simple(const SkPaint & p)32 static bool is_simple(const SkPaint& p) {
33     return NULL == p.getPathEffect() &&
34            NULL == p.getShader() &&
35            NULL == p.getXfermode() &&
36            NULL == p.getMaskFilter() &&
37            NULL == p.getColorFilter() &&
38            NULL == p.getRasterizer() &&
39            NULL == p.getLooper() &&
40            NULL == p.getImageFilter();
41 }
42 
filter_picture(const SkString & inFile,const SkString & outFile)43 static int filter_picture(const SkString& inFile, const SkString& outFile) {
44     SkPicture* inPicture = NULL;
45 
46     SkFILEStream inStream(inFile.c_str());
47     if (inStream.isValid()) {
48         inPicture = SkNEW_ARGS(SkPicture, (&inStream, NULL, &SkImageDecoder::DecodeStream));
49     }
50 
51     if (NULL == inPicture) {
52         SkDebugf("Could not read file %s\n", inFile.c_str());
53         return -1;
54     }
55 
56     SkDebugCanvas debugCanvas(inPicture->width(), inPicture->height());
57     debugCanvas.setBounds(inPicture->width(), inPicture->height());
58     inPicture->draw(&debugCanvas);
59 
60     const SkTDArray<SkDrawCommand*>& commands = debugCanvas.getDrawCommands();
61 
62     for (int i = 0; i < commands.count(); ++i) {
63         // Check for:
64         //    SAVE_LAYER
65         //      DRAW_BITMAP_RECT_TO_RECT
66         //    RESTORE
67         // where the saveLayer's color can be moved into the drawBitmapRect
68         if (SAVE_LAYER == commands[i]->getType() && commands.count() > i+2) {
69             if (DRAW_BITMAP_RECT_TO_RECT == commands[i+1]->getType() &&
70                 RESTORE == commands[i+2]->getType()) {
71                 SaveLayer* sl = (SaveLayer*) commands[i];
72                 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[i+1];
73 
74                 const SkPaint* p0 = sl->paint();
75                 SkPaint* p1 = dbmr->paint();
76 
77                 if (NULL == p0) {
78                     commands[i]->setVisible(false);
79                     commands[i+2]->setVisible(false);
80                 } else if (NULL == p1) {
81                     commands[i]->setVisible(false);
82                     dbmr->setPaint(*p0);
83                     commands[i+2]->setVisible(false);
84                 } else if (is_simple(*p0) &&
85                            (SkColorGetR(p0->getColor()) == SkColorGetR(p1->getColor())) &&
86                            (SkColorGetG(p0->getColor()) == SkColorGetG(p1->getColor())) &&
87                            (SkColorGetB(p0->getColor()) == SkColorGetB(p1->getColor()))) {
88                     commands[i]->setVisible(false);
89                     SkColor newColor = SkColorSetA(p1->getColor(),
90                                                    SkColorGetA(p0->getColor()));
91                     p1->setColor(newColor);
92                     commands[i+2]->setVisible(false);
93                 }
94             }
95         }
96     }
97 
98     if (!outFile.isEmpty()) {
99         SkPicture outPicture;
100 
101         SkCanvas* canvas = outPicture.beginRecording(inPicture->width(), inPicture->height());
102         debugCanvas.draw(canvas);
103         outPicture.endRecording();
104 
105         SkFILEWStream outStream(outFile.c_str());
106 
107         outPicture.serialize(&outStream);
108     }
109 
110     return 0;
111 }
112 
113 // This function is not marked as 'static' so it can be referenced externally
114 // in the iOS build.
115 int tool_main(int argc, char** argv); // suppress a warning on mac
116 
tool_main(int argc,char ** argv)117 int tool_main(int argc, char** argv) {
118     SkGraphics::Init();
119 
120     if (argc < 3) {
121         usage();
122         return -1;
123     }
124 
125     SkString inFile, outFile, inDir, outDir;
126 
127     char* const* stop = argv + argc;
128     for (++argv; argv < stop; ++argv) {
129         if (strcmp(*argv, "-i") == 0) {
130             argv++;
131             if (argv < stop && **argv) {
132                 inFile.set(*argv);
133             } else {
134                 SkDebugf("missing arg for -i\n");
135                 usage();
136                 return -1;
137             }
138         } else if (strcmp(*argv, "--input-dir") == 0) {
139             argv++;
140             if (argv < stop && **argv) {
141                 inDir.set(*argv);
142             } else {
143                 SkDebugf("missing arg for --input-dir\n");
144                 usage();
145                 return -1;
146             }
147         } else if (strcmp(*argv, "--output-dir") == 0) {
148             argv++;
149             if (argv < stop && **argv) {
150                 outDir.set(*argv);
151             } else {
152                 SkDebugf("missing arg for --output-dir\n");
153                 usage();
154                 return -1;
155             }
156         } else if (strcmp(*argv, "-o") == 0) {
157             argv++;
158             if (argv < stop && **argv) {
159                 outFile.set(*argv);
160             } else {
161                 SkDebugf("missing arg for -o\n");
162                 usage();
163                 return -1;
164             }
165         } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
166             usage();
167             return 0;
168         } else {
169             SkDebugf("unknown arg %s\n", *argv);
170             usage();
171             return -1;
172         }
173     }
174 
175     SkOSFile::Iter iter(inDir.c_str(), "skp");
176 
177     SkString inputFilename, outputFilename;
178     if (iter.next(&inputFilename)) {
179 
180         do {
181             sk_tools::make_filepath(&inFile, inDir, inputFilename);
182             if (!outDir.isEmpty()) {
183                 sk_tools::make_filepath(&outFile, outDir, inputFilename);
184             }
185             SkDebugf("Executing %s\n", inputFilename.c_str());
186             filter_picture(inFile, outFile);
187         } while(iter.next(&inputFilename));
188 
189     } else if (!inFile.isEmpty()) {
190         filter_picture(inFile, outFile);
191     } else {
192         usage();
193         return -1;
194     }
195 
196     SkGraphics::Term();
197     return 0;
198 }
199 
200 #if !defined SK_BUILD_FOR_IOS
main(int argc,char * const argv[])201 int main(int argc, char * const argv[]) {
202     return tool_main(argc, (char**) argv);
203 }
204 #endif
205