SkPDF: elimate old IMAGE_STATS, de-dupe image code.
- remove SkPDFDict::emitAll()
- all stream serialization moved into SkPDFDocument.
- SkPDFDocument::endObject() and ::beginOject() now private.
Change-Id: I4d8a5643027f859e1c0307a379c74859faae0d06
Reviewed-on: https://skia-review.googlesource.com/c/180370
Commit-Queue: Hal Canary <halcanary@google.com>
Reviewed-by: Herb Derby <herb@google.com>
diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp
index 4f7ae95..e254156 100644
--- a/src/pdf/SkPDFBitmap.cpp
+++ b/src/pdf/SkPDFBitmap.cpp
@@ -65,37 +65,40 @@
: SK_ColorTRANSPARENT;
}
-static void emit_stream(SkDynamicMemoryWStream* src, SkWStream* dst) {
- dst->writeText(" stream\n");
- src->writeToAndReset(dst);
- dst->writeText("\nendstream");
-}
-
-static void emit_dict(SkWStream* stream, SkISize size, const char* colorSpace,
- const SkPDFIndirectReference* smask, int length) {
+template <typename T>
+static void emit_image_stream(SkPDFDocument* doc,
+ SkPDFIndirectReference ref,
+ T writeStream,
+ SkISize size,
+ const char* colorSpace,
+ SkPDFIndirectReference sMask,
+ int length,
+ bool isJpeg) {
SkPDFDict pdfDict("XObject");
pdfDict.insertName("Subtype", "Image");
pdfDict.insertInt("Width", size.width());
pdfDict.insertInt("Height", size.height());
pdfDict.insertName("ColorSpace", colorSpace);
- if (smask) {
- pdfDict.insertRef("SMask", *smask);
+ if (sMask) {
+ pdfDict.insertRef("SMask", sMask);
}
pdfDict.insertInt("BitsPerComponent", 8);
#ifdef SK_PDF_BASE85_BINARY
auto filters = SkPDFMakeArray();
filters->appendName("ASCII85Decode");
- filters->appendName("FlateDecode");
+ filters->appendName(isJpeg ? "DCTDecode" : "FlateDecode");
pdfDict.insertObject("Filter", std::move(filters));
#else
- pdfDict.insertName("Filter", "FlateDecode");
+ pdfDict.insertName("Filter", isJpeg ? "DCTDecode" : "FlateDecode");
#endif
+ if (isJpeg) {
+ pdfDict.insertInt("ColorTransform", 0);
+ }
pdfDict.insertInt("Length", length);
- pdfDict.emitObject(stream);
+ doc->emitStream(pdfDict, std::move(writeStream), ref);
}
-static SkPDFIndirectReference do_deflated_alpha(const SkPixmap& pm, SkPDFDocument* doc,
- SkPDFIndirectReference ref) {
+static void do_deflated_alpha(const SkPixmap& pm, SkPDFDocument* doc, SkPDFIndirectReference ref) {
SkDynamicMemoryWStream buffer;
SkDeflateWStream deflateWStream(&buffer);
if (kAlpha_8_SkColorType == pm.colorType()) {
@@ -125,17 +128,16 @@
#ifdef SK_PDF_BASE85_BINARY
SkPDFUtils::Base85Encode(buffer.detachAsStream(), &buffer);
#endif
- SkWStream* stream = doc->beginObject(ref);
- emit_dict(stream, pm.info().dimensions(), "DeviceGray", nullptr, buffer.bytesWritten());
- emit_stream(&buffer, stream);
- doc->endObject();
- return ref;
+ int length = SkToInt(buffer.bytesWritten());
+ emit_image_stream(doc, ref, [&buffer](SkWStream* stream) { buffer.writeToAndReset(stream); },
+ pm.info().dimensions(), "DeviceGray", SkPDFIndirectReference(),
+ length, false);
}
-static void do_deflated_image(const SkPixmap& pm,
- SkPDFDocument* doc,
- bool isOpaque,
- SkPDFIndirectReference ref) {
+static void do_deflated_image(const SkPixmap& pm,
+ SkPDFDocument* doc,
+ bool isOpaque,
+ SkPDFIndirectReference ref) {
SkPDFIndirectReference sMask;
if (!isOpaque) {
sMask = doc->reserveRef();
@@ -183,23 +185,20 @@
#ifdef SK_PDF_BASE85_BINARY
SkPDFUtils::Base85Encode(buffer.detachAsStream(), &buffer);
#endif
- SkWStream* stream = doc->beginObject(ref);
- emit_dict(stream, pm.info().dimensions(), colorSpace,
- sMask.fValue != -1 ? &sMask : nullptr,
- buffer.bytesWritten());
- emit_stream(&buffer, stream);
- doc->endObject();
+ int length = SkToInt(buffer.bytesWritten());
+ emit_image_stream(doc, ref, [&buffer](SkWStream* stream) { buffer.writeToAndReset(stream); },
+ pm.info().dimensions(), colorSpace, sMask, length, false);
if (!isOpaque) {
do_deflated_alpha(pm, doc, sMask);
}
}
-static bool do_jpeg(const SkData& data, SkPDFDocument* doc, SkISize size,
+static bool do_jpeg(sk_sp<SkData> data, SkPDFDocument* doc, SkISize size,
SkPDFIndirectReference ref) {
SkISize jpegSize;
SkEncodedInfo::Color jpegColorType;
SkEncodedOrigin exifOrientation;
- if (!SkGetJpegInfo(data.data(), data.size(), &jpegSize,
+ if (!SkGetJpegInfo(data->data(), data->size(), &jpegSize,
&jpegColorType, &exifOrientation)) {
return false;
}
@@ -210,48 +209,16 @@
|| kTopLeft_SkEncodedOrigin != exifOrientation) {
return false;
}
- #ifdef SK_PDF_IMAGE_STATS
- gJpegImageObjects.fetch_add(1);
- #endif
-
#ifdef SK_PDF_BASE85_BINARY
SkDynamicMemoryWStream buffer;
- SkPDFUtils::Base85Encode(SkMemoryStream::MakeDirect(data.data(), data.size()), &buffer);
- int length = SkToInt(buffer.bytesWritten());
- #else
- int length = SkToInt(data.size());
+ SkPDFUtils::Base85Encode(SkMemoryStream::MakeDirect(data->data(), data->size()), &buffer);
+ data = buffer.detachAsData();
#endif
- SkPDFDict pdfDict("XObject");
- pdfDict.insertName("Subtype", "Image");
- pdfDict.insertInt("Width", jpegSize.width());
- pdfDict.insertInt("Height", jpegSize.height());
- if (yuv) {
- pdfDict.insertName("ColorSpace", "DeviceRGB");
- } else {
- pdfDict.insertName("ColorSpace", "DeviceGray");
- }
- pdfDict.insertInt("BitsPerComponent", 8);
- #ifdef SK_PDF_BASE85_BINARY
- auto filters = SkPDFMakeArray();
- filters->appendName("ASCII85Decode");
- filters->appendName("DCTDecode");
- pdfDict.insertObject("Filter", std::move(filters));
- #else
- pdfDict.insertName("Filter", "DCTDecode");
- #endif
- pdfDict.insertInt("ColorTransform", 0);
- pdfDict.insertInt("Length", length);
- SkWStream* stream = doc->beginObject(ref);
- pdfDict.emitObject(stream);
- stream->writeText(" stream\n");
- #ifdef SK_PDF_BASE85_BINARY
- buffer.writeToAndReset(stream);
- #else
- stream->write(data.data(), data.size());
- #endif
- stream->writeText("\nendstream");
- doc->endObject();
+ emit_image_stream(doc, ref,
+ [&data](SkWStream* dst) { dst->write(data->data(), data->size()); },
+ jpegSize, yuv ? "DeviceRGB" : "DeviceGray",
+ SkPDFIndirectReference(), SkToInt(data->size()), true);
return true;
}
@@ -287,7 +254,7 @@
SkASSERT(encodingQuality >= 0);
SkISize dimensions = img->dimensions();
sk_sp<SkData> data = img->refEncodedData();
- if (data && do_jpeg(*data, doc, dimensions, ref)) {
+ if (data && do_jpeg(std::move(data), doc, dimensions, ref)) {
return;
}
SkBitmap bm = to_pixels(img);
@@ -295,7 +262,7 @@
bool isOpaque = pm.isOpaque() || pm.computeIsOpaque();
if (encodingQuality <= 100 && isOpaque) {
sk_sp<SkData> data = img->encodeToData(SkEncodedImageFormat::kJPEG, encodingQuality);
- if (data && do_jpeg(*data, doc, dimensions, ref)) {
+ if (data && do_jpeg(std::move(data), doc, dimensions, ref)) {
return;
}
}