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

Unified Diff: src/pdf/SkPDFBitmap.cpp

Issue 1372783003: SkPDF: Implement drawImage*() properly (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 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 side-by-side diff with in-line comments
Download patch
Index: src/pdf/SkPDFBitmap.cpp
diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp
index de43221630e5ed85e9db28bdf8738c3957c54ada..8fafe95e164fe6857d5973ca94f3b689c585352f 100644
--- a/src/pdf/SkPDFBitmap.cpp
+++ b/src/pdf/SkPDFBitmap.cpp
@@ -8,11 +8,10 @@
#include "SkColorPriv.h"
#include "SkData.h"
#include "SkDeflate.h"
-#include "SkImageGenerator.h"
+#include "SkImage_Base.h"
#include "SkJpegInfo.h"
#include "SkPDFBitmap.h"
#include "SkPDFCanon.h"
-#include "SkPixelRef.h"
#include "SkStream.h"
#include "SkUnPreMultiply.h"
@@ -245,34 +244,41 @@ namespace {
// This SkPDFObject only outputs the alpha layer of the given bitmap.
class PDFAlphaBitmap : public SkPDFObject {
public:
- PDFAlphaBitmap(const SkBitmap& bm) : fBitmap(bm) {}
+ PDFAlphaBitmap(const SkImage* image) : fImage(SkRef(image)) {}
~PDFAlphaBitmap() {}
void emitObject(SkWStream*,
const SkPDFObjNumMap&,
const SkPDFSubstituteMap&) const override;
private:
- const SkBitmap fBitmap;
+ SkAutoTUnref<const SkImage> fImage;
};
void PDFAlphaBitmap::emitObject(SkWStream* stream,
const SkPDFObjNumMap& objNumMap,
const SkPDFSubstituteMap& substitutes) const {
- SkAutoLockPixels autoLockPixels(fBitmap);
- SkASSERT(fBitmap.colorType() != kIndex_8_SkColorType ||
- fBitmap.getColorTable());
+ // Should we lock as a SkPixMap, not a SkBitmap?
+ SkBitmap bitmap;
+ SkISize size = fImage->dimensions();
+ if (!as_IB(fImage.get())->getROPixels(&bitmap) ||
+ bitmap.dimensions() != size) {
+ bitmap.reset(); // bitmap_alpha_to_a8 will fill with zeroes.
+ }
+ SkAutoLockPixels autoLockPixels(bitmap);
+ SkASSERT(bitmap.colorType() != kIndex_8_SkColorType ||
+ bitmap.getColorTable());
// Write to a temporary buffer to get the compressed length.
SkDynamicMemoryWStream buffer;
SkDeflateWStream deflateWStream(&buffer);
- bitmap_alpha_to_a8(fBitmap, &deflateWStream);
+ bitmap_alpha_to_a8(bitmap, &deflateWStream);
deflateWStream.finalize(); // call before detachAsStream().
SkAutoTDelete<SkStreamAsset> asset(buffer.detachAsStream());
SkPDFDict pdfDict("XObject");
pdfDict.insertName("Subtype", "Image");
- pdfDict.insertInt("Width", fBitmap.width());
- pdfDict.insertInt("Height", fBitmap.height());
+ pdfDict.insertInt("Width", size.width());
+ pdfDict.insertInt("Height", size.height());
pdfDict.insertName("ColorSpace", "DeviceGray");
pdfDict.insertInt("BitsPerComponent", 8);
pdfDict.insertName("Filter", "FlateDecode");
@@ -288,16 +294,19 @@ void PDFAlphaBitmap::emitObject(SkWStream* stream,
////////////////////////////////////////////////////////////////////////////////
namespace {
-class PDFDefaultBitmap : public SkPDFBitmap {
+class PDFDefaultBitmap : public SkPDFObject {
public:
- const SkAutoTUnref<SkPDFObject> fSMask;
void emitObject(SkWStream*,
const SkPDFObjNumMap&,
const SkPDFSubstituteMap&) const override;
void addResources(SkPDFObjNumMap*,
const SkPDFSubstituteMap&) const override;
- PDFDefaultBitmap(const SkBitmap& bm, SkPDFObject* smask)
- : SkPDFBitmap(bm), fSMask(smask) {}
+ PDFDefaultBitmap(const SkImage* image, SkPDFObject* smask)
+ : fImage(SkRef(image)), fSMask(smask) {}
+
+private:
+ SkAutoTUnref<const SkImage> fImage;
+ const SkAutoTUnref<SkPDFObject> fSMask;
};
} // namespace
@@ -346,26 +355,33 @@ static SkPDFArray* make_indexed_color_space(const SkColorTable* table) {
void PDFDefaultBitmap::emitObject(SkWStream* stream,
const SkPDFObjNumMap& objNumMap,
const SkPDFSubstituteMap& substitutes) const {
- SkAutoLockPixels autoLockPixels(fBitmap);
- SkASSERT(fBitmap.colorType() != kIndex_8_SkColorType ||
- fBitmap.getColorTable());
+ SkBitmap bitmap; // Should we lock as a SkPixMap, not a SkBitmap?
+ SkISize size = fImage->dimensions();
+ if (!as_IB(fImage.get())->getROPixels(&bitmap) ||
+ bitmap.dimensions() != size) {
+ bitmap.reset(); // bitmap_to_pdf_pixels will fill with zeroes.
+ }
+ SkAutoLockPixels autoLockPixels(bitmap); // TODO(halcanry): test
+ // with malformed images?
+ SkASSERT(bitmap.colorType() != kIndex_8_SkColorType ||
+ bitmap.getColorTable());
// Write to a temporary buffer to get the compressed length.
SkDynamicMemoryWStream buffer;
SkDeflateWStream deflateWStream(&buffer);
- bitmap_to_pdf_pixels(fBitmap, &deflateWStream);
+ bitmap_to_pdf_pixels(bitmap, &deflateWStream);
deflateWStream.finalize(); // call before detachAsStream().
SkAutoTDelete<SkStreamAsset> asset(buffer.detachAsStream());
SkPDFDict pdfDict("XObject");
pdfDict.insertName("Subtype", "Image");
- pdfDict.insertInt("Width", fBitmap.width());
- pdfDict.insertInt("Height", fBitmap.height());
- if (fBitmap.colorType() == kIndex_8_SkColorType) {
- SkASSERT(1 == pdf_color_component_count(fBitmap.colorType()));
+ pdfDict.insertInt("Width", bitmap.width());
+ pdfDict.insertInt("Height", bitmap.height());
+ if (bitmap.colorType() == kIndex_8_SkColorType) {
+ SkASSERT(1 == pdf_color_component_count(bitmap.colorType()));
pdfDict.insertObject("ColorSpace",
- make_indexed_color_space(fBitmap.getColorTable()));
- } else if (1 == pdf_color_component_count(fBitmap.colorType())) {
+ make_indexed_color_space(bitmap.getColorTable()));
+ } else if (1 == pdf_color_component_count(bitmap.colorType())) {
pdfDict.insertName("ColorSpace", "DeviceGray");
} else {
pdfDict.insertName("ColorSpace", "DeviceRGB");
@@ -385,26 +401,19 @@ void PDFDefaultBitmap::emitObject(SkWStream* stream,
////////////////////////////////////////////////////////////////////////////////
-static const SkBitmap& immutable_bitmap(const SkBitmap& bm, SkBitmap* copy) {
- if (bm.isImmutable()) {
- return bm;
- }
- bm.copyTo(copy);
- copy->setImmutable();
- return *copy;
-}
-
namespace {
/**
- * This PDFObject assumes that its constructor was handed YUV JFIF
- * Jpeg-encoded data that can be directly embedded into a PDF.
+ * This PDFObject assumes that its constructor was handed YUV or
+ * Grayscale JFIF Jpeg-encoded data that can be directly embedded
+ * into a PDF.
*/
-class PDFJpegBitmap : public SkPDFBitmap {
+class PDFJpegBitmap : public SkPDFObject {
public:
+ SkISize fSize;
SkAutoTUnref<SkData> fData;
bool fIsYUV;
- PDFJpegBitmap(const SkBitmap& bm, SkData* data, bool isYUV)
- : SkPDFBitmap(bm), fData(SkRef(data)), fIsYUV(isYUV) {}
+ PDFJpegBitmap(SkISize size, SkData* data, bool isYUV)
+ : fSize(size), fData(SkRef(data)), fIsYUV(isYUV) {}
void emitObject(SkWStream*,
const SkPDFObjNumMap&,
const SkPDFSubstituteMap&) const override;
@@ -415,8 +424,8 @@ void PDFJpegBitmap::emitObject(SkWStream* stream,
const SkPDFSubstituteMap& substituteMap) const {
SkPDFDict pdfDict("XObject");
pdfDict.insertName("Subtype", "Image");
- pdfDict.insertInt("Width", fBitmap.width());
- pdfDict.insertInt("Height", fBitmap.height());
+ pdfDict.insertInt("Width", fSize.width());
+ pdfDict.insertInt("Height", fSize.height());
if (fIsYUV) {
pdfDict.insertName("ColorSpace", "DeviceRGB");
} else {
@@ -435,39 +444,17 @@ void PDFJpegBitmap::emitObject(SkWStream* stream,
////////////////////////////////////////////////////////////////////////////////
-SkPDFBitmap* SkPDFBitmap::Create(SkPDFCanon* canon, const SkBitmap& bitmap) {
- SkASSERT(canon);
- if (!SkColorTypeIsValid(bitmap.colorType()) ||
- kUnknown_SkColorType == bitmap.colorType()) {
- return nullptr;
- }
- SkBitmap copy;
- const SkBitmap& bm = immutable_bitmap(bitmap, &copy);
- if (bm.drawsNothing()) {
- return nullptr;
- }
- if (SkPDFBitmap* canonBitmap = canon->findBitmap(bm)) {
- return SkRef(canonBitmap);
- }
-
- if (bm.pixelRef() && bm.pixelRefOrigin().isZero() &&
- bm.dimensions() == bm.pixelRef()->info().dimensions()) {
- // Requires the bitmap to be backed by lazy pixels.
- SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
- SkJFIFInfo info;
- if (data && SkIsJFIF(data, &info)) {
- bool yuv = info.fType == SkJFIFInfo::kYCbCr;
- SkPDFBitmap* pdfBitmap = new PDFJpegBitmap(bm, data, yuv);
- canon->addBitmap(pdfBitmap);
- return pdfBitmap;
+SkPDFObject* SkPDFCreateBitmapObject(const SkImage* image) {
+ SkAutoTUnref<SkData> data(image->refEncoded());
+ SkJFIFInfo info;
+ if (data && SkIsJFIF(data, &info)) {
+ bool yuv = info.fType == SkJFIFInfo::kYCbCr;
+ if (info.fSize == image->dimensions()) { // Sanity check.
+ // hold on to data, not image.
+ return new PDFJpegBitmap(info.fSize, data, yuv);
}
}
-
- SkPDFObject* smask = nullptr;
- if (!bm.isOpaque() && !SkBitmap::ComputeIsOpaque(bm)) {
- smask = new PDFAlphaBitmap(bm);
- }
- SkPDFBitmap* pdfBitmap = new PDFDefaultBitmap(bm, smask);
- canon->addBitmap(pdfBitmap);
- return pdfBitmap;
+ SkPDFObject* smask =
+ image->isOpaque() ? nullptr : new PDFAlphaBitmap(image);
+ return new PDFDefaultBitmap(image, smask);
}
« include/private/SkTHash.h ('K') | « src/pdf/SkPDFBitmap.h ('k') | src/pdf/SkPDFCanon.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698