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

Side by Side Diff: src/core/SkPicturePlayback.cpp

Issue 24826002: Allow creating a picture from skp to fail. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix debugger. Created 7 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkPicturePlayback.h" 8 #include "SkPicturePlayback.h"
9 #include "SkPictureRecord.h" 9 #include "SkPictureRecord.h"
10 #include "SkTypeface.h" 10 #include "SkTypeface.h"
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 466
467 uint32_t rbMask = 0; 467 uint32_t rbMask = 0;
468 for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) { 468 for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
469 if (pictInfoFlags & gSD[i].fSrc) { 469 if (pictInfoFlags & gSD[i].fSrc) {
470 rbMask |= gSD[i].fDst; 470 rbMask |= gSD[i].fDst;
471 } 471 }
472 } 472 }
473 return rbMask; 473 return rbMask;
474 } 474 }
475 475
476 void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag, 476 bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, uint32_t tag,
477 size_t size, SkPicture::InstallPixelRefPr oc proc) { 477 size_t size, SkPicture::InstallPixelRefPr oc proc) {
478 /* 478 /*
479 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen 479 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
480 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required 480 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
481 * but if they are present, they need to have been seen before the buffer. 481 * but if they are present, they need to have been seen before the buffer.
482 * 482 *
483 * We assert that if/when we see either of these, that we have not yet seen 483 * We assert that if/when we see either of these, that we have not yet seen
484 * the buffer tag, because if we have, then its too-late to deal with the 484 * the buffer tag, because if we have, then its too-late to deal with the
485 * factories or typefaces. 485 * factories or typefaces.
486 */ 486 */
487 SkDEBUGCODE(bool haveBuffer = false;) 487 SkDEBUGCODE(bool haveBuffer = false;)
488 488
489 switch (tag) { 489 switch (tag) {
490 case PICT_READER_TAG: { 490 case PICT_READER_TAG: {
491 void* storage = sk_malloc_throw(size); 491 SkAutoMalloc storage(size);
492 stream->read(storage, size); 492 if (stream->read(storage.get(), size) != size) {
493 return false;
494 }
493 SkASSERT(NULL == fOpData); 495 SkASSERT(NULL == fOpData);
494 fOpData = SkData::NewFromMalloc(storage, size); 496 fOpData = SkData::NewFromMalloc(storage.detach(), size);
495 } break; 497 } break;
496 case PICT_FACTORY_TAG: { 498 case PICT_FACTORY_TAG: {
497 SkASSERT(!haveBuffer); 499 SkASSERT(!haveBuffer);
498 fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size)); 500 fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size));
499 for (size_t i = 0; i < size; i++) { 501 for (size_t i = 0; i < size; i++) {
500 SkString str; 502 SkString str;
501 int len = stream->readPackedUInt(); 503 const size_t len = stream->readPackedUInt();
502 str.resize(len); 504 str.resize(len);
503 stream->read(str.writable_str(), len); 505 if (stream->read(str.writable_str(), len) != len) {
506 return false;
507 }
504 fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c _str()); 508 fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c _str());
505 } 509 }
506 } break; 510 } break;
507 case PICT_TYPEFACE_TAG: { 511 case PICT_TYPEFACE_TAG: {
508 SkASSERT(!haveBuffer); 512 SkASSERT(!haveBuffer);
509 fTFPlayback.setCount(size); 513 fTFPlayback.setCount(size);
510 for (size_t i = 0; i < size; i++) { 514 for (size_t i = 0; i < size; i++) {
511 SkAutoTUnref<SkTypeface> tf(SkTypeface::Deserialize(stream)); 515 SkAutoTUnref<SkTypeface> tf(SkTypeface::Deserialize(stream));
512 if (!tf.get()) { // failed to deserialize 516 if (!tf.get()) { // failed to deserialize
513 // fTFPlayback asserts it never has a null, so we plop in 517 // fTFPlayback asserts it never has a null, so we plop in
514 // the default here. 518 // the default here.
515 tf.reset(SkTypeface::RefDefault()); 519 tf.reset(SkTypeface::RefDefault());
516 } 520 }
517 fTFPlayback.set(i, tf); 521 fTFPlayback.set(i, tf);
518 } 522 }
519 } break; 523 } break;
520 case PICT_PICTURE_TAG: { 524 case PICT_PICTURE_TAG: {
521 fPictureCount = size; 525 fPictureCount = size;
522 fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); 526 fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
523 for (int i = 0; i < fPictureCount; i++) { 527 bool success = true;
528 int i = 0;
529 for ( ; i < fPictureCount; i++) {
524 fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc); 530 fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc);
525 // CreateFromStream can only fail if PICTURE_VERSION does not ma tch 531 if (NULL == fPictureRefs[i]) {
526 // (which should never happen from here, since a sub picture wil l 532 success = false;
527 // have the same PICTURE_VERSION as its parent) or if stream->re ad 533 break;
528 // returns 0. In the latter case, we have a bug when writing the 534 }
529 // picture to begin with, which will be alerted to here. 535 }
530 SkASSERT(fPictureRefs[i] != NULL); 536 if (!success) {
537 // Delete all of the pictures that were already created (up to b ut excluding i):
538 for (int j = 0; j < i; j++) {
539 fPictureRefs[j]->unref();
540 }
541 // Delete the array
542 SkDELETE_ARRAY(fPictureRefs);
543 fPictureCount = 0;
544 return false;
531 } 545 }
532 } break; 546 } break;
533 case PICT_BUFFER_SIZE_TAG: { 547 case PICT_BUFFER_SIZE_TAG: {
534 SkAutoMalloc storage(size); 548 SkAutoMalloc storage(size);
535 stream->read(storage.get(), size); 549 if (stream->read(storage.get(), size) != size) {
550 return false;
551 }
536 552
537 SkOrderedReadBuffer buffer(storage.get(), size); 553 SkOrderedReadBuffer buffer(storage.get(), size);
538 buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags)); 554 buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags));
539 555
540 fFactoryPlayback->setupBuffer(buffer); 556 fFactoryPlayback->setupBuffer(buffer);
541 fTFPlayback.setupBuffer(buffer); 557 fTFPlayback.setupBuffer(buffer);
542 buffer.setBitmapDecoder(proc); 558 buffer.setBitmapDecoder(proc);
543 559
544 while (!buffer.eof()) { 560 while (!buffer.eof()) {
545 tag = buffer.readUInt(); 561 tag = buffer.readUInt();
546 size = buffer.readUInt(); 562 size = buffer.readUInt();
547 this->parseBufferTag(buffer, tag, size); 563 if (!this->parseBufferTag(buffer, tag, size)) {
564 return false;
565 }
548 } 566 }
549 SkDEBUGCODE(haveBuffer = true;) 567 SkDEBUGCODE(haveBuffer = true;)
550 } break; 568 } break;
551 } 569 }
570 return true; // success
552 } 571 }
553 572
554 void SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer, 573 bool SkPicturePlayback::parseBufferTag(SkOrderedReadBuffer& buffer,
555 uint32_t tag, size_t size) { 574 uint32_t tag, size_t size) {
556 switch (tag) { 575 switch (tag) {
557 case PICT_BITMAP_BUFFER_TAG: { 576 case PICT_BITMAP_BUFFER_TAG: {
558 fBitmaps = SkTRefArray<SkBitmap>::Create(size); 577 fBitmaps = SkTRefArray<SkBitmap>::Create(size);
559 for (size_t i = 0; i < size; ++i) { 578 for (size_t i = 0; i < size; ++i) {
560 SkBitmap* bm = &fBitmaps->writableAt(i); 579 SkBitmap* bm = &fBitmaps->writableAt(i);
561 buffer.readBitmap(bm); 580 buffer.readBitmap(bm);
562 bm->setImmutable(); 581 bm->setImmutable();
563 } 582 }
564 } break; 583 } break;
(...skipping 13 matching lines...) Expand all
578 if (size > 0) { 597 if (size > 0) {
579 fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer))); 598 fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
580 } 599 }
581 break; 600 break;
582 case PICT_REGION_BUFFER_TAG: { 601 case PICT_REGION_BUFFER_TAG: {
583 fRegions = SkTRefArray<SkRegion>::Create(size); 602 fRegions = SkTRefArray<SkRegion>::Create(size);
584 for (size_t i = 0; i < size; ++i) { 603 for (size_t i = 0; i < size; ++i) {
585 buffer.readRegion(&fRegions->writableAt(i)); 604 buffer.readRegion(&fRegions->writableAt(i));
586 } 605 }
587 } break; 606 } break;
607 default:
608 // The tag was invalid.
609 return false;
588 } 610 }
611 return true; // success
589 } 612 }
590 613
591 SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, 614 SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream,
592 SkPicture::InstallPixelRefProc proc) { 615 const SkPictInfo& info,
593 this->init(); 616 SkPicture::InstallPixelRe fProc proc) {
617 SkAutoTDelete<SkPicturePlayback> playback(SkNEW(SkPicturePlayback));
594 618
619 if (!playback->parseStream(stream, info, proc)) {
620 return NULL;
621 }
622 return playback.detach();
623 }
624
625 bool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info,
626 SkPicture::InstallPixelRefProc proc) {
595 for (;;) { 627 for (;;) {
596 uint32_t tag = stream->readU32(); 628 uint32_t tag = stream->readU32();
597 if (PICT_EOF_TAG == tag) { 629 if (PICT_EOF_TAG == tag) {
598 break; 630 break;
599 } 631 }
600 632
601 uint32_t size = stream->readU32(); 633 uint32_t size = stream->readU32();
602 this->parseStreamTag(stream, info, tag, size, proc); 634 if (!this->parseStreamTag(stream, info, tag, size, proc)) {
635 return false; // we're invalid
636 }
603 } 637 }
638 return true;
604 } 639 }
605 640
606 /////////////////////////////////////////////////////////////////////////////// 641 ///////////////////////////////////////////////////////////////////////////////
607 /////////////////////////////////////////////////////////////////////////////// 642 ///////////////////////////////////////////////////////////////////////////////
608 643
609 #ifdef SPEW_CLIP_SKIPPING 644 #ifdef SPEW_CLIP_SKIPPING
610 struct SkipClipRec { 645 struct SkipClipRec {
611 int fCount; 646 int fCount;
612 size_t fSize; 647 size_t fSize;
613 648
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after
1622 for (index = 0; index < fRegionCount; index++) 1657 for (index = 0; index < fRegionCount; index++)
1623 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ), 1658 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ),
1624 "region%p, ", &fRegions[index]); 1659 "region%p, ", &fRegions[index]);
1625 if (fRegionCount > 0) 1660 if (fRegionCount > 0)
1626 SkDebugf("%s0};\n", pBuffer); 1661 SkDebugf("%s0};\n", pBuffer);
1627 1662
1628 const_cast<SkPicturePlayback*>(this)->dumpStream(); 1663 const_cast<SkPicturePlayback*>(this)->dumpStream();
1629 } 1664 }
1630 1665
1631 #endif 1666 #endif
OLDNEW
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698