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

Side by Side Diff: tools/skimage_main.cpp

Issue 14567011: Test region decoding in skimage, plus fixes. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmap.h" 8 #include "SkBitmap.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkCommandLineFlags.h" 10 #include "SkCommandLineFlags.h"
11 #include "SkData.h" 11 #include "SkData.h"
12 #include "SkGraphics.h" 12 #include "SkGraphics.h"
13 #include "SkImageDecoder.h" 13 #include "SkImageDecoder.h"
14 #include "SkImageEncoder.h" 14 #include "SkImageEncoder.h"
15 #include "SkOSFile.h" 15 #include "SkOSFile.h"
16 #include "SkRandom.h"
16 #include "SkStream.h" 17 #include "SkStream.h"
17 #include "SkTArray.h" 18 #include "SkTArray.h"
18 #include "SkTemplates.h" 19 #include "SkTemplates.h"
19 20
20 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required. "); 21 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required. ");
21 DEFINE_string2(writePath, w, "", "Write rendered images into this directory."); 22 DEFINE_string2(writePath, w, "", "Write rendered images into this directory.");
22 DEFINE_bool(reencode, true, "Reencode the images to test encoding."); 23 DEFINE_bool(reencode, true, "Reencode the images to test encoding.");
24 DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images.");
23 25
24 struct Format { 26 struct Format {
25 SkImageEncoder::Type fType; 27 SkImageEncoder::Type fType;
26 SkImageDecoder::Format fFormat; 28 SkImageDecoder::Format fFormat;
27 const char* fSuffix; 29 const char* fSuffix;
28 }; 30 };
29 31
30 static const Format gFormats[] = { 32 static const Format gFormats[] = {
31 { SkImageEncoder::kBMP_Type, SkImageDecoder::kBMP_Format, ".bmp" }, 33 { SkImageEncoder::kBMP_Type, SkImageDecoder::kBMP_Format, ".bmp" },
32 { SkImageEncoder::kGIF_Type, SkImageDecoder::kGIF_Format, ".gif" }, 34 { SkImageEncoder::kGIF_Type, SkImageDecoder::kGIF_Format, ".gif" },
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 87 }
86 } 88 }
87 89
88 // Store the names of the filenames to report later which ones failed, succeeded , and were 90 // Store the names of the filenames to report later which ones failed, succeeded , and were
89 // invalid. 91 // invalid.
90 static SkTArray<SkString, false> gInvalidStreams; 92 static SkTArray<SkString, false> gInvalidStreams;
91 static SkTArray<SkString, false> gMissingCodecs; 93 static SkTArray<SkString, false> gMissingCodecs;
92 static SkTArray<SkString, false> gDecodeFailures; 94 static SkTArray<SkString, false> gDecodeFailures;
93 static SkTArray<SkString, false> gEncodeFailures; 95 static SkTArray<SkString, false> gEncodeFailures;
94 static SkTArray<SkString, false> gSuccessfulDecodes; 96 static SkTArray<SkString, false> gSuccessfulDecodes;
97 static SkTArray<SkString, false> gSuccessfulSubsetDecodes;
98 static SkTArray<SkString, false> gFailedSubsetDecodes;
95 99
96 static bool write_bitmap(const char outName[], SkBitmap* bm) { 100 static bool write_bitmap(const char outName[], SkBitmap* bm) {
97 SkBitmap bitmap8888; 101 SkBitmap bitmap8888;
98 if (SkBitmap::kARGB_8888_Config != bm->config()) { 102 if (SkBitmap::kARGB_8888_Config != bm->config()) {
99 if (!bm->copyTo(&bitmap8888, SkBitmap::kARGB_8888_Config)) { 103 if (!bm->copyTo(&bitmap8888, SkBitmap::kARGB_8888_Config)) {
100 return false; 104 return false;
101 } 105 }
102 bm = &bitmap8888; 106 bm = &bitmap8888;
103 } 107 }
104 // FIXME: This forces all pixels to be opaque, like the many implementations 108 // FIXME: This forces all pixels to be opaque, like the many implementations
105 // of force_all_opaque. These should be unified if they cannot be eliminated . 109 // of force_all_opaque. These should be unified if they cannot be eliminated .
106 SkAutoLockPixels lock(*bm); 110 SkAutoLockPixels lock(*bm);
107 for (int y = 0; y < bm->height(); y++) { 111 for (int y = 0; y < bm->height(); y++) {
108 for (int x = 0; x < bm->width(); x++) { 112 for (int x = 0; x < bm->width(); x++) {
109 *bm->getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT); 113 *bm->getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT);
110 } 114 }
111 } 115 }
112 return SkImageEncoder::EncodeFile(outName, *bm, SkImageEncoder::kPNG_Type, 1 00); 116 return SkImageEncoder::EncodeFile(outName, *bm, SkImageEncoder::kPNG_Type, 1 00);
113 } 117 }
114 118
119 static SkRandom gRand;
120
121 static SkIRect generate_random_rect(int32_t maxX, int32_t maxY) {
djsollen 2013/05/03 13:50:29 can you document that this function never returns
scroggo 2013/05/03 17:09:24 Actually, it's probably better to not return an em
122 int32_t left = gRand.nextULessThan(maxX);
123 int32_t right = gRand.nextULessThan(maxX);
124 int32_t top = gRand.nextULessThan(maxY);
125 int32_t bottom = gRand.nextULessThan(maxY);
126 SkIRect rect = SkIRect::MakeLTRB(left, top, right, bottom);
127 rect.sort();
128 return rect;
129 }
130
115 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) { 131 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) {
116 SkBitmap bitmap; 132 SkBitmap bitmap;
117 SkFILEStream stream(srcPath); 133 SkFILEStream stream(srcPath);
118 if (!stream.isValid()) { 134 if (!stream.isValid()) {
119 gInvalidStreams.push_back().set(srcPath); 135 gInvalidStreams.push_back().set(srcPath);
120 return; 136 return;
121 } 137 }
122 138
123 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); 139 SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
124 if (NULL == codec) { 140 if (NULL == codec) {
125 gMissingCodecs.push_back().set(srcPath); 141 gMissingCodecs.push_back().set(srcPath);
126 return; 142 return;
127 } 143 }
128 144
129 SkAutoTDelete<SkImageDecoder> ad(codec); 145 SkAutoTDelete<SkImageDecoder> ad(codec);
130 146
131 stream.rewind(); 147 stream.rewind();
132 if (!codec->decode(&stream, &bitmap, SkBitmap::kARGB_8888_Config, 148 if (!codec->decode(&stream, &bitmap, SkBitmap::kARGB_8888_Config,
133 SkImageDecoder::kDecodePixels_Mode)) { 149 SkImageDecoder::kDecodePixels_Mode)) {
134 gDecodeFailures.push_back().set(srcPath); 150 gDecodeFailures.push_back().set(srcPath);
135 return; 151 return;
136 } 152 }
137 153
138 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.width(), bitmap.height()); 154 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.width(), bitmap.height());
139 155
156 if (FLAGS_testSubsetDecoding) {
157 bool couldRewind = stream.rewind();
158 SkASSERT(couldRewind);
159 int width, height;
160 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig ht > 1) {
161 SkASSERT(bitmap.width() == width && bitmap.height() == height);
162 SkBitmap bitmapFromDecodeSubset;
163 // Call decodeSubset multiple times:
164 for (int i = 0; i < 5; i++) {
165 // FIXME: Come up with a good set of rectangles to use so the re sults can be
166 // compared against earlier results.
djsollen 2013/05/03 13:50:29 do you have any ideas on how to make this consiste
scroggo 2013/05/03 17:09:24 Yeah, that was what I was thinking, although I hop
167 SkIRect rect = generate_random_rect(width, height);
168 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft, rect.fTop,
169 rect.fRight, rect.fBottom);
170 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap: :kNo_Config)) {
171 gSuccessfulSubsetDecodes.push_back().printf("Decoded subset %s from %s",
172 subsetDim.c_str(), src Path);
173 if (writePath != NULL) {
174 // Write the region to a file whose name includes the di mensions.
175 SkString suffix = SkStringPrintf("_%s.png", subsetDim.c_ str());
176 SkString outPath;
177 make_outname(&outPath, writePath->c_str(), srcPath, suff ix.c_str());
178 bool success = write_bitmap(outPath.c_str(), &bitmapFrom DecodeSubset);
179 SkASSERT(success);
180 gSuccessfulSubsetDecodes.push_back().printf("\twrote %s" , outPath.c_str());
181 // Also use extractSubset from the original for visual c omparison.
djsollen 2013/05/03 13:50:29 does a pixel compare at this stage fail?
scroggo 2013/05/03 17:09:24 Yes. I do not yet know whether that is due to bugs
182 SkBitmap extractedSubset;
183 if (bitmap.extractSubset(&extractedSubset, rect)) {
184 suffix.printf("_%s_extracted.png", subsetDim.c_str() );
185 make_outname(&outPath, writePath->c_str(), srcPath, suffix.c_str());
186 success = write_bitmap(outPath.c_str(), &extractedSu bset);
187 SkASSERT(success);
188 }
189 }
190 } else {
191 gFailedSubsetDecodes.push_back().printf("Failed to decode re gion %s from %s\n",
192 subsetDim.c_str(), s rcPath);
193 }
194 }
195 }
196 }
140 if (FLAGS_reencode) { 197 if (FLAGS_reencode) {
141 // Encode to the format the file was originally in, or PNG if the encode r for the same 198 // Encode to the format the file was originally in, or PNG if the encode r for the same
142 // format is unavailable. 199 // format is unavailable.
143 SkImageDecoder::Format format = codec->getFormat(); 200 SkImageDecoder::Format format = codec->getFormat();
144 if (SkImageDecoder::kUnknown_Format == format) { 201 if (SkImageDecoder::kUnknown_Format == format) {
145 if (stream.rewind()) { 202 if (stream.rewind()) {
146 format = SkImageDecoder::GetStreamFormat(&stream); 203 format = SkImageDecoder::GetStreamFormat(&stream);
147 } 204 }
148 if (SkImageDecoder::kUnknown_Format == format) { 205 if (SkImageDecoder::kUnknown_Format == format) {
149 const char* dot = strrchr(srcPath, '.'); 206 const char* dot = strrchr(srcPath, '.');
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 339
283 // Add some space, since codecs may print warnings without newline. 340 // Add some space, since codecs may print warnings without newline.
284 SkDebugf("\n\n"); 341 SkDebugf("\n\n");
285 342
286 bool failed = print_strings("Invalid files", gInvalidStreams); 343 bool failed = print_strings("Invalid files", gInvalidStreams);
287 failed |= print_strings("Missing codec", gMissingCodecs); 344 failed |= print_strings("Missing codec", gMissingCodecs);
288 failed |= print_strings("Failed to decode", gDecodeFailures); 345 failed |= print_strings("Failed to decode", gDecodeFailures);
289 failed |= print_strings("Failed to encode", gEncodeFailures); 346 failed |= print_strings("Failed to encode", gEncodeFailures);
290 print_strings("Decoded", gSuccessfulDecodes); 347 print_strings("Decoded", gSuccessfulDecodes);
291 348
349 if (FLAGS_testSubsetDecoding) {
350 failed |= print_strings("Failed subset decodes", gFailedSubsetDecodes);
351 print_strings("Decoded subsets", gSuccessfulSubsetDecodes);
352 }
353
292 return failed ? -1 : 0; 354 return failed ? -1 : 0;
293 } 355 }
294 356
295 #if !defined SK_BUILD_FOR_IOS 357 #if !defined SK_BUILD_FOR_IOS
296 int main(int argc, char * const argv[]) { 358 int main(int argc, char * const argv[]) {
297 return tool_main(argc, (char**) argv); 359 return tool_main(argc, (char**) argv);
298 } 360 }
299 #endif 361 #endif
OLDNEW
« src/images/SkImageDecoder.cpp ('K') | « src/images/SkImageDecoder_libwebp.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698