From c34323549d6cf87691a6db2dd4999e8beaf082fe Mon Sep 17 00:00:00 2001 From: halcanary Date: Thu, 5 May 2016 11:17:08 -0700 Subject: experimental/tools/coreGraphicsPdf2png: remove skia dependency // experimental-only TBR= NOTRY=true Review-Url: https://codereview.chromium.org/1950353002 --- experimental/tools/coreGraphicsPdf2png.cpp | 104 +++++++++++++++++------------ 1 file changed, 60 insertions(+), 44 deletions(-) (limited to 'experimental/tools') diff --git a/experimental/tools/coreGraphicsPdf2png.cpp b/experimental/tools/coreGraphicsPdf2png.cpp index a845932616..c747a269ae 100644 --- a/experimental/tools/coreGraphicsPdf2png.cpp +++ b/experimental/tools/coreGraphicsPdf2png.cpp @@ -5,56 +5,72 @@ * found in the LICENSE file. */ -#include - -#include "SkBitmap.h" -#include "SkCGUtils.h" -#include "SkForceLinking.h" -#include "SkImageEncoder.h" -#include "SkStream.h" - -__SK_FORCE_IMAGE_DECODER_LINKING; - -class StdOutWStream : public SkWStream { -public: - StdOutWStream() : fBytesWritten(0) {} - bool write(const void* buffer, size_t size) final { - fBytesWritten += size; - return size == fwrite(buffer, 1, size, stdout); - } - size_t bytesWritten() const final { return fBytesWritten; } +// c++ --std=c++11 coreGraphicsPdf2png.cpp -o coreGraphicsPdf2png -framework ApplicationServices -private: - size_t fBytesWritten; -}; +#include +#include -static SkStreamAsset* open_for_reading(const char* path) { - if (!path || !path[0] || 0 == strcmp(path, "-")) { - return new SkFILEStream(stdin, SkFILEStream::kCallerRetains_Ownership); - } - return SkStream::NewFromFile(path); -} +#include -static SkWStream* open_for_writing(const char* path) { - if (!path || !path[0] || 0 == strcmp(path, "-")) { - return new StdOutWStream; - } - return new SkFILEWStream(path); -} +#define ASSERT(x) \ + do { \ + if (!(x)) { \ + fprintf(stderr, "ERROR: " __FILE__ \ + ":%d (%s)\n", __LINE__, #x); \ + return 1; \ + } \ + } while (false) \ -static bool to_png(SkWStream* o, const SkBitmap& bm) { - return SkImageEncoder::EncodeStream(o, bm, SkImageEncoder::kPNG_Type, 100); -} +const int PAGE = 1; -// Note: I could implement this using only MacOS|CG API calls, but -// since most of this is already done in Skia, here it is. int main(int argc, char** argv) { - SkBitmap bm; - SkAutoTDelete in(open_for_reading(argc > 1 ? argv[1] : NULL)); - SkAutoTDelete out(open_for_writing(argc > 2 ? argv[2] : NULL)); - if (SkPDFDocumentToBitmap(in.release(), &bm) && to_png(out, bm)) { - return 0; - } else { + if (argc <= 1 || !*(argv[1]) || 0 == strcmp(argv[1], "-")) { + fprintf(stderr, "usage:\n\t%s INPUT_PDF_FILE_PATH [OUTPUT_PNG_PATH]\n", argv[0]); return 1; } + const char* output = argc > 2 ? argv[2] : nullptr; + CGDataProviderRef data = CGDataProviderCreateWithFilename(argv[1]); + ASSERT(data); + CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); + CGDataProviderRelease(data); + ASSERT(pdf); + CGPDFPageRef page = CGPDFDocumentGetPage(pdf, PAGE); + ASSERT(page); + CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); + int w = (int)CGRectGetWidth(bounds); + int h = (int)CGRectGetHeight(bounds); + CGBitmapInfo info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; + CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); + ASSERT(cs); + std::unique_ptr bitmap(new uint32_t[w * h]); + memset(bitmap.get(), 0xFF, 4 * w * h); + CGContextRef ctx = CGBitmapContextCreate(bitmap.get(), w, h, 8, w * 4, cs, info); + ASSERT(ctx); + CGContextDrawPDFPage(ctx, page); + CGPDFDocumentRelease(pdf); + CGImageRef image = CGBitmapContextCreateImage(ctx); + ASSERT(image); + CGDataConsumerCallbacks procs; + procs.putBytes = [](void* f, const void* buf, size_t s) { + return fwrite(buf, 1, s, (FILE*)f); + }; + procs.releaseConsumer = [](void* info) { fclose((FILE*)info); }; + FILE* ofile = (!output || !output[0] || 0 == strcmp(output, "-")) + ? stdout : fopen(output, "wb"); + ASSERT(ofile); + CGDataConsumerRef consumer = CGDataConsumerCreate(ofile, &procs); + ASSERT(consumer); + CGImageDestinationRef dst = + CGImageDestinationCreateWithDataConsumer(consumer, kUTTypePNG, 1, nullptr); + CFRelease(consumer); + ASSERT(dst); + CGImageDestinationAddImage(dst, image, nullptr); + ASSERT(CGImageDestinationFinalize(dst)); + CFRelease(dst); + CGImageRelease(image); + CGColorSpaceRelease(cs); + CGContextRelease(ctx); + return 0; } + + -- cgit v1.2.3