News Software Download Buy Now About Us Developers Contact
software TOC | PREV | NEXT
/* GimmeGIF.h created by andrew on Tue 14-Apr-1998 */

#import <AppKit/AppKit.h>

@interface GimmeGIF : NSObject
{
}
// just use this one:
+ sharedInstance;

// If conversion and write to disk succeed, this returns YES:
- (BOOL)convertImageFile:(NSString *)tiffFile toGIFFile:(NSString *)gifFile;

@end

//
// GimmeGIF.m (c) 1998 Andrew C Stone
// andrew@stone.com (505) 345-4800 http://www.stone.com - Create(TM)
//
// How to get a GIF out of an NSImage
// Permission is granted to use this code, but please retain credit
// And as always, CAVEAT EMPTOR!
//

#import "GimmeGIF.h"

@implementation GimmeGIF

+ sharedInstance
{
    static id gimme = nil;
    if (!gimme) gimme = [[self alloc]init];
    return gimme;
}

//
// We must "deepen" the cache to 24 bits for GIF's to be
// created correctly in RDR...
// NOTE: MACH OPENSTEP, -DOS_API, knows not of this functionality
//

- (void)prepareCache:aCache
{
    NSRect r = { { 0.,0.} ,{ 1.,1.}}; // just one pixel is all it takes!
    [aCache lockFocus];
    [[NSColor colorWithDeviceCyan:.32 magenta:.76 yellow:.29 black:.04 alpha:.05] set];
    NSRectFill(r);
    [aCache unlockFocus];
}

- (NSBitmapImageRep *)getBitmap:(NSImage *)image
{
    NSRect r = { {0.,0.}, {[image size].width, [image size].height}};
    NSBitmapImageRep *bm = nil;
    NSImage *tiffCache = [[[NSImage allocWithZone:[self zone]] initWithSize:r.size]autorelease];
    NSCachedImageRep *rep = [[[NSCachedImageRep alloc] initWithSize:r.size depth:520 separate:YES alpha:YES]autorelease];

    [tiffCache addRepresentation:rep];
    [self prepareCache:tiffCache];    

    // if something should happen, NS_DURING/NS_HANDLER protects us!
    //
NS_DURING
    [tiffCache lockFocusOnRepresentation:rep];
    [image compositeToPoint:NSZeroPoint operation:NSCompositeSourceOver];

// OK, now let's create an NSBitmapImageRep form the data..
    bm = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:r] autorelease];
    if (bm == nil)
        bm = [NSBitmapImageRep imageRepWithData: [tiffCache TIFFRepresentation]];


    [tiffCache unlockFocus];
NS_HANDLER

NS_ENDHANDLER

    if (bm == nil)
        NSLog(@"in getBitMap : no NSBitmapImageRep of the right depth found");


return bm;
}

//
// NOTE: Black & White images fail miserably
// So we must get their data and blast that into a deeper cache
// Yucky, so we wrap this all up inside this object...
//

- (NSBitmapImageRep *)bitmapRep:(NSImage *)image
{
    NSArray *reps = [image representations];
    int i = [reps count];
    while (i--) {
        NSBitmapImageRep *rep = (NSBitmapImageRep *)[reps objectAtIndex:i];
        if ([rep isKindOfClass:[NSBitmapImageRep class]] &&
            ([rep bitsPerPixel] > 2))
        return rep;
    }
    return [self getBitmap:image];
}


- (BOOL)convertImageFile:(NSString *)tiffFile toGIFFile:(NSString *)gifFile
{
    // YellowBox only, my friends
#if !defined(OS_API)
    NSImage *image = [[[NSImage alloc]initWithContentsOfFile:tiffFile]autorelease];
    NSBitmapImageRep *bm = [self bitmapRep:image];
    NSDictionary *properties =
        [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES],
        NSImageDitherTransparency, NULL];
    NSSize size;

    if (!bm) return NO;

    size = [image size];

    if (size.width > 0 && size.height > 0) {
        NSData *data;

NS_DURING
        data = [bm representationUsingType:NSGIFFileType
            properties:properties];
NS_HANDLER
        data = nil;    // must have failed
NS_ENDHANDLER

    if (data != nil) {
        return [data writeToFile:gifFile atomically:NO];
    }
}
#endif
return NO;
}

@end
TOC | PREV | NEXT
Created by Stone Design's Create on 4/30/1998
©2000 Stone Design top