| SkGPipeWriter::kSharedAddressSpace_Flag }
};
-static bool encode_to_dct_stream(SkWStream* stream, const SkBitmap& bitmap, const SkIRect& rect);
+static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap);
const static ErrorCombination kDefaultIgnorableErrorTypes = ErrorCombination()
.plus(kMissingExpectations_ErrorType)
SkScalarRoundToInt(content.height()));
dev = new SkPDFDevice(pageSize, contentSize, initialTransform);
}
- dev->setDCTEncoder(encode_to_dct_stream);
+ dev->setDCTEncoder(encode_to_dct_data);
SkAutoUnref aur(dev);
SkCanvas c(dev);
DEFINE_int32(pdfJpegQuality, -1, "Encodes images in JPEG at quality level N, "
"which can be in range 0-100). N = -1 will disable JPEG compression. "
"Default is N = 100, maximum quality.");
-
// TODO(edisonn): pass a matrix instead of forcePerspectiveMatrix
// Either the 9 numbers defining the matrix
// or probably more readable would be to replace it with a set of a few predicates
// then we can write something reabable like --rotate centerx centery 90
DEFINE_bool(forcePerspectiveMatrix, false, "Force a perspective matrix.");
-static bool encode_to_dct_stream(SkWStream* stream, const SkBitmap& bitmap, const SkIRect& rect) {
+static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap) {
// Filter output of warnings that JPEG is not available for the image.
- if (bitmap.width() >= 65500 || bitmap.height() >= 65500) return false;
- if (FLAGS_pdfJpegQuality == -1) return false;
-
- SkIRect bitmapBounds;
- SkBitmap subset;
- const SkBitmap* bitmapToUse = &bitmap;
- bitmap.getBounds(&bitmapBounds);
- if (rect != bitmapBounds) {
- SkAssertResult(bitmap.extractSubset(&subset, rect));
- bitmapToUse = ⊂
- }
+ if (bitmap.width() >= 65500 || bitmap.height() >= 65500) return NULL;
+ if (FLAGS_pdfJpegQuality == -1) return NULL;
+ SkBitmap bm = bitmap;
#if defined(SK_BUILD_FOR_MAC)
// Workaround bug #1043 where bitmaps with referenced pixels cause
// CGImageDestinationFinalize to crash
SkBitmap copy;
- bitmapToUse->deepCopyTo(©, bitmapToUse->config());
- bitmapToUse = ©
+ bitmap.deepCopyTo(©, bitmap.config());
+ bm = copy;
#endif
- return SkImageEncoder::EncodeStream(stream,
- *bitmapToUse,
- SkImageEncoder::kJPEG_Type,
- FLAGS_pdfJpegQuality);
+ SkPixelRef* pr = bm.pixelRef();
+ if (pr != NULL) {
+ SkData* data = pr->refEncodedData();
+ if (data != NULL) {
+ *pixelRefOffset = bm.pixelRefOffset();
+ return data;
+ }
+ }
+
+ *pixelRefOffset = 0;
+ return SkImageEncoder::EncodeData(bm,
+ SkImageEncoder::kJPEG_Type,
+ FLAGS_pdfJpegQuality);
}
static int findConfig(const char config[]) {
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPath.h"
+#include "SkPicture.h"
#include "SkRect.h"
#include "SkRefCnt.h"
#include "SkStream.h"
struct GraphicStateEntry;
struct NamedDestination;
-typedef bool (*EncodeToDCTStream)(SkWStream* stream, const SkBitmap& bitmap, const SkIRect& rect);
-
/** \class SkPDFDevice
The drawing context for the PDF backend.
* encoding and decoding might not be worth the space savings,
* if any at all.
*/
- void setDCTEncoder(EncodeToDCTStream encoder) {
+ void setDCTEncoder(SkPicture::EncodeBitmap encoder) {
fEncoder = encoder;
}
// Glyph ids used for each font on this device.
SkAutoTDelete<SkPDFGlyphSetMap> fFontGlyphUsage;
- EncodeToDCTStream fEncoder;
+ SkPicture::EncodeBitmap fEncoder;
SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
const SkRegion& existingClipRegion);
// static
SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap,
const SkIRect& srcRect,
- EncodeToDCTStream encoder) {
+ SkPicture::EncodeBitmap encoder) {
if (bitmap.getConfig() == SkBitmap::kNo_Config) {
return NULL;
}
const SkBitmap& bitmap,
bool isAlpha,
const SkIRect& srcRect,
- EncodeToDCTStream encoder)
+ SkPicture::EncodeBitmap encoder)
: fIsAlpha(isAlpha),
fSrcRect(srcRect),
fEncoder(encoder) {
// Initializing image data for the first time.
SkDynamicMemoryWStream dctCompressedWStream;
if (!skip_compression(catalog) && fEncoder &&
- get_uncompressed_size(fBitmap, fSrcRect) > 1 &&
- fEncoder(&dctCompressedWStream, fBitmap, fSrcRect) &&
- dctCompressedWStream.getOffset() <
- get_uncompressed_size(fBitmap, fSrcRect)) {
- SkAutoTUnref<SkData> data(dctCompressedWStream.copyToData());
- SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
- setData(stream.get());
-
- insertName("Filter", "DCTDecode");
- insertInt("ColorTransform", kNoColorTransform);
- insertInt("Length", getData()->getLength());
- setState(kCompressed_State);
- return true;
+ get_uncompressed_size(fBitmap, fSrcRect) > 1) {
+ SkBitmap subset;
+ // Extract subset
+ if (!fBitmap.extractSubset(&subset, fSrcRect)) {
+ // TODO(edisonn) It fails only for kA1_Config, if that is a
+ // major concern we will fix it later, so far it is NYI.
+ return false;
+ }
+ size_t pixelRefOffset = 0;
+ SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
+ if (data.get() && data->size() < get_uncompressed_size(fBitmap,
+ fSrcRect)) {
+ SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream,
+ (data)));
+ setData(stream.get());
+
+ insertName("Filter", "DCTDecode");
+ insertInt("ColorTransform", kNoColorTransform);
+ insertInt("Length", getData()->getLength());
+ setState(kCompressed_State);
+ return true;
+ }
}
// Fallback method
if (!fStreamValid) {
#ifndef SkPDFImage_DEFINED
#define SkPDFImage_DEFINED
+#include "SkPicture.h"
#include "SkPDFDevice.h"
#include "SkPDFStream.h"
#include "SkPDFTypes.h"
*/
static SkPDFImage* CreateImage(const SkBitmap& bitmap,
const SkIRect& srcRect,
- EncodeToDCTStream encoder);
+ SkPicture::EncodeBitmap encoder);
virtual ~SkPDFImage();
SkBitmap fBitmap;
bool fIsAlpha;
SkIRect fSrcRect;
- EncodeToDCTStream fEncoder;
+ SkPicture::EncodeBitmap fEncoder;
bool fStreamValid;
SkTDArray<SkPDFObject*> fResources;
* May be NULL.
*/
SkPDFImage(SkStream* stream, const SkBitmap& bitmap, bool isAlpha,
- const SkIRect& srcRect, EncodeToDCTStream encoder);
+ const SkIRect& srcRect, SkPicture::EncodeBitmap encoder);
/** Copy constructor, used to generate substitutes.
* @param image The SkPDFImage to copy.
SkTDArray<SkPDFObject*> fResources;
};
-static bool encode_to_dct_stream(SkWStream* stream, const SkBitmap& bitmap, const SkIRect& rect) {
- stream->writeText("DCT compessed stream.");
- return true;
+#define DUMMY_TEXT "DCT compessed stream."
+
+static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap) {
+ *pixelRefOffset = 0;
+ return SkData::NewWithProc(DUMMY_TEXT, sizeof(DUMMY_TEXT) - 1, NULL, NULL);
}
static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset,
SkAutoTUnref<SkPDFDevice> dev(new SkPDFDevice(pageSize, pageSize, SkMatrix::I()));
if (useDCTEncoder) {
- dev->setDCTEncoder(encode_to_dct_stream);
+ dev->setDCTEncoder(encode_to_dct_data);
}
SkCanvas c(dev);
virtual void render() = 0;
virtual void end();
- PdfRenderer(EncodeToDCTStream encoder)
+ PdfRenderer(SkPicture::EncodeBitmap encoder)
: fPicture(NULL)
, fPDFDevice(NULL)
, fEncoder(encoder)
SkAutoTUnref<SkCanvas> fCanvas;
SkPicture* fPicture;
SkPDFDevice* fPDFDevice;
- EncodeToDCTStream fEncoder;
+ SkPicture::EncodeBitmap fEncoder;
private:
typedef SkRefCnt INHERITED;
class SimplePdfRenderer : public PdfRenderer {
public:
- SimplePdfRenderer(EncodeToDCTStream encoder)
+ SimplePdfRenderer(SkPicture::EncodeBitmap encoder)
: PdfRenderer(encoder) {}
virtual void render() SK_OVERRIDE;
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPicture.h"
+#include "SkPixelRef.h"
#include "SkStream.h"
#include "SkTArray.h"
#include "PdfRenderer.h"
}
int gJpegQuality = 100;
-static bool encode_to_dct_stream(SkWStream* stream, const SkBitmap& bitmap, const SkIRect& rect) {
- if (gJpegQuality == -1) return false;
-
- SkIRect bitmapBounds;
- SkBitmap subset;
- const SkBitmap* bitmapToUse = &bitmap;
- bitmap.getBounds(&bitmapBounds);
- if (rect != bitmapBounds) {
- SkAssertResult(bitmap.extractSubset(&subset, rect));
- bitmapToUse = ⊂
- }
+static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap) {
+ if (gJpegQuality == -1) {
+ return NULL;
+ }
+ SkBitmap bm = bitmap;
#if defined(SK_BUILD_FOR_MAC)
- // Workaround bug #1043 where bitmaps with referenced pixels cause
- // CGImageDestinationFinalize to crash
- SkBitmap copy;
- bitmapToUse->deepCopyTo(©, bitmapToUse->config());
- bitmapToUse = ©
+ // Workaround bug #1043 where bitmaps with referenced pixels cause
+ // CGImageDestinationFinalize to crash
+ SkBitmap copy;
+ bitmap.deepCopyTo(©, bitmap.config());
+ bm = copy;
#endif
- return SkImageEncoder::EncodeStream(stream,
- *bitmapToUse,
- SkImageEncoder::kJPEG_Type,
- gJpegQuality);
+ SkPixelRef* pr = bm.pixelRef();
+ if (pr != NULL) {
+ SkData* data = pr->refEncodedData();
+ if (data != NULL) {
+ *pixelRefOffset = bm.pixelRefOffset();
+ return data;
+ }
+ }
+
+ *pixelRefOffset = 0;
+ return SkImageEncoder::EncodeData(bm,
+ SkImageEncoder::kJPEG_Type,
+ gJpegQuality);
}
/** Builds the output filename. path = dir/name, and it replaces expected
SkTArray<SkString> inputs;
SkAutoTUnref<sk_tools::PdfRenderer>
- renderer(SkNEW_ARGS(sk_tools::SimplePdfRenderer, (encode_to_dct_stream)));
+ renderer(SkNEW_ARGS(sk_tools::SimplePdfRenderer, (encode_to_dct_data)));
SkASSERT(renderer.get());
SkString outputDir;