OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "DMSrcSink.h" | 8 #include "DMSrcSink.h" |
9 #include "SamplePipeControllers.h" | 9 #include "SamplePipeControllers.h" |
10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 return gm->getName(); | 57 return gm->getName(); |
58 } | 58 } |
59 | 59 |
60 void GMSrc::modifyGrContextOptions(GrContextOptions* options) const { | 60 void GMSrc::modifyGrContextOptions(GrContextOptions* options) const { |
61 SkAutoTDelete<skiagm::GM> gm(fFactory(NULL)); | 61 SkAutoTDelete<skiagm::GM> gm(fFactory(NULL)); |
62 gm->modifyGrContextOptions(options); | 62 gm->modifyGrContextOptions(options); |
63 } | 63 } |
64 | 64 |
65 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 65 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
66 | 66 |
67 CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType) | 67 CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale) |
68 : fPath(path) | 68 : fPath(path) |
69 , fMode(mode) | 69 , fMode(mode) |
70 , fDstColorType(dstColorType) | 70 , fDstColorType(dstColorType) |
71 , fScale(scale) | |
71 {} | 72 {} |
72 | 73 |
73 Error CodecSrc::draw(SkCanvas* canvas) const { | 74 Error CodecSrc::draw(SkCanvas* canvas) const { |
74 SkImageInfo canvasInfo; | 75 SkImageInfo canvasInfo; |
75 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { | 76 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { |
76 // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a de ferred decode to | 77 // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a de ferred decode to |
77 // let the GPU handle it. | 78 // let the GPU handle it. |
78 return Error::Nonfatal("No need to test decoding to non-raster backend." ); | 79 return Error::Nonfatal("No need to test decoding to non-raster backend." ); |
79 } | 80 } |
80 | 81 |
(...skipping 20 matching lines...) Expand all Loading... | |
101 decodeInfo = codec->getInfo().makeColorType(kGray_8_SkColorType); | 102 decodeInfo = codec->getInfo().makeColorType(kGray_8_SkColorType); |
102 if (kRGB_565_SkColorType == canvasColorType) { | 103 if (kRGB_565_SkColorType == canvasColorType) { |
103 return Error::Nonfatal("Testing non-565 to 565 is uninteresting. "); | 104 return Error::Nonfatal("Testing non-565 to 565 is uninteresting. "); |
104 } | 105 } |
105 break; | 106 break; |
106 default: | 107 default: |
107 decodeInfo = decodeInfo.makeColorType(canvasColorType); | 108 decodeInfo = decodeInfo.makeColorType(canvasColorType); |
108 break; | 109 break; |
109 } | 110 } |
110 | 111 |
112 // Try to scale the image if it is desired | |
113 SkISize size = codec->getScaledDimensions(fScale); | |
114 if (size == decodeInfo.dimensions() && 1.0f != fScale) { | |
115 return Error::Nonfatal("Test without scaling is uninteresting."); | |
116 } | |
117 decodeInfo = decodeInfo.makeWH(size.width(), size.height()); | |
118 | |
111 // Construct a color table for the decode if necessary | 119 // Construct a color table for the decode if necessary |
112 SkAutoTUnref<SkColorTable> colorTable(NULL); | 120 SkAutoTUnref<SkColorTable> colorTable(NULL); |
113 SkPMColor* colorPtr = NULL; | 121 SkPMColor* colorPtr = NULL; |
114 int* colorCountPtr = NULL; | 122 int* colorCountPtr = NULL; |
115 int maxColors = 256; | 123 int maxColors = 256; |
116 if (kIndex_8_SkColorType == decodeInfo.colorType()) { | 124 if (kIndex_8_SkColorType == decodeInfo.colorType()) { |
117 SkPMColor colors[256]; | 125 SkPMColor colors[256]; |
118 colorTable.reset(SkNEW_ARGS(SkColorTable, (colors, maxColors))); | 126 colorTable.reset(SkNEW_ARGS(SkColorTable, (colors, maxColors))); |
119 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); | 127 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); |
120 colorCountPtr = &maxColors; | 128 colorCountPtr = &maxColors; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 const int extraY = h % divisor; | 196 const int extraY = h % divisor; |
189 /* | 197 /* |
190 * if w or h are not evenly divided by divisor need to adjust width a nd height of end | 198 * if w or h are not evenly divided by divisor need to adjust width a nd height of end |
191 * subsets to cover entire image. | 199 * subsets to cover entire image. |
192 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width | 200 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width |
193 * and height of end subsets. | 201 * and height of end subsets. |
194 * subsetBm is extracted from largestSubsetBm. | 202 * subsetBm is extracted from largestSubsetBm. |
195 * subsetBm's size is determined based on the current subset and may be larger for end | 203 * subsetBm's size is determined based on the current subset and may be larger for end |
196 * subsets. | 204 * subsets. |
197 */ | 205 */ |
198 SkImageInfo largestSubsetDecodeInfo = | 206 SkImageInfo largestSubsetDecodeInfo = |
199 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); | 207 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); |
200 SkBitmap largestSubsetBm; | 208 SkBitmap largestSubsetBm; |
201 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { | 209 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { |
202 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), | 210 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), |
203 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); | 211 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); |
204 } | 212 } |
205 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); | 213 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); |
206 SkAutoTDeleteArray<char> lineDeleter(line); | 214 SkAutoTDeleteArray<char> lineDeleter(line); |
207 for (int col = 0; col < divisor; col++) { | 215 for (int col = 0; col < divisor; col++) { |
208 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets | 216 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets |
(...skipping 10 matching lines...) Expand all Loading... | |
219 NULL, colorPtr, colorCountPtr); | 227 NULL, colorPtr, colorCountPtr); |
220 if (NULL == subsetScanlineDecoder) { | 228 if (NULL == subsetScanlineDecoder) { |
221 if (x == 0 && y == 0) { | 229 if (x == 0 && y == 0) { |
222 //first try, image may not be compatible | 230 //first try, image may not be compatible |
223 return Error::Nonfatal("Cannot use scanline decoder for all images"); | 231 return Error::Nonfatal("Cannot use scanline decoder for all images"); |
224 } else { | 232 } else { |
225 return "Error scanline decoder is NULL"; | 233 return "Error scanline decoder is NULL"; |
226 } | 234 } |
227 } | 235 } |
228 //skip to first line of subset | 236 //skip to first line of subset |
229 const SkImageGenerator::Result skipResult = | 237 const SkImageGenerator::Result skipResult = |
230 subsetScanlineDecoder->skipScanlines(y); | 238 subsetScanlineDecoder->skipScanlines(y); |
231 switch (skipResult) { | 239 switch (skipResult) { |
232 case SkImageGenerator::kSuccess: | 240 case SkImageGenerator::kSuccess: |
233 case SkImageGenerator::kIncompleteInput: | 241 case SkImageGenerator::kIncompleteInput: |
234 break; | 242 break; |
235 default: | 243 default: |
236 return SkStringPrintf("%s failed after attempting to skip %d scanlines" | 244 return SkStringPrintf("%s failed after attempting to skip %d scanlines" |
237 "with error message %d", fPath.c_str(), y, ( int) skipResult); | 245 "with error message %d", fPath.c_str(), y, ( int) skipResult); |
238 } | 246 } |
239 //create and set size of subsetBm | 247 //create and set size of subsetBm |
(...skipping 15 matching lines...) Expand all Loading... | |
255 default: | 263 default: |
256 return SkStringPrintf("%s failed after %d scanli nes with error" | 264 return SkStringPrintf("%s failed after %d scanli nes with error" |
257 "message %d", fPath.c_str(), y-1, (int) subsetResult); | 265 "message %d", fPath.c_str(), y-1, (int) subsetResult); |
258 } | 266 } |
259 } | 267 } |
260 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); | 268 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); |
261 } | 269 } |
262 } | 270 } |
263 break; | 271 break; |
264 } | 272 } |
273 // This mode tests the skipping of scanlines. | |
scroggo
2015/06/11 20:12:48
Maybe the description belongs in the header, by th
msarett
2015/06/11 21:20:27
Done.
| |
274 case kStripe_Mode: { | |
275 int width = decodeInfo.width(); | |
scroggo
2015/06/11 20:12:48
Can these be const?
msarett
2015/06/11 21:20:27
Done.
| |
276 int height = decodeInfo.height(); | |
277 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that | |
278 // does not align with image blocks. | |
279 const int stripeHeight = 37; | |
280 const int numStripes = (height + stripeHeight - 1) / stripeHeight; | |
281 | |
282 // Create bitmap | |
283 SkBitmap bitmap; | |
284 if (!bitmap.tryAllocPixels(decodeInfo, NULL, colorTable.get())) { | |
285 return SkStringPrintf("Cannot allocate pixels for %s %dx%d", fPa th.c_str(), | |
286 width, height); | |
287 } | |
288 | |
289 // Decode odd stripes | |
290 SkScanlineDecoder* decoder = codec->getScanlineDecoder(decodeInfo, N ULL, colorPtr, | |
291 colorCountPtr); | |
292 if (NULL == decoder) { | |
293 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); | |
294 } | |
295 for (int i = 0; i < numStripes; i += 2) { | |
296 // Skip a stripe | |
297 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); | |
scroggo
2015/06/11 20:12:48
Will this ever be less than stripeHeight? It seems
msarett
2015/06/11 21:20:27
Yes, we might read 0 scanlines below.
| |
298 decoder->skipScanlines(linesToSkip); | |
scroggo
2015/06/11 20:12:48
I think we want to return an error if this or getS
msarett
2015/06/11 21:20:27
Done.
| |
299 | |
300 // Read a stripe | |
301 const int startY = SkTMin((i + 1) * stripeHeight, height - 1); | |
scroggo
2015/06/11 20:12:48
When will we use height - 1? It seems like if the
msarett
2015/06/11 21:20:27
Yes this is tricky and a bug. The original code w
| |
302 const int linesToRead = SkTMax(0, SkTMin(stripeHeight, height - startY)); | |
303 decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bi tmap.rowBytes()); | |
304 } | |
305 | |
306 // Decode even stripes | |
307 decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, colo rCountPtr); | |
scroggo
2015/06/11 20:12:48
I think we want to return an error if decoder is n
msarett
2015/06/11 21:20:27
Done.
| |
308 for (int i = 0; i < numStripes; i += 2) { | |
309 // Read a stripe | |
310 const int startY = i * stripeHeight; | |
311 const int linesToRead = SkTMin(stripeHeight, height - startY); | |
312 decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bi tmap.rowBytes()); | |
313 | |
314 // Skip a stripe | |
315 const int linesToSkip = SkTMax(0, SkTMin(stripeHeight, | |
316 height - (i + 1) * stripeHeight)); | |
317 decoder->skipScanlines(linesToSkip); | |
318 } | |
319 canvas->drawBitmap(bitmap, 0, 0); | |
320 } | |
265 } | 321 } |
266 return ""; | 322 return ""; |
267 } | 323 } |
268 | 324 |
269 SkISize CodecSrc::size() const { | 325 SkISize CodecSrc::size() const { |
270 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 326 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
271 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 327 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
272 if (NULL != codec) { | 328 if (NULL != codec) { |
273 return codec->getInfo().dimensions(); | 329 SkISize size = codec->getScaledDimensions(fScale); |
330 return size; | |
274 } else { | 331 } else { |
275 return SkISize::Make(0, 0); | 332 return SkISize::Make(0, 0); |
276 } | 333 } |
277 } | 334 } |
278 | 335 |
279 Name CodecSrc::name() const { | 336 Name CodecSrc::name() const { |
280 return SkOSPath::Basename(fPath.c_str()); | 337 if (1.0f == fScale) { |
338 return SkOSPath::Basename(fPath.c_str()); | |
339 } else { | |
340 return SkStringPrintf("%s_%.3f", SkOSPath::Basename(fPath.c_str()).c_str (), fScale); | |
341 } | |
281 } | 342 } |
282 | 343 |
283 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 344 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
284 | 345 |
285 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} | 346 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} |
286 | 347 |
287 Error ImageSrc::draw(SkCanvas* canvas) const { | 348 Error ImageSrc::draw(SkCanvas* canvas) const { |
288 SkImageInfo canvasInfo; | 349 SkImageInfo canvasInfo; |
289 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { | 350 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { |
290 // TODO: Instead, use lazy decoding to allow the GPU to handle cases lik e YUV. | 351 // TODO: Instead, use lazy decoding to allow the GPU to handle cases lik e YUV. |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
882 skr.visit<void>(i, drawsAsSingletonPictures); | 943 skr.visit<void>(i, drawsAsSingletonPictures); |
883 } | 944 } |
884 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 945 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
885 | 946 |
886 canvas->drawPicture(macroPic); | 947 canvas->drawPicture(macroPic); |
887 return ""; | 948 return ""; |
888 }); | 949 }); |
889 } | 950 } |
890 | 951 |
891 } // namespace DM | 952 } // namespace DM |
OLD | NEW |