1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9 #include "SkData.h" 10 #include "SkFlate.h" 11 #include "SkPDFCatalog.h" 12 #include "SkPDFImageStream.h" 13 #include "SkStream.h" 14 15 #define kNoColorTransform 0 16 17 static bool skip_compression(SkPDFCatalog* catalog) { 18 return SkToBool(catalog->getDocumentFlags() & 19 SkPDFDocument::kFavorSpeedOverSize_Flags); 20 } 21 22 // TODO(edisonn): Use SkData (after removing deprecated constructor in SkPDFStream). 23 SkPDFImageStream::SkPDFImageStream(SkStream* stream, 24 const SkBitmap& bitmap, 25 const SkIRect& srcRect, 26 EncodeToDCTStream encoder) 27 : SkPDFStream(stream), 28 fBitmap(bitmap), 29 fSrcRect(srcRect), 30 fEncoder(encoder) { 31 } 32 33 SkPDFImageStream::SkPDFImageStream(const SkPDFImageStream& pdfStream) 34 : SkPDFStream(pdfStream), 35 fBitmap(pdfStream.fBitmap), 36 fSrcRect(pdfStream.fSrcRect), 37 fEncoder(pdfStream.fEncoder) { 38 } 39 40 SkPDFImageStream::~SkPDFImageStream() {} 41 42 bool SkPDFImageStream::populate(SkPDFCatalog* catalog) { 43 if (getState() == kUnused_State) { 44 if (!skip_compression(catalog)) { 45 SkDynamicMemoryWStream dctCompressedWStream; 46 if (!fEncoder || !fEncoder(&dctCompressedWStream, fBitmap, fSrcRect)) { 47 return INHERITED::populate(catalog); 48 } 49 50 if (dctCompressedWStream.getOffset() < getData()->getLength()) { 51 SkData* data = dctCompressedWStream.copyToData(); 52 SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (data)); 53 setData(stream); 54 stream->unref(); 55 if (data) { 56 // copyToData and new SkMemoryStream both call ref(), supress one. 57 data->unref(); 58 } 59 60 insertName("Filter", "DCTDecode"); 61 insertInt("ColorTransform", kNoColorTransform); 62 setState(kCompressed_State); 63 } 64 } 65 setState(kNoCompression_State); 66 insertInt("Length", getData()->getLength()); 67 } else if (getState() == kNoCompression_State && !skip_compression(catalog) && 68 (SkFlate::HaveFlate() || fEncoder)) { 69 // Compression has not been requested when the stream was first created. 70 // But a new Catalog would want it compressed. 71 if (!getSubstitute()) { 72 SkPDFImageStream* substitute = SkNEW_ARGS(SkPDFImageStream, (*this)); 73 setSubstitute(substitute); 74 catalog->setSubstitute(this, substitute); 75 } 76 return false; 77 } 78 return true; 79 } 80