Merge pull request #10 from gunyarakun/fix-invalid-return
[cocotron.git] / AppKit / NSImageRep.m
blob9521d7acb2366fd9337a4e5fb1e60bab06001a96
1 /* Copyright (c) 2006-2007 Christopher J. W. Lloyd
3 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
9 #import <AppKit/NSImageRep.h>
10 #import <AppKit/NSBitmapImageRep.h>
11 #import <AppKit/NSPDFImageRep.h>
12 #import <AppKit/NSPasteboard.h>
13 #import <AppKit/NSGraphicsContextFunctions.h>
14 #import <AppKit/NSRaise.h>
16 @implementation NSImageRep
18 static NSMutableArray *_registeredClasses=nil;
20 +(void)initialize {
21    if(self==[NSImageRep class]){
22     _registeredClasses=[NSMutableArray new];
23     [_registeredClasses addObject:[NSBitmapImageRep class]];
25  * // PDF is not ready for primetime
26  * [_registeredClasses addObject:[NSPDFImageRep class]];
27  */
28            
29    }
32 +(NSArray *)registeredImageRepClasses {
33    return _registeredClasses;
36 +(void)registerImageRepClass:(Class)class {
37    [_registeredClasses addObject:class];
40 +(void)unregisterImageRepClass:(Class)class {
41    [_registeredClasses removeObjectIdenticalTo:class];
44 +(NSArray *)imageFileTypes {
45    NSMutableSet *result=[NSMutableSet set];
46    int           i,count=[_registeredClasses count];
47    
48    for(i=0;i<count;i++){
49     Class cls=[_registeredClasses objectAtIndex:i];
50     
51     [result addObjectsFromArray:[cls imageUnfilteredFileTypes]];
52    }
53    
54    return [result allObjects];
57 +(NSArray *)imageUnfilteredFileTypes {
58    return [NSArray array];
61 +(NSArray *)imagePasteboardTypes {
62    NSMutableSet *result=[NSMutableSet set];
63    int           i,count=[_registeredClasses count];
64    
65    for(i=0;i<count;i++){
66     Class cls=[_registeredClasses objectAtIndex:i];
67     
68     [result addObjectsFromArray:[cls imageUnfilteredPasteboardTypes]];
69    }
70    
71    return [result allObjects];
74 +(NSArray *)imageUnfilteredPasteboardTypes {
75    return [NSArray array];
78 +(BOOL)canInitWithData:(NSData *)data {
79    return NO;
82 +(BOOL)canInitWithPasteboard:(NSPasteboard *)pasteboard {
83    NSString *available=[pasteboard availableTypeFromArray:[self imageUnfilteredPasteboardTypes]];
84    
85    return (available!=nil)?YES:NO;
88 +(Class)imageRepClassForData:(NSData *)data {
89    int count=[_registeredClasses count];
90    
91    while(--count>=0){
92     Class check=[_registeredClasses objectAtIndex:count];
93     
94     if([check canInitWithData:data])
95      return check;
96    }
97    
98    return nil;
101 +(Class)imageRepClassForFileType:(NSString *)type {
102    int count=[_registeredClasses count];
103    
104    while(--count>=0){
105     Class    checkClass=[_registeredClasses objectAtIndex:count];
106     NSArray *types=[checkClass imageUnfilteredFileTypes];
107     
108     for(NSString *checkType in types)
109      if([checkType caseInsensitiveCompare:type]==NSOrderedSame)
110       return checkClass;
111    }
112    
113    return nil;
116 +(Class)imageRepClassForPasteboardType:(NSString *)type {
117    int count=[_registeredClasses count];
118    
119    while(--count>=0){
120     Class    checkClass=[_registeredClasses objectAtIndex:count];
121     NSArray *types=[checkClass imageUnfilteredPasteboardTypes];
122     
123     if([types containsObject:type])
124      return checkClass;
125    }
126    
127    return nil;
130 +(NSArray *)imageRepsWithContentsOfFile:(NSString *)path {
131         // Try to guess which class to use from the path extension
132    NSString *type=[path pathExtension];
133    Class     class=[self imageRepClassForFileType:type];
134         if (class == nil) {
135                 // Else use the content of the file to guess the class to use
136                 NSData *data=[NSData dataWithContentsOfFile:path];
137                 
138                 if(data==nil) {
139                         return nil;
140                 }
141                 
142                 if(self==[NSImageRep class]){    
143                         class=[self imageRepClassForData:data];
144                 }
145                 return [class imageRepsWithData:data];
146         }
147    return [class imageRepsWithContentsOfFile:path];
150 +(NSArray *)imageRepsWithContentsOfURL:(NSURL *)url {
151    Class   class=self;
152    NSData *data=[NSData dataWithContentsOfURL:url];
153    
154    if(data==nil)
155     return nil;
157    if(self==[NSImageRep class]){    
158     if((class=[self imageRepClassForData:data])==nil)
159      return nil;
160    }
161    
162    return [class imageRepsWithData:data];
165 +(NSArray *)imageRepsWithPasteboard:(NSPasteboard *)pasteboard {
166    NSArray *imageTypes=[self imagePasteboardTypes];
167    NSArray *pbTypes=[pasteboard types];
168    
169    for(NSString *check in pbTypes){
170     if([imageTypes containsObject:check]){
171      NSData *data=[pasteboard dataForType:check];
172      Class   class;
173      
174      if((class=[self imageRepClassForData:data])!=nil){
175       NSArray *result;
176      
177       if((result=[class imageRepsWithData:data])!=nil)
178        return result;
179      }
180     }
181    }
182    
183    return nil;
186 +imageRepWithContentsOfFile:(NSString *)path {
187    Class   class=self;
188    NSData *data=[NSData dataWithContentsOfFile:path];
189    
190    if(data==nil)
191     return nil;
192     
193    if(self==[NSImageRep class]){
194     NSString *type=[path pathExtension];
196     if((class=[self imageRepClassForFileType:type])==nil)
197      return nil;
198    }
200    return [class imageRepWithData:data];
203 +imageRepWithContentsOfURL:(NSURL *)url {
204    Class   class=self;
205    NSData *data=[NSData dataWithContentsOfURL:url];
206    
207    if(data==nil)
208     return nil;
210    if(self==[NSImageRep class]){    
211     if((class=[self imageRepClassForData:data])==nil)
212      return nil;
213    }
214    
215    return [class imageRepWithData:data];
218 +imageRepWithPasteboard:(NSPasteboard *)pasteboard {
219    NSArray *imageTypes=[self imagePasteboardTypes];
220    NSArray *pbTypes=[pasteboard types];
221    
222    for(NSString *check in pbTypes){
223     if([imageTypes containsObject:check]){
224      NSData *data=[pasteboard dataForType:check];
225      Class   class;
226      
227      if((class=[self imageRepClassForData:data])!=nil){
228       NSArray *result;
229      
230       if((result=[class imageRepWithData:data])!=nil)
231        return result;
232      }
233     }
234    }
235    
236    return nil;
239 -copyWithZone:(NSZone *)zone {
240    NSImageRep *result=NSCopyObject(self,0,zone);
241    result->_colorSpaceName=[_colorSpaceName copy];
242    return result;
245 -(NSSize)size {
246    return _size;
249 -(int)pixelsWide {
250    return _pixelsWide;
253 -(int)pixelsHigh {
254    return _pixelsHigh;
257 -(BOOL)isOpaque {
258    return _isOpaque;
261 -(BOOL)hasAlpha {
262    return _hasAlpha;
265 -(NSString *)colorSpaceName {
266    return _colorSpaceName;
269 -(NSInteger)bitsPerSample {
270    return _bitsPerSample;
273 -(void)setSize:(NSSize)value {
274    _size=value;
277 -(void)setPixelsWide:(int)value {
278    _pixelsWide=value;
281 -(void)setPixelsHigh:(int)value {
282    _pixelsHigh=value;
285 -(void)setOpaque:(BOOL)value {
286    _isOpaque=value;
289 -(void)setAlpha:(BOOL)value {
290    _hasAlpha=value;
293 -(void)setColorSpaceName:(NSString *)value {
294    value=[value copy];
295    [_colorSpaceName release];
296    _colorSpaceName=value;
299 -(void)setBitsPerSample:(int)value {
300    _bitsPerSample=value;
303 -(BOOL)draw {
304 // do nothing
305    return YES;
308 -(BOOL)drawAtPoint:(NSPoint)point {
309    CGContextRef context=NSCurrentGraphicsPort();
310    BOOL         result;
311    
312    CGContextSaveGState(context);
313    CGContextTranslateCTM(context,point.x,point.y);
314    result=[self draw];
315    CGContextRestoreGState(context);
316    
317    return result;
320 -(BOOL)drawInRect:(NSRect)rect {
321    CGContextRef context=NSCurrentGraphicsPort();
322    NSSize       size=[self size];
323    BOOL         result;
324    
325    CGContextSaveGState(context);
326    CGContextTranslateCTM(context,rect.origin.x,rect.origin.y);
327    CGContextScaleCTM(context,rect.size.width/size.width,rect.size.height/size.height);
328    result=[self draw];
329    CGContextRestoreGState(context);
330    
331    return result;
334 -(NSString *)description {
335     return [NSString stringWithFormat:@"<%@[0x%lx] size: { %f, %f } colorSpace: %@ (%dx%d @ %d bps) alpha: %@ opaque: %@>", 
336         [self class], self, _size.width, _size.height, _colorSpaceName, _pixelsWide, _pixelsHigh, _bitsPerSample,
337         _hasAlpha ? @"YES" : @"NO", _isOpaque ? @"YES" : @"NO"];
340 @end