| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| // c++ --std=c++11 coreGraphicsPdf2png.cpp -o coreGraphicsPdf2png -framework ApplicationServices |
| |
| #include <cstdio> |
| #include <memory> |
| |
| #include <ApplicationServices/ApplicationServices.h> |
| |
| #define ASSERT(x) \ |
| do { \ |
| if (!(x)) { \ |
| fprintf(stderr, "ERROR: " __FILE__ \ |
| ":%d (%s)\n", __LINE__, #x); \ |
| return 1; \ |
| } \ |
| } while (false) \ |
| |
| const int PAGE = 1; |
| |
| int main(int argc, char** argv) { |
| 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<uint32_t[]> 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; |
| } |
| |
| |