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

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: Response to comments in Patch Set 5 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;
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 // The failed call to getScanlines() will take care of
251 return result; 256 // filling the failed row, so we indicate that we have
257 // decoded (y + 1) rows.
258 *rowsDecoded = y + 1;
259 return kIncompleteInput;
252 } 260 }
253 if (y < dstHeight - 1) { 261 if (y < dstHeight - 1) {
254 result = fCodec->skipScanlines(sampleY - 1); 262 if (!fCodec->skipScanlines(sampleY - 1)) {
255 if (kSuccess != result && kIncompleteInput != result) { 263 *rowsDecoded = y + 1;
256 return result; 264 return kIncompleteInput;
257 } 265 }
258 } 266 }
259 dst = SkTAddOffset<void>(dst, rowBytes); 267 dst = SkTAddOffset<void>(dst, rowBytes);
260 } 268 }
261 return result; 269 return kSuccess;
262 } 270 }
263 case SkCodec::kBottomUp_SkScanlineOrder: 271 case SkCodec::kBottomUp_SkScanlineOrder:
264 case SkCodec::kOutOfOrder_SkScanlineOrder: { 272 case SkCodec::kOutOfOrder_SkScanlineOrder: {
265 for (int y = 0; y < srcHeight; y++) { 273 Result result = kSuccess;
274 int y;
275 for (y = 0; y < srcHeight; y++) {
266 int srcY = fCodec->nextScanline(); 276 int srcY = fCodec->nextScanline();
267 if (is_coord_necessary(srcY, sampleY, dstHeight)) { 277 if (is_coord_necessary(srcY, sampleY, dstHeight)) {
268 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * get_dst_co ord(srcY, sampleY)); 278 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * get_dst_co ord(srcY, sampleY));
269 result = fCodec->getScanlines(dstPtr, 1, rowBytes); 279 if (1 != fCodec->getScanlines(dstPtr, 1, rowBytes)) {
270 if (kSuccess != result && kIncompleteInput != result) { 280 result = kIncompleteInput;
271 return result; 281 break;
272 } 282 }
273 } else { 283 } else {
274 result = fCodec->skipScanlines(1); 284 if (!fCodec->skipScanlines(1)) {
275 if (kSuccess != result && kIncompleteInput != result) { 285 result = kIncompleteInput;
276 return result; 286 break;
277 } 287 }
278 } 288 }
279 } 289 }
290
291 // We handle filling uninitialized memory here instead of in the par ent class.
292 // The parent class does not know that we are sampling.
293 if (kIncompleteInput == result) {
294 const SkImageInfo fillInfo = requestedInfo.makeWH(requestedInfo. width(), 1);
295 const uint32_t fillValue = fCodec->getFillValue(fillInfo.colorTy pe(),
296 fillInfo.alphaType());
297 for (; y < srcHeight; y++) {
298 int srcY = fCodec->outputScanline(y);
299 if (is_coord_necessary(srcY, sampleY, dstHeight)) {
300 void* dstRow = SkTAddOffset<void>(dst,
301 rowBytes * get_dst_coord(srcY, sampleY));
302 SkSwizzler::Fill(dstRow, fillInfo, rowBytes, fillValue,
303 options.fZeroInitialized);
304 }
305 }
306 *rowsDecoded = dstHeight;
307 }
280 return result; 308 return result;
281 } 309 }
282 case SkCodec::kNone_SkScanlineOrder: { 310 case SkCodec::kNone_SkScanlineOrder: {
283 SkAutoMalloc storage(srcHeight * rowBytes); 311 SkAutoMalloc storage(srcHeight * rowBytes);
284 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); 312 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
285 result = fCodec->getScanlines(storagePtr, srcHeight, rowBytes); 313 int scanlines = fCodec->getScanlines(storagePtr, srcHeight, rowBytes );
286 if (kSuccess != result && kIncompleteInput != result) {
287 return result;
288 }
289 storagePtr += Y0 * rowBytes; 314 storagePtr += Y0 * rowBytes;
290 for (int y = 0; y < dstHeight; y++) { 315 scanlines -= Y0;
316 int y = 0;
317 while(y < dstHeight && scanlines > 0) {
scroggo 2015/10/01 20:48:58 nit: while (
msarett 2015/10/01 22:34:52 Done.
291 memcpy(dst, storagePtr, rowBytes); 318 memcpy(dst, storagePtr, rowBytes);
292 storagePtr += sampleY * rowBytes; 319 storagePtr += sampleY * rowBytes;
293 dst = SkTAddOffset<void>(dst, rowBytes); 320 dst = SkTAddOffset<void>(dst, rowBytes);
321 scanlines -= sampleY;
322 y++;
294 } 323 }
295 return result; 324 if (y < dstHeight) {
325 // fCodec has already handled filling uninitialized memory.
326 *rowsDecoded = dstHeight;
327 return kIncompleteInput;
328 }
329 return kSuccess;
296 } 330 }
297 default: 331 default:
298 SkASSERT(false); 332 SkASSERT(false);
299 return kUnimplemented; 333 return kUnimplemented;
300 } 334 }
301 } 335 }
336
337 uint32_t SkScaledCodec::onGetFillValue(SkColorType colorType, SkAlphaType alphaT ype) const {
338 return fCodec->getFillValue(colorType, alphaType);
339 }
340
341 SkCodec::SkScanlineOrder SkScaledCodec::onGetScanlineOrder() const {
342 return fCodec->getScanlineOrder();
343 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698