Respect the maximum size of CIContexts

This commit is contained in:
Garrett Moon
2015-11-20 18:04:01 -08:00
parent 022b554b7b
commit db588e49cc

View File

@@ -24,8 +24,6 @@
@property (nonatomic, strong) UIImage *cachedImage;
@property (nonatomic, assign) NSUInteger currentThreshold;
@property (nonatomic, assign) float bytesPerSecond;
@property (nonatomic, strong) CIContext *processingContext;
@property (nonatomic, strong) CIFilter *gaussianFilter;
@property (nonatomic, assign) NSUInteger scannedByte;
@property (nonatomic, assign) NSInteger sosCount;
@property (nonatomic, strong) NSLock *lock;
@@ -43,12 +41,22 @@
@synthesize estimatedRemainingTimeThreshold = _estimatedRemainingTimeThreshold;
@synthesize startTime = _startTime;
static CIContext *GPUProcessingContext = nil;
static CIContext *CPUProcessingContext = nil;
- (instancetype)init
{
if (self = [super init]) {
self.lock = [[NSLock alloc] init];
self.lock.name = @"PINProgressiveImage";
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//CIContexts are immutable and threadsafe
CPUProcessingContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @YES}];
GPUProcessingContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @NO, kCIContextPriorityRequestLow: @YES}];
});
_imageSource = CGImageSourceCreateIncremental(NULL);;
self.size = CGSizeZero;
self.isProgressiveJPEG = NO;
@@ -76,7 +84,6 @@
- (void)dealloc
{
[self.lock lock];
self.processingContext = nil;
if (self.imageSource) {
CFRelease(_imageSource);
}
@@ -92,7 +99,6 @@
{
[self.lock lock];
self.inBackground = YES;
self.processingContext = nil;
[self.lock unlock];
}
@@ -336,32 +342,36 @@
//Must be called within lock
- (UIImage *)postProcessImage:(UIImage *)inputImage withProgress:(float)progress
{
if (inputImage == nil) {
if (inputImage.CGImage == nil) {
return nil;
}
if (self.processingContext == nil) {
self.processingContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(self.inBackground), kCIContextPriorityRequestLow: @YES}];
}
if (self.gaussianFilter == nil) {
self.gaussianFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[self.gaussianFilter setDefaults];
}
CIFilter *gaussianFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[gaussianFilter setDefaults];
UIImage *outputUIImage = nil;
if (self.processingContext && self.gaussianFilter) {
[self.gaussianFilter setValue:[CIImage imageWithCGImage:inputImage.CGImage]
CIContext *processingContext = GPUProcessingContext;
if (self.inBackground) {
processingContext = CPUProcessingContext;
}
if (processingContext.inputImageMaximumSize.height < inputImage.size.height || processingContext.inputImageMaximumSize.width < inputImage.size.width || processingContext.outputImageMaximumSize.height < inputImage.size.height || processingContext.outputImageMaximumSize.width < inputImage.size.width) {
return nil;
}
if (processingContext && gaussianFilter) {
[gaussianFilter setValue:[CIImage imageWithCGImage:inputImage.CGImage]
forKey:kCIInputImageKey];
CGFloat radius = inputImage.size.width / 50.0;
radius = radius * MAX(0, 1.0 - progress);
[self.gaussianFilter setValue:[NSNumber numberWithFloat:radius]
[gaussianFilter setValue:[NSNumber numberWithFloat:radius]
forKey:kCIInputRadiusKey];
CIImage *outputImage = [self.gaussianFilter outputImage];
CIImage *outputImage = [gaussianFilter outputImage];
if (outputImage) {
CGImageRef outputImageRef = [self.processingContext createCGImage:outputImage fromRect:CGRectMake(0, 0, inputImage.size.width, inputImage.size.height)];
CGImageRef outputImageRef = [processingContext createCGImage:outputImage fromRect:CGRectMake(0, 0, inputImage.size.width, inputImage.size.height)];
if (outputImageRef) {
//"decoding" the image here copies it to CPU memory?
@@ -371,10 +381,6 @@
}
}
if (outputUIImage == nil) {
outputUIImage = inputImage;
}
return outputUIImage;
}