YYImage's Wrong Row Stride Turns EXIF-Rotated JPEGs into Stripes on iOS
iOS apps that normalize camera photos with YYImage can silently corrupt landscape EXIF-tagged JPEGs until they adopt this two-line stride fix; the symptom looks like a download or encoding problem at the business layer, but the bug lives in the image library's memory handling.
Landscape JPEGs that carry EXIF orientation 6 or 8 trigger YYImage's rotation pipeline. Inside that pipeline, vImage writes the rotated pixels into a temporary 'dest' buffer and pads each row to a CPU/SIMD-friendly alignment boundary. YYImage then creates a CGImage from that buffer, passing destBytesPerRow, its own width-based estimate, instead of dest.rowBytes, the actual stride vImage reports. The first row lands correctly; every subsequent row reads from a drifting offset, which is why users see horizontal stripes on the large-image page.
The fix touches two lines: give both the data provider and CGImageCreate the true dest.rowBytes from vImage. That corrects the memory layout for every path through the affine transform helper, so teams no longer need to re-encode images or strip EXIF orientation. The bug shows up most reliably with landscape photos from Android or Samsung devices, because those shots commonly carry rotation metadata, and it is intermittent because padding depends on image size, pixel format, system, and memory alignment.
The failure's intermittency is a direct consequence of vImage's alignment padding: whether the computed stride differs from the actual rowBytes depends on image dimensions and system alignment, so the same class of photo may render fine in one build and corrupt in another.
The bug is a reminder that bridging vImage buffers into CGImage requires trusting the buffer's reported rowBytes, not a recomputed width-based value; one-off-by-a-few bytes silently corrupts every row after the first.
The same underlying mismatch appears in YYImage issue #131, where a workaround re-oriented the image client-side; fixing the stride once is cheaper than patching every consumer.