SkPDF: debugging flag SK_PDF_BASE85_BINARY applies to JPEG

Change-Id: I16e21d492df7de5d17fcce6070642e3e732b7d96
Reviewed-on: https://skia-review.googlesource.com/c/179727
Reviewed-by: Hal Canary <halcanary@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
Hal Canary 2018-12-20 16:15:17 -05:00 committed by Skia Commit-Bot
parent 02cb969e13
commit d104cc4730
5 changed files with 56 additions and 49 deletions

View File

@ -123,7 +123,7 @@ static SkPDFIndirectReference do_deflated_alpha(const SkPixmap& pm, SkPDFDocumen
deflateWStream.finalize();
#ifdef SK_PDF_BASE85_BINARY
SkPDFUtils::Base85Encode(&buffer);
SkPDFUtils::Base85Encode(buffer.detachAsStream(), &buffer);
#endif
SkWStream* stream = doc->beginObject(ref);
emit_dict(stream, pm.info().dimensions(), "DeviceGray", nullptr, buffer.bytesWritten());
@ -181,7 +181,7 @@ static void do_deflated_image(const SkPixmap& pm,
}
deflateWStream.finalize();
#ifdef SK_PDF_BASE85_BINARY
SkPDFUtils::Base85Encode(&buffer);
SkPDFUtils::Base85Encode(buffer.detachAsStream(), &buffer);
#endif
SkWStream* stream = doc->beginObject(ref);
emit_dict(stream, pm.info().dimensions(), colorSpace,
@ -214,7 +214,13 @@ static bool do_jpeg(const SkData& data, SkPDFDocument* doc, SkISize size,
gJpegImageObjects.fetch_add(1);
#endif
SkWStream* stream = doc->beginObject(ref);
#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());
#endif
SkPDFDict pdfDict("XObject");
pdfDict.insertName("Subtype", "Image");
pdfDict.insertInt("Width", jpegSize.width());
@ -225,12 +231,25 @@ static bool do_jpeg(const SkData& data, SkPDFDocument* doc, SkISize size,
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", SkToInt(data.size()));
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();
return true;

View File

@ -440,7 +440,7 @@ static void serialize_stream(const SkPDFDict* origDict,
deflateWStream.finalize();
#ifdef SK_PDF_BASE85_BINARY
{
SkPDFUtils::Base85Encode(&compressedData);
SkPDFUtils::Base85Encode(compressedData.detachAsStream(), &compressedData);
tmp = compressedData.detachAsStream();
stream = tmp.get();
auto filters = SkPDFMakeArray();

View File

@ -337,52 +337,38 @@ bool SkPDFUtils::ToBitmap(const SkImage* img, SkBitmap* dst) {
}
#ifdef SK_PDF_BASE85_BINARY
static void base85_fourbytes(uint32_t v, char dst[5]) {
void SkPDFUtils::Base85Encode(std::unique_ptr<SkStreamAsset> stream, SkDynamicMemoryWStream* dst) {
SkASSERT(dst);
SkASSERT(stream);
dst->writeText("\n");
int column = 0;
while (true) {
uint8_t src[4] = {0, 0, 0, 0};
size_t count = stream->read(src, 4);
SkASSERT(count < 5);
if (0 == count) {
dst->writeText("~>\n");
return;
}
uint32_t v = ((uint32_t)src[0] << 24) | ((uint32_t)src[1] << 16) |
((uint32_t)src[2] << 8) | src[3];
if (v == 0 && count == 4) {
dst->writeText("z");
column += 1;
} else {
char buffer[5];
for (int n = 4; n > 0; --n) {
dst[n] = (v % 85) + '!';
buffer[n] = (v % 85) + '!';
v /= 85;
}
dst[0] = v + '!';
buffer[0] = v + '!';
dst->write(buffer, count + 1);
column += count + 1;
}
static uint32_t big_end(const uint8_t s[4]) {
return ((uint32_t)s[0] << 24) | ((uint32_t)s[1] << 16) | ((uint32_t)s[2] << 8) | s[3];
}
void SkPDFUtils::Base85Encode(SkDynamicMemoryWStream* dst) {
SkASSERT(dst);
std::unique_ptr<SkStreamAsset> stream = dst->detachAsStream();
SkASSERT(src);
size_t remaining = stream->getLength();
if (column > 74) {
dst->writeText("\n");
int line = 0;
while (remaining > 3) {
uint8_t src[4];
(void)stream->read(src, 4);
remaining -= 4;
uint32_t v = big_end(src);
if (v != 0) {
char buffer[5];
base85_fourbytes(v, buffer);
dst->write(buffer, 5);
line += 5;
} else {
dst->writeText("z");
line += 1;
}
if (line > 74) {
dst->writeText("\n");
line = 0;
column = 0;
}
}
if (remaining > 0) {
SkASSERT(remaining < 4);
uint8_t src[4] = {0, 0, 0, 0};
(void)stream->read(src, remaining);
char buffer[5];
base85_fourbytes(big_end(src), buffer);
dst->write(buffer, remaining + 1);
}
dst->writeText("~>\n");
}
#endif // SK_PDF_BASE85_BINARY

View File

@ -127,7 +127,7 @@ void PopulateTilingPatternDict(SkPDFDict* pattern,
bool ToBitmap(const SkImage* img, SkBitmap* dst);
#ifdef SK_PDF_BASE85_BINARY
void Base85Encode(SkDynamicMemoryWStream*);
void Base85Encode(std::unique_ptr<SkStreamAsset> src, SkDynamicMemoryWStream* dst);
#endif // SK_PDF_BASE85_BINARY
} // namespace SkPDFUtils

View File

@ -71,7 +71,9 @@ DEF_TEST(SkPDF_JpegEmbedTest, r) {
sk_sp<SkData> pdfData = pdf.detachAsData();
SkASSERT(pdfData);
#ifndef SK_PDF_BASE85_BINARY
REPORTER_ASSERT(r, is_subset_of(mandrillData.get(), pdfData.get()));
#endif
// This JPEG uses a nonstandard colorspace - it can not be
// embedded into the PDF directly.