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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 // We consider incomplete to be valid, since we should still decode what is | 134 // We consider incomplete to be valid, since we should still decode what is |
| 135 // available. | 135 // available. |
| 136 case SkImageGenerator::kIncompleteInput: | 136 case SkImageGenerator::kIncompleteInput: |
| 137 break; | 137 break; |
| 138 case SkImageGenerator::kInvalidConversion: | 138 case SkImageGenerator::kInvalidConversion: |
| 139 return Error::Nonfatal("Incompatible colortype conversion"); | 139 return Error::Nonfatal("Incompatible colortype conversion"); |
| 140 default: | 140 default: |
| 141 // Everything else is considered a failure. | 141 // Everything else is considered a failure. |
| 142 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); | 142 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); |
| 143 } | 143 } |
| 144 canvas->drawBitmap(bitmap, 0, 0); | |
| 144 break; | 145 break; |
| 145 case kScanline_Mode: { | 146 case kScanline_Mode: { |
| 146 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decod eInfo, NULL, | 147 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decod eInfo, NULL, |
| 147 colorPtr, colorCountPtr); | 148 colorPtr, colorCountPtr); |
| 148 if (NULL == scanlineDecoder) { | 149 if (NULL == scanlineDecoder) { |
| 149 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); | 150 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); |
| 150 } | 151 } |
| 151 for (int y = 0; y < decodeInfo.height(); ++y) { | 152 for (int y = 0; y < decodeInfo.height(); ++y) { |
| 152 const SkImageGenerator::Result result = scanlineDecoder->getScan lines( | 153 const SkImageGenerator::Result result = scanlineDecoder->getScan lines( |
| 153 bitmap.getAddr(0, y), 1, 0); | 154 bitmap.getAddr(0, y), 1, 0); |
| 154 switch (result) { | 155 switch (result) { |
| 155 case SkImageGenerator::kSuccess: | 156 case SkImageGenerator::kSuccess: |
| 156 case SkImageGenerator::kIncompleteInput: | 157 case SkImageGenerator::kIncompleteInput: |
| 157 break; | 158 break; |
| 158 default: | 159 default: |
| 159 return SkStringPrintf("%s failed after %d scanlines with error message %d", | 160 return SkStringPrintf("%s failed after %d scanlines with error message %d", |
| 160 fPath.c_str(), y-1, (int) result); | 161 fPath.c_str(), y-1, (int) result); |
| 161 } | 162 } |
| 162 } | 163 } |
| 164 canvas->drawBitmap(bitmap, 0, 0); | |
| 165 break; | |
| 166 } | |
| 167 case kScanline_Subset_Mode: { | |
| 168 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder | |
| 169 const int divisor = 2; | |
| 170 const int w = decodeInfo.width(); | |
| 171 const int h = decodeInfo.height(); | |
| 172 if (divisor > w || divisor > h) { | |
| 173 return SkStringPrintf("divisor %d is too big for %s with dimensi ons (%d x %d)", | |
| 174 divisor, fPath.c_str(), w, h); | |
| 175 } | |
| 176 const int subsetWidth = w/divisor; | |
| 177 const int subsetHeight = h/divisor; | |
| 178 // One of our subsets will be larger to contain any pixels that do n ot divide evenly. | |
| 179 const int extraX = w % divisor; | |
| 180 const int extraY = h % divisor; | |
| 181 /* | |
| 182 * if w or h are not evenly divided by divisor need to adjust width a nd height of end | |
| 183 * subsets to cover entire image. | |
| 184 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width | |
| 185 * and height of end subsets. | |
| 186 * subsetBm is extracted from largestSubsetBm. | |
| 187 * subsetBm's size is determined based on the current subset and may be larger for end | |
| 188 * subsets. | |
| 189 */ | |
| 190 SkImageInfo largestSubsetDecodeInfo = | |
| 191 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); | |
| 192 SkBitmap largestSubsetBm; | |
| 193 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { | |
| 194 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), | |
| 195 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); | |
| 196 } | |
| 197 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); | |
| 198 SkAutoTDeleteArray<char> lineDeleter(line); | |
| 199 for (int col = 0; col < divisor; col++) { | |
| 200 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets | |
| 201 const int currentSubsetWidth = (col + 1 == divisor) ? | |
| 202 subsetWidth + extraX : subsetWidth; | |
| 203 const int x = col * subsetWidth; | |
| 204 for (int row = 0; row < divisor; row++) { | |
| 205 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets | |
| 206 const int currentSubsetHeight = (row + 1 == divisor) ? | |
| 207 subsetHeight + extraY : subsetHeight; | |
| 208 const int y = row * subsetHeight; | |
| 209 //create scanline decoder for each subset | |
| 210 SkScanlineDecoder* subsetScanlineDecoder = codec->getScanlin eDecoder(decodeInfo, | |
|
scroggo
2015/05/26 19:44:30
nit: Does this go over 100 columns? reitveld looks
| |
| 211 NULL, colorPtr, colorCountPtr); | |
| 212 if (NULL == subsetScanlineDecoder) { | |
| 213 if (x == 0 && y == 0) { | |
| 214 //first try, image may not be compatible | |
| 215 return Error::Nonfatal("Cannot use scanline decoder for all images"); | |
| 216 } else { | |
| 217 return "Error scanline decoder is NULL"; | |
| 218 } | |
| 219 } | |
| 220 //skip to first line of subset | |
| 221 const SkImageGenerator::Result skipResult = | |
| 222 subsetScanlineDecoder->skipScanlines(y); | |
| 223 switch (skipResult) { | |
| 224 case SkImageGenerator::kSuccess: | |
| 225 case SkImageGenerator::kIncompleteInput: | |
| 226 break; | |
| 227 default: | |
| 228 return SkStringPrintf("%s failed after attempting to skip %d scanlines" | |
| 229 "with error message %d", fPath.c_str(), y, ( int) skipResult); | |
| 230 } | |
| 231 //create and set size of subsetBm | |
| 232 SkBitmap subsetBm; | |
| 233 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); | |
| 234 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); | |
| 235 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); | |
| 236 SkAutoLockPixels autlockSubsetBm(subsetBm, true); | |
| 237 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) { | |
| 238 const SkImageGenerator::Result subsetResult = | |
| 239 subsetScanlineDecoder->getScanlines(line, 1, 0); | |
| 240 const size_t bpp = decodeInfo.bytesPerPixel(); | |
| 241 //copy section of line based on x value | |
| 242 memcpy(subsetBm.getAddr(0, subsetY), line + x*bpp, curre ntSubsetWidth*bpp); | |
| 243 switch (subsetResult) { | |
| 244 case SkImageGenerator::kSuccess: | |
| 245 case SkImageGenerator::kIncompleteInput: | |
| 246 break; | |
| 247 default: | |
| 248 return SkStringPrintf("%s failed after %d scanli nes with error" | |
| 249 "message %d", fPath.c_str(), y-1, (int) subsetResult); | |
| 250 } | |
| 251 } | |
| 252 canvas->drawBitmap(subsetBm, x, y); | |
| 253 } | |
| 254 } | |
| 163 break; | 255 break; |
| 164 } | 256 } |
| 165 } | 257 } |
| 166 canvas->drawBitmap(bitmap, 0, 0); | |
| 167 return ""; | 258 return ""; |
| 168 } | 259 } |
| 169 | 260 |
| 170 SkISize CodecSrc::size() const { | 261 SkISize CodecSrc::size() const { |
| 171 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 262 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 172 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 263 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 173 if (NULL != codec) { | 264 if (NULL != codec) { |
| 174 return codec->getInfo().dimensions(); | 265 return codec->getInfo().dimensions(); |
| 175 } else { | 266 } else { |
| 176 return SkISize::Make(0, 0); | 267 return SkISize::Make(0, 0); |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 skr.visit<void>(i, drawsAsSingletonPictures); | 871 skr.visit<void>(i, drawsAsSingletonPictures); |
| 781 } | 872 } |
| 782 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 873 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
| 783 | 874 |
| 784 canvas->drawPicture(macroPic); | 875 canvas->drawPicture(macroPic); |
| 785 return ""; | 876 return ""; |
| 786 }); | 877 }); |
| 787 } | 878 } |
| 788 | 879 |
| 789 } // namespace DM | 880 } // namespace DM |
| OLD | NEW |