Changeset 2874

Show
Ignore:
Timestamp:
05/19/05 18:42:20 (4 years ago)
Author:
morris
Message:

Add support for JPEG thumbnails, by directly interfacing with libjpeg and extracting a low resolution image from the JPEG data

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • Footagehead/trunk/English.lproj/Credits.rtf

    r2871 r2874  
    2323\f1\b0 \cf0 \ 
    2424Contains software written by the\ 
    25 Independent JPEG Group.
     25Independent JPEG Group
    2626\ 
    2727axel@zankasoftware.com\ 
  • Footagehead/trunk/FHController.h

    r2858 r2874  
    6060        FHHandler                                               *_handler; 
    6161         
    62         NSTimer                                                 *_timer; 
    63         NSConditionLock                                 *_lock; 
     62        NSTimer                                                 *_loadImageTimer; 
     63        NSConditionLock                                 *_loadImageLock; 
     64        NSConditionLock                                 *_loadThumbnailsLock; 
    6465        unsigned int                                    _row; 
    6566         
  • Footagehead/trunk/FHController.m

    r2858 r2874  
    2727 */ 
    2828 
     29#import "NSImage-FHAdditions.h" 
     30 
    2931#import "FHCache.h" 
    3032#import "FHController.h" 
     
    4143 
    4244 
    43 - (FHFile *)                   selectedFile; 
    44 - (FHFile *)                   fileAtIndex:(unsigned int)index; 
    45  
    46 - (void)                               loadURL:(ZAURL *)url withHint:(FHHandlerHint)hint selectRow:(int)row; 
    47 - (void)                               loadFile:(FHFile *)file; 
    48  
    49 - (void)                               addMenuItemWithPath:(NSString *)path keyEquivalent:(NSString *)keyEquivalent; 
    50 - (void)                               reloadVolumesMenu; 
    51 - (void)                               reloadPathMenu; 
    52  
    53 - (void)                               startSpinning; 
    54 - (void)                               stopSpinning; 
    55 - (void)                               updateImage; 
    56 - (void)                               updateButtons; 
    57 - (void)                               updateStatus; 
    58 - (void)                               updateLeftStatus; 
    59 - (void)                               updateRightStatus; 
    60 - (void)                               updateFullscreenStatus; 
    61 - (void)                               updateTableView; 
     45- (FHFile *)selectedFile; 
     46- (FHFile *)fileAtIndex:(unsigned int)index; 
     47 
     48- (void)loadURL:(ZAURL *)url withHint:(FHHandlerHint)hint selectRow:(int)row; 
     49- (void)loadFile:(FHFile *)file; 
     50 
     51- (void)addMenuItemWithPath:(NSString *)path keyEquivalent:(NSString *)keyEquivalent; 
     52- (void)reloadVolumesMenu; 
     53- (void)reloadPathMenu; 
     54 
     55- (void)startSpinning; 
     56- (void)stopSpinning; 
     57- (void)updateImage; 
     58- (void)updateButtons; 
     59- (void)updateStatus; 
     60- (void)updateLeftStatus; 
     61- (void)updateRightStatus; 
     62- (void)updateFullscreenStatus; 
     63- (void)updateTableView; 
    6264 
    6365@end 
     
    120122        [_screenAutoSwitchTextField setIntValue:[FHSettings intForKey:FHAutoSwitchTime]]; 
    121123 
    122         // --- create lock 
    123         _lock = [[NSConditionLock alloc] initWithCondition:0]; 
     124        // --- create locks 
     125        _loadImageLock          = [[NSConditionLock alloc] initWithCondition:0]; 
     126        _loadThumbnailsLock     = [[NSConditionLock alloc] initWithCondition:0]; 
    124127         
    125128        // --- open last directory by default (unset if started by opening a file) 
     
    158161         
    159162        // --- detach loader thread 
    160         [NSThread detachNewThreadSelector:@selector(loadFileThread:) toTarget:self withObject:[_handler files]]; 
     163        [NSThread detachNewThreadSelector:@selector(loadImageThread:) toTarget:self withObject:NULL]; 
     164        [NSThread detachNewThreadSelector:@selector(loadThumbnailsThread:) toTarget:self withObject:NULL]; 
    161165} 
    162166 
     
    241245- (void)windowWillClose:(NSNotification *)notification { 
    242246        if([notification object] == _fullscreenWindow) { 
    243                 [_timer invalidate]; 
    244                 [_timer release]; 
    245                 _timer = NULL; 
     247                [_loadImageTimer invalidate]; 
     248                [_loadImageTimer release]; 
     249                _loadImageTimer = NULL; 
    246250 
    247251                [self showWindow:self]; 
     
    394398 
    395399                if([FHSettings boolForKey:FHAutoSwitch]) { 
    396                         _timer = [[NSTimer scheduledTimerWithTimeInterval:[FHSettings intForKey:FHAutoSwitchTime] 
    397                                                                                                            target:self 
    398                                                                                                         selector:@selector(loadFileTimer:) 
    399                                                                                                         userInfo:NULL 
    400                                                                                                           repeats:YES] retain]; 
     400                        _loadImageTimer = [[NSTimer scheduledTimerWithTimeInterval:[FHSettings intForKey:FHAutoSwitchTime] 
     401                                                                                                                               target:self 
     402                                                                                                                        selector:@selector(loadFileTimer:) 
     403                                                                                                                        userInfo:NULL 
     404                                                                                                                          repeats:YES] retain]; 
    401405                } 
    402406        } 
     
    508512                } 
    509513                 
    510                 [_timer setFireDate:[NSDate distantFuture]]; 
     514                [_loadImageTimer setFireDate:[NSDate distantFuture]]; 
    511515                [_tableView selectRow:i byExtendingSelection:NO]; 
    512516                [_tableView scrollRowToVisible:i]; 
     
    540544                        i = 0; 
    541545                 
    542                 [_timer setFireDate:[NSDate distantFuture]]; 
     546                [_loadImageTimer setFireDate:[NSDate distantFuture]]; 
    543547                [_tableView selectRow:i byExtendingSelection:NO]; 
    544548                [_tableView scrollRowToVisible:i]; 
     
    562566                } 
    563567                 
    564                 [_timer setFireDate:[NSDate distantFuture]]; 
     568                [_loadImageTimer setFireDate:[NSDate distantFuture]]; 
    565569                [_tableView selectRow:i byExtendingSelection:NO]; 
    566570                [_tableView scrollRowToVisible:i]; 
     
    594598                        i = count - 1; 
    595599                 
    596                 [_timer setFireDate:[NSDate distantFuture]]; 
     600                [_loadImageTimer setFireDate:[NSDate distantFuture]]; 
    597601                [_tableView selectRow:i byExtendingSelection:NO]; 
    598602                [_tableView scrollRowToVisible:i]; 
     
    688692                [_tableView selectRow:row byExtendingSelection:NO]; 
    689693        } else { 
    690                 [_lock lock]; 
     694                [_loadImageLock lock]; 
    691695                _row = row; 
    692                 [_lock unlockWithCondition:1]; 
    693         } 
    694          
     696                [_loadImageLock unlockWithCondition:1]; 
     697        } 
     698 
    695699        [_tableView scrollRowToVisible:row]; 
     700 
     701        if([_handler isLocal]) { 
     702                [_loadThumbnailsLock lock]; 
     703                [_loadThumbnailsLock unlockWithCondition:1]; 
     704        } 
    696705 
    697706        [self stopSpinning]; 
     
    711720 
    712721 
    713 - (void)loadFileThread:(id)arg { 
     722- (void)loadFileTimer:(NSTimer *)timer { 
     723        NSArray         *files; 
     724        int                     i, count; 
     725        BOOL            next = NO; 
     726 
     727        [self nextImage:self]; 
     728         
     729        i = [_tableView selectedRow]; 
     730        files = [_handler files]; 
     731        count = [files count]; 
     732         
     733        while(i < count - 1) { 
     734                if(![[files objectAtIndex:i] isDirectory]) { 
     735                        next = YES; 
     736                         
     737                        break; 
     738                } 
     739        } 
     740         
     741        if(!next) 
     742                [timer invalidate]; 
     743
     744 
     745 
     746 
     747- (void)loadImageThread:(id)arg { 
    714748        NSAutoreleasePool   *pool; 
    715749        NSArray                         *files; 
    716750        NSImage                         *image; 
    717751        FHFile                          *file; 
    718         int                                     i, row, images, count, lastRow = 0; 
     752        unsigned int            i, count, images, row, lastRow; 
     753         
     754        lastRow = 0; 
    719755         
    720756        while(YES) { 
    721757                pool = [[NSAutoreleasePool alloc] init]; 
    722758 
    723                 // --- wait for row switch 
    724                 [_lock lockWhenCondition:1]; 
     759                [_loadImageLock lockWhenCondition:1]; 
    725760                row = _row; 
    726761                files = [[_handler files] retain]; 
    727                 [_lock unlockWithCondition:0]; 
     762                [_loadImageLock unlockWithCondition:0]; 
    728763                 
    729764                if(row >= 0 && (row == 0 || row >= lastRow + 5 || row < lastRow)) { 
     
    731766                         
    732767                        // --- purge all but the last 5 images 
    733                         for(i = 0; i < row - 5; i++) { 
     768                        for(i = 0; i < count && i < row - 5; i++) { 
    734769                                file = [files objectAtIndex:i]; 
    735770                                 
     
    760795                                [image release]; 
    761796 
    762                                 [self performSelectorOnMainThread:@selector(fileDidLoadImage:) withObject:file]; 
     797                                [self performSelectorOnMainThread:@selector(fileDidLoadImage:) withObject:file waitUntilDone:YES]; 
    763798                        } 
    764799                         
     
    773808 
    774809 
    775 - (void)loadFileTimer:(NSTimer *)timer { 
    776         NSArray         *files; 
    777         int                     i, count; 
    778         BOOL            next = NO; 
    779  
    780         [self nextImage:self]; 
    781          
    782         i = [_tableView selectedRow]; 
    783         files = [_handler files]; 
    784         count = [files count]; 
    785          
    786         while(i < count - 1) { 
    787                 if(![[files objectAtIndex:i] isDirectory]) { 
    788                         next = YES; 
    789                          
    790                         break; 
    791                 } 
    792         } 
    793          
    794         if(!next) 
    795                 [timer invalidate]; 
     810- (void)loadThumbnailsThread:(id)arg { 
     811        NSAutoreleasePool   *pool; 
     812        NSArray                         *files; 
     813        NSImage                         *image; 
     814        FHFile                          *file; 
     815        unsigned int            i, count; 
     816         
     817        while(YES) { 
     818                pool = [[NSAutoreleasePool alloc] init]; 
     819 
     820                [_loadThumbnailsLock lockWhenCondition:1]; 
     821                files = [[_handler files] retain]; 
     822                [_loadThumbnailsLock unlockWithCondition:0]; 
     823                 
     824                count = [files count]; 
     825 
     826                for(i = 0; i < count; i++) { 
     827                        file = [files objectAtIndex:i]; 
     828                         
     829                        if([file isDirectory]) 
     830                                continue; 
     831                         
     832                        if([file hasThumbnail]) 
     833                                continue; 
     834 
     835                        image = [[NSImage alloc] initWithJPEGFile:[file path] preferredSize:NSMakeSize(128.0, 128.0)]; 
     836                         
     837                        if(image) { 
     838                                [file setThumbnail:image]; 
     839                                [image release]; 
     840                         
     841                                [self performSelectorOnMainThread:@selector(fileDidLoadThumbnail:) withObject:file waitUntilDone:YES]; 
     842                        } 
     843                } 
     844 
     845                [files release]; 
     846                [pool release]; 
     847        } 
    796848} 
    797849 
     
    824876                                [_fullscreenImageView setImage:image]; 
    825877                                [self updateFullscreenStatus]; 
    826                                 [_timer setFireDate:[NSDate dateWithTimeIntervalSinceNow: 
     878                                [_loadImageTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow: 
    827879                                        [FHSettings intForKey:FHAutoSwitchTime]]]; 
    828880                        } else { 
     
    833885                } 
    834886        } 
     887} 
     888 
     889 
     890 
     891- (void)fileDidLoadThumbnail:(FHFile *)file { 
     892        [_tableView reloadData]; 
    835893} 
    836894 
     
    11041162         
    11051163        file = [self fileAtIndex:row]; 
    1106         icon = [file icon]; 
    1107         [icon setSize:NSMakeSize(128.0, 128.0)]; 
     1164        icon = [file thumbnail]; 
     1165         
     1166        if(![file hasThumbnail]) 
     1167                [icon setSize:NSMakeSize(128.0, 128.0)]; 
    11081168         
    11091169        return [NSDictionary dictionaryWithObjectsAndKeys: 
     
    11241184        [self updateImage]; 
    11251185         
    1126         [_lock lock]; 
     1186        [_loadImageLock lock]; 
    11271187        _row = [_tableView selectedRow]; 
    1128         [_lock unlockWithCondition:1]; 
     1188        [_loadImageLock unlockWithCondition:1]; 
    11291189} 
    11301190 
  • Footagehead/trunk/FHFile.h

    r920 r2874  
    1 /* $Id: FHFile.h,v 1.7 2005/01/08 22:55:46 morris Exp $ */ 
     1/* $Id$ */ 
    22 
    33/* 
     
    2929#import "FHHandler.h" 
    3030 
    31 @interface FHFile : ZAObject <NSCoding>
     31@interface FHFile : ZAObject
    3232        NSString                                *_name; 
    3333        ZAURL                                   *_url; 
     
    3636        NSImage                                 *_image; 
    3737        NSImage                                 *_icon; 
    38         BOOL                                   _loading
     38        NSImage                                        *_thumbnail
    3939        BOOL                                    _directory; 
    4040        int                                             _index; 
     
    4343 
    4444 
    45 - (id)                                         initWithURL:(ZAURL *)url isDirectory:(BOOL)isDirectory index:(int)index; 
    46 - (id)                                         initWithURL:(ZAURL *)url isDirectory:(BOOL)isDirectory index:(int)index hint:(FHHandlerHint)hint; 
     45- (id)initWithURL:(ZAURL *)url isDirectory:(BOOL)isDirectory index:(int)index; 
     46- (id)initWithURL:(ZAURL *)url isDirectory:(BOOL)isDirectory index:(int)index hint:(FHHandlerHint)hint; 
    4747 
    48 - (void)                                        setImage:(NSImage *)image; 
    49 - (NSImage *)                           image; 
     48- (void)setImage:(NSImage *)image; 
     49- (NSImage *)image; 
     50- (void)setThumbnail:(NSImage *)thumbnaill; 
     51- (NSImage *)thumbnail; 
     52- (BOOL)hasThumbnail; 
    5053 
    51 - (void)                                        setLoading:(BOOL)value; 
    52 - (BOOL)                                        isLoading; 
    53  
    54 - (NSString *)                          name; 
    55 - (ZAURL *)                                     URL; 
    56 - (NSString *)                          path; 
    57 - (NSString *)                          extension; 
    58 - (NSImage *)                           icon; 
    59 - (BOOL)                                        isDirectory; 
    60 - (int)                                         index; 
    61 - (FHHandlerHint)                       hint; 
     54- (NSString *)name; 
     55- (ZAURL *)URL; 
     56- (NSString *)path; 
     57- (NSString *)extension; 
     58- (BOOL)isDirectory; 
     59- (int)index; 
     60- (FHHandlerHint)hint; 
    6261 
    6362@end 
  • Footagehead/trunk/FHFile.m

    r2857 r2874  
    9696#pragma mark - 
    9797 
    98 - (id)initWithCoder:(NSCoder *)coder { 
    99         self = [super init]; 
    100          
    101         ZADecode(coder, _url); 
    102         ZADecode(coder, _path); 
    103         ZADecode(coder, _extension); 
    104         ZADecode(coder, _name); 
    105         ZADecode(coder, _image); 
    106         ZADecode(coder, _icon); 
    107         ZADecode(coder, _loading); 
    108         ZADecode(coder, _directory); 
    109         ZADecode(coder, _hint); 
    110          
    111         return self; 
    112 } 
    113  
    114  
    115  
    116 - (void)encodeWithCoder:(NSCoder *)coder { 
    117         ZAEncode(coder, _url); 
    118         ZAEncode(coder, _path); 
    119         ZAEncode(coder, _extension); 
    120         ZAEncode(coder, _name); 
    121         ZAEncode(coder, _icon); 
    122         ZAEncode(coder, _image); 
    123         ZAEncode(coder, _loading); 
    124         ZAEncode(coder, _directory); 
    125         ZAEncode(coder, _hint); 
    126 } 
    127  
    128  
    129  
    130 #pragma mark - 
    131  
    13298- (void)setImage:(NSImage *)image { 
    13399        [image retain]; 
     
    145111 
    146112 
    147  
    148 - (void)setLoading:(BOOL)value { 
    149         _loading = value; 
     113- (void)setThumbnail:(NSImage *)thumbnail { 
     114        [thumbnail retain]; 
     115        [_thumbnail release]; 
     116         
     117        _thumbnail = thumbnail; 
    150118} 
    151119 
    152120 
    153121 
    154 - (BOOL)isLoading { 
    155         return _loading; 
     122- (NSImage *)thumbnail { 
     123        if(_thumbnail) 
     124                return _thumbnail; 
     125         
     126        return _icon; 
     127
     128 
     129 
     130 
     131- (BOOL)hasThumbnail { 
     132        return (_thumbnail != NULL); 
    156133} 
    157134 
     
    184161 
    185162 
    186 - (NSImage *)icon { 
    187         return _icon; 
    188 } 
    189  
    190  
    191  
    192163- (BOOL)isDirectory { 
    193164        return _directory; 
  • Footagehead/trunk/FHFileCell.m

    r920 r2874  
    1 /* $Id: FHFileCell.m,v 1.3 2005/01/08 22:55:46 morris Exp $ */ 
     1/* $Id$ */ 
    22 
    33/* 
  • Footagehead/trunk/FHImageView.m

    r2855 r2874  
    8282        float           dx, dy, d; 
    8383         
     84        [[NSColor lightGrayColor] set]; 
     85        NSFrameRect(frame); 
     86        frame = NSInsetRect(frame, 2.0, 2.0); 
     87 
    8488        [_backgroundColor set]; 
    8589        NSRectFill(frame); 
     
    113117                } 
    114118 
    115                 point.x = (frame.size.width  - size.width)  / 2.0; 
    116                 point.y = (frame.size.height - size.height) / 2.0; 
     119                point.x = ((frame.size.width  - size.width)  / 2.0) + 1.0; 
     120                point.y = ((frame.size.height - size.height) / 2.0) + 1.0; 
    117121 
    118122                [image compositeToPoint:point operation:NSCompositeSourceOver]; 
  • Footagehead/trunk/Footagehead.xcode/project.pbxproj

    r2872 r2874  
    2222                        ); 
    2323                        isa = PBXGroup; 
    24                         name = "Footagehead Interface"
     24                        name = Interface
    2525                        refType = 4; 
    2626                        sourceTree = "<group>"; 
     
    167167                        ); 
    168168                        isa = PBXGroup; 
    169                         name = "Footagehead Sources"; 
     169                        name = "Other Sources"; 
    170170                        path = ""; 
    171171                        refType = 4; 
     
    310310                        target = 77CDC142083BA689003BE654; 
    311311                        targetProxy = 770EB7A8083BA9880094BD6C; 
     312                }; 
     313                770EBFC2083C94CE0094BD6C = { 
     314                        fileEncoding = 4; 
     315                        isa = PBXFileReference; 
     316                        lastKnownFileType = sourcecode.c.h; 
     317                        path = "NSBitmapImageRep-FHAdditions.h"; 
     318                        refType = 4; 
     319                        sourceTree = "<group>"; 
     320                }; 
     321                770EBFC3083C94CE0094BD6C = { 
     322                        fileEncoding = 4; 
     323                        isa = PBXFileReference; 
     324                        lastKnownFileType = sourcecode.c.objc; 
     325                        path = "NSBitmapImageRep-FHAdditions.m"; 
     326                        refType = 4; 
     327                        sourceTree = "<group>"; 
     328                }; 
     329                770EBFC4083C94CE0094BD6C = { 
     330                        fileRef = 770EBFC2083C94CE0094BD6C; 
     331                        isa = PBXBuildFile; 
     332                        settings = { 
     333                        }; 
     334                }; 
     335                770EBFC5083C94CE0094BD6C = { 
     336                        fileRef = 770EBFC3083C94CE0094BD6C; 
     337                        isa = PBXBuildFile; 
     338                        settings = { 
     339                        }; 
    312340                }; 
    313341                775BA322075F59E000F0941E = { 
     
    15121540                                77BD99520760B7380007D034, 
    15131541                                77CDB023083B6B85003BE654, 
     1542                                770EBFC5083C94CE0094BD6C, 
    15141543                        ); 
    15151544                        isa = PBXSourcesBuildPhase; 
     
    18361865                        files = ( 
    18371866                                A54D42DD07663AA300227EBE, 
     1867                                770EBFC4083C94CE0094BD6C, 
    18381868                        ); 
    18391869                        isa = PBXCopyFilesBuildPhase; 
     
    18781908                        ); 
    18791909                        isa = PBXGroup; 
    1880                         name = "Footagehead Handlers"
     1910                        name = Handlers
    18811911                        refType = 4; 
    18821912                        sourceTree = "<group>"; 
     
    19361966                        ); 
    19371967                        isa = PBXGroup; 
    1938                         name = "Footagehead Data"
     1968                        name = Data
    19391969                        refType = 4; 
    19401970                        sourceTree = "<group>"; 
     
    21632193                A5EE94DA055AA5EE00CC2AD8 = { 
    21642194                        children = ( 
     2195                                770EBFC3083C94CE0094BD6C, 
     2196                                770EBFC2083C94CE0094BD6C, 
    21652197                                775BA4F0075F70ED00F0941E, 
    21662198                                775BA4EF075F70ED00F0941E, 
    21672199                        ); 
    21682200                        isa = PBXGroup; 
    2169                         name = "Footagehead Additions"
     2201                        name = Additions
    21702202                        refType = 4; 
    21712203                        sourceTree = "<group>"; 
  • Footagehead/trunk/NSImage-FHAdditions.h

    r920 r2874  
    1 /* $Id: NSImage-FHAdditions.h,v 1.2 2005/01/08 22:55:46 morris Exp $ */ 
     1/* $Id$ */ 
    22 
    33/* 
     
    2929@interface NSImage(FHAdditions) 
    3030 
    31 + (NSArray *)                           FHImageFileTypes; 
     31+ (NSArray *)FHImageFileTypes; 
     32 
     33+ (id)imageWithJPEGFile:(NSString *)path preferredSize:(NSSize)size; 
     34- (id)initWithJPEGFile:(NSString *)path preferredSize:(NSSize)size; 
    3235 
    3336@end 
  • Footagehead/trunk/NSImage-FHAdditions.m

    r920 r2874  
    1 /* $Id: NSImage-FHAdditions.m,v 1.2 2005/01/08 22:55:46 morris Exp $ */ 
     1/* $Id$ */ 
    22 
    33/* 
     
    2727 */ 
    2828 
     29#import "NSBitmapImageRep-FHAdditions.h" 
    2930#import "NSImage-FHAdditions.h" 
    3031 
     
    4546} 
    4647 
     48 
     49 
     50#pragma mark - 
     51 
     52+ (id)imageWithJPEGFile:(NSString *)path preferredSize:(NSSize)size { 
     53        return [[[self alloc] initWithJPEGFile:path preferredSize:size] autorelease]; 
     54} 
     55 
     56 
     57 
     58- (id)initWithJPEGFile:(NSString *)path preferredSize:(NSSize)size { 
     59        NSBitmapImageRep                *imageRep; 
     60         
     61        imageRep = [[NSBitmapImageRep alloc] initWithJPEGFile:path preferredSize:size]; 
     62         
     63        if(!imageRep) { 
     64                [self release]; 
     65                 
     66                return NULL; 
     67        } 
     68         
     69        self = [self initWithSize:NSMakeSize([imageRep pixelsWide], [imageRep pixelsHigh])]; 
     70        [self addRepresentation:imageRep]; 
     71         
     72        return self; 
     73} 
     74 
    4775@end