DEF_TEST(SkDeflateWStream, r) { SkRandom random(123456); for (int i = 0; i < 50; ++i) { uint32_t size = random.nextULessThan(10000); SkAutoTMalloc<uint8_t> buffer(size); for (uint32_t j = 0; j < size; ++j) { buffer[j] = random.nextU() & 0xff; } SkDynamicMemoryWStream dynamicMemoryWStream; { SkDeflateWStream deflateWStream(&dynamicMemoryWStream); uint32_t j = 0; while (j < size) { uint32_t writeSize = SkTMin(size - j, random.nextRangeU(1, 400)); if (!deflateWStream.write(&buffer[j], writeSize)) { ERRORF(r, "something went wrong."); return; } j += writeSize; } } SkAutoTDelete<SkStreamAsset> compressed( dynamicMemoryWStream.detachAsStream()); SkAutoTDelete<SkStreamAsset> decompressed(stream_inflate(compressed)); if (decompressed->getLength() != size) { ERRORF(r, "Decompression failed to get right size [%d]." " %u != %u", i, (unsigned)(decompressed->getLength()), (unsigned)size); SkString s = SkStringPrintf("/tmp/deftst_compressed_%d", i); SkFILEWStream o(s.c_str()); o.writeStream(compressed.get(), compressed->getLength()); compressed->rewind(); s = SkStringPrintf("/tmp/deftst_input_%d", i); SkFILEWStream o2(s.c_str()); o2.write(&buffer[0], size); continue; } uint32_t minLength = SkTMin(size, (uint32_t)(decompressed->getLength())); for (uint32_t i = 0; i < minLength; ++i) { uint8_t c; SkDEBUGCODE(size_t rb =)decompressed->read(&c, sizeof(uint8_t)); SkASSERT(sizeof(uint8_t) == rb); if (buffer[i] != c) { ERRORF(r, "Decompression failed at byte %u.", (unsigned)i); break; } } } }
static void emit_image_xobject(SkWStream* stream, const SkImage* image, bool alpha, const sk_sp<SkPDFObject>& smask, const SkPDFObjNumMap& objNumMap, const SkPDFSubstituteMap& substitutes) { SkBitmap bitmap; image_get_ro_pixels(image, &bitmap); // TODO(halcanary): test SkAutoLockPixels autoLockPixels(bitmap); // with malformed images. // Write to a temporary buffer to get the compressed length. SkDynamicMemoryWStream buffer; SkDeflateWStream deflateWStream(&buffer); if (alpha) { bitmap_alpha_to_a8(bitmap, &deflateWStream); } else { bitmap_to_pdf_pixels(bitmap, &deflateWStream); } deflateWStream.finalize(); // call before detachAsStream(). std::unique_ptr<SkStreamAsset> asset(buffer.detachAsStream()); SkPDFDict pdfDict("XObject"); pdfDict.insertName("Subtype", "Image"); pdfDict.insertInt("Width", bitmap.width()); pdfDict.insertInt("Height", bitmap.height()); if (alpha) { pdfDict.insertName("ColorSpace", "DeviceGray"); } else if (bitmap.colorType() == kIndex_8_SkColorType) { SkASSERT(1 == pdf_color_component_count(bitmap.colorType())); pdfDict.insertObject("ColorSpace", make_indexed_color_space(bitmap.getColorTable(), bitmap.alphaType())); } else if (1 == pdf_color_component_count(bitmap.colorType())) { pdfDict.insertName("ColorSpace", "DeviceGray"); } else { pdfDict.insertName("ColorSpace", "DeviceRGB"); } if (smask) { pdfDict.insertObjRef("SMask", smask); } pdfDict.insertInt("BitsPerComponent", 8); pdfDict.insertName("Filter", "FlateDecode"); pdfDict.insertInt("Length", asset->getLength()); pdfDict.emitObject(stream, objNumMap, substitutes); pdf_stream_begin(stream); stream->writeStream(asset.get(), asset->getLength()); pdf_stream_end(stream); }
static void TestPDFStream(skiatest::Reporter* reporter) { char streamBytes[] = "Test\nFoo\tBar"; SkAutoTDelete<SkMemoryStream> streamData(new SkMemoryStream( streamBytes, strlen(streamBytes), true)); SkAutoTUnref<SkPDFStream> stream(new SkPDFStream(streamData.get())); ASSERT_EMIT_EQ(reporter, *stream, "<</Length 12>> stream\nTest\nFoo\tBar\nendstream"); stream->insertInt("Attribute", 42); ASSERT_EMIT_EQ(reporter, *stream, "<</Length 12\n/Attribute 42>> stream\n" "Test\nFoo\tBar\nendstream"); { char streamBytes2[] = "This is a longer string, so that compression " "can do something with it. With shorter strings, " "the short circuit logic cuts in and we end up " "with an uncompressed string."; SkAutoDataUnref streamData2(SkData::NewWithCopy(streamBytes2, strlen(streamBytes2))); SkAutoTUnref<SkPDFStream> stream(new SkPDFStream(streamData2.get())); SkDynamicMemoryWStream compressedByteStream; SkDeflateWStream deflateWStream(&compressedByteStream); deflateWStream.write(streamBytes2, strlen(streamBytes2)); deflateWStream.finalize(); SkDynamicMemoryWStream expected; expected.writeText("<</Filter /FlateDecode\n/Length 116>> stream\n"); compressedByteStream.writeToStream(&expected); compressedByteStream.reset(); expected.writeText("\nendstream"); SkAutoDataUnref expectedResultData2(expected.copyToData()); SkString result = emit_to_string(*stream); ASSERT_EQL(reporter, result, (const char*)expectedResultData2->data(), expectedResultData2->size()); } }
void PDFDefaultBitmap::emitObject(SkWStream* stream, const SkPDFObjNumMap& objNumMap, const SkPDFSubstituteMap& substitutes) const { SkAutoLockPixels autoLockPixels(fBitmap); SkASSERT(fBitmap.colorType() != kIndex_8_SkColorType || fBitmap.getColorTable()); // Write to a temporary buffer to get the compressed length. SkDynamicMemoryWStream buffer; SkDeflateWStream deflateWStream(&buffer); bitmap_to_pdf_pixels(fBitmap, &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.insertObject("ColorSpace", make_indexed_color_space(fBitmap.getColorTable())); } else if (1 == pdf_color_component_count(fBitmap.colorType())) { pdfDict.insertName("ColorSpace", "DeviceGray"); } else { pdfDict.insertName("ColorSpace", "DeviceRGB"); } pdfDict.insertInt("BitsPerComponent", 8); if (fSMask) { pdfDict.insertObjRef("SMask", SkRef(fSMask.get())); } pdfDict.insertName("Filter", "FlateDecode"); pdfDict.insertInt("Length", asset->getLength()); pdfDict.emitObject(stream, objNumMap, substitutes); pdf_stream_begin(stream); stream->writeStream(asset.get(), asset->getLength()); pdf_stream_end(stream); }