1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-12 01:19:42 +01:00
Telegram/legacy/TelegraphKit/TGImageManager.m
2015-10-01 19:19:52 +03:00

278 lines
8.7 KiB
Objective-C

/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import "TGImageManager.h"
#import "TGImageManagerTask.h"
@interface TGImageManager ()
{
NSMutableArray *_dataSourceList;
}
@end
@implementation TGImageManager
+ (TGImageManager *)instance
{
static TGImageManager *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
singleton = [[TGImageManager alloc] init];
});
return singleton;
}
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_dataSourceList = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark -
static UIImage *forceImageDecoding(UIImage *image)
{
if (image == nil || CGSizeEqualToSize(image.size, CGSizeZero))
return nil;
UIGraphicsBeginImageContextWithOptions(image.size, true, image.scale);
[image drawAtPoint:CGPointZero blendMode:kCGBlendModeCopy alpha:1.0f];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
- (UIImage *)loadImageSyncWithUri:(NSString *)uri canWait:(bool)canWait decode:(bool)decode acceptPartialData:(bool)acceptPartialData asyncTaskId:(__autoreleasing id *)asyncTaskId progress:(void (^)(float))progress partialCompletion:(void (^)(UIImage *))partialCompletion completion:(void (^)(UIImage *))completion
{
TGDataResource *imageData = [self loadDataSyncWithUri:uri canWait:canWait acceptPartialData:acceptPartialData asyncTaskId:asyncTaskId progress:progress partialCompletion:^(TGDataResource *resource)
{
if (resource != nil)
{
UIImage *image = [resource image];
if (image != nil)
{
if (decode && ![resource isImageDecoded])
image = forceImageDecoding(image);
if (partialCompletion != nil)
partialCompletion(image);
}
else
{
NSData *data = [resource data];
UIImage *dataImage = [[UIImage alloc] initWithData:data];
if (dataImage != nil && decode)
dataImage = forceImageDecoding(dataImage);
if (partialCompletion != nil)
partialCompletion(dataImage);
}
}
} completion:^(TGDataResource *resource)
{
if (resource != nil)
{
UIImage *image = [resource image];
if (image != nil)
{
if (decode && ![resource isImageDecoded])
image = forceImageDecoding(image);
if (completion != nil)
completion(image);
}
else
{
NSData *data = [resource data];
UIImage *dataImage = [[UIImage alloc] initWithData:data];
if (dataImage != nil && decode)
dataImage = forceImageDecoding(dataImage);
if (completion != nil)
completion(dataImage);
}
}
else if (completion != nil)
completion(nil);
}];
if (imageData != nil)
{
UIImage *image = [imageData image];
if (image != nil)
{
if (decode && ![imageData isImageDecoded])
image = forceImageDecoding(image);
return image;
}
else
{
NSData *data = [imageData data];
UIImage *dataImage = [[UIImage alloc] initWithData:data];
if (dataImage != nil)
{
if (decode)
return forceImageDecoding(dataImage);
else
return dataImage;
}
}
}
return nil;
}
- (id)beginLoadingImageAsyncWithUri:(NSString *)uri decode:(bool)decode progress:(void (^)(float))progress partialCompletion:(void (^)(UIImage *))partialCompletion completion:(void (^)(UIImage *))completion
{
return [self _loadDataAsyncWithUri:uri progress:progress partialCompletion:^(TGDataResource *resource)
{
if (resource != nil)
{
UIImage *image = [resource image];
if (image != nil)
{
if (decode && ![resource isImageDecoded])
image = forceImageDecoding(image);
if (partialCompletion != nil)
partialCompletion(image);
}
else
{
NSData *data = [resource data];
UIImage *dataImage = [[UIImage alloc] initWithData:data];
if (dataImage != nil && decode)
dataImage = forceImageDecoding(dataImage);
if (partialCompletion != nil)
partialCompletion(dataImage);
}
}
} completion:^(TGDataResource *resource)
{
if (resource != nil)
{
UIImage *image = [resource image];
if (image != nil)
{
if (decode && ![resource isImageDecoded])
image = forceImageDecoding(image);
if (completion != nil)
completion(image);
}
else
{
NSData *data = [resource data];
UIImage *dataImage = [[UIImage alloc] initWithData:data];
if (dataImage != nil && decode)
dataImage = forceImageDecoding(dataImage);
if (completion != nil)
completion(dataImage);
}
}
else if (completion != nil)
completion(nil);
}];
}
- (TGDataResource *)loadDataSyncWithUri:(NSString *)uri canWait:(bool)canWait acceptPartialData:(bool)acceptPartialData asyncTaskId:(__autoreleasing id *)asyncTaskId progress:(void (^)(float))progress partialCompletion:(void (^)(TGDataResource *))partialCompletion completion:(void (^)(TGDataResource *))completion
{
__block TGImageDataSource *selectedDataSource = nil;
[TGImageDataSource enumerateDataSources:^bool(TGImageDataSource *dataSource)
{
if ([dataSource canHandleUri:uri])
{
selectedDataSource = dataSource;
return true;
}
return false;
}];
if (selectedDataSource != nil)
return [selectedDataSource loadDataSyncWithUri:uri canWait:canWait acceptPartialData:acceptPartialData asyncTaskId:asyncTaskId progress:progress partialCompletion:partialCompletion completion:completion];
return nil;
}
- (id)loadAttributeSyncForUri:(NSString *)uri attribute:(NSString *)attribute
{
__block TGImageDataSource *selectedDataSource = nil;
[TGImageDataSource enumerateDataSources:^bool(TGImageDataSource *dataSource)
{
if ([dataSource canHandleAttributeUri:uri])
{
selectedDataSource = dataSource;
return true;
}
return false;
}];
if (selectedDataSource != nil)
return [selectedDataSource loadAttributeSyncForUri:uri attribute:attribute];
return nil;
}
- (id)_loadDataAsyncWithUri:(NSString *)uri progress:(void (^)(float progress))progress partialCompletion:(void (^)(TGDataResource *resource))partialCompletion completion:(void (^)(TGDataResource *resource))completion
{
__block TGImageDataSource *selectedDataSource = nil;
[TGImageDataSource enumerateDataSources:^bool(TGImageDataSource *dataSource)
{
if ([dataSource canHandleUri:uri])
{
selectedDataSource = dataSource;
return true;
}
return false;
}];
if (selectedDataSource != nil)
{
TGImageManagerTask *taskId = [[TGImageManagerTask alloc] init];
taskId.dataSource = selectedDataSource;
taskId.childTaskId = [selectedDataSource loadDataAsyncWithUri:uri progress:progress partialCompletion:partialCompletion completion:completion];
return taskId;
}
else
{
TGLog(@"[TGImageManager#%p Data source not found for URI: %@]", self, uri);
if (completion)
completion(nil);
}
return nil;
}
- (void)cancelTaskWithId:(id)taskId
{
if ([taskId isKindOfClass:[TGImageManagerTask class]])
{
TGImageManagerTask *concreteTaskId = (TGImageManagerTask *)taskId;
concreteTaskId->_isCancelled = true;
if (concreteTaskId.childTaskId != nil)
[concreteTaskId.dataSource cancelTaskById:concreteTaskId.childTaskId];
}
}
@end