Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: experimental/tools/skp_to_pdf_md5.cpp

Issue 1233093004: experimental: remove old PDF benchmarking tools (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/tools/multipage_pdf_profiler.sh ('k') | gyp/experimental.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 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 #include "SkCanvas.h"
8 #include "SkCommandLineFlags.h"
9 #include "SkDocument.h"
10 #include "SkForceLinking.h"
11 #include "SkGraphics.h"
12 #include "SkMD5.h"
13 #include "SkOSFile.h"
14 #include "SkPicture.h"
15 #include "SkStream.h"
16 #include "SkTArray.h"
17 #include "SkTSort.h"
18
19 #include "SkDmuxWStream.h"
20
21 static const char kUsage[] =
22 "This program takes a list of Skia Picture (SKP) files and renders\n"
23 "each as a multipage PDF, then prints out the MD5 checksum of the\n"
24 "PDF file. This can be used to verify that changes to the PDF\n"
25 "backend will not change PDF output.\n";
26
27 __SK_FORCE_IMAGE_DECODER_LINKING;
28
29 DEFINE_string2(inputPaths,
30 r,
31 "",
32 "A list of directories and files to use as input.\n"
33 "Files are expected to have the .skp extension.");
34
35 DEFINE_string2(outputDirectoryPath, w, "", "TODO: document this");
36
37 static const char SKP_FILE_EXTENSION[] = ".skp";
38 static const char PDF_FILE_EXTENSION[] = ".pdf";
39
40 // Used by SkTQSort<SkString>()
41 static bool operator<(const SkString& a, const SkString& b) {
42 return strcmp(a.c_str(), b.c_str()) < 0;
43 }
44
45 // Process --inputPaths defined on the command line. Return false if
46 // no files found.
47 static bool process_input_files(SkTArray<SkString>* files) {
48 for (int i = 0; i < FLAGS_inputPaths.count(); i++) {
49 const char* input = FLAGS_inputPaths[i];
50 if (sk_isdir(input)) {
51 SkOSFile::Iter iter(input, SKP_FILE_EXTENSION);
52 SkString inputFilename;
53 while (iter.next(&inputFilename)) {
54 files->push_back(SkOSPath::Join(input, inputFilename.c_str()));
55 }
56 } else {
57 if (SkStrEndsWith(input, SKP_FILE_EXTENSION)) {
58 if (sk_exists(input)) {
59 files->push_back(SkString(input));
60 } else {
61 SkDebugf("file_does_not_exist %s\n", input);
62 }
63 } else {
64 SkDebugf("skipping_file %s\n", input);
65 }
66 }
67 }
68 if (files->count() > 0) {
69 SkTQSort<SkString>(files->begin(), files->end() - 1);
70 return true;
71 }
72 return false;
73 }
74
75 // Print the given SkPicture to a PDF, breaking on 8.5x11 pages.
76 static void picture_to_pdf(const SkPicture& picture, SkWStream* out) {
77 SkAutoTUnref<SkDocument> pdfDocument(SkDocument::CreatePDF(out));
78
79 int width = picture.cullRect().width();
80 int height = picture.cullRect().height();
81
82 const int kLetterWidth = 612; // 8.5 * 72
83 const int kLetterHeight = 792; // 11 * 72
84 SkRect letterRect = SkRect::MakeWH(SkIntToScalar(kLetterWidth),
85 SkIntToScalar(kLetterHeight));
86
87 int xPages = ((width - 1) / kLetterWidth) + 1;
88 int yPages = ((height - 1) / kLetterHeight) + 1;
89
90 for (int y = 0; y < yPages; ++y) {
91 for (int x = 0; x < xPages; ++x) {
92 int w = SkTMin(kLetterWidth, width - (x * kLetterWidth));
93 int h = SkTMin(kLetterHeight, height - (y * kLetterHeight));
94 SkCanvas* canvas = pdfDocument->beginPage(w, h);
95 canvas->clipRect(letterRect);
96 canvas->translate(SkIntToScalar(-kLetterWidth * x),
97 SkIntToScalar(-kLetterHeight * y));
98 canvas->drawPicture(&picture);
99 canvas->flush();
100 pdfDocument->endPage();
101 }
102 }
103 pdfDocument->close();
104 out->flush();
105 }
106
107 static bool skp_to_pdf_md5(SkStream* input, SkMD5::Digest* digest) {
108 SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(input));
109 if (NULL == picture.get()) {
110 return false;
111 }
112
113 SkMD5 checksumWStream;
114 picture_to_pdf(*picture, &checksumWStream);
115 checksumWStream.finish(*digest);
116 return true;
117 }
118
119 static bool skp_to_pdf_and_md5(SkStream* input,
120 const char* path,
121 SkMD5::Digest* digest) {
122 SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(input));
123 if (NULL == picture.get()) {
124 return false;
125 }
126
127 SkMD5 checksumWStream;
128 SkFILEWStream fileWStream(path);
129 SkWStream* wStreamArray[] = {&checksumWStream, &fileWStream};
130 SkDmuxWStream dmuxWStream(wStreamArray, SK_ARRAY_COUNT(wStreamArray));
131
132 picture_to_pdf(*picture, &dmuxWStream);
133 checksumWStream.finish(*digest);
134 return true;
135 }
136
137 SkString digest_to_hex(const SkMD5::Digest& digest) {
138 static const char kHex[] = "0123456789ABCDEF";
139 SkString string(2 * sizeof(digest.data));
140 char* p = string.writable_str();
141 for (size_t i = 0; i < sizeof(digest.data); ++i) {
142 uint8_t c = digest.data[i];
143 *(p++) = kHex[c >> 4];
144 *(p++) = kHex[c & 0xF];
145 }
146 return string;
147 }
148
149 static void str_replace_ending(SkString* str,
150 const char* oldExt,
151 const char* newExt) {
152 SkASSERT(str->endsWith(oldExt));
153 SkASSERT(str->size() >= strlen(oldExt));
154 str->remove(str->size() - strlen(oldExt), strlen(oldExt));
155 str->append(newExt);
156 }
157
158 int main(int argc, char** argv) {
159 SkCommandLineFlags::SetUsage(kUsage);
160 SkCommandLineFlags::Parse(argc, argv);
161 const char* outputDir = FLAGS_outputDirectoryPath.count() > 0
162 ? FLAGS_outputDirectoryPath[0]
163 : NULL;
164 if (outputDir) {
165 sk_mkdir(outputDir);
166 }
167
168 SkAutoGraphics ag;
169 int successCount = 0;
170 SkTArray<SkString> files;
171 if (!process_input_files(&files)) {
172 SkDebugf("You need to specify a --inputPaths option.\n");
173 return 1;
174 }
175 for (int i = 0; i < files.count(); ++i) {
176 SkString basename = SkOSPath::Basename(files[i].c_str());
177 SkFILEStream inputStream(files[i].c_str());
178 if (!inputStream.isValid()) {
179 SkDebugf("could_not_open %s\n", basename.c_str());
180 continue;
181 }
182 SkMD5::Digest digest;
183
184 if (outputDir) {
185 SkString path = SkOSPath::Join(outputDir, basename.c_str());
186 str_replace_ending(&path, SKP_FILE_EXTENSION, PDF_FILE_EXTENSION);
187 if (!skp_to_pdf_and_md5(&inputStream, path.c_str(), &digest)) {
188 SkDebugf("invalid_skp %s\n", basename.c_str());
189 continue;
190 }
191 } else {
192 if (!skp_to_pdf_md5(&inputStream, &digest)) {
193 SkDebugf("invalid_skp %s\n", basename.c_str());
194 continue;
195 }
196 }
197 SkString hexDigest = digest_to_hex(digest);
198 printf("%s %s\n", hexDigest.c_str(), basename.c_str());
199 ++successCount;
200 }
201 return successCount == files.count() ? 0 : 1;
202 }
203
OLDNEW
« no previous file with comments | « experimental/tools/multipage_pdf_profiler.sh ('k') | gyp/experimental.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698