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