OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010 The Android Open Source Project | 2 * Copyright 2010 The Android Open Source Project |
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 "SkPDFImage.h" | 8 #include "SkPDFImage.h" |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 buf[2] = SkGetPackedB32(color); | 332 buf[2] = SkGetPackedB32(color); |
333 index.append(buf, 3); | 333 index.append(buf, 3); |
334 } | 334 } |
335 result->append(new SkPDFString(index))->unref(); | 335 result->append(new SkPDFString(index))->unref(); |
336 return result; | 336 return result; |
337 } | 337 } |
338 | 338 |
339 // static | 339 // static |
340 SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap, | 340 SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap, |
341 const SkIRect& srcRect, | 341 const SkIRect& srcRect, |
342 EncodeToDCTStream encoder) { | 342 SkPicture::EncodeBitmap encoder) { |
343 if (bitmap.getConfig() == SkBitmap::kNo_Config) { | 343 if (bitmap.getConfig() == SkBitmap::kNo_Config) { |
344 return NULL; | 344 return NULL; |
345 } | 345 } |
346 | 346 |
347 bool isTransparent = false; | 347 bool isTransparent = false; |
348 SkAutoTUnref<SkStream> alphaData; | 348 SkAutoTUnref<SkStream> alphaData; |
349 if (!bitmap.isOpaque()) { | 349 if (!bitmap.isOpaque()) { |
350 // Note that isOpaque is not guaranteed to return false for bitmaps | 350 // Note that isOpaque is not guaranteed to return false for bitmaps |
351 // with alpha support but a completely opaque alpha channel, | 351 // with alpha support but a completely opaque alpha channel, |
352 // so alphaData may still be NULL if we have a completely opaque | 352 // so alphaData may still be NULL if we have a completely opaque |
(...skipping 30 matching lines...) Expand all Loading... |
383 | 383 |
384 void SkPDFImage::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 384 void SkPDFImage::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, |
385 SkTSet<SkPDFObject*>* newResourceObjects) { | 385 SkTSet<SkPDFObject*>* newResourceObjects) { |
386 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); | 386 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); |
387 } | 387 } |
388 | 388 |
389 SkPDFImage::SkPDFImage(SkStream* stream, | 389 SkPDFImage::SkPDFImage(SkStream* stream, |
390 const SkBitmap& bitmap, | 390 const SkBitmap& bitmap, |
391 bool isAlpha, | 391 bool isAlpha, |
392 const SkIRect& srcRect, | 392 const SkIRect& srcRect, |
393 EncodeToDCTStream encoder) | 393 SkPicture::EncodeBitmap encoder) |
394 : fIsAlpha(isAlpha), | 394 : fIsAlpha(isAlpha), |
395 fSrcRect(srcRect), | 395 fSrcRect(srcRect), |
396 fEncoder(encoder) { | 396 fEncoder(encoder) { |
397 | 397 |
398 if (bitmap.isImmutable()) { | 398 if (bitmap.isImmutable()) { |
399 fBitmap = bitmap; | 399 fBitmap = bitmap; |
400 } else { | 400 } else { |
401 bitmap.deepCopyTo(&fBitmap, bitmap.config()); | 401 bitmap.deepCopyTo(&fBitmap, bitmap.config()); |
402 fBitmap.setImmutable(); | 402 fBitmap.setImmutable(); |
403 } | 403 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 // Nothing to do here - the image params are already copied in SkPDFStream's | 475 // Nothing to do here - the image params are already copied in SkPDFStream's |
476 // constructor, and the bitmap will be regenerated and encoded in | 476 // constructor, and the bitmap will be regenerated and encoded in |
477 // populate. | 477 // populate. |
478 } | 478 } |
479 | 479 |
480 bool SkPDFImage::populate(SkPDFCatalog* catalog) { | 480 bool SkPDFImage::populate(SkPDFCatalog* catalog) { |
481 if (getState() == kUnused_State) { | 481 if (getState() == kUnused_State) { |
482 // Initializing image data for the first time. | 482 // Initializing image data for the first time. |
483 SkDynamicMemoryWStream dctCompressedWStream; | 483 SkDynamicMemoryWStream dctCompressedWStream; |
484 if (!skip_compression(catalog) && fEncoder && | 484 if (!skip_compression(catalog) && fEncoder && |
485 get_uncompressed_size(fBitmap, fSrcRect) > 1 && | 485 get_uncompressed_size(fBitmap, fSrcRect) > 1) { |
486 fEncoder(&dctCompressedWStream, fBitmap, fSrcRect) && | 486 SkBitmap subset; |
487 dctCompressedWStream.getOffset() < | 487 // Extract subset |
488 get_uncompressed_size(fBitmap, fSrcRect)) { | 488 if (!fBitmap.extractSubset(&subset, fSrcRect)) { |
489 SkAutoTUnref<SkData> data(dctCompressedWStream.copyToData()); | 489 // TODO(edisonn) It fails only for kA1_Config, if that is a |
490 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data))); | 490 // major concern we will fix it later, so far it is NYI. |
491 setData(stream.get()); | 491 return false; |
| 492 } |
| 493 size_t pixelRefOffset = 0; |
| 494 SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset)); |
| 495 if (data.get() && data->size() < get_uncompressed_size(fBitmap, |
| 496 fSrcRect)) { |
| 497 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, |
| 498 (data))); |
| 499 setData(stream.get()); |
492 | 500 |
493 insertName("Filter", "DCTDecode"); | 501 insertName("Filter", "DCTDecode"); |
494 insertInt("ColorTransform", kNoColorTransform); | 502 insertInt("ColorTransform", kNoColorTransform); |
495 insertInt("Length", getData()->getLength()); | 503 insertInt("Length", getData()->getLength()); |
496 setState(kCompressed_State); | 504 setState(kCompressed_State); |
497 return true; | 505 return true; |
| 506 } |
498 } | 507 } |
499 // Fallback method | 508 // Fallback method |
500 if (!fStreamValid) { | 509 if (!fStreamValid) { |
501 SkAutoTUnref<SkStream> stream( | 510 SkAutoTUnref<SkStream> stream( |
502 extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL)); | 511 extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL)); |
503 setData(stream); | 512 setData(stream); |
504 fStreamValid = true; | 513 fStreamValid = true; |
505 } | 514 } |
506 return INHERITED::populate(catalog); | 515 return INHERITED::populate(catalog); |
507 } else if (getState() == kNoCompression_State && | 516 } else if (getState() == kNoCompression_State && |
508 !skip_compression(catalog) && | 517 !skip_compression(catalog) && |
509 (SkFlate::HaveFlate() || fEncoder)) { | 518 (SkFlate::HaveFlate() || fEncoder)) { |
510 // Compression has not been requested when the stream was first created, | 519 // Compression has not been requested when the stream was first created, |
511 // but the new catalog wants it compressed. | 520 // but the new catalog wants it compressed. |
512 if (!getSubstitute()) { | 521 if (!getSubstitute()) { |
513 SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this)); | 522 SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this)); |
514 setSubstitute(substitute); | 523 setSubstitute(substitute); |
515 catalog->setSubstitute(this, substitute); | 524 catalog->setSubstitute(this, substitute); |
516 } | 525 } |
517 return false; | 526 return false; |
518 } | 527 } |
519 return true; | 528 return true; |
520 } | 529 } |
OLD | NEW |