• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main(int argc,char ** argv)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