mirror of
https://github.com/danog/Telegram.git
synced 2024-12-12 01:19:42 +01:00
278 lines
8.7 KiB
Objective-C
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
|