1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 // c++ --std=c++11 coreGraphicsPdf2png.cpp -o coreGraphicsPdf2png -framework ApplicationServices 9 10 #include <cstdio> 11 #include <memory> 12 13 #include <ApplicationServices/ApplicationServices.h> 14 15 #define ASSERT(x) \ 16 do { \ 17 if (!(x)) { \ 18 fprintf(stderr, "ERROR: " __FILE__ \ 19 ":%d (%s)\n", __LINE__, #x); \ 20 return 1; \ 21 } \ 22 } while (false) \ 23 24 const int PAGE = 1; 25 26 int main(int argc, char** argv) { 27 if (argc <= 1 || !*(argv[1]) || 0 == strcmp(argv[1], "-")) { 28 fprintf(stderr, "usage:\n\t%s INPUT_PDF_FILE_PATH [OUTPUT_PNG_PATH]\n", argv[0]); 29 return 1; 30 } 31 const char* output = argc > 2 ? argv[2] : nullptr; 32 CGDataProviderRef data = CGDataProviderCreateWithFilename(argv[1]); 33 ASSERT(data); 34 CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); 35 CGDataProviderRelease(data); 36 ASSERT(pdf); 37 CGPDFPageRef page = CGPDFDocumentGetPage(pdf, PAGE); 38 ASSERT(page); 39 CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); 40 int w = (int)CGRectGetWidth(bounds); 41 int h = (int)CGRectGetHeight(bounds); 42 CGBitmapInfo info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; 43 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 44 ASSERT(cs); 45 std::unique_ptr<uint32_t[]> bitmap(new uint32_t[w * h]); 46 memset(bitmap.get(), 0xFF, 4 * w * h); 47 CGContextRef ctx = CGBitmapContextCreate(bitmap.get(), w, h, 8, w * 4, cs, info); 48 ASSERT(ctx); 49 CGContextDrawPDFPage(ctx, page); 50 CGPDFDocumentRelease(pdf); 51 CGImageRef image = CGBitmapContextCreateImage(ctx); 52 ASSERT(image); 53 CGDataConsumerCallbacks procs; 54 procs.putBytes = [](void* f, const void* buf, size_t s) { 55 return fwrite(buf, 1, s, (FILE*)f); 56 }; 57 procs.releaseConsumer = [](void* info) { fclose((FILE*)info); }; 58 FILE* ofile = (!output || !output[0] || 0 == strcmp(output, "-")) 59 ? stdout : fopen(output, "wb"); 60 ASSERT(ofile); 61 CGDataConsumerRef consumer = CGDataConsumerCreate(ofile, &procs); 62 ASSERT(consumer); 63 CGImageDestinationRef dst = 64 CGImageDestinationCreateWithDataConsumer(consumer, kUTTypePNG, 1, nullptr); 65 CFRelease(consumer); 66 ASSERT(dst); 67 CGImageDestinationAddImage(dst, image, nullptr); 68 ASSERT(CGImageDestinationFinalize(dst)); 69 CFRelease(dst); 70 CGImageRelease(image); 71 CGColorSpaceRelease(cs); 72 CGContextRelease(ctx); 73 return 0; 74 } 75 76 77