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

Side by Side Diff: dm/DMWriteTask.cpp

Issue 549203003: Hash .pngs instead of SkBitmaps. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: gypi Created 6 years, 3 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 | « no previous file | gyp/tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "DMWriteTask.h" 1 #include "DMWriteTask.h"
2 2
3 #include "DMUtil.h" 3 #include "DMUtil.h"
4 #include "SkColorPriv.h" 4 #include "SkColorPriv.h"
5 #include "SkCommonFlags.h" 5 #include "SkCommonFlags.h"
6 #include "SkImageEncoder.h" 6 #include "SkImageEncoder.h"
7 #include "SkMD5.h" 7 #include "SkMD5.h"
8 #include "SkMallocPixelRef.h" 8 #include "SkMallocPixelRef.h"
9 #include "SkOSFile.h" 9 #include "SkOSFile.h"
10 #include "SkStream.h" 10 #include "SkStream.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 SkASSERT(fData.get()); 60 SkASSERT(fData.get());
61 SkASSERT(fData->unique()); 61 SkASSERT(fData->unique());
62 } 62 }
63 63
64 void WriteTask::makeDirOrFail(SkString dir) { 64 void WriteTask::makeDirOrFail(SkString dir) {
65 if (!sk_mkdir(dir.c_str())) { 65 if (!sk_mkdir(dir.c_str())) {
66 this->fail(); 66 this->fail();
67 } 67 }
68 } 68 }
69 69
70 static bool save_bitmap_to_file(SkBitmap bitmap, const char* path) { 70 static SkStreamAsset* encode_to_png(const SkBitmap& bitmap) {
71 SkFILEWStream stream(path); 71 SkDynamicMemoryWStream png;
72 if (!stream.isValid() || 72 if (!SkImageEncoder::EncodeStream(&png, bitmap, SkImageEncoder::kPNG_Type, 1 00)) {
73 !SkImageEncoder::EncodeStream(&stream, bitmap, SkImageEncoder::kPNG_Type , 100)) { 73 return NULL;
74 SkDebugf("Can't write a PNG to %s.\n", path);
75 return false;
76 } 74 }
77 return true; 75 png.copyToData()->unref(); // Forces detachAsStream() to be contiguous.
76 return png.detachAsStream();
78 } 77 }
79 78
80 // Does not take ownership of data. 79 static SkString get_md5(SkStreamAsset* src) {
81 static bool save_data_to_file(SkStreamAsset* data, const char* path) {
82 data->rewind();
83 SkFILEWStream stream(path);
84 if (!stream.isValid() || !stream.writeStream(data, data->getLength())) {
85 SkDebugf("Can't write data to %s.\n", path);
86 return false;
87 }
88 return true;
89 }
90
91 static SkString finish_hash(SkMD5* hasher) {
92 SkMD5::Digest digest;
93 hasher->finish(digest);
94
95 SkString out;
96 for (int i = 0; i < 16; i++) {
97 out.appendf("%02x", digest.data[i]);
98 }
99 return out;
100 }
101
102 static SkString hash(const SkBitmap& src) {
103 SkMD5 hasher;
104 {
105 SkAutoLockPixels lock(src);
106 hasher.write(src.getPixels(), src.getSize());
107 }
108 return finish_hash(&hasher);
109 }
110
111 static SkString hash(SkStreamAsset* src) {
112 SkMD5 hasher; 80 SkMD5 hasher;
113 hasher.write(src->getMemoryBase(), src->getLength()); 81 hasher.write(src->getMemoryBase(), src->getLength());
114 return finish_hash(&hasher); 82 SkMD5::Digest digest;
83 hasher.finish(digest);
84
85 SkString md5;
86 for (int i = 0; i < 16; i++) {
87 md5.appendf("%02x", digest.data[i]);
88 }
89 return md5;
115 } 90 }
116 91
117 void WriteTask::draw() { 92 void WriteTask::draw() {
118 JsonData entry = { 93 if (!fData.get()) {
119 fFullName, 94 fData.reset(encode_to_png(fBitmap));
120 fData ? hash(fData) : hash(fBitmap), 95 if (!fData.get()) {
121 }; 96 this->fail("Can't encode to PNG.");
97 }
98 }
122 99
100 JsonData entry = { fFullName, get_md5(fData) };
123 { 101 {
124 SkAutoMutexAcquire lock(&gJsonDataLock); 102 SkAutoMutexAcquire lock(&gJsonDataLock);
125 gJsonData.push_back(entry); 103 gJsonData.push_back(entry);
126 } 104 }
127 105
128 SkString dir(FLAGS_writePath[0]); 106 SkString dir(FLAGS_writePath[0]);
129 #if SK_BUILD_FOR_IOS 107 #if SK_BUILD_FOR_IOS
130 if (dir.equals("@")) { 108 if (dir.equals("@")) {
131 dir.set(FLAGS_resourcePath[0]); 109 dir.set(FLAGS_resourcePath[0]);
132 } 110 }
(...skipping 16 matching lines...) Expand all
149 for (int i = 0; i < fSuffixes.count(); i++) { 127 for (int i = 0; i < fSuffixes.count(); i++) {
150 dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str()); 128 dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str());
151 this->makeDirOrFail(dir); 129 this->makeDirOrFail(dir);
152 } 130 }
153 path = SkOSPath::Join(dir.c_str(), fBaseName.c_str()); 131 path = SkOSPath::Join(dir.c_str(), fBaseName.c_str());
154 path.append(fExtension); 132 path.append(fExtension);
155 // The path is unique, so two threads can't both write to the same file. 133 // The path is unique, so two threads can't both write to the same file.
156 // If already present we overwrite here, since the content may have chan ged. 134 // If already present we overwrite here, since the content may have chan ged.
157 } 135 }
158 136
159 const bool ok = fData.get() ? save_data_to_file(fData.get(), path.c_str()) 137 SkFILEWStream file(path.c_str());
160 : save_bitmap_to_file(fBitmap, path.c_str()); 138 if (!file.isValid()) {
161 if (!ok) { 139 return this->fail("Can't open file.");
162 this->fail(); 140 }
141
142 fData->rewind();
143 if (!file.writeStream(fData, fData->getLength())) {
144 return this->fail("Can't write to file.");
163 } 145 }
164 } 146 }
165 147
166 SkString WriteTask::name() const { 148 SkString WriteTask::name() const {
167 SkString name("writing "); 149 SkString name("writing ");
168 for (int i = 0; i < fSuffixes.count(); i++) { 150 for (int i = 0; i < fSuffixes.count(); i++) {
169 name.appendf("%s/", fSuffixes[i].c_str()); 151 name.appendf("%s/", fSuffixes[i].c_str());
170 } 152 }
171 name.append(fBaseName.c_str()); 153 name.append(fBaseName.c_str());
172 return name; 154 return name;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 return expectations.detach(); 188 return expectations.detach();
207 } 189 }
208 190
209 bool WriteTask::Expectations::check(const Task& task, SkBitmap bitmap) const { 191 bool WriteTask::Expectations::check(const Task& task, SkBitmap bitmap) const {
210 const SkString name = task.name(); 192 const SkString name = task.name();
211 if (fJson[name.c_str()].isNull()) { 193 if (fJson[name.c_str()].isNull()) {
212 return true; // No expectations. 194 return true; // No expectations.
213 } 195 }
214 196
215 const char* expected = fJson[name.c_str()].asCString(); 197 const char* expected = fJson[name.c_str()].asCString();
216 SkString actual = hash(bitmap); 198 SkAutoTDelete<SkStreamAsset> png(encode_to_png(bitmap));
199 SkString actual = get_md5(png);
217 return actual.equals(expected); 200 return actual.equals(expected);
218 } 201 }
219 202
220 void WriteTask::DumpJson() { 203 void WriteTask::DumpJson() {
221 if (FLAGS_writePath.isEmpty()) { 204 if (FLAGS_writePath.isEmpty()) {
222 return; 205 return;
223 } 206 }
224 207
225 // FIXME: This JSON format is a complete MVP strawman. 208 // FIXME: This JSON format is a complete MVP strawman.
226 Json::Value root; 209 Json::Value root;
227 { 210 {
228 SkAutoMutexAcquire lock(&gJsonDataLock); 211 SkAutoMutexAcquire lock(&gJsonDataLock);
229 for (int i = 0; i < gJsonData.count(); i++) { 212 for (int i = 0; i < gJsonData.count(); i++) {
230 root[gJsonData[i].name.c_str()] = gJsonData[i].md5.c_str(); 213 root[gJsonData[i].name.c_str()] = gJsonData[i].md5.c_str();
231 } 214 }
232 } 215 }
233 216
234 SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json"); 217 SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
235 SkFILEWStream stream(path.c_str()); 218 SkFILEWStream stream(path.c_str());
236 stream.writeText(Json::StyledWriter().write(root).c_str()); 219 stream.writeText(Json::StyledWriter().write(root).c_str());
237 stream.flush(); 220 stream.flush();
238 } 221 }
239 222
240 } // namespace DM 223 } // namespace DM
OLDNEW
« no previous file with comments | « no previous file | gyp/tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698