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

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

Issue 1199473002: change old picture serialization to really handle images (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: address scroggo comments Created 5 years, 6 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
« no previous file with comments | « src/core/SkPictureData.h ('k') | src/core/SkPictureFlat.h » ('j') | 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 * Copyright 2011 Google Inc. 2 * Copyright 2011 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 #include <new> 7 #include <new>
8 #include "SkPictureData.h" 8 #include "SkPictureData.h"
9 #include "SkPictureRecord.h" 9 #include "SkPictureRecord.h"
10 #include "SkReadBuffer.h" 10 #include "SkReadBuffer.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 // templatize to consolidate with similar picture logic? 62 // templatize to consolidate with similar picture logic?
63 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs(); 63 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs();
64 fTextBlobCount = blobs.count(); 64 fTextBlobCount = blobs.count();
65 if (fTextBlobCount > 0) { 65 if (fTextBlobCount > 0) {
66 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); 66 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount);
67 for (int i = 0; i < fTextBlobCount; ++i) { 67 for (int i = 0; i < fTextBlobCount; ++i) {
68 fTextBlobRefs[i] = SkRef(blobs[i]); 68 fTextBlobRefs[i] = SkRef(blobs[i]);
69 } 69 }
70 } 70 }
71
72 const SkTDArray<const SkImage*>& imgs = record.getImageRefs();
73 fImageCount = imgs.count();
74 if (fImageCount > 0) {
75 fImageRefs = SkNEW_ARRAY(const SkImage*, fImageCount);
76 for (int i = 0; i < fImageCount; ++i) {
77 fImageRefs[i] = SkRef(imgs[i]);
78 }
79 }
71 } 80 }
72 81
73 void SkPictureData::init() { 82 void SkPictureData::init() {
74 fPictureRefs = NULL; 83 fPictureRefs = NULL;
75 fPictureCount = 0; 84 fPictureCount = 0;
76 fTextBlobRefs = NULL; 85 fTextBlobRefs = NULL;
77 fTextBlobCount = 0; 86 fTextBlobCount = 0;
87 fImageRefs = NULL;
88 fImageCount = 0;
78 fOpData = NULL; 89 fOpData = NULL;
79 fFactoryPlayback = NULL; 90 fFactoryPlayback = NULL;
80 } 91 }
81 92
82 SkPictureData::~SkPictureData() { 93 SkPictureData::~SkPictureData() {
83 SkSafeUnref(fOpData); 94 SkSafeUnref(fOpData);
84 95
85 for (int i = 0; i < fPictureCount; i++) { 96 for (int i = 0; i < fPictureCount; i++) {
86 fPictureRefs[i]->unref(); 97 fPictureRefs[i]->unref();
87 } 98 }
88 SkDELETE_ARRAY(fPictureRefs); 99 SkDELETE_ARRAY(fPictureRefs);
89 100
90 for (int i = 0; i < fTextBlobCount; i++) { 101 for (int i = 0; i < fTextBlobCount; i++) {
91 fTextBlobRefs[i]->unref(); 102 fTextBlobRefs[i]->unref();
92 } 103 }
93 SkDELETE_ARRAY(fTextBlobRefs); 104 SkDELETE_ARRAY(fTextBlobRefs);
94 105
106 for (int i = 0; i < fImageCount; i++) {
107 fImageRefs[i]->unref();
108 }
109 SkDELETE_ARRAY(fImageRefs);
110
95 SkDELETE(fFactoryPlayback); 111 SkDELETE(fFactoryPlayback);
96 } 112 }
97 113
98 bool SkPictureData::containsBitmaps() const { 114 bool SkPictureData::containsBitmaps() const {
99 if (fBitmaps.count() > 0) { 115 if (fBitmaps.count() > 0 || fImageCount > 0) {
100 return true; 116 return true;
101 } 117 }
102 for (int i = 0; i < fPictureCount; ++i) { 118 for (int i = 0; i < fPictureCount; ++i) {
103 if (fPictureRefs[i]->willPlayBackBitmaps()) { 119 if (fPictureRefs[i]->willPlayBackBitmaps()) {
104 return true; 120 return true;
105 } 121 }
106 } 122 }
107 return false; 123 return false;
108 } 124 }
109 125
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 buffer.writePath(fPaths[i]); 226 buffer.writePath(fPaths[i]);
211 } 227 }
212 } 228 }
213 229
214 if (fTextBlobCount > 0) { 230 if (fTextBlobCount > 0) {
215 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); 231 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount);
216 for (i = 0; i < fTextBlobCount; ++i) { 232 for (i = 0; i < fTextBlobCount; ++i) {
217 fTextBlobRefs[i]->flatten(buffer); 233 fTextBlobRefs[i]->flatten(buffer);
218 } 234 }
219 } 235 }
236
237 if (fImageCount > 0) {
238 write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount);
239 for (i = 0; i < fImageCount; ++i) {
240 buffer.writeImage(fImageRefs[i]);
241 }
242 }
220 } 243 }
221 244
222 void SkPictureData::serialize(SkWStream* stream, 245 void SkPictureData::serialize(SkWStream* stream,
223 SkPixelSerializer* pixelSerializer) const { 246 SkPixelSerializer* pixelSerializer) const {
224 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); 247 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
225 stream->write(fOpData->bytes(), fOpData->size()); 248 stream->write(fOpData->bytes(), fOpData->size());
226 249
227 if (fPictureCount > 0) { 250 if (fPictureCount > 0) {
228 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); 251 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
229 for (int i = 0; i < fPictureCount; i++) { 252 for (int i = 0; i < fPictureCount; i++) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 } 419 }
397 if (!buffer.isValid()) { 420 if (!buffer.isValid()) {
398 return false; 421 return false;
399 } 422 }
400 SkDEBUGCODE(haveBuffer = true;) 423 SkDEBUGCODE(haveBuffer = true;)
401 } break; 424 } break;
402 } 425 }
403 return true; // success 426 return true; // success
404 } 427 }
405 428
406 bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, 429 static const SkImage* create_image_from_buffer(SkReadBuffer& buffer) {
407 uint32_t tag, uint32_t size) { 430 int width = buffer.read32();
431 int height = buffer.read32();
432 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension
433 buffer.validate(false);
434 return NULL;
435 }
436
437 SkAutoTUnref<SkData> encoded(buffer.readByteArrayAsData());
438 int originX = buffer.read32();
439 int originY = buffer.read32();
440 if (0 == encoded->size() || originX < 0 || originY < 0) {
441 buffer.validate(false);
442 return NULL;
443 }
444
445 const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height);
446 return SkImage::NewFromEncoded(encoded, &subset);
447 }
448
449 // Need a shallow wrapper to return const SkPicture* to match the other factorie s,
450 // as SkPicture::CreateFromBuffer() returns SkPicture*
451 static const SkPicture* create_picture_from_buffer(SkReadBuffer& buffer) {
452 return SkPicture::CreateFromBuffer(buffer);
453 }
454
455 template <typename T>
456 bool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount,
457 const T*** array, int* outCount, const T* (*factory)( SkReadBuffer&)) {
458 if (!buffer.validate((0 == inCount) && (NULL == array))) {
scroggo 2015/06/22 18:48:05 This part I found confusing - you actually do want
reed1 2015/06/22 19:19:35 Yea, that's odd. I'll change it to do that.
459 return false;
460 }
461 *outCount = inCount;
462 if (0 == inCount) {
463 *array = NULL;
464 return true;
465 }
466
467 *array = SkNEW_ARRAY(const T*, *outCount);
468 bool success = true;
469 int i = 0;
470 for (; i < *outCount; i++) {
471 (*array)[i] = factory(buffer);
472 if (NULL == (*array)[i]) {
473 success = false;
474 break;
475 }
476 }
477 if (!success) {
478 // Delete all of the blobs that were already created (up to but excludin g i):
479 for (int j = 0; j < i; j++) {
480 (*array)[j]->unref();
481 }
482 // Delete the array
483 SkDELETE_ARRAY(*array);
484 *array = NULL;
485 *outCount = 0;
486 return false;
487 }
488 return true;
489 }
490
491 bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) {
408 switch (tag) { 492 switch (tag) {
409 case SK_PICT_BITMAP_BUFFER_TAG: { 493 case SK_PICT_BITMAP_BUFFER_TAG: {
410 const int count = SkToInt(size); 494 const int count = SkToInt(size);
411 fBitmaps.reset(count); 495 fBitmaps.reset(count);
412 for (int i = 0; i < count; ++i) { 496 for (int i = 0; i < count; ++i) {
413 SkBitmap* bm = &fBitmaps[i]; 497 SkBitmap* bm = &fBitmaps[i];
414 if (buffer.readBitmap(bm)) { 498 if (buffer.readBitmap(bm)) {
415 bm->setImmutable(); 499 bm->setImmutable();
416 } else { 500 } else {
417 return false; 501 return false;
418 } 502 }
419 } 503 }
420 } break; 504 } break;
421 case SK_PICT_PAINT_BUFFER_TAG: { 505 case SK_PICT_PAINT_BUFFER_TAG: {
422 const int count = SkToInt(size); 506 const int count = SkToInt(size);
423 fPaints.reset(count); 507 fPaints.reset(count);
424 for (int i = 0; i < count; ++i) { 508 for (int i = 0; i < count; ++i) {
425 buffer.readPaint(&fPaints[i]); 509 buffer.readPaint(&fPaints[i]);
426 } 510 }
427 } break; 511 } break;
428 case SK_PICT_PATH_BUFFER_TAG: 512 case SK_PICT_PATH_BUFFER_TAG:
429 if (size > 0) { 513 if (size > 0) {
430 const int count = buffer.readInt(); 514 const int count = buffer.readInt();
431 fPaths.reset(count); 515 fPaths.reset(count);
432 for (int i = 0; i < count; i++) { 516 for (int i = 0; i < count; i++) {
433 buffer.readPath(&fPaths[i]); 517 buffer.readPath(&fPaths[i]);
434 } 518 }
435 } break; 519 } break;
436 case SK_PICT_TEXTBLOB_BUFFER_TAG: { 520 case SK_PICT_TEXTBLOB_BUFFER_TAG:
437 if (!buffer.validate((0 == fTextBlobCount) && (NULL == fTextBlobRefs ))) { 521 if (!new_array_from_buffer(buffer, size, &fTextBlobRefs, &fTextBlobC ount,
522 SkTextBlob::CreateFromBuffer)) {
438 return false; 523 return false;
439 } 524 }
440 fTextBlobCount = size; 525 break;
441 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); 526 case SK_PICT_IMAGE_BUFFER_TAG:
442 bool success = true; 527 if (!new_array_from_buffer(buffer, size, &fImageRefs, &fImageCount,
443 int i = 0; 528 create_image_from_buffer)) {
444 for ( ; i < fTextBlobCount; i++) {
445 fTextBlobRefs[i] = SkTextBlob::CreateFromBuffer(buffer);
446 if (NULL == fTextBlobRefs[i]) {
447 success = false;
448 break;
449 }
450 }
451 if (!success) {
452 // Delete all of the blobs that were already created (up to but excluding i):
453 for (int j = 0; j < i; j++) {
454 fTextBlobRefs[j]->unref();
455 }
456 // Delete the array
457 SkDELETE_ARRAY(fTextBlobRefs);
458 fTextBlobRefs = NULL;
459 fTextBlobCount = 0;
460 return false; 529 return false;
461 } 530 }
462 } break; 531 break;
463 case SK_PICT_READER_TAG: { 532 case SK_PICT_READER_TAG: {
464 SkAutoDataUnref data(SkData::NewUninitialized(size)); 533 SkAutoDataUnref data(SkData::NewUninitialized(size));
465 if (!buffer.readByteArray(data->writable_data(), size) || 534 if (!buffer.readByteArray(data->writable_data(), size) ||
466 !buffer.validate(NULL == fOpData)) { 535 !buffer.validate(NULL == fOpData)) {
467 return false; 536 return false;
468 } 537 }
469 SkASSERT(NULL == fOpData); 538 SkASSERT(NULL == fOpData);
470 fOpData = data.detach(); 539 fOpData = data.detach();
471 } break; 540 } break;
472 case SK_PICT_PICTURE_TAG: { 541 case SK_PICT_PICTURE_TAG:
473 if (!buffer.validate((0 == fPictureCount) && (NULL == fPictureRefs)) ) { 542 if (!new_array_from_buffer(buffer, size, &fPictureRefs, &fPictureCou nt,
543 create_picture_from_buffer)) {
474 return false; 544 return false;
475 } 545 }
476 fPictureCount = size;
477 fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
478 bool success = true;
479 int i = 0;
480 for ( ; i < fPictureCount; i++) {
481 fPictureRefs[i] = SkPicture::CreateFromBuffer(buffer);
482 if (NULL == fPictureRefs[i]) {
483 success = false;
484 break;
485 }
486 }
487 if (!success) {
488 // Delete all of the pictures that were already created (up to b ut excluding i):
489 for (int j = 0; j < i; j++) {
490 fPictureRefs[j]->unref();
491 }
492 // Delete the array
493 SkDELETE_ARRAY(fPictureRefs);
494 fPictureCount = 0;
495 return false;
496 }
497 } break;
498 default: 546 default:
499 // The tag was invalid. 547 // The tag was invalid.
500 return false; 548 return false;
501 } 549 }
502 return true; // success 550 return true; // success
503 } 551 }
504 552
505 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream, 553 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
506 const SkPictInfo& info, 554 const SkPictInfo& info,
507 SkPicture::InstallPixelRefProc pr oc) { 555 SkPicture::InstallPixelRefProc pr oc) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 } 623 }
576 } 624 }
577 625
578 bool SkPictureData::suitableForLayerOptimization() const { 626 bool SkPictureData::suitableForLayerOptimization() const {
579 return fContentInfo.numLayers() > 0; 627 return fContentInfo.numLayers() > 0;
580 } 628 }
581 #endif 629 #endif
582 /////////////////////////////////////////////////////////////////////////////// 630 ///////////////////////////////////////////////////////////////////////////////
583 631
584 632
OLDNEW
« no previous file with comments | « src/core/SkPictureData.h ('k') | src/core/SkPictureFlat.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698