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.
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.