Use SkPicture::ExtractBitmap callback in pdf too, there is no need for a specialized function pointer for pdf only only to pass a rectangle, when we can use subseted bitmaps.
R=scroggo@google.com, reed@google.com, vandebo@chromium.org, bsalomon@google.com Author: edisonn@google.com Review URL: https://codereview.chromium.org/25054002 git-svn-id: http://skia.googlecode.com/svn/trunk@11591 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
f7f5b7c506
commit
608ea6508a
@ -193,7 +193,7 @@ static PipeFlagComboData gPipeWritingFlagCombos[] = {
|
||||
| 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)
|
||||
@ -633,7 +633,7 @@ public:
|
||||
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);
|
||||
@ -1422,7 +1422,6 @@ DEFINE_string2(writePicturePath, p, "", "Write .skp files into this directory.")
|
||||
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
|
||||
@ -1431,32 +1430,33 @@ DEFINE_int32(pdfJpegQuality, -1, "Encodes images in JPEG at quality level N, "
|
||||
// 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[]) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkStream.h"
|
||||
@ -38,8 +39,6 @@ struct ContentEntry;
|
||||
struct GraphicStateEntry;
|
||||
struct NamedDestination;
|
||||
|
||||
typedef bool (*EncodeToDCTStream)(SkWStream* stream, const SkBitmap& bitmap, const SkIRect& rect);
|
||||
|
||||
/** \class SkPDFDevice
|
||||
|
||||
The drawing context for the PDF backend.
|
||||
@ -140,7 +139,7 @@ public:
|
||||
* 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;
|
||||
}
|
||||
|
||||
@ -232,7 +231,7 @@ private:
|
||||
// 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);
|
||||
|
@ -339,7 +339,7 @@ static SkPDFArray* make_indexed_color_space(SkColorTable* table) {
|
||||
// static
|
||||
SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap,
|
||||
const SkIRect& srcRect,
|
||||
EncodeToDCTStream encoder) {
|
||||
SkPicture::EncodeBitmap encoder) {
|
||||
if (bitmap.getConfig() == SkBitmap::kNo_Config) {
|
||||
return NULL;
|
||||
}
|
||||
@ -390,7 +390,7 @@ SkPDFImage::SkPDFImage(SkStream* stream,
|
||||
const SkBitmap& bitmap,
|
||||
bool isAlpha,
|
||||
const SkIRect& srcRect,
|
||||
EncodeToDCTStream encoder)
|
||||
SkPicture::EncodeBitmap encoder)
|
||||
: fIsAlpha(isAlpha),
|
||||
fSrcRect(srcRect),
|
||||
fEncoder(encoder) {
|
||||
@ -482,19 +482,28 @@ bool SkPDFImage::populate(SkPDFCatalog* catalog) {
|
||||
// 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());
|
||||
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;
|
||||
insertName("Filter", "DCTDecode");
|
||||
insertInt("ColorTransform", kNoColorTransform);
|
||||
insertInt("Length", getData()->getLength());
|
||||
setState(kCompressed_State);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Fallback method
|
||||
if (!fStreamValid) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef SkPDFImage_DEFINED
|
||||
#define SkPDFImage_DEFINED
|
||||
|
||||
#include "SkPicture.h"
|
||||
#include "SkPDFDevice.h"
|
||||
#include "SkPDFStream.h"
|
||||
#include "SkPDFTypes.h"
|
||||
@ -38,7 +39,7 @@ public:
|
||||
*/
|
||||
static SkPDFImage* CreateImage(const SkBitmap& bitmap,
|
||||
const SkIRect& srcRect,
|
||||
EncodeToDCTStream encoder);
|
||||
SkPicture::EncodeBitmap encoder);
|
||||
|
||||
virtual ~SkPDFImage();
|
||||
|
||||
@ -60,7 +61,7 @@ private:
|
||||
SkBitmap fBitmap;
|
||||
bool fIsAlpha;
|
||||
SkIRect fSrcRect;
|
||||
EncodeToDCTStream fEncoder;
|
||||
SkPicture::EncodeBitmap fEncoder;
|
||||
bool fStreamValid;
|
||||
|
||||
SkTDArray<SkPDFObject*> fResources;
|
||||
@ -80,7 +81,7 @@ private:
|
||||
* 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.
|
||||
|
@ -39,9 +39,11 @@ private:
|
||||
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,
|
||||
@ -253,7 +255,7 @@ static void TestImage(skiatest::Reporter* reporter, const SkBitmap& bitmap,
|
||||
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);
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
virtual void render() = 0;
|
||||
virtual void end();
|
||||
|
||||
PdfRenderer(EncodeToDCTStream encoder)
|
||||
PdfRenderer(SkPicture::EncodeBitmap encoder)
|
||||
: fPicture(NULL)
|
||||
, fPDFDevice(NULL)
|
||||
, fEncoder(encoder)
|
||||
@ -48,7 +48,7 @@ protected:
|
||||
SkAutoTUnref<SkCanvas> fCanvas;
|
||||
SkPicture* fPicture;
|
||||
SkPDFDevice* fPDFDevice;
|
||||
EncodeToDCTStream fEncoder;
|
||||
SkPicture::EncodeBitmap fEncoder;
|
||||
|
||||
private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
@ -56,7 +56,7 @@ private:
|
||||
|
||||
class SimplePdfRenderer : public PdfRenderer {
|
||||
public:
|
||||
SimplePdfRenderer(EncodeToDCTStream encoder)
|
||||
SimplePdfRenderer(SkPicture::EncodeBitmap encoder)
|
||||
: PdfRenderer(encoder) {}
|
||||
virtual void render() SK_OVERRIDE;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "SkImageEncoder.h"
|
||||
#include "SkOSFile.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTArray.h"
|
||||
#include "PdfRenderer.h"
|
||||
@ -81,30 +82,33 @@ static bool replace_filename_extension(SkString* path,
|
||||
}
|
||||
|
||||
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
|
||||
@ -264,7 +268,7 @@ int tool_main_core(int argc, char** argv) {
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user