iOS 27: PDFDocument.dataRepresentation() writes corrupt 16-bpc annotation images (half the data missing)

Since iOS/iPadOS 27.0, saving a PDF with PDFDocument.dataRepresentation() produces a corrupt file when a page contains a PDFAnnotation subclass that overrides draw(with:in:) and draws a 16-bits-per-component image. The same code works correctly on iOS 26.4.

Filed as FBxxxxxxxx.

What happens:

  • The annotation is written with /AAPL:AKExtras, and its appearance (/AP) references an image XObject declared as /BitsPerComponent 16 (RGB).
  • The image stream contains only half of the required data (8-bpc worth). Example: 1429 x 2021 image. Required: 17,328,054 bytes. Actual: 8,664,027 bytes.
  • Adobe Acrobat reports "Insufficient data for an image".
  • Other viewers read the 8-bpc data as 16-bpc, so the drawing is squeezed into the upper half of the page and the lower half is empty. In PDFKit, colors may turn black.
  • The problem is in the writing step: a PDF written on iOS 27.0 is broken everywhere, while a PDF written on iOS 26.4 opens correctly on iOS 27.0.

How to reproduce:

  1. Create a 16-bpc image with UIGraphicsImageRenderer (preferredRange = .extended, or the default format on a wide-color device).
  2. Add a PDFAnnotation subclass whose draw(with:in:) draws that image with context.draw(cgImage, in: bounds).
  3. Call dataRepresentation() and reopen the result.

Current workaround: Create the image with an 8-bpc standard-range format before drawing it in the annotation:

let format = UIGraphicsImageRendererFormat.preferred()
format.preferredRange = .standard   // 8 bpc, sRGB
let renderer = UIGraphicsImageRenderer(size: size, format: format)

With this, the declared bit depth and the data length match, and the PDF is valid on iOS 27.0. However, this gives up 16-bpc / wide-color output, so I would prefer a solution that keeps the original image quality.

Possibly related: FB24882188 / FB24843022 (iOS 27 regression in PDFAnnotation subclasses that override draw(with:in:)).

Questions:

  1. Does anyone know a way to avoid this issue without downgrading the image to 8 bpc? For example, a different way to create or attach the annotation appearance so that PDFKit on iOS 27 writes the 16-bpc data correctly.
  2. Has anyone else seen this, or confirmed whether it is fixed in a later iOS 27 release?

Update: This issue still reproduces on the iOS 27.2 beta simulator when the app is built with Xcode 27.2 beta (iOS 27.2 SDK).

With the same code (16-bpc image drawn in a PDFAnnotation subclass, then dataRepresentation()), the saved PDF is still corrupt: the image is declared as /BitsPerComponent 16 but contains only 8-bpc data, and the drawing is squeezed into the upper half of the page after reopening.

So rebuilding with the latest SDK does not change the behavior. (The original issue on iOS 27.0 was confirmed on physical iPad devices; the 27.2 beta result is from the simulator.)

The 8-bpc workaround (preferredRange = .standard) still works on the 27.2 beta simulator.

I'm still looking for a way to keep 16-bpc output, if anyone has ideas.

Feedback: FB25195006

iOS 27: PDFDocument.dataRepresentation() writes corrupt 16-bpc annotation images (half the data missing)
 
 
Q