| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |