Generating image of first PDF page in iOS

I have an iPad system that holds a large number of PDF files. For each PDF file I generate an image of the first page (to support a visual index within the UI).

The code I use to generate the images has worked successfully for thousands of different PDF files. However, I have now encountered a PDF file that opens fine in Adobe Reader but which causes an bad access exception when I try generating the image in iOS. The actual document causing the problem is here: PDF document

The code I am using to generate the image is as follows:

+(void)createLiteratureImageWithMeta:(HPSLiteratureMeta*)literatureMeta andData:(NSData*)literatureData
{
    // Used to create a .png image file of the first page of a pdf document.
    // The image is written to the file system, and has a name of the literatureId for the corresponding literature coredata record.

    CFDataRef myPDFData = (__bridge CFDataRef)literatureData;
    CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);

    if (pdf)
    {

        CGPDFPageRef PDFPage = CGPDFDocumentGetPage(pdf, 1);

        if (PDFPage)
        {

            UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 210, 297)]; // A4 = 210mm x 297mm

            // Determine the size of the PDF page.
            CGRect pageRect = CGPDFPageGetBoxRect(PDFPage, kCGPDFMediaBox);
            CGFloat PDFScale = view.frame.size.width/pageRect.size.width;
            pageRect.size = CGSizeMake(pageRect.size.width*PDFScale, pageRect.size.height*PDFScale);


            /*
             Create a low resolution image representation of the PDF page to display before the TiledPDFView renders its content.
             */
            UIGraphicsBeginImageContext(pageRect.size);

            CGContextRef context = UIGraphicsGetCurrentContext();

            // First fill the background with white.
            CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
            CGContextFillRect(context,pageRect);

            CGContextSaveGState(context);
            // Flip the context so that the PDF page is rendered right side up.
            CGContextTranslateCTM(context, 0.0, pageRect.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);

            // Scale the context so that the PDF page is rendered at the correct size for the zoom level.
            CGContextScaleCTM(context, PDFScale,PDFScale);    
            CGContextDrawPDFPage(context, PDFPage);
            CGContextRestoreGState(context);

            UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();

            UIGraphicsEndImageContext();

            UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:backgroundImage];
            backgroundImageView.frame = pageRect;
            backgroundImageView.contentMode = UIViewContentModeScaleAspectFit;
            [view addSubview:backgroundImageView];

            [view sendSubviewToBack:backgroundImageView];

            NSData* imageData = UIImagePNGRepresentation(backgroundImageView.image);

            NSString* filename = [NSString stringWithFormat:@"%@.png",literatureMeta.id];
            filename = [HPSFileHelper encodeFilename:filename];
            [HPSFileHelper writeDataToFileWithData:imageData andFilename:filename];
        }

        CGPDFDocumentRelease (pdf);
        CGDataProviderRelease (provider);
    }

    pdf = nil;
    provider = nil;
}

The exception is thrown for the following line (about 47 lines down from the start):

CGContextDrawPDFPage(context, PDFPage);

It crashes consistently on this line.

The crash looks like this:

