SDWebImageDecoder.m
4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* Created by james <https://github.com/mystcolor> on 9/28/11.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageDecoder.h"
#define DECOMPRESSED_IMAGE_KEY @"decompressedImage"
#define DECODE_INFO_KEY @"decodeInfo"
#define IMAGE_KEY @"image"
#define DELEGATE_KEY @"delegate"
#define USER_INFO_KEY @"userInfo"
@implementation SDWebImageDecoder
static SDWebImageDecoder *sharedInstance;
- (void)notifyDelegateOnMainThreadWithInfo:(NSDictionary *)dict
{
SDWIRetain(dict);
NSDictionary *decodeInfo = [dict objectForKey:DECODE_INFO_KEY];
UIImage *decodedImage = [dict objectForKey:DECOMPRESSED_IMAGE_KEY];
id <SDWebImageDecoderDelegate> delegate = [decodeInfo objectForKey:DELEGATE_KEY];
NSDictionary *userInfo = [decodeInfo objectForKey:USER_INFO_KEY];
[delegate imageDecoder:self didFinishDecodingImage:decodedImage userInfo:userInfo];
SDWIRelease(dict);
}
- (void)decodeImageWithInfo:(NSDictionary *)decodeInfo
{
UIImage *image = [decodeInfo objectForKey:IMAGE_KEY];
UIImage *decompressedImage = [UIImage decodedImageWithImage:image];
if (!decompressedImage)
{
// If really have any error occurs, we use the original image at this moment
decompressedImage = image;
}
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
decompressedImage, DECOMPRESSED_IMAGE_KEY,
decodeInfo, DECODE_INFO_KEY, nil];
[self performSelectorOnMainThread:@selector(notifyDelegateOnMainThreadWithInfo:) withObject:dict waitUntilDone:NO];
}
- (id)init
{
if ((self = [super init]))
{
// Initialization code here.
imageDecodingQueue = [[NSOperationQueue alloc] init];
}
return self;
}
- (void)decodeImage:(UIImage *)image withDelegate:(id<SDWebImageDecoderDelegate>)delegate userInfo:(NSDictionary *)info
{
NSDictionary *decodeInfo = [NSDictionary dictionaryWithObjectsAndKeys:
image, IMAGE_KEY,
delegate, DELEGATE_KEY,
info, USER_INFO_KEY, nil];
NSOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(decodeImageWithInfo:) object:decodeInfo];
[imageDecodingQueue addOperation:operation];
SDWIRelease(operation);
}
- (void)dealloc
{
SDWISafeRelease(imageDecodingQueue);
SDWISuperDealoc;
}
+ (SDWebImageDecoder *)sharedImageDecoder
{
if (!sharedInstance)
{
sharedInstance = [[SDWebImageDecoder alloc] init];
}
return sharedInstance;
}
@end
@implementation UIImage (ForceDecode)
+ (UIImage *)decodedImageWithImage:(UIImage *)image
{
CGImageRef imageRef = image.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);
BOOL imageHasAlphaInfo = (alphaInfo != kCGImageAlphaNone);
int bytesPerPixel = imageHasAlphaInfo ? 4 : 3;
CGBitmapInfo bitmapInfo = imageHasAlphaInfo ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone;
CGContextRef context = CGBitmapContextCreate(NULL,
CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef),
8,
// Just always return width * bytesPerPixel will be enough
CGImageGetWidth(imageRef) * bytesPerPixel,
// System only supports RGB, set explicitly
colorSpace,
bitmapInfo);
CGColorSpaceRelease(colorSpace);
if (!context) return nil;
CGRect rect = (CGRect){CGPointZero,{CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}};
CGContextDrawImage(context, rect, imageRef);
CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];
CGImageRelease(decompressedImageRef);
return SDWIReturnAutoreleased(decompressedImage);
}
@end