Chromium Code Reviews| 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType); | 133 decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType); |
| 134 } | 134 } |
| 135 | 135 |
| 136 SkBitmap bitmap; | 136 SkBitmap bitmap; |
| 137 if (!bitmap.tryAllocPixels(decodeInfo, NULL, colorTable.get())) { | 137 if (!bitmap.tryAllocPixels(decodeInfo, NULL, colorTable.get())) { |
| 138 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str( ), | 138 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str( ), |
| 139 decodeInfo.width(), decodeInfo.height()); | 139 decodeInfo.width(), decodeInfo.height()); |
| 140 } | 140 } |
| 141 | 141 |
| 142 switch (fMode) { | 142 switch (fMode) { |
| 143 case kNormal_Mode: | 143 case kNormal_Mode: { |
| 144 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), NULL, | 144 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), NULL, |
| 145 colorPtr, colorCountPtr)) { | 145 colorPtr, colorCountPtr)) { |
| 146 case SkImageGenerator::kSuccess: | 146 case SkImageGenerator::kSuccess: |
| 147 // We consider incomplete to be valid, since we should still decode what is | 147 // We consider incomplete to be valid, since we should still decode what is |
| 148 // available. | 148 // available. |
| 149 case SkImageGenerator::kIncompleteInput: | 149 case SkImageGenerator::kIncompleteInput: |
| 150 break; | 150 break; |
| 151 case SkImageGenerator::kInvalidConversion: | 151 case SkImageGenerator::kInvalidConversion: |
| 152 return Error::Nonfatal("Incompatible colortype conversion"); | 152 return Error::Nonfatal("Incompatible colortype conversion"); |
| 153 default: | 153 default: |
| 154 // Everything else is considered a failure. | 154 // Everything else is considered a failure. |
| 155 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); | 155 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); |
| 156 } | 156 } |
| 157 canvas->drawBitmap(bitmap, 0, 0); | 157 canvas->drawBitmap(bitmap, 0, 0); |
| 158 break; | 158 break; |
| 159 } | |
| 159 case kScanline_Mode: { | 160 case kScanline_Mode: { |
| 160 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decod eInfo, NULL, | 161 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decod eInfo, NULL, |
| 161 colorPtr, colorCountPtr); | 162 colorPtr, colorCountPtr); |
| 162 if (NULL == scanlineDecoder) { | 163 if (NULL == scanlineDecoder) { |
| 163 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); | 164 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); |
| 164 } | 165 } |
| 165 for (int y = 0; y < decodeInfo.height(); ++y) { | 166 const SkImageGenerator::Result result = scanlineDecoder->getScanline s( |
| 166 const SkImageGenerator::Result result = scanlineDecoder->getScan lines( | 167 bitmap.getAddr(0, 0), decodeInfo.height(), decodeInfo.minRow Bytes()); |
|
scroggo
2015/06/19 15:45:52
This is a little tricky: in this case it happens t
emmaleer
2015/06/19 22:12:19
Done.
| |
| 167 bitmap.getAddr(0, y), 1, 0); | 168 switch (result) { |
| 168 switch (result) { | 169 case SkImageGenerator::kSuccess: |
| 169 case SkImageGenerator::kSuccess: | 170 case SkImageGenerator::kIncompleteInput: |
| 170 case SkImageGenerator::kIncompleteInput: | 171 break; |
| 171 break; | 172 default: |
| 172 default: | 173 return SkStringPrintf("%s failed with error message %d", |
| 173 return SkStringPrintf("%s failed after %d scanlines with error message %d", | 174 fPath.c_str(), (int) result); |
| 174 fPath.c_str(), y-1, (int) result); | |
| 175 } | |
| 176 } | 175 } |
| 177 canvas->drawBitmap(bitmap, 0, 0); | 176 canvas->drawBitmap(bitmap, 0, 0); |
| 178 break; | 177 break; |
| 179 } | 178 } |
| 180 case kScanline_Subset_Mode: { | 179 case kScanline_Subset_Mode: { |
| 181 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder | 180 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder |
| 182 const int divisor = 2; | 181 const int divisor = 2; |
| 183 const int w = decodeInfo.width(); | 182 const int w = decodeInfo.width(); |
| 184 const int h = decodeInfo.height(); | 183 const int h = decodeInfo.height(); |
| 185 if (w*h == 1) { | 184 if (w*h == 1) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 203 * subsetBm's size is determined based on the current subset and may be larger for end | 202 * subsetBm's size is determined based on the current subset and may be larger for end |
| 204 * subsets. | 203 * subsets. |
| 205 */ | 204 */ |
| 206 SkImageInfo largestSubsetDecodeInfo = | 205 SkImageInfo largestSubsetDecodeInfo = |
| 207 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); | 206 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); |
| 208 SkBitmap largestSubsetBm; | 207 SkBitmap largestSubsetBm; |
| 209 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { | 208 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { |
| 210 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), | 209 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), |
| 211 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); | 210 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); |
| 212 } | 211 } |
| 213 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); | 212 const int rowBytes = decodeInfo.minRowBytes(); |
| 214 SkAutoTDeleteArray<char> lineDeleter(line); | 213 char* buffer = SkNEW_ARRAY(char, h * rowBytes); |
|
msarett
2015/06/19 13:35:54
Can we allocate this buffer with some kind of maxS
emmaleer
2015/06/19 14:28:08
On 2015/06/19 13:35:54, msarett wrote:
> Can we al
| |
| 214 SkAutoTDeleteArray<char> lineDeleter(buffer); | |
| 215 for (int col = 0; col < divisor; col++) { | 215 for (int col = 0; col < divisor; col++) { |
| 216 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets | 216 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets |
| 217 const int currentSubsetWidth = (col + 1 == divisor) ? | 217 const int currentSubsetWidth = (col + 1 == divisor) ? |
| 218 subsetWidth + extraX : subsetWidth; | 218 subsetWidth + extraX : subsetWidth; |
| 219 const int x = col * subsetWidth; | 219 const int x = col * subsetWidth; |
| 220 for (int row = 0; row < divisor; row++) { | 220 for (int row = 0; row < divisor; row++) { |
| 221 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets | 221 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets |
| 222 const int currentSubsetHeight = (row + 1 == divisor) ? | 222 const int currentSubsetHeight = (row + 1 == divisor) ? |
| 223 subsetHeight + extraY : subsetHeight; | 223 subsetHeight + extraY : subsetHeight; |
| 224 const int y = row * subsetHeight; | 224 const int y = row * subsetHeight; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 243 default: | 243 default: |
| 244 return SkStringPrintf("%s failed after attempting to skip %d scanlines" | 244 return SkStringPrintf("%s failed after attempting to skip %d scanlines" |
| 245 "with error message %d", fPath.c_str(), y, ( int) skipResult); | 245 "with error message %d", fPath.c_str(), y, ( int) skipResult); |
| 246 } | 246 } |
| 247 //create and set size of subsetBm | 247 //create and set size of subsetBm |
| 248 SkBitmap subsetBm; | 248 SkBitmap subsetBm; |
| 249 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); | 249 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); |
| 250 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); | 250 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); |
| 251 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); | 251 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); |
| 252 SkAutoLockPixels autlockSubsetBm(subsetBm, true); | 252 SkAutoLockPixels autlockSubsetBm(subsetBm, true); |
| 253 const SkImageGenerator::Result subsetResult = | |
| 254 subsetScanlineDecoder->getScanlines(buffer, currentS ubsetHeight, rowBytes); | |
|
scroggo
2015/06/19 15:45:52
nit: I believe this exceeds 100 characters. We try
emmaleer
2015/06/19 22:12:20
Acknowledged.
| |
| 255 switch (subsetResult) { | |
| 256 case SkImageGenerator::kSuccess: | |
| 257 case SkImageGenerator::kIncompleteInput: | |
| 258 break; | |
| 259 default: | |
| 260 return SkStringPrintf("%s failed after %d scanlines with error" | |
| 261 "message %d", fPath.c_str(), y-1, (int) subs etResult); | |
|
scroggo
2015/06/19 15:45:52
It probably is not useful to print the y value, si
emmaleer
2015/06/19 22:12:20
Acknowledged.
| |
| 262 } | |
| 263 const size_t bpp = decodeInfo.bytesPerPixel(); | |
| 264 //copy section of lines based on x value | |
| 265 char* bufferRow = buffer; | |
| 253 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) { | 266 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) { |
| 254 const SkImageGenerator::Result subsetResult = | 267 memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp, currentSubsetWidth*bpp); |
|
scroggo
2015/06/19 15:45:52
nit: over 100 characters.
| |
| 255 subsetScanlineDecoder->getScanlines(line, 1, 0); | 268 bufferRow += rowBytes; |
|
msarett
2015/06/19 13:35:54
I have a theory that it is faster to copy from a r
emmaleer
2015/06/19 14:28:08
On 2015/06/19 13:35:54, msarett wrote:
> I have a
scroggo
2015/06/19 15:45:52
Agreed. We should confirm that theory in order to
emmaleer
2015/06/19 22:12:20
I added a comment explaining why we decode this wa
| |
| 256 const size_t bpp = decodeInfo.bytesPerPixel(); | |
| 257 //copy section of line based on x value | |
| 258 memcpy(subsetBm.getAddr(0, subsetY), line + x*bpp, curre ntSubsetWidth*bpp); | |
| 259 switch (subsetResult) { | |
| 260 case SkImageGenerator::kSuccess: | |
| 261 case SkImageGenerator::kIncompleteInput: | |
| 262 break; | |
| 263 default: | |
| 264 return SkStringPrintf("%s failed after %d scanli nes with error" | |
| 265 "message %d", fPath.c_str(), y-1, (int) subsetResult); | |
| 266 } | |
| 267 } | 269 } |
| 270 | |
| 268 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); | 271 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); |
| 269 } | 272 } |
| 270 } | 273 } |
| 271 break; | 274 break; |
| 272 } | 275 } |
| 273 case kStripe_Mode: { | 276 case kStripe_Mode: { |
| 274 const int height = decodeInfo.height(); | 277 const int height = decodeInfo.height(); |
| 275 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that | 278 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that |
| 276 // does not align with image blocks. | 279 // does not align with image blocks. |
| 277 const int stripeHeight = 37; | 280 const int stripeHeight = 37; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 switch (result) { | 340 switch (result) { |
| 338 case SkImageGenerator::kSuccess: | 341 case SkImageGenerator::kSuccess: |
| 339 case SkImageGenerator::kIncompleteInput: | 342 case SkImageGenerator::kIncompleteInput: |
| 340 break; | 343 break; |
| 341 default: | 344 default: |
| 342 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str()); | 345 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str()); |
| 343 } | 346 } |
| 344 } | 347 } |
| 345 } | 348 } |
| 346 canvas->drawBitmap(bitmap, 0, 0); | 349 canvas->drawBitmap(bitmap, 0, 0); |
| 350 break; | |
| 347 } | 351 } |
| 348 } | 352 } |
| 349 return ""; | 353 return ""; |
| 350 } | 354 } |
| 351 | 355 |
| 352 SkISize CodecSrc::size() const { | 356 SkISize CodecSrc::size() const { |
| 353 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 357 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 354 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 358 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 355 if (NULL != codec) { | 359 if (NULL != codec) { |
| 356 SkISize size = codec->getScaledDimensions(fScale); | 360 SkISize size = codec->getScaledDimensions(fScale); |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 970 skr.visit<void>(i, drawsAsSingletonPictures); | 974 skr.visit<void>(i, drawsAsSingletonPictures); |
| 971 } | 975 } |
| 972 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 976 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
| 973 | 977 |
| 974 canvas->drawPicture(macroPic); | 978 canvas->drawPicture(macroPic); |
| 975 return ""; | 979 return ""; |
| 976 }); | 980 }); |
| 977 } | 981 } |
| 978 | 982 |
| 979 } // namespace DM | 983 } // namespace DM |
| OLD | NEW |