Thread : Crashed: NSOperationQueue 0x1562f060
0  ImageIO                        0x2e254032 transfer_fixed_point(kdu_line_buf*, int, int, unsigned char*, int, bool) + 477
1  ???                            0x00001010
2  ImageIO                        0x2e2537d3 kdu_region_decompressor::process_generic(int, int, kdu_coords, int, int, int, kdu_dims&, kdu_dims&, int, bool) + 8570
3  ImageIO                        0x2e251651 kdu_region_decompressor::process(unsigned char**, bool, int, kdu_coords, int, int, int, kdu_dims&, kdu_dims&, int, bool) + 208
4  ImageIO                        0x2e247365 kdrc_stream::process(int, kdu_dims&, int&) + 588
5  ImageIO                        0x2e24db69 kdu_region_compositor::process(int, kdu_dims&) + 268
6  ImageIO                        0x2e2b5ef3 _cg_JP2DecompressBlock + 374
7  ImageIO                        0x2e2b76b9 copyImageBlockSetJP2 + 1016
8  ImageIO                        0x2e17f71f ImageProviderCopyImageBlockSetCallback + 542
9  CoreGraphics                   0x2d4c545d CGImageProviderCopyImageBlockSetWithOptions + 136
10 CoreGraphics                   0x2d4e817b CGImageProviderCopyImageBlockSet + 26
11 CoreGraphics                   0x2d4c512b img_blocks_create + 406
12 CoreGraphics                   0x2d4e814b img_blocks_extent + 62
13 CoreGraphics                   0x2d4e8105 img_interpolate_extent + 108
14 CoreGraphics                   0x2d4b9179 img_data_lock + 4408
15 CoreGraphics                   0x2d4b783d CGSImageDataLock + 88
16 libRIP.A.dylib                 0x2d803e67 ripc_AcquireImage + 98
17 libRIP.A.dylib                 0x2d80320d ripc_DrawImage + 588
18 CoreGraphics                   0x2d4b7753 CGContextDelegateDrawImage + 50
19 CoreGraphics                   0x2d4b75e9 CGContextDrawImage + 284
20 CoreGraphics                   0x2d5776b3 draw_image + 82
21 CoreGraphics                   0x2d57764b CGPDFDrawingContextDrawImage + 218
22 CoreGraphics                   0x2d537831 op_Do + 96
23 CoreGraphics                   0x2d551419 pdf_scanner_handle_xname + 76
24 CoreGraphics                   0x2d550fa7 CGPDFScannerScan + 202
25 CoreGraphics                   0x2d54bbc3 CGPDFDrawingContextDrawGroupStream + 194
26 CoreGraphics                   0x2d59df4d CGPDFDrawingContextDrawGroup + 284
27 CoreGraphics                   0x2d53781f op_Do + 78
28 CoreGraphics                   0x2d551419 pdf_scanner_handle_xname + 76
29 CoreGraphics                   0x2d550fa7 CGPDFScannerScan + 202
30 CoreGraphics                   0x2d54b7e7 CGPDFDrawingContextDrawPage + 358
31 CoreGraphics                   0x2d59d7c1 pdf_page_draw_in_context + 88
32 CoreGraphics                   0x2d57e541 CGContextDrawPDFPage + 36
33 HPS                            0x00060737 +[HPSImageHelper createLiteratureImageWithMeta:andData:] (HPSImageHelper.m:690)
34 HPS                            0x00092d0d -[HPSDbOperationFileDownload doTheWorkWithMOC:] (HPSDbOperationFileDownload.m:63)
35 HPS                            0x00070eb1 -[HPSDbOperationBase main] (HPSDbOperationBase.m:80)
36 Foundation                     0x2dd6c7db -[__NSOperationInternal _start:] + 770
37 Foundation                     0x2de10995 __NSOQSchedule_f + 60
38 libdispatch.dylib              0x380bd68f _dispatch_async_redirect_invoke$VARIANT$mp + 110
39 libdispatch.dylib              0x380bed71 _dispatch_root_queue_drain + 220
40 libdispatch.dylib              0x380bef59 _dispatch_worker_thread2 + 56
41 libsystem_pthread.dylib        0x381f9dbf _pthread_wqthread + 298

Can anyone see an issue with the code (which has worked well for thousands of other documents so far)? Is anyone able to detect an issue with the actual PDF?

Thanks very much.

Answers


It seems the developers of PSPDFKit are experiencing a similar issue, and it seems to go back to some of Apple's code that has been repaired with the release of iOS 7.1 Beta 1.

Here is the link to their ticket discussing the issue: https://github.com/PSPDFKit/PSPDFKit-Demo/wiki/Help!-This-PDF-is-crashing-PSPDFKit

I would suggest running it on iOS 7.1 Beta 1 or later and see if the problem persists. Alternatively, try what they suggest on the ticket, and re-save the pdf through Preview to see if that fixes it.


Need Your Help

IE8 ignores zero-width space when it comes before a slash in standards mode

html internet-explorer-8

I have a table with variable-width cells, and I want to give the browser the option to insert a line break before a slash, without forcing it. I tried this by inserting a zero-width space (ZWSP)