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

Side by Side Diff: src/codec/SkScaledCodec.cpp

Issue 1332053002: Fill incomplete images in SkCodec parent class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase on merged SkCodec and SkScanlineDecoder Created 5 years, 2 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
OLDNEW
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 "SkCodecPriv.h" 8 #include "SkCodecPriv.h"
9 #include "SkScaledCodec.h" 9 #include "SkScaledCodec.h"
10 #include "SkStream.h" 10 #include "SkStream.h"
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 } 171 }
172 if (sampleYPtr) { 172 if (sampleYPtr) {
173 *sampleYPtr = sampleY; 173 *sampleYPtr = sampleY;
174 } 174 }
175 } 175 }
176 176
177 // TODO: Implement subsetting in onGetPixels which works when and when not sampl ing 177 // TODO: Implement subsetting in onGetPixels which works when and when not sampl ing
178 178
179 SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi d* dst, 179 SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi d* dst,
180 size_t rowBytes, const Options& optio ns, 180 size_t rowBytes, const Options& optio ns,
181 SkPMColor ctable[], int* ctableCount) { 181 SkPMColor ctable[], int* ctableCount,
182 int* rowsDecoded) {
182 183
183 if (options.fSubset) { 184 if (options.fSubset) {
184 // Subsets are not supported. 185 // Subsets are not supported.
185 return kUnimplemented; 186 return kUnimplemented;
186 } 187 }
187 188
188 // FIXME: If no scaling/subsets are requested, we can call fCodec->getPixels . 189 // FIXME: If no scaling/subsets are requested, we can call fCodec->getPixels .
189 Result result = fCodec->startScanlineDecode(requestedInfo, &options, ctable, ctableCount); 190 Result result = fCodec->startScanlineDecode(requestedInfo, &options, ctable, ctableCount);
190 if (kSuccess == result) { 191 if (kSuccess == result) {
191 // native decode supported 192 // native decode supported
192 switch (fCodec->getScanlineOrder()) { 193 switch (fCodec->getScanlineOrder()) {
193 case SkCodec::kTopDown_SkScanlineOrder: 194 case SkCodec::kTopDown_SkScanlineOrder:
194 case SkCodec::kBottomUp_SkScanlineOrder: 195 case SkCodec::kBottomUp_SkScanlineOrder:
195 case SkCodec::kNone_SkScanlineOrder: 196 case SkCodec::kNone_SkScanlineOrder:
196 return fCodec->getScanlines(dst, requestedInfo.height(), rowByte s); 197 if (fCodec->getScanlines(dst, requestedInfo.height(), rowBytes) !=
198 requestedInfo.height()) {
199 // fCodec has already handled filling uninitialized memory.
200 *rowsDecoded = requestedInfo.height();
201 return kIncompleteInput;
202 }
203 return kSuccess;
197 case SkCodec::kOutOfOrder_SkScanlineOrder: { 204 case SkCodec::kOutOfOrder_SkScanlineOrder: {
198 for (int y = 0; y < requestedInfo.height(); y++) { 205 for (int y = 0; y < requestedInfo.height(); y++) {
199 int dstY = fCodec->nextScanline(); 206 int dstY = fCodec->nextScanline();
200 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY); 207 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY);
201 result = fCodec->getScanlines(dstPtr, 1, rowBytes); 208 if (1 != fCodec->getScanlines(dstPtr, 1, rowBytes)) {
202 // FIXME (msarett): Make the SkCodec base class take care of filling 209 *rowsDecoded = y + 1;
scroggo 2015/10/01 14:48:32 Why is this y+1 and not y? (Same for other instanc
msarett 2015/10/01 18:14:14 The failed call to getScanlines(1) will fill the s
203 // uninitialized pixels so we can return immediately on kInc ompleteInput. 210 return kIncompleteInput;
204 if (kSuccess != result && kIncompleteInput != result) {
205 return result;
206 } 211 }
207 } 212 }
208 return result; 213 return kSuccess;
209 } 214 }
210 } 215 }
211 } 216 }
212 217
213 if (kInvalidScale != result) { 218 if (kInvalidScale != result) {
214 // no scaling requested 219 // no scaling requested
215 return result; 220 return result;
216 } 221 }
217 222
218 // scaling requested 223 // scaling requested
(...skipping 15 matching lines...) Expand all
234 // update codec with new info 239 // update codec with new info
235 // FIXME: The previous call to start returned kInvalidScale. This call may 240 // FIXME: The previous call to start returned kInvalidScale. This call may
236 // require a rewind. (skbug.com/4284) 241 // require a rewind. (skbug.com/4284)
237 result = fCodec->startScanlineDecode(info, &options, ctable, ctableCount); 242 result = fCodec->startScanlineDecode(info, &options, ctable, ctableCount);
238 if (kSuccess != result) { 243 if (kSuccess != result) {
239 return result; 244 return result;
240 } 245 }
241 246
242 switch(fCodec->getScanlineOrder()) { 247 switch(fCodec->getScanlineOrder()) {
243 case SkCodec::kTopDown_SkScanlineOrder: { 248 case SkCodec::kTopDown_SkScanlineOrder: {
244 result = fCodec->skipScanlines(Y0); 249 if (!fCodec->skipScanlines(Y0)) {
245 if (kSuccess != result && kIncompleteInput != result) { 250 *rowsDecoded = 0;
246 return result; 251 return kIncompleteInput;
247 } 252 }
248 for (int y = 0; y < dstHeight; y++) { 253 for (int y = 0; y < dstHeight; y++) {
249 result = fCodec->getScanlines(dst, 1, rowBytes); 254 if (1 != fCodec->getScanlines(dst, 1, rowBytes)) {
250 if (kSuccess != result && kIncompleteInput != result) { 255 *rowsDecoded = y + 1;
251 return result; 256 return kIncompleteInput;
252 } 257 }
253 if (y < dstHeight - 1) { 258 if (y < dstHeight - 1) {
254 result = fCodec->skipScanlines(sampleY - 1); 259 if (!fCodec->skipScanlines(sampleY - 1)) {
255 if (kSuccess != result && kIncompleteInput != result) { 260 *rowsDecoded = y + 1;
256 return result; 261 return kIncompleteInput;
257 } 262 }
258 } 263 }
259 dst = SkTAddOffset<void>(dst, rowBytes); 264 dst = SkTAddOffset<void>(dst, rowBytes);
260 } 265 }
261 return result; 266 return kSuccess;
262 } 267 }
263 case SkCodec::kBottomUp_SkScanlineOrder: 268 case SkCodec::kBottomUp_SkScanlineOrder:
264 case SkCodec::kOutOfOrder_SkScanlineOrder: { 269 case SkCodec::kOutOfOrder_SkScanlineOrder: {
265 for (int y = 0; y < srcHeight; y++) { 270 Result result = kSuccess;
271 int y;
272 for (y = 0; y < srcHeight; y++) {
266 int srcY = fCodec->nextScanline(); 273 int srcY = fCodec->nextScanline();
267 if (is_coord_necessary(srcY, sampleY, dstHeight)) { 274 if (is_coord_necessary(srcY, sampleY, dstHeight)) {
268 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * get_dst_co ord(srcY, sampleY)); 275 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * get_dst_co ord(srcY, sampleY));
269 result = fCodec->getScanlines(dstPtr, 1, rowBytes); 276 if (1 != fCodec->getScanlines(dstPtr, 1, rowBytes)) {
270 if (kSuccess != result && kIncompleteInput != result) { 277 result = kIncompleteInput;
271 return result; 278 break;
272 } 279 }
273 } else { 280 } else {
274 result = fCodec->skipScanlines(1); 281 if (!fCodec->skipScanlines(1)) {
275 if (kSuccess != result && kIncompleteInput != result) { 282 result = kIncompleteInput;
276 return result; 283 break;
277 } 284 }
278 } 285 }
279 } 286 }
287
288 // We handle filling uninitialized memory here instead of in the par ent class.
289 // The parent class does not know that we are sampling.
290 if (kIncompleteInput == result) {
291 const SkImageInfo fillInfo = requestedInfo.makeWH(requestedInfo. width(), 1);
292 const uint32_t fillValue = this->getFillValue(fillInfo.colorType (),
293 fillInfo.alphaType());
294 for (; y < srcHeight; y++) {
295 int srcY = fCodec->nextScanline(y);
296 if (is_coord_necessary(srcY, sampleY, dstHeight)) {
297 void* dstRow = SkTAddOffset<void>(dst,
298 rowBytes * get_dst_coord(srcY, sampleY));
299 SkSwizzler::Fill(dstRow, fillInfo, rowBytes, fillValue,
300 options.fZeroInitialized);
301 }
302 }
303 *rowsDecoded = dstHeight;
304 }
280 return result; 305 return result;
281 } 306 }
282 case SkCodec::kNone_SkScanlineOrder: { 307 case SkCodec::kNone_SkScanlineOrder: {
283 SkAutoMalloc storage(srcHeight * rowBytes); 308 SkAutoMalloc storage(srcHeight * rowBytes);
284 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); 309 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
285 result = fCodec->getScanlines(storagePtr, srcHeight, rowBytes); 310 int scanlines = (int) fCodec->getScanlines(storagePtr, srcHeight, ro wBytes);
scroggo 2015/10/01 14:48:32 It's weird to me that getScanlines returns one typ
msarett 2015/10/01 18:14:14 Yeah I also thought this was strange. I feel stro
scroggo 2015/10/01 20:48:57 +1 to consistency. I'm not sure why width and heig
286 if (kSuccess != result && kIncompleteInput != result) {
287 return result;
288 }
289 storagePtr += Y0 * rowBytes; 311 storagePtr += Y0 * rowBytes;
290 for (int y = 0; y < dstHeight; y++) { 312 scanlines -= Y0;
313 int y = 0;
314 while(y < dstHeight && scanlines > 0) {
291 memcpy(dst, storagePtr, rowBytes); 315 memcpy(dst, storagePtr, rowBytes);
292 storagePtr += sampleY * rowBytes; 316 storagePtr += sampleY * rowBytes;
293 dst = SkTAddOffset<void>(dst, rowBytes); 317 dst = SkTAddOffset<void>(dst, rowBytes);
318 scanlines -= sampleY;
319 y++;
294 } 320 }
295 return result; 321 if (y < dstHeight) {
322 // fCodec has already handled filling uninitialized memory.
323 *rowsDecoded = dstHeight;
324 return kIncompleteInput;
325 }
326 return kSuccess;
296 } 327 }
297 default: 328 default:
298 SkASSERT(false); 329 SkASSERT(false);
299 return kUnimplemented; 330 return kUnimplemented;
300 } 331 }
301 } 332 }
333
334 uint32_t SkScaledCodec::onGetFillValue(SkColorType colorType, SkAlphaType alphaT ype) const {
335 return fCodec->getFillValue(colorType, alphaType);
336 }
337
338 SkCodec::SkScanlineOrder SkScaledCodec::onGetScanlineOrder() const {
339 return fCodec->getScanlineOrder();
340 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698