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

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: Small comment fix. 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
« no previous file with comments | « src/images/SkImageDecoder_libwebp.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /**
120 * Return a random SkIRect inside the range specified.
121 * @param rand Random number generator.
122 * @param maxX Exclusive maximum x-coordinate. SkIRect's fLeft and fRight will be
123 * in the range [0, maxX)
124 * @param maxY Exclusive maximum y-coordinate. SkIRect's fTop and fBottom will be
125 * in the range [0, maxY)
126 * @return SkIRect Non-empty, non-degenerate rectangle.
127 */
128 static SkIRect generate_random_rect(SkRandom* rand, int32_t maxX, int32_t maxY) {
129 SkASSERT(maxX > 1 && maxY > 1);
130 int32_t left = rand->nextULessThan(maxX);
131 int32_t right = rand->nextULessThan(maxX);
132 int32_t top = rand->nextULessThan(maxY);
133 int32_t bottom = rand->nextULessThan(maxY);
134 SkIRect rect = SkIRect::MakeLTRB(left, top, right, bottom);
135 rect.sort();
136 // Make sure rect is not empty.
137 if (rect.fLeft == rect.fRight) {
138 if (rect.fLeft > 0) {
139 rect.fLeft--;
140 } else {
141 rect.fRight++;
142 // This branch is only taken if 0 == rect.fRight, and
143 // maxX must be at least 2, so it must still be in
144 // range.
145 SkASSERT(rect.fRight < maxX);
146 }
147 }
148 if (rect.fTop == rect.fBottom) {
149 if (rect.fTop > 0) {
150 rect.fTop--;
151 } else {
152 rect.fBottom++;
153 // Again, this must be in range.
154 SkASSERT(rect.fBottom < maxY);
155 }
156 }
157 return rect;
158 }
159
115 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) { 160 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) {
116 SkBitmap bitmap; 161 SkBitmap bitmap;
117 SkFILEStream stream(srcPath); 162 SkFILEStream stream(srcPath);
118 if (!stream.isValid()) { 163 if (!stream.isValid()) {
119 gInvalidStreams.push_back().set(srcPath); 164 gInvalidStreams.push_back().set(srcPath);
120 return; 165 return;
121 } 166 }
122 167
123 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); 168 SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
124 if (NULL == codec) { 169 if (NULL == codec) {
125 gMissingCodecs.push_back().set(srcPath); 170 gMissingCodecs.push_back().set(srcPath);
126 return; 171 return;
127 } 172 }
128 173
129 SkAutoTDelete<SkImageDecoder> ad(codec); 174 SkAutoTDelete<SkImageDecoder> ad(codec);
130 175
131 stream.rewind(); 176 stream.rewind();
132 if (!codec->decode(&stream, &bitmap, SkBitmap::kARGB_8888_Config, 177 if (!codec->decode(&stream, &bitmap, SkBitmap::kARGB_8888_Config,
133 SkImageDecoder::kDecodePixels_Mode)) { 178 SkImageDecoder::kDecodePixels_Mode)) {
134 gDecodeFailures.push_back().set(srcPath); 179 gDecodeFailures.push_back().set(srcPath);
135 return; 180 return;
136 } 181 }
137 182
138 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.width(), bitmap.height()); 183 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.width(), bitmap.height());
139 184
185 if (FLAGS_testSubsetDecoding) {
186 bool couldRewind = stream.rewind();
187 SkASSERT(couldRewind);
188 int width, height;
189 // Build the tile index for decoding subsets. If the image is 1x1, skip subset
190 // decoding since there are no smaller subsets.
191 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig ht > 1) {
192 SkASSERT(bitmap.width() == width && bitmap.height() == height);
193 // Call decodeSubset multiple times:
194 SkRandom rand(0);
195 for (int i = 0; i < 5; i++) {
196 SkBitmap bitmapFromDecodeSubset;
197 // FIXME: Come up with a more representative set of rectangles.
198 SkIRect rect = generate_random_rect(&rand, width, height);
199 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft, rect.fTop,
200 rect.fRight, rect.fBottom);
201 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap: :kNo_Config)) {
202 gSuccessfulSubsetDecodes.push_back().printf("Decoded subset %s from %s",
203 subsetDim.c_str(), src Path);
204 if (writePath != NULL) {
205 // Write the region to a file whose name includes the di mensions.
206 SkString suffix = SkStringPrintf("_%s.png", subsetDim.c_ str());
207 SkString outPath;
208 make_outname(&outPath, writePath->c_str(), srcPath, suff ix.c_str());
209 bool success = write_bitmap(outPath.c_str(), &bitmapFrom DecodeSubset);
210 SkASSERT(success);
211 gSuccessfulSubsetDecodes.push_back().printf("\twrote %s" , outPath.c_str());
212 // Also use extractSubset from the original for visual c omparison.
213 SkBitmap extractedSubset;
214 if (bitmap.extractSubset(&extractedSubset, rect)) {
215 suffix.printf("_%s_extracted.png", subsetDim.c_str() );
216 make_outname(&outPath, writePath->c_str(), srcPath, suffix.c_str());
217 success = write_bitmap(outPath.c_str(), &extractedSu bset);
218 SkASSERT(success);
219 }
220 }
221 } else {
222 gFailedSubsetDecodes.push_back().printf("Failed to decode re gion %s from %s\n",
223 subsetDim.c_str(), s rcPath);
224 }
225 }
226 }
227 }
140 if (FLAGS_reencode) { 228 if (FLAGS_reencode) {
141 // Encode to the format the file was originally in, or PNG if the encode r for the same 229 // Encode to the format the file was originally in, or PNG if the encode r for the same
142 // format is unavailable. 230 // format is unavailable.
143 SkImageDecoder::Format format = codec->getFormat(); 231 SkImageDecoder::Format format = codec->getFormat();
144 if (SkImageDecoder::kUnknown_Format == format) { 232 if (SkImageDecoder::kUnknown_Format == format) {
145 if (stream.rewind()) { 233 if (stream.rewind()) {
146 format = SkImageDecoder::GetStreamFormat(&stream); 234 format = SkImageDecoder::GetStreamFormat(&stream);
147 } 235 }
148 if (SkImageDecoder::kUnknown_Format == format) { 236 if (SkImageDecoder::kUnknown_Format == format) {
149 const char* dot = strrchr(srcPath, '.'); 237 const char* dot = strrchr(srcPath, '.');
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 370
283 // Add some space, since codecs may print warnings without newline. 371 // Add some space, since codecs may print warnings without newline.
284 SkDebugf("\n\n"); 372 SkDebugf("\n\n");
285 373
286 bool failed = print_strings("Invalid files", gInvalidStreams); 374 bool failed = print_strings("Invalid files", gInvalidStreams);
287 failed |= print_strings("Missing codec", gMissingCodecs); 375 failed |= print_strings("Missing codec", gMissingCodecs);
288 failed |= print_strings("Failed to decode", gDecodeFailures); 376 failed |= print_strings("Failed to decode", gDecodeFailures);
289 failed |= print_strings("Failed to encode", gEncodeFailures); 377 failed |= print_strings("Failed to encode", gEncodeFailures);
290 print_strings("Decoded", gSuccessfulDecodes); 378 print_strings("Decoded", gSuccessfulDecodes);
291 379
380 if (FLAGS_testSubsetDecoding) {
381 failed |= print_strings("Failed subset decodes", gFailedSubsetDecodes);
382 print_strings("Decoded subsets", gSuccessfulSubsetDecodes);
383 }
384
292 return failed ? -1 : 0; 385 return failed ? -1 : 0;
293 } 386 }
294 387
295 #if !defined SK_BUILD_FOR_IOS 388 #if !defined SK_BUILD_FOR_IOS
296 int main(int argc, char * const argv[]) { 389 int main(int argc, char * const argv[]) {
297 return tool_main(argc, (char**) argv); 390 return tool_main(argc, (char**) argv);
298 } 391 }
299 #endif 392 #endif
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_libwebp.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698