Home | History | Annotate | Download | only in tools
      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