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

Side by Side Diff: src/pdf/SkPDFImage.cpp

Issue 515493003: JPEG(JFIF only) directly embedded into PDF (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: nits from reed@ Created 6 years, 3 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/pdf/SkPDFImage.h ('k') | tests/PDFJpegEmbedTest.cpp » ('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 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"
11 #include "SkColor.h" 11 #include "SkColor.h"
12 #include "SkColorPriv.h" 12 #include "SkColorPriv.h"
13 #include "SkData.h" 13 #include "SkData.h"
14 #include "SkFlate.h" 14 #include "SkFlate.h"
15 #include "SkPDFCatalog.h" 15 #include "SkPDFCatalog.h"
16 #include "SkPixelRef.h"
16 #include "SkRect.h" 17 #include "SkRect.h"
17 #include "SkStream.h" 18 #include "SkStream.h"
18 #include "SkString.h" 19 #include "SkString.h"
19 #include "SkUnPreMultiply.h" 20 #include "SkUnPreMultiply.h"
20 21
21 static const int kNoColorTransform = 0; 22 static const int kNoColorTransform = 0;
22 23
23 static bool skip_compression(SkPDFCatalog* catalog) { 24 static bool skip_compression(SkPDFCatalog* catalog) {
24 return SkToBool(catalog->getDocumentFlags() & 25 return SkToBool(catalog->getDocumentFlags() &
25 SkPDFDocument::kFavorSpeedOverSize_Flags); 26 SkPDFDocument::kFavorSpeedOverSize_Flags);
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 // but the new catalog wants it compressed. 622 // but the new catalog wants it compressed.
622 if (!getSubstitute()) { 623 if (!getSubstitute()) {
623 SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this)); 624 SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this));
624 setSubstitute(substitute); 625 setSubstitute(substitute);
625 catalog->setSubstitute(this, substitute); 626 catalog->setSubstitute(this, substitute);
626 } 627 }
627 return false; 628 return false;
628 } 629 }
629 return true; 630 return true;
630 } 631 }
632
633 namespace {
634 /**
635 * This PDFObject assumes that its constructor was handed
636 * Jpeg-encoded data that can be directly embedded into a PDF.
637 */
638 class PDFJPEGImage : public SkPDFObject {
639 SkAutoTUnref<SkData> fData;
640 int fWidth;
641 int fHeight;
642 public:
643 PDFJPEGImage(SkData* data, int width, int height)
644 : fData(SkRef(data)), fWidth(width), fHeight(height) {}
645 virtual void getResources(const SkTSet<SkPDFObject*>&,
646 SkTSet<SkPDFObject*>*) SK_OVERRIDE {}
647 virtual void emitObject(
648 SkWStream* stream,
649 SkPDFCatalog* catalog, bool indirect) SK_OVERRIDE {
650 if (indirect) {
651 this->emitIndirectObject(stream, catalog);
652 return;
653 }
654 SkASSERT(fData.get());
655 const char kPrefaceFormat[] =
656 "<<"
657 "/Type /XObject\n"
658 "/Subtype /Image\n"
659 "/Width %d\n"
660 "/Height %d\n"
661 "/ColorSpace /DeviceRGB\n"
662 "/BitsPerComponent 8\n"
663 "/Filter /DCTDecode\n"
664 "/ColorTransform 0\n"
665 "/Length " SK_SIZE_T_SPECIFIER "\n"
666 ">> stream\n";
667 SkString preface(
668 SkStringPrintf(kPrefaceFormat, fWidth, fHeight, fData->size()));
669 const char kPostface[] = "\nendstream";
670 stream->write(preface.c_str(), preface.size());
671 stream->write(fData->data(), fData->size());
672 stream->write(kPostface, sizeof(kPostface));
673 }
674 };
675
676 /**
677 * If the bitmap is not subsetted, return its encoded data, if
678 * availible.
679 */
680 static inline SkData* ref_encoded_data(const SkBitmap& bm) {
681 if ((NULL == bm.pixelRef())
682 || !bm.pixelRefOrigin().isZero()
683 || (bm.info().dimensions() != bm.pixelRef()->info().dimensions())) {
684 return NULL;
685 }
686 return bm.pixelRef()->refEncodedData();
687 }
688
689 /*
690 * This functions may give false negatives but no false positives.
691 */
692 static bool is_jfif_jpeg(SkData* data) {
693 if (!data || (data->size() < 11)) {
694 return false;
695 }
696 const uint8_t bytesZeroToThree[] = {0xFF, 0xD8, 0xFF, 0xE0};
697 const uint8_t bytesSixToTen[] = {'J', 'F', 'I', 'F', 0};
698 // 0 1 2 3 4 5 6 7 8 9 10
699 // FF D8 FF E0 ?? ?? 'J' 'F' 'I' 'F' 00 ...
700 return ((0 == memcmp(data->bytes(), bytesZeroToThree,
701 sizeof(bytesZeroToThree)))
702 && (0 == memcmp(data->bytes() + 6, bytesSixToTen,
703 sizeof(bytesSixToTen))));
704 }
705 } // namespace
706
707 SkPDFObject* SkPDFCreateImageObject(
708 const SkBitmap& bitmap,
709 const SkIRect& subset,
710 SkPicture::EncodeBitmap encoder) {
711 if (SkIRect::MakeWH(bitmap.width(), bitmap.height()) == subset) {
712 SkAutoTUnref<SkData> encodedData(ref_encoded_data(bitmap));
713 if (is_jfif_jpeg(encodedData)) {
714 return SkNEW_ARGS(PDFJPEGImage,
715 (encodedData, bitmap.width(), bitmap.height()));
716 }
717 }
718 return SkPDFImage::CreateImage(bitmap, subset, encoder);
719 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFImage.h ('k') | tests/PDFJpegEmbedTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698