Add support for images that won't fit in memory
Just got crash on decoding huge JPG image of size 5000x6500: http://lake-central.lcsc.us/userfiles/richard-ohlenkamp/Alg_%20II%20Chap%202%20Rev%20KEY%20pg_%203.JPG
Callstack:

Reason:
Crashed: com.apple.root.utility-qos
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00000001217fc000
I think we need to think how to handle this case without crashing an app :)
// 5000x6500x4bytes = 130MB
We could add something akin to progressiveRendersMaxProgressiveRenderSize
Anton - what would you expect the framework to do in this case? Shouldn't you be setting skipDecode = YES if you're downloading a really large image and don't want it decoded, and make sure it is drawn into a context of the size you want?
I know that PINRemoteImage's integration with AsyncDisplayKit would handle this correctly (e.g. if you have an ASNetworkImageNode or ASMultiplexImageNode, they will decode / draw the image at the size the node is onscreen). If you use PINRemoteImage directly with UIKit, it's up to the app to provide enough info to the framework or control the decoding to manage big images.
On Oct 20, 2016, at 1:13 PM, Garrett Moon [email protected] wrote:
We could add something akin to progressiveRendersMaxProgressiveRenderSize
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pinterest/PINRemoteImage/issues/258#issuecomment-255214876, or mute the thread https://github.com/notifications/unsubscribe-auth/AAigA090xQCarlSrTmc-2HCS8-frxDB9ks5q18tagaJpZM4Kb7u2.
Maybe do some tricky memory allocation in this case?
- Create temp file and resize it
- Map it into memory
- Close file
- Use file mapping as image context
This mapped memory will work really fast as RAM. File will not be deleted until mapping is unmapped, which will happen on context dealloc. I had some experiments a few years ago with this idea: https://github.com/k06a/UIImage-DecompressAndMap/blob/master/UIImage%2BDecompressAndMap.m
We do something similar for Animated GIFs (decode to a memory-mapped file). I'll point out a few things:
- PINRemoteImage isn't particularly designed (or described as) having special support for ultra-high-res images; this would be a nice feature request / extension though!
- Even with a mapped file, are you confident that performing the resize operation will not cause that data to be pulled into memory all at once for at least a brief period? If it does create that memory spike, then there's no need for the mapped file - just resize to the size that will be displayed.
- 5000x5000 is dramatically larger than the largest iOS devices' screens. --- If you're on an iPad Pro 12.9", it's still too big, but that device has 4GB of RAM and could easily handle a 130MB decoded image. --- If you're on a 512MB device (no longer supported by iOS 10), then you have only 640x960 pixels — Literally 2.45% the number of pixels in the image!! And yet, it can still hold it in memory if you manage it carefully, but it would heavily burden the A5 CPU to perform the decoding and resizing (file mapping will only make it slower as flash is not nearly as fast on those devices)
All that said, I think the right solution both for your app and for PINRemoteImage will depend on the use case for such large images. If you have a photo editing / manipulation app, you'll need a more sophisticated (e.g. CATiledLayer) approach to managing this anyway. If you're managing a local photo library, you should create a version of the files that is lower resolution, which will only take up ~10% of the total storage space while providing big user advantages.
Let us know a bit more about your use case. If you'd like to take a crack at integrating the memory mapped decoding approach, I think we'd be eager to look at upstreaming it!
On Oct 25, 2016, at 1:07 PM, Anton Bukov [email protected] wrote:
Maybe do some tricky memory allocation in this case?
- Create temp file and resize it
- Map it into memory
- Close file
- Use file mapping as image context
This mapped memory will work really fast as RAM. File will not be deleted until mapping is unmapped, which will happen on context dealloc. I had some experiments a few years ago with this idea: https://github.com/k06a/UIImage-DecompressAndMap/blob/master/UIImage%2BDecompressAndMap.m https://github.com/k06a/UIImage-DecompressAndMap/blob/master/UIImage%2BDecompressAndMap.m — You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/pinterest/PINRemoteImage/issues/258#issuecomment-256160382, or mute the thread https://github.com/notifications/unsubscribe-auth/AAigAzTs_UkDkbq9D0sz2OGRuqCdXS3fks5q3mFkgaJpZM4Kb7u2.