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 (w*h == 1) { |
| 173 return Error::Nonfatal("Subset decoding not supported."); |
| 174 } |
| 175 if (divisor > w || divisor > h) { |
| 176 return SkStringPrintf("divisor %d is too big for %s with dimensi
ons (%d x %d)", |
| 177 divisor, fPath.c_str(), w, h); |
| 178 } |
| 179 const int subsetWidth = w/divisor; |
| 180 const int subsetHeight = h/divisor; |
| 181 // One of our subsets will be larger to contain any pixels that do n
ot divide evenly. |
| 182 const int extraX = w % divisor; |
| 183 const int extraY = h % divisor; |
| 184 /* |
| 185 * if w or h are not evenly divided by divisor need to adjust width a
nd height of end |
| 186 * subsets to cover entire image. |
| 187 * Add extraX and extraY to largestSubsetBm's width and height to adj
ust width |
| 188 * and height of end subsets. |
| 189 * subsetBm is extracted from largestSubsetBm. |
| 190 * subsetBm's size is determined based on the current subset and may
be larger for end |
| 191 * subsets. |
| 192 */ |
| 193 SkImageInfo largestSubsetDecodeInfo = |
| 194 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra
Y); |
| 195 SkBitmap largestSubsetBm; |
| 196 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c
olorTable.get())) { |
| 197 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat
h.c_str(), |
| 198 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo
.height()); |
| 199 } |
| 200 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); |
| 201 SkAutoTDeleteArray<char> lineDeleter(line); |
| 202 for (int col = 0; col < divisor; col++) { |
| 203 //currentSubsetWidth may be larger than subsetWidth for rightmos
t subsets |
| 204 const int currentSubsetWidth = (col + 1 == divisor) ? |
| 205 subsetWidth + extraX : subsetWidth; |
| 206 const int x = col * subsetWidth; |
| 207 for (int row = 0; row < divisor; row++) { |
| 208 //currentSubsetHeight may be larger than subsetHeight for bo
ttom subsets |
| 209 const int currentSubsetHeight = (row + 1 == divisor) ? |
| 210 subsetHeight + extraY : subsetHeight; |
| 211 const int y = row * subsetHeight; |
| 212 //create scanline decoder for each subset |
| 213 SkScanlineDecoder* subsetScanlineDecoder = codec->getScanlin
eDecoder(decodeInfo, |
| 214 NULL, colorPtr, colorCountPtr); |
| 215 if (NULL == subsetScanlineDecoder) { |
| 216 if (x == 0 && y == 0) { |
| 217 //first try, image may not be compatible |
| 218 return Error::Nonfatal("Cannot use scanline decoder
for all images"); |
| 219 } else { |
| 220 return "Error scanline decoder is NULL"; |
| 221 } |
| 222 } |
| 223 //skip to first line of subset |
| 224 const SkImageGenerator::Result skipResult = |
| 225 subsetScanlineDecoder->skipScanlines(y); |
| 226 switch (skipResult) { |
| 227 case SkImageGenerator::kSuccess: |
| 228 case SkImageGenerator::kIncompleteInput: |
| 229 break; |
| 230 default: |
| 231 return SkStringPrintf("%s failed after attempting to
skip %d scanlines" |
| 232 "with error message %d", fPath.c_str(), y, (
int) skipResult); |
| 233 } |
| 234 //create and set size of subsetBm |
| 235 SkBitmap subsetBm; |
| 236 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); |
| 237 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight
); |
| 238 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun
ds)); |
| 239 SkAutoLockPixels autlockSubsetBm(subsetBm, true); |
| 240 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse
tY) { |
| 241 const SkImageGenerator::Result subsetResult = |
| 242 subsetScanlineDecoder->getScanlines(line, 1, 0); |
| 243 const size_t bpp = decodeInfo.bytesPerPixel(); |
| 244 //copy section of line based on x value |
| 245 memcpy(subsetBm.getAddr(0, subsetY), line + x*bpp, curre
ntSubsetWidth*bpp); |
| 246 switch (subsetResult) { |
| 247 case SkImageGenerator::kSuccess: |
| 248 case SkImageGenerator::kIncompleteInput: |
| 249 break; |
| 250 default: |
| 251 return SkStringPrintf("%s failed after %d scanli
nes with error" |
| 252 "message %d", fPath.c_str(), y-1, (int)
subsetResult); |
| 253 } |
| 254 } |
| 255 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar
(y)); |
| 256 } |
| 257 } |
163 break; | 258 break; |
164 } | 259 } |
165 } | 260 } |
166 canvas->drawBitmap(bitmap, 0, 0); | |
167 return ""; | 261 return ""; |
168 } | 262 } |
169 | 263 |
170 SkISize CodecSrc::size() const { | 264 SkISize CodecSrc::size() const { |
171 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 265 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
172 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 266 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
173 if (NULL != codec) { | 267 if (NULL != codec) { |
174 return codec->getInfo().dimensions(); | 268 return codec->getInfo().dimensions(); |
175 } else { | 269 } else { |
176 return SkISize::Make(0, 0); | 270 return SkISize::Make(0, 0); |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 skr.visit<void>(i, drawsAsSingletonPictures); | 874 skr.visit<void>(i, drawsAsSingletonPictures); |
781 } | 875 } |
782 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 876 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
783 | 877 |
784 canvas->drawPicture(macroPic); | 878 canvas->drawPicture(macroPic); |
785 return ""; | 879 return ""; |
786 }); | 880 }); |
787 } | 881 } |
788 | 882 |
789 } // namespace DM | 883 } // namespace DM |
OLD | NEW |