OLD | NEW |
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 "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
9 #include "SkData.h" | 9 #include "SkData.h" |
10 #include "SkDeflate.h" | 10 #include "SkDeflate.h" |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 } | 339 } |
340 SkString tableString(tableArray, 3 * table->count()); | 340 SkString tableString(tableArray, 3 * table->count()); |
341 result->appendString(tableString); | 341 result->appendString(tableString); |
342 return result; | 342 return result; |
343 } | 343 } |
344 | 344 |
345 static void emit_image_xobject(SkWStream* stream, | 345 static void emit_image_xobject(SkWStream* stream, |
346 const SkImage* image, | 346 const SkImage* image, |
347 bool alpha, | 347 bool alpha, |
348 const sk_sp<SkPDFObject>& smask, | 348 const sk_sp<SkPDFObject>& smask, |
349 const SkPDFObjNumMap& objNumMap, | 349 const SkPDFObjNumMap& objNumMap) { |
350 const SkPDFSubstituteMap& substitutes) { | |
351 SkBitmap bitmap; | 350 SkBitmap bitmap; |
352 image_get_ro_pixels(image, &bitmap); // TODO(halcanary): test | 351 image_get_ro_pixels(image, &bitmap); // TODO(halcanary): test |
353 SkAutoLockPixels autoLockPixels(bitmap); // with malformed images. | 352 SkAutoLockPixels autoLockPixels(bitmap); // with malformed images. |
354 | 353 |
355 // Write to a temporary buffer to get the compressed length. | 354 // Write to a temporary buffer to get the compressed length. |
356 SkDynamicMemoryWStream buffer; | 355 SkDynamicMemoryWStream buffer; |
357 SkDeflateWStream deflateWStream(&buffer); | 356 SkDeflateWStream deflateWStream(&buffer); |
358 if (alpha) { | 357 if (alpha) { |
359 bitmap_alpha_to_a8(bitmap, &deflateWStream); | 358 bitmap_alpha_to_a8(bitmap, &deflateWStream); |
360 } else { | 359 } else { |
(...skipping 17 matching lines...) Expand all Loading... |
378 pdfDict.insertName("ColorSpace", "DeviceGray"); | 377 pdfDict.insertName("ColorSpace", "DeviceGray"); |
379 } else { | 378 } else { |
380 pdfDict.insertName("ColorSpace", "DeviceRGB"); | 379 pdfDict.insertName("ColorSpace", "DeviceRGB"); |
381 } | 380 } |
382 if (smask) { | 381 if (smask) { |
383 pdfDict.insertObjRef("SMask", smask); | 382 pdfDict.insertObjRef("SMask", smask); |
384 } | 383 } |
385 pdfDict.insertInt("BitsPerComponent", 8); | 384 pdfDict.insertInt("BitsPerComponent", 8); |
386 pdfDict.insertName("Filter", "FlateDecode"); | 385 pdfDict.insertName("Filter", "FlateDecode"); |
387 pdfDict.insertInt("Length", asset->getLength()); | 386 pdfDict.insertInt("Length", asset->getLength()); |
388 pdfDict.emitObject(stream, objNumMap, substitutes); | 387 pdfDict.emitObject(stream, objNumMap); |
389 | 388 |
390 pdf_stream_begin(stream); | 389 pdf_stream_begin(stream); |
391 stream->writeStream(asset.get(), asset->getLength()); | 390 stream->writeStream(asset.get(), asset->getLength()); |
392 pdf_stream_end(stream); | 391 pdf_stream_end(stream); |
393 } | 392 } |
394 | 393 |
395 //////////////////////////////////////////////////////////////////////////////// | 394 //////////////////////////////////////////////////////////////////////////////// |
396 | 395 |
397 namespace { | 396 namespace { |
398 // This SkPDFObject only outputs the alpha layer of the given bitmap. | 397 // This SkPDFObject only outputs the alpha layer of the given bitmap. |
399 class PDFAlphaBitmap final : public SkPDFObject { | 398 class PDFAlphaBitmap final : public SkPDFObject { |
400 public: | 399 public: |
401 PDFAlphaBitmap(sk_sp<SkImage> image) : fImage(std::move(image)) { SkASSERT(f
Image); } | 400 PDFAlphaBitmap(sk_sp<SkImage> image) : fImage(std::move(image)) { SkASSERT(f
Image); } |
402 void emitObject(SkWStream* stream, | 401 void emitObject(SkWStream* stream, |
403 const SkPDFObjNumMap& objNumMap, | 402 const SkPDFObjNumMap& objNumMap) const override { |
404 const SkPDFSubstituteMap& subs) const override { | |
405 SkASSERT(fImage); | 403 SkASSERT(fImage); |
406 emit_image_xobject(stream, fImage.get(), true, nullptr, objNumMap, subs)
; | 404 emit_image_xobject(stream, fImage.get(), true, nullptr, objNumMap); |
407 } | 405 } |
408 void drop() override { fImage = nullptr; } | 406 void drop() override { fImage = nullptr; } |
409 | 407 |
410 private: | 408 private: |
411 sk_sp<SkImage> fImage; | 409 sk_sp<SkImage> fImage; |
412 }; | 410 }; |
413 | 411 |
414 } // namespace | 412 } // namespace |
415 | 413 |
416 //////////////////////////////////////////////////////////////////////////////// | 414 //////////////////////////////////////////////////////////////////////////////// |
417 | 415 |
418 namespace { | 416 namespace { |
419 class PDFDefaultBitmap final : public SkPDFObject { | 417 class PDFDefaultBitmap final : public SkPDFObject { |
420 public: | 418 public: |
421 void emitObject(SkWStream* stream, | 419 void emitObject(SkWStream* stream, |
422 const SkPDFObjNumMap& objNumMap, | 420 const SkPDFObjNumMap& objNumMap) const override { |
423 const SkPDFSubstituteMap& subs) const override { | |
424 SkASSERT(fImage); | 421 SkASSERT(fImage); |
425 emit_image_xobject(stream, fImage.get(), false, fSMask, objNumMap, subs)
; | 422 emit_image_xobject(stream, fImage.get(), false, fSMask, objNumMap); |
426 } | 423 } |
427 void addResources(SkPDFObjNumMap* catalog, | 424 void addResources(SkPDFObjNumMap* catalog) const override { |
428 const SkPDFSubstituteMap& subs) const override { | 425 catalog->addObjectRecursively(fSMask.get()); |
429 SkASSERT(fImage); | |
430 if (fSMask.get()) { | |
431 SkPDFObject* obj = subs.getSubstitute(fSMask.get()); | |
432 SkASSERT(obj); | |
433 catalog->addObjectRecursively(obj, subs); | |
434 } | |
435 } | 426 } |
436 void drop() override { fImage = nullptr; fSMask = nullptr; } | 427 void drop() override { fImage = nullptr; fSMask = nullptr; } |
437 PDFDefaultBitmap(sk_sp<SkImage> image, sk_sp<SkPDFObject> smask) | 428 PDFDefaultBitmap(sk_sp<SkImage> image, sk_sp<SkPDFObject> smask) |
438 : fImage(std::move(image)), fSMask(std::move(smask)) { SkASSERT(fImage);
} | 429 : fImage(std::move(image)), fSMask(std::move(smask)) { SkASSERT(fImage);
} |
439 | 430 |
440 private: | 431 private: |
441 sk_sp<SkImage> fImage; | 432 sk_sp<SkImage> fImage; |
442 sk_sp<SkPDFObject> fSMask; | 433 sk_sp<SkPDFObject> fSMask; |
443 }; | 434 }; |
444 } // namespace | 435 } // namespace |
445 | 436 |
446 //////////////////////////////////////////////////////////////////////////////// | 437 //////////////////////////////////////////////////////////////////////////////// |
447 | 438 |
448 namespace { | 439 namespace { |
449 /** | 440 /** |
450 * This PDFObject assumes that its constructor was handed YUV or | 441 * This PDFObject assumes that its constructor was handed YUV or |
451 * Grayscale JFIF Jpeg-encoded data that can be directly embedded | 442 * Grayscale JFIF Jpeg-encoded data that can be directly embedded |
452 * into a PDF. | 443 * into a PDF. |
453 */ | 444 */ |
454 class PDFJpegBitmap final : public SkPDFObject { | 445 class PDFJpegBitmap final : public SkPDFObject { |
455 public: | 446 public: |
456 SkISize fSize; | 447 SkISize fSize; |
457 sk_sp<SkData> fData; | 448 sk_sp<SkData> fData; |
458 bool fIsYUV; | 449 bool fIsYUV; |
459 PDFJpegBitmap(SkISize size, SkData* data, bool isYUV) | 450 PDFJpegBitmap(SkISize size, SkData* data, bool isYUV) |
460 : fSize(size), fData(SkRef(data)), fIsYUV(isYUV) { SkASSERT(data); } | 451 : fSize(size), fData(SkRef(data)), fIsYUV(isYUV) { SkASSERT(data); } |
461 void emitObject(SkWStream*, | 452 void emitObject(SkWStream*, const SkPDFObjNumMap&) const override; |
462 const SkPDFObjNumMap&, | |
463 const SkPDFSubstituteMap&) const override; | |
464 void drop() override { fData = nullptr; } | 453 void drop() override { fData = nullptr; } |
465 }; | 454 }; |
466 | 455 |
467 void PDFJpegBitmap::emitObject(SkWStream* stream, | 456 void PDFJpegBitmap::emitObject(SkWStream* stream, |
468 const SkPDFObjNumMap& objNumMap, | 457 const SkPDFObjNumMap& objNumMap) const { |
469 const SkPDFSubstituteMap& substituteMap) const { | |
470 SkASSERT(fData); | 458 SkASSERT(fData); |
471 SkPDFDict pdfDict("XObject"); | 459 SkPDFDict pdfDict("XObject"); |
472 pdfDict.insertName("Subtype", "Image"); | 460 pdfDict.insertName("Subtype", "Image"); |
473 pdfDict.insertInt("Width", fSize.width()); | 461 pdfDict.insertInt("Width", fSize.width()); |
474 pdfDict.insertInt("Height", fSize.height()); | 462 pdfDict.insertInt("Height", fSize.height()); |
475 if (fIsYUV) { | 463 if (fIsYUV) { |
476 pdfDict.insertName("ColorSpace", "DeviceRGB"); | 464 pdfDict.insertName("ColorSpace", "DeviceRGB"); |
477 } else { | 465 } else { |
478 pdfDict.insertName("ColorSpace", "DeviceGray"); | 466 pdfDict.insertName("ColorSpace", "DeviceGray"); |
479 } | 467 } |
480 pdfDict.insertInt("BitsPerComponent", 8); | 468 pdfDict.insertInt("BitsPerComponent", 8); |
481 pdfDict.insertName("Filter", "DCTDecode"); | 469 pdfDict.insertName("Filter", "DCTDecode"); |
482 pdfDict.insertInt("ColorTransform", 0); | 470 pdfDict.insertInt("ColorTransform", 0); |
483 pdfDict.insertInt("Length", SkToInt(fData->size())); | 471 pdfDict.insertInt("Length", SkToInt(fData->size())); |
484 pdfDict.emitObject(stream, objNumMap, substituteMap); | 472 pdfDict.emitObject(stream, objNumMap); |
485 pdf_stream_begin(stream); | 473 pdf_stream_begin(stream); |
486 stream->write(fData->data(), fData->size()); | 474 stream->write(fData->data(), fData->size()); |
487 pdf_stream_end(stream); | 475 pdf_stream_end(stream); |
488 } | 476 } |
489 } // namespace | 477 } // namespace |
490 | 478 |
491 //////////////////////////////////////////////////////////////////////////////// | 479 //////////////////////////////////////////////////////////////////////////////// |
492 | 480 |
493 sk_sp<SkPDFObject> SkPDFCreateBitmapObject(sk_sp<SkImage> image, | 481 sk_sp<SkPDFObject> SkPDFCreateBitmapObject(sk_sp<SkImage> image, |
494 SkPixelSerializer* pixelSerializer) { | 482 SkPixelSerializer* pixelSerializer) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 | 515 |
528 sk_sp<SkPDFObject> smask; | 516 sk_sp<SkPDFObject> smask; |
529 if (!image_compute_is_opaque(image.get())) { | 517 if (!image_compute_is_opaque(image.get())) { |
530 smask = sk_make_sp<PDFAlphaBitmap>(image); | 518 smask = sk_make_sp<PDFAlphaBitmap>(image); |
531 } | 519 } |
532 #ifdef SK_PDF_IMAGE_STATS | 520 #ifdef SK_PDF_IMAGE_STATS |
533 gRegularImageObjects.fetch_add(1); | 521 gRegularImageObjects.fetch_add(1); |
534 #endif | 522 #endif |
535 return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask)); | 523 return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask)); |
536 } | 524 } |
OLD | NEW |