├── .gitignore ├── ANGif ├── .DS_Store ├── ColorTable │ ├── ANAvgColorTable.h │ ├── Cut │ │ ├── ANCutColorTable.h │ │ ├── ANMutableColorArray.h │ │ ├── ANCutColorTable.m │ │ └── ANMutableColorArray.m │ ├── ANAvgColorTable.m │ ├── ANColorTable.h │ └── ANColorTable.m ├── App Extensions │ ├── ANGifNetscapeAppExtension.h │ ├── ANGifAppExtension.h │ ├── ANGifNetscapeAppExtension.m │ └── ANGifAppExtension.m ├── ImageFrame │ ├── ANGifImageFramePixelSource.h │ ├── ANGifDataSubblock.h │ ├── ANGifImageDescriptor.h │ ├── ANGifImageDescriptor.m │ ├── ANGifDataSubblock.m │ ├── ANGifImageFrame.m │ └── ANGifImageFrame.h ├── ANGifLogicalScreenDesc.h ├── ANGifGraphicControlExt.h ├── LZW │ ├── LZWSpoof.h │ └── LZWSpoof.m ├── ANGifLogicalScreenDesc.m ├── ANGifGraphicControlExt.m ├── ANGifEncoder.h └── ANGifEncoder.m ├── ANImageBitmapRep ├── .DS_Store ├── CoreGraphics │ ├── CGContextCreator.h │ ├── CGImageContainer.m │ ├── CGImageContainer.h │ └── CGContextCreator.m ├── Compatibility │ ├── OSCommonImage.h │ ├── UIImage+ANImageBitmapRep.h │ ├── NSImage+ANImageBitmapRep.h │ ├── OSCommonImage.m │ ├── UIImage+ANImageBitmapRep.m │ └── NSImage+ANImageBitmapRep.m ├── Manipulators │ ├── BitmapContextManipulator.m │ ├── BitmapContextManipulator.h │ ├── BitmapRotationManipulator.h │ ├── BitmapScaleManipulator.h │ ├── BitmapCropManipulator.h │ ├── BitmapScaleManipulator.m │ ├── BitmapCropManipulator.m │ └── BitmapRotationManipulator.m ├── ANImageBitmapRep.h ├── BitmapContextRep.m ├── BitmapContextRep.h └── ANImageBitmapRep.m ├── Giraffe_Prefix.pch ├── Classes ├── NSMutableArray+Move.h ├── PhotoEntry.h ├── UIImagePixelSource.h ├── GiraffeAppDelegate.h ├── ExportViewController.h ├── NSMutableArray+Move.m ├── GiraffeViewController.h ├── PhotoEntry.m ├── UIImagePixelSource.m ├── GiraffeAppDelegate.m ├── ExportViewController.m └── GiraffeViewController.m ├── main.m ├── Giraffe-Info.plist ├── README.md ├── Giraffe.xcodeproj ├── alex.pbxuser └── project.pbxproj ├── MainWindow.xib └── GiraffeViewController.xib /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcdebugger 3 | xcuserdata 4 | UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ANGif/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/Giraffe/HEAD/ANGif/.DS_Store -------------------------------------------------------------------------------- /ANImageBitmapRep/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/Giraffe/HEAD/ANImageBitmapRep/.DS_Store -------------------------------------------------------------------------------- /Giraffe_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Giraffe' target in the 'Giraffe' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /ANGif/ColorTable/ANAvgColorTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifBasicColorTable.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANColorTable.h" 10 | 11 | @interface ANAvgColorTable : ANColorTable { 12 | 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/NSMutableArray+Move.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+Move.h 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableArray (Move) 12 | 13 | - (void)swapValueAtIndex:(NSInteger)source withValueAtIndex:(NSInteger)destination; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 1/20/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /ANGif/App Extensions/ANGifNetscapeAppExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifNetscapeAppExtension.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANGifAppExtension.h" 10 | 11 | @interface ANGifNetscapeAppExtension : ANGifAppExtension { 12 | UInt16 numberOfRepeats; 13 | } 14 | 15 | @property (readonly) UInt16 numberOfRepeats; 16 | 17 | - (id)initWithRepeatCount:(UInt16)repeats; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifImageFramePixelSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // PixelSource.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol ANGifImageFramePixelSource 12 | 13 | - (NSUInteger)pixelsWide; 14 | - (NSUInteger)pixelsHigh; 15 | - (void)getPixel:(NSUInteger *)pixel atX:(NSInteger)x y:(NSInteger)y; 16 | - (BOOL)hasTransparency; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /ANGif/ColorTable/Cut/ANCutColorTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANCutColorTable.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANColorTable.h" 10 | #import "ANGifImageFramePixelSource.h" 11 | #import "ANMutableColorArray.h" 12 | 13 | @interface ANCutColorTable : ANColorTable { 14 | BOOL finishedInit; 15 | } 16 | 17 | - (id)initWithTransparentFirst:(BOOL)hasAlpha pixelSource:(id)pixelSource; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/PhotoEntry.h: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoEntry.h 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BitmapScaleManipulator.h" 11 | 12 | @interface PhotoEntry : NSObject { 13 | NSString * imageName; 14 | UIImage * image; 15 | } 16 | 17 | @property (readonly) UIImage * image; 18 | @property (readonly) NSString * imageName; 19 | 20 | - (id)initWithName:(NSString *)name image:(UIImage *)anImage; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifDataSubblock.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifDataSubblock.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ANGifDataSubblock : NSObject { 12 | NSData * subblockData; 13 | } 14 | 15 | + (NSArray *)dataSubblocksForData:(NSData *)largeData; 16 | 17 | - (id)initWithBlockData:(NSData *)theData; 18 | - (NSData *)encodeBlock; 19 | - (void)writeToFileHandle:(NSFileHandle *)fileHandle; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Classes/UIImagePixelSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImagePixelSource.h 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANGifImageFramePixelSource.h" 11 | #import "ANImageBitmapRep.h" 12 | 13 | @interface UIImagePixelSource : NSObject { 14 | ANImageBitmapRep * imageRep; 15 | } 16 | 17 | - (id)initWithImage:(UIImage *)anImage; 18 | + (UIImagePixelSource *)pixelSourceWithImage:(UIImage *)anImage; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Classes/GiraffeAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // GiraffeAppDelegate.h 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 1/20/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class GiraffeViewController; 12 | 13 | @interface GiraffeAppDelegate : NSObject { 14 | UIWindow *window; 15 | GiraffeViewController *viewController; 16 | } 17 | 18 | @property (nonatomic, retain) IBOutlet UIWindow *window; 19 | @property (nonatomic, retain) IBOutlet GiraffeViewController *viewController; 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifImageDescriptor.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifImageDescriptor.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANGifImageFrame.h" 11 | 12 | #define kImageSeparator 0x2C 13 | 14 | @interface ANGifImageDescriptor : NSObject { 15 | #if __has_feature(objc_arc) 16 | __weak ANGifImageFrame * imageFrame; 17 | #else 18 | ANGifImageFrame * imageFrame; 19 | #endif 20 | } 21 | 22 | - (id)initWithImageFrame:(ANGifImageFrame *)anImage; 23 | - (NSData *)encodeBlock; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /ANGif/App Extensions/ANGifAppExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifAppExtension.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ANGifAppExtension : NSObject { 12 | NSData * applicationIdentifier; 13 | NSData * applicationAuthCode; 14 | NSData * applicationData; 15 | } 16 | 17 | @property (nonatomic, retain) NSData * applicationIdentifier; 18 | @property (nonatomic, retain) NSData * applicationAuthCode; 19 | @property (nonatomic, retain) NSData * applicationData; 20 | 21 | - (NSData *)encodeBlock; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /ANImageBitmapRep/CoreGraphics/CGContextCreator.h: -------------------------------------------------------------------------------- 1 | // 2 | // CGContextCreator.h 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 7/4/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * This class has several static methods for creating bitmap contexts. 13 | * These methods are pretty much only called when creating a new 14 | * ANImageBitmapRep. 15 | */ 16 | @interface CGContextCreator : NSObject { 17 | 18 | } 19 | 20 | + (CGContextRef)newARGBBitmapContextWithSize:(CGSize)size; 21 | + (CGContextRef)newARGBBitmapContextWithImage:(CGImageRef)image; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Compatibility/OSCommonImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSCommonImage.h 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 10/23/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #ifndef ImageBitmapRep_OSCommonImage_h 10 | #define ImageBitmapRep_OSCommonImage_h 11 | 12 | #import "CGImageContainer.h" 13 | 14 | #if TARGET_OS_IPHONE 15 | #import 16 | typedef UIImage ANImageObj; 17 | #elif TARGET_OS_MAC 18 | #import 19 | typedef NSImage ANImageObj; 20 | #endif 21 | 22 | CGImageRef CGImageFromANImage (ANImageObj * anImageObj); 23 | ANImageObj * ANImageFromCGImage (CGImageRef imageRef); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /ANGif/ANGifLogicalScreenDesc.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifLogicalScreenDescriptor.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ANGifLogicalScreenDesc : NSObject { 12 | UInt16 screenWidth; 13 | UInt16 screenHeight; 14 | BOOL globalColorTable; 15 | UInt8 gtcSize; 16 | UInt8 backgroundColor; 17 | } 18 | 19 | @property (readwrite) UInt16 screenWidth; 20 | @property (readwrite) UInt16 screenHeight; 21 | @property (readwrite) BOOL globalColorTable; 22 | @property (readwrite) UInt8 gctSize; 23 | @property (readwrite) UInt8 backgroundColor; 24 | 25 | - (NSData *)encodeBlock; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /ANGif/ANGifGraphicControlExt.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifGraphicControlExtension.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define kGraphicControlLabel 0xF9 12 | 13 | @interface ANGifGraphicControlExt : NSObject { 14 | BOOL userInputFlag; 15 | BOOL transparentColorFlag; 16 | UInt8 transparentColorIndex; 17 | NSTimeInterval delayTime; 18 | } 19 | 20 | @property (readwrite) BOOL userInputFlag; 21 | @property (readwrite) BOOL transparentColorFlag; 22 | @property (readwrite) UInt8 transparentColorIndex; 23 | @property (readwrite) NSTimeInterval delayTime; 24 | 25 | - (NSData *)encodeBlock; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /ANGif/ColorTable/Cut/ANMutableColorArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANMutableColorArray.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANColorTable.h" 11 | 12 | @interface ANMutableColorArray : NSObject { 13 | ANGifColor * _colors; 14 | NSUInteger _entryCount; 15 | NSUInteger _totalAlloced; 16 | } 17 | 18 | - (NSUInteger)count; 19 | - (void)addColor:(ANGifColor)color; 20 | - (void)removeAtIndex:(NSUInteger)index; 21 | - (ANGifColor)colorAtIndex:(NSUInteger)index; 22 | 23 | - (void)sortByBrightness; 24 | - (ANMutableColorArray *)colorArrayByAveragingSplit:(NSUInteger)numColors; 25 | - (void)removeDuplicates; 26 | - (ANGifColor)averagePopFirst; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/ExportViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExportViewController.h 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PhotoEntry.h" 11 | 12 | #import "ANGifEncoder.h" 13 | #import "ANCutColorTable.h" 14 | #import "ANGifNetscapeAppExtension.h" 15 | #import "ANImageBitmapRep.h" 16 | #import "UIImagePixelSource.h" 17 | 18 | @interface ExportViewController : UIViewController { 19 | NSArray * images; 20 | UILabel * progressStatus; 21 | UIProgressView * progressView; 22 | void (^doneCallback)(NSString * file); 23 | } 24 | 25 | - (id)initWithImages:(NSArray *)imageArray; 26 | - (void)encodeToFile:(NSString *)fileName callback:(void (^)(NSString * file))callback; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapContextManipulator.m: -------------------------------------------------------------------------------- 1 | // 2 | // BitmapContextManip.m 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 10/14/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "BitmapContextManipulator.h" 10 | 11 | @implementation BitmapContextManipulator 12 | 13 | @synthesize bitmapContext; 14 | 15 | - (id)initWithContext:(BitmapContextRep *)aContext { 16 | if ((self = [super init])) { 17 | self.bitmapContext = aContext; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 23 | [anInvocation invokeWithTarget:bitmapContext]; 24 | } 25 | 26 | #if __has_feature(objc_arc) != 1 27 | 28 | - (void)dealloc { 29 | self.bitmapContext = nil; 30 | [super dealloc]; 31 | } 32 | 33 | #endif 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapContextManipulator.h: -------------------------------------------------------------------------------- 1 | // 2 | // BitmapContextManip.h 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 10/14/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BitmapContextRep.h" 11 | 12 | @interface BitmapContextManipulator : NSObject { 13 | #if __has_feature(objc_arc) == 1 14 | __unsafe_unretained BitmapContextRep * bitmapContext; 15 | #else 16 | BitmapContextRep * bitmapContext; 17 | #endif 18 | } 19 | 20 | #if __has_feature(objc_arc) == 1 21 | @property (nonatomic, assign) BitmapContextRep * bitmapContext; 22 | #else 23 | @property (nonatomic, assign) BitmapContextRep * bitmapContext; 24 | #endif 25 | 26 | - (id)initWithContext:(BitmapContextRep *)aContext; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/NSMutableArray+Move.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+Move.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "NSMutableArray+Move.h" 10 | 11 | @implementation NSMutableArray (Move) 12 | 13 | - (void)swapValueAtIndex:(NSInteger)source withValueAtIndex:(NSInteger)destination { 14 | NSObject * object1 = [self objectAtIndex:source]; 15 | NSObject * object2 = [self objectAtIndex:destination]; 16 | #if !__has_feature(objc_arc) 17 | [object1 retain]; 18 | [object2 retain]; 19 | #endif 20 | 21 | [self replaceObjectAtIndex:source withObject:object2]; 22 | [self replaceObjectAtIndex:destination withObject:object1]; 23 | 24 | #if !__has_feature(objc_arc) 25 | [object1 release]; 26 | [object2 release]; 27 | #endif 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /ANGif/LZW/LZWSpoof.h: -------------------------------------------------------------------------------- 1 | // 2 | // LZWSpoof.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define BitOutOfRangeException @"BitOutOfRangeException" 12 | 13 | void LZWDataAddBit (UInt8 ** _bytePool, NSUInteger * _totalSize, NSUInteger * numBits, BOOL flag); 14 | BOOL LZWDataGetBit (UInt8 * _bytePool, NSUInteger bitIndex); 15 | 16 | @interface LZWSpoof : NSObject { 17 | UInt8 * _bytePool; 18 | NSUInteger _totalSize; 19 | NSUInteger numBits; 20 | } 21 | 22 | @property (readonly) NSUInteger numBits; 23 | 24 | + (NSData *)lzwExpandData:(NSData *)existingData; 25 | 26 | - (id)initWithData:(NSData *)initialData; 27 | - (void)addBit:(BOOL)flag; 28 | - (BOOL)getBitAtIndex:(NSUInteger)bitIndex; 29 | 30 | - (void)addLZWClearCode; 31 | - (void)addByte:(NSUInteger)startBit fromBuffer:(LZWSpoof *)source; 32 | 33 | - (NSData *)convertToData; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Giraffe-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | com.yourcompany.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSMainNibFile 28 | MainWindow 29 | 30 | 31 | -------------------------------------------------------------------------------- /ANImageBitmapRep/CoreGraphics/CGImageContainer.m: -------------------------------------------------------------------------------- 1 | // 2 | // CGImageContainer.m 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 5/3/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "CGImageContainer.h" 10 | 11 | #if __has_feature(objc_arc) != 1 12 | 13 | @implementation CGImageContainer 14 | 15 | @synthesize image; 16 | 17 | - (id)initWithImage:(CGImageRef)anImage { 18 | if ((self = [super init])) { 19 | image = CGImageRetain(anImage); 20 | } 21 | return self; 22 | } 23 | 24 | + (CGImageContainer *)imageContainerWithImage:(CGImageRef)anImage { 25 | CGImageContainer * container = [(CGImageContainer *)[CGImageContainer alloc] initWithImage:anImage]; 26 | return [container autorelease]; 27 | } 28 | 29 | - (void)dealloc { 30 | CGImageRelease(image); 31 | [super dealloc]; 32 | } 33 | 34 | @end 35 | 36 | #else 37 | 38 | __attribute__((ns_returns_autoreleased)) 39 | id CGImageReturnAutoreleased (CGImageRef original) { 40 | // CGImageRetain(original); 41 | return (__bridge id)original; 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /Classes/GiraffeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GiraffeViewController.h 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 1/20/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "PhotoEntry.h" 12 | #import "NSMutableArray+Move.h" 13 | #import "ExportViewController.h" 14 | 15 | @interface GiraffeViewController : UIViewController { 16 | IBOutlet UIBarButtonItem * doneButton; 17 | IBOutlet UIBarButtonItem * editButton; 18 | NSMutableArray * imageFrames; 19 | UIImagePickerController * imagePicker; 20 | NSUInteger itemID; 21 | IBOutlet UINavigationItem * navItem; 22 | IBOutlet UITableView * tableView; 23 | } 24 | 25 | - (IBAction)addFrame:(id)sender; 26 | - (IBAction)doneEditing:(id)sender; 27 | - (IBAction)edit:(id)sender; 28 | - (IBAction)exportVideo:(id)sender; 29 | 30 | - (void)showViewController:(UIViewController *)controller; 31 | 32 | @end 33 | 34 | -------------------------------------------------------------------------------- /ANGif/App Extensions/ANGifNetscapeAppExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifNetscapeAppExtension.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifNetscapeAppExtension.h" 11 | 12 | @implementation ANGifNetscapeAppExtension 13 | 14 | @synthesize numberOfRepeats; 15 | 16 | - (id)init { 17 | if ((self = [self initWithRepeatCount:0xffff])) { 18 | } 19 | return self; 20 | } 21 | 22 | - (id)initWithRepeatCount:(UInt16)repeats { 23 | if ((self = [super init])) { 24 | numberOfRepeats = repeats; 25 | // calculate application data 26 | NSMutableData * appData = [NSMutableData data]; 27 | [appData appendBytes:"\x03\x01" length:2]; 28 | [appData appendBytes:&numberOfRepeats length:2]; 29 | self.applicationData = [NSData dataWithData:appData]; 30 | // app ID and signature 31 | self.applicationIdentifier = [NSData dataWithBytes:"\x4E\x45\x54\x53\x43\x41\x50\x45" length:8]; 32 | self.applicationAuthCode = [NSData dataWithBytes:"\x32\x2E\x30" length:3]; 33 | } 34 | return self; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Compatibility/UIImage+ANImageBitmapRep.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+ANImageBitmapRep.h 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 8/11/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE 10 | 11 | @class ANImageBitmapRep; 12 | 13 | #import 14 | 15 | @interface UIImage (ANImageBitmapRep) 16 | 17 | #if __has_feature(objc_arc) == 1 18 | + (UIImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr __attribute__((ns_returns_autoreleased)); 19 | - (ANImageBitmapRep *)imageBitmapRep __attribute__((ns_returns_autoreleased)); 20 | - (UIImage *)imageByScalingToSize:(CGSize)sz __attribute__((ns_returns_autoreleased)); 21 | - (UIImage *)imageFittingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased)); 22 | - (UIImage *)imageFillingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased)); 23 | #else 24 | + (UIImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr; 25 | - (ANImageBitmapRep *)imageBitmapRep; 26 | - (UIImage *)imageByScalingToSize:(CGSize)sz; 27 | - (UIImage *)imageFittingFrame:(CGSize)sz; 28 | - (UIImage *)imageFillingFrame:(CGSize)sz; 29 | #endif 30 | 31 | @end 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Compatibility/NSImage+ANImageBitmapRep.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+ANImageBitmapRep.h 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 10/23/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE != 1 10 | 11 | #import 12 | 13 | @class ANImageBitmapRep; 14 | 15 | @interface NSImage (ANImageBitmapRep) 16 | 17 | #if __has_feature(objc_arc) == 1 18 | + (NSImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr __attribute__((ns_returns_autoreleased)); 19 | - (ANImageBitmapRep *)imageBitmapRep __attribute__((ns_returns_autoreleased)); 20 | - (NSImage *)imageByScalingToSize:(CGSize)sz __attribute__((ns_returns_autoreleased)); 21 | - (NSImage *)imageFittingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased)); 22 | - (NSImage *)imageFillingFrame:(CGSize)sz __attribute__((ns_returns_autoreleased)); 23 | #else 24 | + (NSImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr; 25 | - (ANImageBitmapRep *)imageBitmapRep; 26 | - (NSImage *)imageByScalingToSize:(CGSize)sz; 27 | - (NSImage *)imageFittingFrame:(CGSize)sz; 28 | - (NSImage *)imageFillingFrame:(CGSize)sz; 29 | #endif 30 | 31 | @end 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapRotationManipulator.h: -------------------------------------------------------------------------------- 1 | // 2 | // RotatableBitmapRep.h 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BitmapContextManipulator.h" 11 | 12 | @protocol BitmapRotationManipulator 13 | 14 | @optional 15 | - (void)rotate:(CGFloat)degrees; 16 | - (CGImageRef)imageByRotating:(CGFloat)degrees; 17 | 18 | @end 19 | 20 | @interface BitmapRotationManipulator : BitmapContextManipulator { 21 | 22 | } 23 | 24 | /** 25 | * Rotate the image bitmap around its center by a certain number of degrees. 26 | * @param degrees The degrees from 0 to 360. This is not measured in radians. 27 | * @discussion This will resize the image if needed. 28 | */ 29 | - (void)rotate:(CGFloat)degrees; 30 | 31 | /** 32 | * Create a new image by rotating this image bitmap around its center by a specified 33 | * number of degrees. 34 | * @param degrees The degrees (not in radians) by which the image should be rotated. 35 | * @discussion This will resize the image if needed. 36 | */ 37 | - (CGImageRef)imageByRotating:(CGFloat)degrees; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ANGif/ANGifLogicalScreenDesc.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifLogicalScreenDescriptor.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifLogicalScreenDesc.h" 11 | 12 | @implementation ANGifLogicalScreenDesc 13 | 14 | @synthesize screenWidth; 15 | @synthesize screenHeight; 16 | @synthesize globalColorTable; 17 | @synthesize gctSize; 18 | @synthesize backgroundColor; 19 | 20 | - (NSData *)encodeBlock { 21 | NSMutableData * encoded = [NSMutableData data]; 22 | 23 | UInt8 aByte; 24 | 25 | [encoded appendBytes:&screenWidth length:2]; 26 | [encoded appendBytes:&screenHeight length:2]; 27 | // packed flags with 3*8 bits/pixel, GCT present, and GCT size 28 | aByte = (globalColorTable << 7) | (3 << 4) | (gctSize & 7); 29 | if (globalColorTable) { 30 | // aByte |= (1 << 3); // global color table sorted 31 | } 32 | [encoded appendBytes:&aByte length:1]; // flags 33 | [encoded appendBytes:&backgroundColor length:1]; 34 | aByte = 0; 35 | [encoded appendBytes:&aByte length:1]; // pixel aspect ratio 36 | 37 | return [NSData dataWithData:encoded]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ANGif/App Extensions/ANGifAppExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifAppExtension.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifAppExtension.h" 11 | 12 | @implementation ANGifAppExtension 13 | 14 | @synthesize applicationIdentifier; 15 | @synthesize applicationAuthCode; 16 | @synthesize applicationData; 17 | 18 | - (NSData *)encodeBlock { 19 | NSMutableData * data = [NSMutableData data]; 20 | 21 | UInt8 aByte = 0x21; 22 | [data appendBytes:&aByte length:1]; // extension introducer 23 | aByte = 0xFF; 24 | [data appendBytes:&aByte length:1]; // extension label 25 | aByte = [applicationIdentifier length] + [applicationAuthCode length]; 26 | [data appendBytes:&aByte length:1]; // block length 27 | [data appendData:applicationIdentifier]; 28 | [data appendData:applicationAuthCode]; 29 | [data appendData:applicationData]; 30 | aByte = 0; 31 | [data appendBytes:&aByte length:1]; // application terminator 32 | 33 | return [NSData dataWithData:data]; 34 | } 35 | 36 | #if !__has_feature(objc_arc) 37 | 38 | - (void)dealloc { 39 | self.applicationIdentifier = nil; 40 | self.applicationAuthCode = nil; 41 | self.applicationData = nil; 42 | [super dealloc]; 43 | } 44 | 45 | #endif 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Classes/PhotoEntry.m: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoEntry.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "PhotoEntry.h" 10 | 11 | @implementation PhotoEntry 12 | 13 | @synthesize image; 14 | @synthesize imageName; 15 | 16 | - (id)initWithName:(NSString *)name image:(UIImage *)anImage { 17 | if ((self = [super init])) { 18 | #if __has_feature(objc_arc) 19 | imageName = name; 20 | #else 21 | imageName = [name retain]; 22 | #endif 23 | if (anImage.size.width > 640 || anImage.size.height > 480) { 24 | BitmapContextRep * bitmap = [[BitmapContextRep alloc] initWithImage:anImage]; 25 | BitmapScaleManipulator * scale = [[BitmapScaleManipulator alloc] initWithContext:bitmap]; 26 | [scale setSizeFittingFrame:BMPointMake(640, 480)]; 27 | anImage = [[UIImage alloc] initWithCGImage:[scale CGImage]]; 28 | #if !__has_feature(objc_arc) 29 | [scale release]; 30 | [bitmap release]; 31 | #endif 32 | } else { 33 | #if __has_feature(objc_arc) 34 | image = anImage; 35 | #else 36 | image = [anImage retain]; 37 | #endif 38 | } 39 | } 40 | return self; 41 | } 42 | 43 | #if !__has_feature(objc_arc) 44 | 45 | - (void)dealloc { 46 | [image release]; 47 | [imageName release]; 48 | [super dealloc]; 49 | } 50 | 51 | #endif 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /ANGif/ANGifGraphicControlExt.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifGraphicControlExtension.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifGraphicControlExt.h" 11 | 12 | @implementation ANGifGraphicControlExt 13 | 14 | @synthesize userInputFlag; 15 | @synthesize transparentColorFlag; 16 | @synthesize transparentColorIndex; 17 | @synthesize delayTime; 18 | 19 | - (NSData *)encodeBlock { 20 | NSMutableData * encoded = [NSMutableData data]; 21 | UInt8 aByte = 0x21; 22 | UInt16 doubleByte; 23 | 24 | [encoded appendBytes:&aByte length:1]; // extension introducer 25 | aByte = kGraphicControlLabel; 26 | [encoded appendBytes:&aByte length:1]; // graphic control label 27 | aByte = 4; 28 | [encoded appendBytes:&aByte length:1]; // block length (fixed) 29 | 30 | // w/ disposal method #3 31 | aByte = (3 << 2) | (userInputFlag << 1) | transparentColorFlag; 32 | [encoded appendBytes:&aByte length:1]; 33 | 34 | doubleByte = (UInt16)round(delayTime * 100); 35 | [encoded appendBytes:&doubleByte length:2]; // delay time 36 | [encoded appendBytes:&transparentColorIndex length:1]; 37 | 38 | // terminator block 39 | aByte = 0; 40 | [encoded appendBytes:&aByte length:1]; 41 | 42 | return [NSData dataWithData:encoded]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /ANGif/ColorTable/ANAvgColorTable.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifBasicColorTable.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANAvgColorTable.h" 11 | 12 | @implementation ANAvgColorTable 13 | 14 | - (UInt8)addColor:(ANGifColor)aColor { 15 | NSUInteger firstIndex = (self.hasTransparentFirst ? 1 : 0); 16 | UInt8 bestToCut = firstIndex; 17 | NSUInteger variance = UINT_MAX; 18 | 19 | for (NSUInteger index = firstIndex; index < _entryCount; index++) { 20 | NSUInteger lvariance = 0; 21 | ANGifColor color = [self colorAtIndex:index]; 22 | lvariance += abs((int)color.red - (int)aColor.red); 23 | lvariance += abs((int)color.green - (int)aColor.green); 24 | lvariance += abs((int)color.blue - (int)aColor.blue); 25 | lvariance *= _entries[index].priority; 26 | if (lvariance < variance) { 27 | bestToCut = index; 28 | variance = lvariance; 29 | if (lvariance == 0) return bestToCut; 30 | } 31 | } 32 | 33 | if (_entryCount < maxColors && variance > 10) { 34 | return [super addColor:aColor]; 35 | } 36 | 37 | // do a cut 38 | ANGifColor cutColor = [self colorAtIndex:bestToCut]; 39 | cutColor = ANGifColorAverage(cutColor, aColor); 40 | _entries[bestToCut].color = cutColor; 41 | 42 | _entries[bestToCut].priority += 1; 43 | return bestToCut; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Classes/UIImagePixelSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImagePixelSource.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "UIImagePixelSource.h" 10 | 11 | @implementation UIImagePixelSource 12 | 13 | - (id)initWithImage:(UIImage *)anImage { 14 | if ((self = [super init])) { 15 | imageRep = [[ANImageBitmapRep alloc] initWithImage:anImage]; 16 | } 17 | return self; 18 | } 19 | 20 | + (UIImagePixelSource *)pixelSourceWithImage:(UIImage *)anImage { 21 | #if __has_feature(objc_arc) 22 | return [[UIImagePixelSource alloc] initWithImage:anImage]; 23 | #else 24 | return [[[UIImagePixelSource alloc] initWithImage:anImage] autorelease]; 25 | #endif 26 | } 27 | 28 | - (NSUInteger)pixelsWide { 29 | return [imageRep bitmapSize].x; 30 | } 31 | 32 | - (NSUInteger)pixelsHigh { 33 | return [imageRep bitmapSize].y; 34 | } 35 | 36 | - (void)getPixel:(NSUInteger *)pixel atX:(NSInteger)x y:(NSInteger)y { 37 | BMPixel bpixel = [imageRep getPixelAtPoint:BMPointMake(x, y)]; 38 | pixel[0] = (NSUInteger)round(bpixel.red * 255.0); 39 | pixel[1] = (NSUInteger)round(bpixel.green * 255.0); 40 | pixel[2] = (NSUInteger)round(bpixel.blue * 255.0); 41 | pixel[3] = (NSUInteger)round(bpixel.alpha * 255.0); 42 | } 43 | 44 | - (BOOL)hasTransparency { 45 | return YES; 46 | } 47 | 48 | #if !__has_feature(objc_arc) 49 | - (void)dealloc { 50 | [imageRep release]; 51 | [super dealloc]; 52 | } 53 | #endif 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifImageDescriptor.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifImageDescriptor.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifImageDescriptor.h" 11 | 12 | @implementation ANGifImageDescriptor 13 | 14 | - (id)initWithImageFrame:(ANGifImageFrame *)anImage { 15 | if ((self = [super init])) { 16 | imageFrame = anImage; 17 | } 18 | return self; 19 | } 20 | 21 | - (NSData *)encodeBlock { 22 | NSMutableData * encoded = [NSMutableData data]; 23 | 24 | UInt8 aByte = kImageSeparator; 25 | UInt16 doubleByte; 26 | 27 | [encoded appendBytes:&aByte length:1]; 28 | doubleByte = (UInt16)[imageFrame offsetX]; 29 | [encoded appendBytes:&doubleByte length:2]; 30 | doubleByte = (UInt16)[imageFrame offsetY]; 31 | [encoded appendBytes:&doubleByte length:2]; 32 | doubleByte = (UInt16)[[imageFrame pixelSource] pixelsWide]; 33 | [encoded appendBytes:&doubleByte length:2]; 34 | doubleByte = (UInt16)[[imageFrame pixelSource] pixelsHigh]; 35 | [encoded appendBytes:&doubleByte length:2]; 36 | 37 | UInt8 packedInfo = 0; 38 | if ([imageFrame localColorTable]) { 39 | UInt8 lctSize = [[imageFrame localColorTable] colorTableSizeValue]; 40 | packedInfo |= 128; 41 | packedInfo |= lctSize; 42 | // packedInfo |= (1 << 3); // sort flag 43 | } 44 | [encoded appendBytes:&packedInfo length:1]; 45 | 46 | return [NSData dataWithData:encoded]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Compatibility/OSCommonImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSCommonImage.c 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 10/23/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #include "OSCommonImage.h" 10 | 11 | CGImageRef CGImageFromANImage (ANImageObj * anImageObj) { 12 | #if TARGET_OS_IPHONE 13 | return [anImageObj CGImage]; 14 | #elif TARGET_OS_MAC 15 | CGImageSourceRef source; 16 | #if __has_feature(objc_arc) == 1 17 | source = CGImageSourceCreateWithData((__bridge CFDataRef)[anImageObj TIFFRepresentation], NULL); 18 | #else 19 | source = CGImageSourceCreateWithData((CFDataRef)[anImageObj TIFFRepresentation], NULL); 20 | #endif 21 | CGImageRef maskRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); 22 | #if __has_feature(objc_arc) == 1 23 | CGImageRef autoreleased = (__bridge CGImageRef)CGImageReturnAutoreleased(maskRef); 24 | CGImageRelease(maskRef); 25 | return autoreleased; 26 | #else 27 | CGImageContainer * container = [CGImageContainer imageContainerWithImage:maskRef]; 28 | CGImageRelease(maskRef); 29 | return [container image]; 30 | #endif 31 | #endif 32 | } 33 | 34 | ANImageObj * ANImageFromCGImage (CGImageRef imageRef) { 35 | #if TARGET_OS_IPHONE 36 | return [UIImage imageWithCGImage:imageRef]; 37 | #elif TARGET_OS_MAC 38 | NSImage * image = [[NSImage alloc] initWithCGImage:imageRef size:NSZeroSize]; 39 | #if __has_feature(objc_arc) == 1 40 | return image; 41 | #else 42 | return [image autorelease]; 43 | #endif 44 | #endif 45 | } 46 | -------------------------------------------------------------------------------- /ANImageBitmapRep/CoreGraphics/CGImageContainer.h: -------------------------------------------------------------------------------- 1 | // 2 | // CGImageContainer.h 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 5/3/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | 10 | #if __has_feature(objc_arc) != 1 11 | 12 | #import 13 | 14 | #if TARGET_OS_IPHONE 15 | #import 16 | #elif TARGET_OS_MAC 17 | #import 18 | #endif 19 | 20 | 21 | @interface CGImageContainer : NSObject { 22 | CGImageRef image; 23 | } 24 | 25 | /** 26 | * The image that this container encloses. 27 | */ 28 | @property (readonly) CGImageRef image; 29 | 30 | /** 31 | * Create a new image container with an image. 32 | * @param anImage Will be retained and enclosed in this class. 33 | * This object will be released when the CGImageContainer is 34 | * deallocated. This can be nil. 35 | * @return The new image container, or nil if anImage is nil. 36 | */ 37 | - (id)initWithImage:(CGImageRef)anImage; 38 | 39 | /** 40 | * Create a new image container with an image. 41 | * @param anImage Will be retained and enclosed in this class. 42 | * This object will be released when the CGImageContainer is 43 | * deallocated. This can be nil. 44 | * @return The new image container, or nil if anImage is nil. 45 | * The image container returned will be autoreleased. 46 | */ 47 | + (CGImageContainer *)imageContainerWithImage:(CGImageRef)anImage; 48 | 49 | @end 50 | 51 | #else 52 | 53 | id CGImageReturnAutoreleased (CGImageRef original) __attribute__((ns_returns_autoreleased)); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapScaleManipulator.h: -------------------------------------------------------------------------------- 1 | // 2 | // ScalableBitmapRep.h 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BitmapContextManipulator.h" 11 | 12 | @protocol BitmapScaleManipulator 13 | 14 | @optional 15 | - (void)setSize:(BMPoint)aSize; 16 | - (void)setSizeFittingFrame:(BMPoint)aSize; 17 | - (void)setSizeFillingFrame:(BMPoint)aSize; 18 | 19 | @end 20 | 21 | @interface BitmapScaleManipulator : BitmapContextManipulator { 22 | 23 | } 24 | 25 | /** 26 | * Stretches the bitmap context to a specified size. 27 | * @param aSize The new size to make the bitmap. 28 | * If this is the same as the current size, the bitmap 29 | * will not be changed. 30 | */ 31 | - (void)setSize:(BMPoint)aSize; 32 | 33 | /** 34 | * Scales the image to fit a particular frame without stretching (bringing out of scale). 35 | * @param aSize The size to which the image scaled. 36 | * @discussion The actual image itself will most likely be smaller than the specified 37 | * size, leaving transparent edges to make the image fit the exact size. 38 | */ 39 | - (void)setSizeFittingFrame:(BMPoint)aSize; 40 | 41 | /** 42 | * Scales the image to fill a particular frame without stretching. 43 | * This will most likely cause the left and right or top and bottom 44 | * edges of the image to be cut off. 45 | * @param aSize The size that the image will be forced to fill. 46 | */ 47 | - (void)setSizeFillingFrame:(BMPoint)aSize; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapCropManipulator.h: -------------------------------------------------------------------------------- 1 | // 2 | // CroppableBitmapRep.h 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BitmapContextManipulator.h" 11 | 12 | @protocol BitmapCropManipulator 13 | 14 | @optional 15 | - (void)cropFrame:(CGRect)frame; 16 | - (void)cropTopFrame:(CGRect)frame; 17 | - (CGImageRef)croppedImageWithFrame:(CGRect)frame; 18 | 19 | @end 20 | 21 | @interface BitmapCropManipulator : BitmapContextManipulator { 22 | 23 | } 24 | 25 | /** 26 | * Cuts a part of the bitmap out for a new bitmap. 27 | * @param frame The rectangle from which a portion of the image will 28 | * be cut. 29 | * The coordinates for this start at (0,0). 30 | * @discussion The coordinates for this method begin in the bottom 31 | * left corner. For a coordinate system starting from the top 32 | * left corner, use cropTopFrame: instead. 33 | */ 34 | - (void)cropFrame:(CGRect)frame; 35 | 36 | /** 37 | * Cuts a part of the bitmap out for a new bitmap. 38 | * @param frame The rectangle from which a portion of the image will 39 | * be cut. 40 | * The coordinates for this start at (0,0). 41 | * @discussion The coordinates for this method begin in the top 42 | * left corner. For a coordinate system starting from the bottom 43 | * left corner, use cropFrame: instead. 44 | */ 45 | - (void)cropTopFrame:(CGRect)frame; 46 | 47 | /** 48 | * Creates a new CGImageRef by cutting out a portion of this one. 49 | * This takes its behavoir from cropFrame. 50 | * @return An autoreleased CGImageRef that has been cropped from this 51 | * image. 52 | */ 53 | - (CGImageRef)croppedImageWithFrame:(CGRect)frame; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /ANGif/ColorTable/ANColorTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifColorTable.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef struct { 12 | UInt8 red; 13 | UInt8 green; 14 | UInt8 blue; 15 | } ANGifColor; 16 | 17 | BOOL ANGifColorIsEqual (ANGifColor color1, ANGifColor color2); 18 | NSUInteger ANGifColorVariance (ANGifColor color1, ANGifColor color2); 19 | ANGifColor ANGifColorAverage (ANGifColor color1, ANGifColor color2); 20 | ANGifColor ANGifColorMake (UInt8 red, UInt8 green, UInt8 blue); 21 | 22 | typedef struct { 23 | ANGifColor color; 24 | NSUInteger priority; 25 | } ANGifColorTableEntry; 26 | 27 | #define ANGifColorIndexOutOfBoundsException @"ANGifColorIndexOutOfBoundsException" 28 | #define ANGifColorTableFullException @"ANGifColorTableFullException" 29 | 30 | @interface ANColorTable : NSObject { 31 | ANGifColorTableEntry * _entries; 32 | NSUInteger _entryCount; 33 | NSUInteger _totalAlloced; 34 | NSUInteger maxColors; 35 | BOOL hasTransparentFirst; 36 | } 37 | 38 | @property (readwrite) NSUInteger maxColors; 39 | @property (readonly) BOOL hasTransparentFirst; 40 | 41 | - (id)initWithTransparentFirst:(BOOL)transparentFirst; 42 | 43 | - (NSUInteger)numberOfEntries; 44 | - (void)setColor:(ANGifColor)color atIndex:(UInt8)index; 45 | - (UInt8)addColor:(ANGifColor)aColor; 46 | - (ANGifColor)colorAtIndex:(UInt8)index; 47 | - (UInt8)transparentIndex; 48 | 49 | - (void)sortByPriority; 50 | - (BOOL)singleSortStep; 51 | 52 | /** 53 | * Returns a value x where 2^(x + 1) is the number (or more than the number) 54 | * of entries in this color table. 55 | */ 56 | - (UInt8)colorTableSizeValue; 57 | - (NSData *)encodeRawColorTable; 58 | - (NSData *)encodeRawColorTableCount:(NSUInteger)numEntries; 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Compatibility/UIImage+ANImageBitmapRep.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+ANImageBitmapRep.m 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 8/11/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE 10 | 11 | #import "UIImage+ANImageBitmapRep.h" 12 | #import "ANImageBitmapRep.h" 13 | 14 | @implementation UIImage (ANImageBitmapRep) 15 | 16 | 17 | + (UIImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr { 18 | return [ibr image]; 19 | } 20 | 21 | - (ANImageBitmapRep *)imageBitmapRep { 22 | #if __has_feature(objc_arc) == 1 23 | return [[ANImageBitmapRep alloc] initWithImage:self]; 24 | #else 25 | return [[[ANImageBitmapRep alloc] initWithImage:self] autorelease]; 26 | #endif 27 | } 28 | 29 | - (UIImage *)imageByScalingToSize:(CGSize)sz { 30 | ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self]; 31 | [imageBitmap setSize:BMPointMake(round(sz.width), round(sz.height))]; 32 | UIImage * scaled = [imageBitmap image]; 33 | #if __has_feature(objc_arc) != 1 34 | [imageBitmap release]; 35 | #endif 36 | return scaled; 37 | } 38 | 39 | - (UIImage *)imageFittingFrame:(CGSize)sz { 40 | ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self]; 41 | [imageBitmap setSizeFittingFrame:BMPointMake(round(sz.width), round(sz.height))]; 42 | UIImage * scaled = [imageBitmap image]; 43 | #if __has_feature(objc_arc) != 1 44 | [imageBitmap release]; 45 | #endif 46 | return scaled; 47 | } 48 | 49 | - (UIImage *)imageFillingFrame:(CGSize)sz { 50 | ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self]; 51 | [imageBitmap setSizeFillingFrame:BMPointMake(round(sz.width), round(sz.height))]; 52 | UIImage * scaled = [imageBitmap image]; 53 | #if __has_feature(objc_arc) != 1 54 | [imageBitmap release]; 55 | #endif 56 | return scaled; 57 | } 58 | 59 | @end 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Compatibility/NSImage+ANImageBitmapRep.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+ANImageBitmapRep.m 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 10/23/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE != 1 10 | 11 | #import "NSImage+ANImageBitmapRep.h" 12 | #import "ANImageBitmapRep.h" 13 | 14 | @implementation NSImage (ANImageBitmapRep) 15 | 16 | 17 | + (NSImage *)imageFromImageBitmapRep:(ANImageBitmapRep *)ibr { 18 | return [ibr image]; 19 | } 20 | 21 | - (ANImageBitmapRep *)imageBitmapRep { 22 | #if __has_feature(objc_arc) == 1 23 | return [[ANImageBitmapRep alloc] initWithImage:self]; 24 | #else 25 | return [[[ANImageBitmapRep alloc] initWithImage:self] autorelease]; 26 | #endif 27 | } 28 | 29 | - (NSImage *)imageByScalingToSize:(CGSize)sz { 30 | ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self]; 31 | [imageBitmap setSize:BMPointMake(round(sz.width), round(sz.height))]; 32 | NSImage * scaled = [imageBitmap image]; 33 | #if __has_feature(objc_arc) != 1 34 | [imageBitmap release]; 35 | #endif 36 | return scaled; 37 | } 38 | 39 | - (NSImage *)imageFittingFrame:(CGSize)sz { 40 | ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self]; 41 | [imageBitmap setSizeFittingFrame:BMPointMake(round(sz.width), round(sz.height))]; 42 | NSImage * scaled = [imageBitmap image]; 43 | #if __has_feature(objc_arc) != 1 44 | [imageBitmap release]; 45 | #endif 46 | return scaled; 47 | } 48 | 49 | - (NSImage *)imageFillingFrame:(CGSize)sz { 50 | ANImageBitmapRep * imageBitmap = [[ANImageBitmapRep alloc] initWithImage:self]; 51 | [imageBitmap setSizeFillingFrame:BMPointMake(round(sz.width), round(sz.height))]; 52 | NSImage * scaled = [imageBitmap image]; 53 | #if __has_feature(objc_arc) != 1 54 | [imageBitmap release]; 55 | #endif 56 | return scaled; 57 | } 58 | 59 | @end 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifDataSubblock.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifDataSubblock.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifDataSubblock.h" 11 | 12 | @implementation ANGifDataSubblock 13 | 14 | + (NSArray *)dataSubblocksForData:(NSData *)largeData { 15 | NSMutableArray * array = [NSMutableArray array]; 16 | 17 | NSUInteger length = [largeData length]; 18 | const char * bytes = (const char *)[largeData bytes]; 19 | 20 | for (NSUInteger index = 0; index < length; index += 255) { 21 | NSUInteger blockLen = 255; 22 | if (length - index < blockLen) blockLen = length - index; 23 | 24 | NSData * theData = [NSData dataWithBytes:&bytes[index] length:blockLen]; 25 | ANGifDataSubblock * subblock = [[ANGifDataSubblock alloc] initWithBlockData:theData]; 26 | [array addObject:subblock]; 27 | #if !__has_feature(objc_arc) 28 | [subblock release]; 29 | #endif 30 | } 31 | 32 | return [NSArray arrayWithArray:array]; 33 | } 34 | 35 | - (id)initWithBlockData:(NSData *)theData { 36 | if ((self = [super init])) { 37 | #if __has_feature(objc_arc) 38 | subblockData = theData; 39 | #else 40 | subblockData = [theData retain]; 41 | #endif 42 | } 43 | return self; 44 | } 45 | 46 | - (NSData *)encodeBlock { 47 | NSMutableData * data = [NSMutableData data]; 48 | UInt8 length = (UInt8)[subblockData length]; 49 | [data appendBytes:&length length:1]; 50 | [data appendData:subblockData]; 51 | 52 | return [NSData dataWithData:data]; 53 | } 54 | 55 | - (void)writeToFileHandle:(NSFileHandle *)fileHandle { 56 | UInt8 length = (UInt8)[subblockData length]; 57 | [fileHandle writeData:[NSData dataWithBytes:&length length:1]]; 58 | [fileHandle writeData:subblockData]; 59 | } 60 | 61 | #if !__has_feature(objc_arc) 62 | 63 | - (void)dealloc { 64 | [subblockData release]; 65 | [super dealloc]; 66 | } 67 | 68 | #endif 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /ANGif/ANGifEncoder.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifEncoder.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANGifGraphicControlExt.h" 11 | #import "ANGifImageDescriptor.h" 12 | #import "ANGifLogicalScreenDesc.h" 13 | #import "ANAvgColorTable.h" 14 | #import "LZWSpoof.h" 15 | #import "ANGifDataSubblock.h" 16 | #import "ANGifAppExtension.h" 17 | 18 | #define kGifHeader "GIF89a" 19 | #define kGifTrailer "\x3B" 20 | 21 | @interface ANGifEncoder : NSObject { 22 | NSFileHandle * fileHandle; 23 | ANColorTable * globalColorTable; 24 | NSUInteger screenWidth; 25 | NSUInteger screenHeight; 26 | NSUInteger gctOffset; 27 | } 28 | 29 | /** 30 | * Creates a new ANGifEncoder with a given file handle, a canvas size, 31 | * and a global color table. 32 | * @param handle The output file handle that will be written to. 33 | * @param aSize The dimensions of the "virtual screen" created by 34 | * the gif decoder. 35 | * @param gct The global descriptor table, or nil if no GCT should be used. 36 | */ 37 | - (id)initWithFileHandle:(NSFileHandle *)handle size:(CGSize)aSize 38 | globalColorTable:(ANColorTable *)gct; 39 | 40 | /** 41 | * A call to this method is equivalent to a call to 42 | * initWithFileHandle:size:globalColorTable: with a valid file descriptor 43 | * opened for writing to fileName. 44 | */ 45 | - (id)initWithOutputFile:(NSString *)fileName size:(CGSize)aSize 46 | globalColorTable:(ANColorTable *)gct; 47 | 48 | /** 49 | * Add an application extension to the GIF file. 50 | */ 51 | - (void)addApplicationExtension:(ANGifAppExtension *)ext; 52 | 53 | /** 54 | * Add an image to the image sequence contained in the GIF file. 55 | */ 56 | - (void)addImageFrame:(ANGifImageFrame *)imageFrame; 57 | 58 | /** 59 | * Writes any headers and terminators that may need to get written. 60 | * @discussion This does not close the file handle. 61 | */ 62 | - (void)finishDataStream; 63 | 64 | /** 65 | * Calls finishDataStream before closing the underlying file handle. 66 | */ 67 | - (void)closeFile; 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifImageFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifImageFrame.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifImageFrame.h" 11 | 12 | @implementation ANGifImageFrame 13 | 14 | @synthesize pixelSource; 15 | @synthesize localColorTable; 16 | @synthesize offsetX, offsetY; 17 | @synthesize delayTime; 18 | 19 | - (id)initWithPixelSource:(id)aSource colorTable:(ANColorTable *)table delayTime:(NSTimeInterval)delay { 20 | if ((self = [super init])) { 21 | self.pixelSource = aSource; 22 | self.localColorTable = table; 23 | self.delayTime = delay; 24 | } 25 | return self; 26 | } 27 | 28 | - (id)initWithPixelSource:(id)aSource delayTime:(NSTimeInterval)delay { 29 | self = [self initWithPixelSource:aSource 30 | colorTable:nil delayTime:delay]; 31 | return self; 32 | } 33 | 34 | - (NSData *)encodeImageUsingColorTable:(ANColorTable *)colorTable { 35 | NSUInteger color[4]; 36 | ANGifColor gifColor; 37 | NSMutableData * encodedData = [NSMutableData data]; 38 | NSUInteger width = [pixelSource pixelsWide]; 39 | NSUInteger height = [pixelSource pixelsHigh]; 40 | 41 | for (NSUInteger y = 0; y < height; y++) { 42 | for (NSUInteger x = 0; x < width; x++) { 43 | UInt8 myByte; 44 | [pixelSource getPixel:color atX:x y:y]; 45 | if ([colorTable hasTransparentFirst] && color[3] < 0x20 && [pixelSource hasTransparency]) { 46 | myByte = [colorTable transparentIndex]; 47 | [encodedData appendBytes:&myByte length:1]; 48 | } else { 49 | gifColor.red = color[0]; 50 | gifColor.green = color[1]; 51 | gifColor.blue = color[2]; 52 | myByte = [colorTable addColor:gifColor]; 53 | [encodedData appendBytes:&myByte length:1]; 54 | } 55 | } 56 | } 57 | 58 | return [NSData dataWithData:encodedData]; // return immutable version 59 | } 60 | 61 | #if !__has_feature(objc_arc) 62 | 63 | - (void)dealloc { 64 | self.pixelSource = nil; 65 | self.localColorTable = nil; 66 | [super dealloc]; 67 | } 68 | 69 | #endif 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /ANGif/ImageFrame/ANGifImageFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifImageFrame.h 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ANColorTable.h" 11 | #import "ANGifImageFramePixelSource.h" 12 | 13 | @interface ANGifImageFrame : NSObject { 14 | id pixelSource; 15 | ANColorTable * localColorTable; 16 | UInt16 offsetX; 17 | UInt16 offsetY; 18 | NSTimeInterval delayTime; 19 | } 20 | 21 | @property (nonatomic, retain) id pixelSource; 22 | @property (nonatomic, retain) ANColorTable * localColorTable; 23 | @property (readwrite) UInt16 offsetX, offsetY; 24 | @property (readwrite) NSTimeInterval delayTime; 25 | 26 | /** 27 | * Create an ANGifImageFrame with an image source, a local color table (should be empty), and a delay. 28 | * @param aSource A non-nil pixel data source from which image data will come. 29 | * @param table The local color table that will be used by this image. If this is nil, the global color table 30 | * will be used for this image. 31 | * @param delay The delay in seconds before the next frame will be shown. This is accurate to the millisecond. 32 | */ 33 | - (id)initWithPixelSource:(id)aSource colorTable:(ANColorTable *)table delayTime:(NSTimeInterval)delay; 34 | 35 | /** 36 | * Create an ANGifImageFrame with an image source and a delay. 37 | * @param aSource A non-nil pixel data source from which image data will come. 38 | * @param delay The delay in seconds before the next frame will be shown. This is accurate to the millisecond. 39 | * @discussion Despite the fact that no color table was provided, the encoder may chose to use 40 | * a local color table if no global color table has been created. 41 | */ 42 | - (id)initWithPixelSource:(id)aSource delayTime:(NSTimeInterval)delay; 43 | 44 | /** 45 | * Encodes each pixel using the specified color table, adding colors as it goes along. 46 | * @param colorTable Either a local color table or a global color table. This will be mutated 47 | * only by calling the addColor: method. This may not be nil. 48 | * @return The encoded data of the image, or nil upon error. 49 | */ 50 | - (NSData *)encodeImageUsingColorTable:(ANColorTable *)colorTable; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapScaleManipulator.m: -------------------------------------------------------------------------------- 1 | // 2 | // ScalableBitmapRep.m 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "BitmapScaleManipulator.h" 10 | 11 | 12 | @implementation BitmapScaleManipulator 13 | 14 | - (void)setSize:(BMPoint)aSize { 15 | CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(aSize.x, aSize.y)]; 16 | CGImageRef image = [bitmapContext CGImage]; 17 | CGContextDrawImage(newContext, CGRectMake(0, 0, aSize.x, aSize.y), image); 18 | [bitmapContext setContext:newContext]; 19 | CGContextRelease(newContext); 20 | } 21 | 22 | - (void)setSizeFittingFrame:(BMPoint)aSize { 23 | CGSize oldSize = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y); 24 | CGSize newSize = CGSizeMake(aSize.x, aSize.y); 25 | 26 | float wratio = newSize.width / oldSize.width; 27 | float hratio = newSize.height / oldSize.height; 28 | float scaleRatio = 0; 29 | if (wratio < hratio) { 30 | scaleRatio = wratio; 31 | } else { 32 | scaleRatio = hratio; 33 | } 34 | 35 | CGSize newContentSize = CGSizeMake(oldSize.width * scaleRatio, oldSize.height * scaleRatio); 36 | CGImageRef image = [bitmapContext CGImage]; 37 | CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:newSize]; 38 | CGContextDrawImage(newContext, CGRectMake(newSize.width / 2 - (newContentSize.width / 2), 39 | newSize.height / 2 - (newContentSize.height / 2), 40 | newContentSize.width, newContentSize.height), image); 41 | [bitmapContext setContext:newContext]; 42 | CGContextRelease(newContext); 43 | } 44 | 45 | - (void)setSizeFillingFrame:(BMPoint)aSize { 46 | CGSize oldSize = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y); 47 | CGSize newSize = CGSizeMake(aSize.x, aSize.y); 48 | 49 | float wratio = newSize.width / oldSize.width; 50 | float hratio = newSize.height / oldSize.height; 51 | float scaleRatio; 52 | if (wratio > hratio) { // only difference from -setSizeFittingFrame: 53 | scaleRatio = wratio; 54 | } else { 55 | scaleRatio = hratio; 56 | } 57 | scaleRatio = scaleRatio; 58 | 59 | CGSize newContentSize = CGSizeMake(oldSize.width * scaleRatio, oldSize.height * scaleRatio); 60 | CGImageRef image = [bitmapContext CGImage]; 61 | CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(aSize.x, aSize.y)]; 62 | CGContextDrawImage(newContext, CGRectMake(newSize.width / 2 - (newContentSize.width / 2), 63 | newSize.height / 2 - (newContentSize.height / 2), 64 | newContentSize.width, newContentSize.height), image); 65 | [bitmapContext setContext:newContext]; 66 | CGContextRelease(newContext); 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /ANGif/ColorTable/Cut/ANCutColorTable.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANCutColorTable.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/3/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANCutColorTable.h" 11 | 12 | @implementation ANCutColorTable 13 | 14 | - (id)initWithTransparentFirst:(BOOL)hasAlpha pixelSource:(id)pixelSource { 15 | if ((self = [super initWithTransparentFirst:hasAlpha])) { 16 | ANMutableColorArray * colorArray = [[ANMutableColorArray alloc] init]; 17 | NSUInteger color[4]; 18 | NSUInteger numberOfPoints = 512; 19 | NSUInteger totalPixels = [pixelSource pixelsWide] * [pixelSource pixelsHigh]; 20 | double pixelsPerSample = (double)totalPixels / (double)numberOfPoints; 21 | if (pixelsPerSample < 1) pixelsPerSample = 1; 22 | double pixelIndex = 0; 23 | BOOL hasTransparency = [pixelSource hasTransparency]; 24 | for (NSUInteger y = 0; y < [pixelSource pixelsHigh]; y++) { 25 | for (NSUInteger x = 0; x < [pixelSource pixelsWide]; x++) { 26 | pixelIndex += 1.0; 27 | if (pixelIndex >= pixelsPerSample) { 28 | pixelIndex -= pixelsPerSample; 29 | ANGifColor aColor; 30 | [pixelSource getPixel:color atX:x y:y]; 31 | if (!(color[3] < 0x20 && hasTransparency && hasAlpha)) { 32 | aColor.red = color[0]; 33 | aColor.green = color[1]; 34 | aColor.blue = color[2]; 35 | [colorArray addColor:aColor]; 36 | } 37 | } 38 | } 39 | } 40 | [colorArray sortByBrightness]; 41 | // split colorArray up if needed, create new color array 42 | NSUInteger maxGenColors = (hasAlpha ? 254 : 255); 43 | if ([colorArray count] > maxGenColors) { 44 | #if !__has_feature(objc_arc) 45 | [colorArray autorelease]; 46 | #endif 47 | colorArray = [colorArray colorArrayByAveragingSplit:maxGenColors]; 48 | #if !__has_feature(objc_arc) 49 | [colorArray retain]; 50 | #endif 51 | } 52 | for (NSUInteger i = 0; i < [colorArray count]; i++) { 53 | [super addColor:[colorArray colorAtIndex:i]]; 54 | } 55 | 56 | #if !__has_feature(objc_arc) 57 | [colorArray release]; 58 | #endif 59 | 60 | finishedInit = YES; 61 | } 62 | return self; 63 | } 64 | 65 | - (UInt8)addColor:(ANGifColor)aColor { 66 | if (!finishedInit) { 67 | return [super addColor:aColor]; 68 | } 69 | 70 | UInt8 firstIndex = (self.hasTransparentFirst ? 1 : 0); 71 | NSUInteger variance = INT_MAX; 72 | UInt8 selectedColor = firstIndex; 73 | for (NSUInteger i = firstIndex; i < _entryCount; i++) { 74 | ANGifColor color = [self colorAtIndex:i]; 75 | NSUInteger lvariance = ANGifColorVariance(color, aColor); 76 | if (lvariance < variance) { 77 | variance = lvariance; 78 | selectedColor = i; 79 | } 80 | } 81 | 82 | return selectedColor; 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /Classes/GiraffeAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // GiraffeAppDelegate.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 1/20/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "GiraffeAppDelegate.h" 10 | #import "GiraffeViewController.h" 11 | 12 | @implementation GiraffeAppDelegate 13 | 14 | @synthesize window; 15 | @synthesize viewController; 16 | 17 | 18 | #pragma mark - 19 | #pragma mark Application lifecycle 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | 23 | // Override point for customization after application launch. 24 | 25 | // Add the view controller's view to the window and display. 26 | [self.window addSubview:viewController.view]; 27 | [self.window makeKeyAndVisible]; 28 | 29 | return YES; 30 | } 31 | 32 | 33 | - (void)applicationWillResignActive:(UIApplication *)application { 34 | /* 35 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 36 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 37 | */ 38 | } 39 | 40 | 41 | - (void)applicationDidEnterBackground:(UIApplication *)application { 42 | /* 43 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 44 | If your application supports background execution, called instead of applicationWillTerminate: when the user quits. 45 | */ 46 | } 47 | 48 | 49 | - (void)applicationWillEnterForeground:(UIApplication *)application { 50 | /* 51 | Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. 52 | */ 53 | } 54 | 55 | 56 | - (void)applicationDidBecomeActive:(UIApplication *)application { 57 | /* 58 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 59 | */ 60 | } 61 | 62 | 63 | - (void)applicationWillTerminate:(UIApplication *)application { 64 | /* 65 | Called when the application is about to terminate. 66 | See also applicationDidEnterBackground:. 67 | */ 68 | } 69 | 70 | 71 | #pragma mark - 72 | #pragma mark Memory management 73 | 74 | - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { 75 | /* 76 | Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. 77 | */ 78 | } 79 | 80 | 81 | - (void)dealloc { 82 | [viewController release]; 83 | [window release]; 84 | [super dealloc]; 85 | } 86 | 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapCropManipulator.m: -------------------------------------------------------------------------------- 1 | // 2 | // CroppableBitmapRep.m 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "BitmapCropManipulator.h" 10 | 11 | 12 | @implementation BitmapCropManipulator 13 | 14 | - (void)cropFrame:(CGRect)frame { 15 | BMPoint size = [bitmapContext bitmapSize]; 16 | // It's kind of rude to prevent them from doing something kind of cool, so let's not. 17 | // NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap."); 18 | // NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap."); 19 | 20 | CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size]; 21 | CGPoint offset = CGPointMake(-frame.origin.x, -frame.origin.y); 22 | CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]); 23 | [bitmapContext setContext:newBitmap]; 24 | CGContextRelease(newBitmap); 25 | } 26 | 27 | - (void)cropTopFrame:(CGRect)frame { 28 | BMPoint size = [bitmapContext bitmapSize]; 29 | // It's kind of rude to prevent them from doing something kind of cool, so let's not. 30 | // NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap."); 31 | // NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap."); 32 | 33 | CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size]; 34 | CGPoint offset = CGPointMake(-frame.origin.x, -(size.y - (frame.origin.y + frame.size.height))); 35 | CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]); 36 | [bitmapContext setContext:newBitmap]; 37 | CGContextRelease(newBitmap); 38 | } 39 | 40 | - (CGImageRef)croppedImageWithFrame:(CGRect)frame { 41 | BMPoint size = [bitmapContext bitmapSize]; 42 | // It's kind of rude to prevent them from doing something kind of cool, so let's not. 43 | // NSAssert(frame.origin.x >= 0 && frame.origin.x + frame.size.width <= size.x, @"Cropping frame must be within the bitmap."); 44 | // NSAssert(frame.origin.y >= 0 && frame.origin.y + frame.size.height <= size.y, @"Cropping frame must be within the bitmap."); 45 | 46 | CGContextRef newBitmap = [CGContextCreator newARGBBitmapContextWithSize:frame.size]; 47 | CGPoint offset = CGPointMake(-frame.origin.x, -frame.origin.y); 48 | CGContextDrawImage(newBitmap, CGRectMake(offset.x, offset.y, size.x, size.y), [bitmapContext CGImage]); 49 | CGImageRef image = CGBitmapContextCreateImage(newBitmap); 50 | CGContextRelease(newBitmap); 51 | #if __has_feature(objc_arc) == 1 52 | CGImageRef retainedAutorelease = (__bridge CGImageRef)CGImageReturnAutoreleased(image); 53 | CGImageRelease(image); 54 | return retainedAutorelease; 55 | #else 56 | CGImageContainer * container = [CGImageContainer imageContainerWithImage:image]; 57 | CGImageRelease(image); 58 | return [container image]; 59 | #endif 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Giraffe 2 | ======= 3 | 4 | Giraffe is a legacy name for a GIF encoder that I wrote long ago. Now, the GIF encoding library used in this project is ANGif, a much better, more advanced GIF encoder. The soul purpose of this repository is to provide an example of how one might use ANGif in an iOS project. 5 | 6 | Someone with the intention of using ANGif in their project should have a look at both the UIImagePixelSource.m and ExportViewController.m files. These are what use ANGif in conjunction with ANImageBitmapRep to export GIF images on the iPhone. ANGif itself does not require ANImageBitmapRep to work, but my example does require it. 7 | 8 | ANGif Example 9 | ------------- 10 | 11 | Just to give a sense of the easy-to-use ANGif library, here is an example of what encoding an animated GIF could look like: 12 | 13 | ANGifEncoder * encoder = [[ANGifEncoder alloc] initWithOutputFile:@"myFile.gif" size:CGSizeMake(100, 100) globalColorTable:nil]; 14 | [encoder addApplicationExtension:[[ANGifNetscapeAppExtension alloc] init]]; 15 | [encoder addImageFrame:anImageFrame]; 16 | [encoder addImageFrame:anotherImageFrame]; 17 | [encoder closeFile]; 18 | 19 | The addImageFrame: method takes an instance of ANGifImageFrame, which can be created in several different ways. In order to provide a UIImage to work with ANGif, a class must be made that implements the ANGifImageFramePixelSource protocol. In Giraffe, the UIImagePixelSource class is a simple UIImage wrapper that implements this protocol. The ANGifImageFrame object is also what includes the delay time (a.k.a. frame rate). 20 | 21 | License 22 | ======= 23 | 24 | Copyright (c) 2011 Alex Nichol 25 | All rights reserved. 26 | 27 | Redistribution and use in source and binary forms, with or without 28 | modification, are permitted provided that the following conditions 29 | are met: 30 | 1. Redistributions of source code must retain the above copyright 31 | notice, this list of conditions and the following disclaimer. 32 | 2. Redistributions in binary form must reproduce the above copyright 33 | notice, this list of conditions and the following disclaimer in the 34 | documentation and/or other materials provided with the distribution. 35 | 3. The name of the author may not be used to endorse or promote products 36 | derived from this software without specific prior written permission. 37 | 38 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 39 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 40 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 41 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 42 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 44 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 45 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 46 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 47 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 48 | -------------------------------------------------------------------------------- /ANImageBitmapRep/ANImageBitmapRep.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANImageBitmapRep.h 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "OSCommonImage.h" 10 | #import "BitmapScaleManipulator.h" 11 | #import "BitmapCropManipulator.h" 12 | #import "BitmapRotationManipulator.h" 13 | #import "UIImage+ANImageBitmapRep.h" 14 | 15 | typedef struct { 16 | CGFloat red; 17 | CGFloat green; 18 | CGFloat blue; 19 | CGFloat alpha; 20 | } BMPixel; 21 | 22 | BMPixel BMPixelMake (CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha); 23 | #if TARGET_OS_IPHONE 24 | UIColor * UIColorFromBMPixel (BMPixel pixel); 25 | #elif TARGET_OS_MAC 26 | NSColor * NSColorFromBMPixel (BMPixel pixel); 27 | #endif 28 | 29 | @interface ANImageBitmapRep : BitmapContextRep { 30 | #if __has_feature(objc_arc) == 1 31 | __strong NSArray * baseClasses; 32 | #else 33 | NSArray * baseClasses; 34 | #endif 35 | } 36 | 37 | #if __has_feature(objc_arc) == 1 38 | + (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize __attribute__((ns_returns_autoreleased)); 39 | + (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage __attribute__((ns_returns_autoreleased)); 40 | #else 41 | + (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize; 42 | + (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage; 43 | #endif 44 | 45 | /** 46 | * Reverses the RGB values of all pixels in the bitmap. This causes 47 | * an "inverted" effect. 48 | */ 49 | - (void)invertColors; 50 | 51 | /** 52 | * Scales the image down, then back up again. Use this to blur an image. 53 | * @param quality A percentage from 0 to 1, 0 being horrible quality, 1 being 54 | * perfect quality. 55 | */ 56 | - (void)setQuality:(CGFloat)quality; 57 | 58 | /** 59 | * Darken or brighten the image. 60 | * @param brightness A percentage from 0 to 2. In this case, 0 is the darkest 61 | * and 2 is the brightest. If this is 1, no change will be made. 62 | */ 63 | - (void)setBrightness:(CGFloat)brightness; 64 | 65 | /** 66 | * Returns a pixel at a given location. 67 | * @param point The point from which a pixel will be taken. For all points 68 | * in a BitmapContextRep, the x and y values start at 0 and end at 69 | * width - 1 and height - 1 respectively. 70 | * @return The pixel with values taken from the specified point. 71 | */ 72 | - (BMPixel)getPixelAtPoint:(BMPoint)point; 73 | 74 | /** 75 | * Sets a pixel at a specific location. 76 | * @param pixel An RGBA pixel represented by an array of four floats. 77 | * Each component is one float long, and goes from 0 to 1. 78 | * In this case, 0 is black and 1 is white. 79 | * @param point The location of the pixel to change. For all points 80 | * in a BitmapContextRep, the x and y values start at 0 and end at 81 | * width - 1 and height - 1 respectively. 82 | */ 83 | - (void)setPixel:(BMPixel)pixel atPoint:(BMPoint)point; 84 | 85 | /** 86 | * Creates a new UIImage or NSImage from the bitmap context. 87 | */ 88 | #if __has_feature(objc_arc) == 1 89 | - (ANImageObj *)image __attribute__((ns_returns_autoreleased)); 90 | #else 91 | - (ANImageObj *)image; 92 | #endif 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /ANImageBitmapRep/BitmapContextRep.m: -------------------------------------------------------------------------------- 1 | // 2 | // BitmapContextRep.m 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "BitmapContextRep.h" 10 | 11 | BMPoint BMPointMake (long x, long y) { 12 | BMPoint p; 13 | p.x = x; 14 | p.y = y; 15 | return p; 16 | } 17 | 18 | BMPoint BMPointFromSize (CGSize size) { 19 | return BMPointMake(round(size.width), round(size.height)); 20 | } 21 | 22 | BMPoint BMPointFromPoint (CGPoint point) { 23 | return BMPointMake(round(point.x), round(point.y)); 24 | } 25 | 26 | @implementation BitmapContextRep 27 | 28 | - (id)initWithImage:(ANImageObj *)image { 29 | if ((self = [super init])) { 30 | context = [CGContextCreator newARGBBitmapContextWithImage:CGImageFromANImage(image)]; 31 | bitmapData = CGBitmapContextGetData(context); 32 | lastImage = CGBitmapContextCreateImage(context); 33 | } 34 | return self; 35 | } 36 | 37 | - (id)initWithSize:(BMPoint)sizePoint { 38 | if ((self = [super init])) { 39 | context = [CGContextCreator newARGBBitmapContextWithSize:CGSizeMake(sizePoint.x, sizePoint.y)]; 40 | bitmapData = CGBitmapContextGetData(context); 41 | lastImage = CGBitmapContextCreateImage(context); 42 | } 43 | return self; 44 | } 45 | 46 | - (CGContextRef)context { 47 | return context; 48 | } 49 | 50 | - (void)setContext:(CGContextRef)aContext { 51 | if (context == aContext) return; 52 | // free previous. 53 | CGContextRelease(context); 54 | free(bitmapData); 55 | // create new. 56 | context = CGContextRetain(aContext); 57 | bitmapData = CGBitmapContextGetData(aContext); 58 | [self setNeedsUpdate:YES]; 59 | } 60 | 61 | - (BMPoint)bitmapSize { 62 | BMPoint point; 63 | point.x = (long)CGBitmapContextGetWidth(context); 64 | point.y = (long)CGBitmapContextGetHeight(context); 65 | return point; 66 | } 67 | 68 | - (void)setNeedsUpdate:(BOOL)flag { 69 | needsUpdate = flag; 70 | } 71 | 72 | - (void)getRawPixel:(UInt8 *)rgba atPoint:(BMPoint)point { 73 | size_t width = CGBitmapContextGetWidth(context); 74 | size_t height = CGBitmapContextGetHeight(context); 75 | NSAssert(point.x >= 0 || point.x < width, @"Point must be within bitmap."); 76 | NSAssert(point.y >= 0 || point.y < height, @"Point must be within bitmap."); 77 | unsigned char * argbData = &bitmapData[((point.y * width) + point.x) * 4]; 78 | rgba[0] = argbData[1]; // red 79 | rgba[1] = argbData[2]; // green 80 | rgba[2] = argbData[3]; // blue 81 | rgba[3] = argbData[0]; // alpha 82 | [self setNeedsUpdate:YES]; 83 | } 84 | 85 | - (void)setRawPixel:(const UInt8 *)rgba atPoint:(BMPoint)point { 86 | size_t width = CGBitmapContextGetWidth(context); 87 | size_t height = CGBitmapContextGetHeight(context); 88 | NSAssert(point.x >= 0 || point.x < width, @"Point must be within bitmap."); 89 | NSAssert(point.y >= 0 || point.y < height, @"Point must be within bitmap."); 90 | unsigned char * argbData = &bitmapData[((point.y * width) + point.x) * 4]; 91 | argbData[1] = rgba[0]; // red 92 | argbData[2] = rgba[1]; // green 93 | argbData[3] = rgba[2]; // blue 94 | argbData[0] = rgba[3]; // alpha 95 | [self setNeedsUpdate:YES]; 96 | } 97 | 98 | - (CGImageRef)CGImage { 99 | if (needsUpdate) { 100 | CGImageRelease(lastImage); 101 | lastImage = CGBitmapContextCreateImage(context); 102 | needsUpdate = NO; 103 | } 104 | #if __has_feature(objc_arc) == 1 105 | return (__bridge CGImageRef)CGImageReturnAutoreleased(lastImage); 106 | #else 107 | return (CGImageRef)[[CGImageContainer imageContainerWithImage:lastImage] image]; 108 | #endif 109 | } 110 | 111 | - (void)dealloc { 112 | CGContextRelease(context); 113 | free(bitmapData); 114 | if (lastImage != NULL) { 115 | CGImageRelease(lastImage); 116 | } 117 | #if __has_feature(objc_arc) != 1 118 | [super dealloc]; 119 | #endif 120 | } 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /ANImageBitmapRep/BitmapContextRep.h: -------------------------------------------------------------------------------- 1 | // 2 | // BitmapContextRep.h 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "OSCommonImage.h" 10 | #import "CGImageContainer.h" 11 | #import "CGContextCreator.h" 12 | 13 | /** 14 | * A structure that defines a point in bitmap space. 15 | * This is similar to the CGPoint structure, but it 16 | * does not use floating points, making it more accurate. 17 | */ 18 | typedef struct { 19 | long x; 20 | long y; 21 | } BMPoint; 22 | 23 | BMPoint BMPointMake (long x, long y); 24 | BMPoint BMPointFromSize (CGSize size); 25 | BMPoint BMPointFromPoint (CGPoint point); 26 | 27 | /** 28 | * BitmapContextRep is a concrete subclass of NSObject that provides a basic 29 | * class for mutating image's bitmaps. This class is very barebones, 30 | * and generally will not be enough for most image manipulation. 31 | */ 32 | @interface BitmapContextRep : NSObject { 33 | CGContextRef context; 34 | CGImageRef lastImage; 35 | unsigned char * bitmapData; 36 | BOOL needsUpdate; 37 | } 38 | 39 | /** 40 | * Creates a bitmap context with pixels and dimensions from an image. 41 | * @param image The image to wrap in a bitmap context. 42 | */ 43 | - (id)initWithImage:(ANImageObj *)image; 44 | 45 | /** 46 | * Creates a blank bitmap context with specified dimensions. 47 | * @param sizePoint The size to use for the new bitmap. The x value 48 | * of this is used for the width, and the y value is used for height. 49 | */ 50 | - (id)initWithSize:(BMPoint)sizePoint; 51 | 52 | /** 53 | * Returns the bitmap context underlying the image. 54 | */ 55 | - (CGContextRef)context; 56 | 57 | /** 58 | * Replaces the current context with a new one. 59 | * @param aContext The new bitmap context for the image which will be retained 60 | * and released automatically by the BitmapContextRep. 61 | */ 62 | - (void)setContext:(CGContextRef)aContext; 63 | 64 | /** 65 | * Returns the current size of the bitmap. 66 | */ 67 | - (BMPoint)bitmapSize; 68 | 69 | /** 70 | * Tells the BitmapContext that a new image should be generated when 71 | * one is requested because the internal context has been externally 72 | * modified. 73 | * @param needsUpdate This should almost always be YES. If this is no, 74 | * a new CGImageRef will not be generated when one is requested. 75 | */ 76 | - (void)setNeedsUpdate:(BOOL)flag; 77 | 78 | /** 79 | * Returns by reference a 4-byte RGBA pixel at a certain point. 80 | * @param rgba A pointer to a 4-byte or more pixel buffer. 81 | * @param point The point from which a pixel will be read. For all 82 | * points in a BitmapContextRep, the x and y values start at 0 and end 83 | * at width - 1 and height - 1 respectively. 84 | */ 85 | - (void)getRawPixel:(UInt8 *)rgba atPoint:(BMPoint)point; 86 | 87 | /** 88 | * Sets a 4-byte ARGB pixel at a specified point. 89 | * @param rgba The pixel buffer containing at least 4 bytes. 90 | * @param point The point at which the pixel will be set. For all 91 | * points in a BitmapContextRep, the x and y values start at 0 and end 92 | * at width - 1 and height - 1 respectively. 93 | * @discussion Since alpha is premultiplied, it is important to remember to multiply 94 | * the alpha as a percentage by the RGB values. This means that a white pixel 95 | * with 50% alpha would become rgba(128, 128, 128, 128). 96 | */ 97 | - (void)setRawPixel:(const UInt8 *)rgba atPoint:(BMPoint)point; 98 | 99 | /** 100 | * Returns an autoreleased CGImageRef of the current BitmapContext. 101 | */ 102 | - (CGImageRef)CGImage; 103 | 104 | @end 105 | 106 | @protocol BitmapContextRep 107 | 108 | @optional 109 | - (CGContextRef)context; 110 | - (void)setContext:(CGContextRef)aContext; 111 | - (BMPoint)bitmapSize; 112 | - (void)setNeedsUpdate:(BOOL)flag; 113 | - (void)getRawPixel:(UInt8 *)rgba atPoint:(BMPoint)point; 114 | - (void)setRawPixel:(const UInt8 *)rgba atPoint:(BMPoint)point; 115 | - (CGImageRef)CGImage; 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /ANGif/LZW/LZWSpoof.m: -------------------------------------------------------------------------------- 1 | // 2 | // LZWSpoof.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "LZWSpoof.h" 11 | 12 | #define kAllocBufferSize 512 13 | 14 | @implementation LZWSpoof 15 | 16 | @synthesize numBits; 17 | 18 | #pragma mark LZW 19 | 20 | + (NSData *)lzwExpandData:(NSData *)existingData { 21 | LZWSpoof * destinationBuffer = [[LZWSpoof alloc] init]; 22 | LZWSpoof * existingBuffer = [[LZWSpoof alloc] initWithData:existingData]; 23 | 24 | NSUInteger clearCodeCount = 254; 25 | [destinationBuffer addLZWClearCode]; 26 | // loop through every byte, write it, and then write a clear code. 27 | for (NSUInteger byteIndex = 0; byteIndex < [existingData length]; byteIndex++) { 28 | [destinationBuffer addByte:(byteIndex * 8) fromBuffer:existingBuffer]; 29 | [destinationBuffer addBit:NO]; 30 | clearCodeCount--; 31 | if (clearCodeCount == 0) { 32 | [destinationBuffer addLZWClearCode]; 33 | clearCodeCount = 254; 34 | } 35 | } 36 | 37 | // LZW "STOP" directive 38 | [destinationBuffer addBit:YES]; 39 | for (int i = 0; i < 7; i++) { 40 | [destinationBuffer addBit:NO]; 41 | } 42 | [destinationBuffer addBit:YES]; 43 | 44 | #if !__has_feature(objc_arc) 45 | [existingBuffer release]; 46 | NSData * theData = [destinationBuffer convertToData]; 47 | [destinationBuffer release]; 48 | return theData; 49 | #else 50 | return [destinationBuffer convertToData]; 51 | #endif 52 | } 53 | 54 | #pragma mark Bit Buffer 55 | 56 | - (id)initWithData:(NSData *)initialData { 57 | if ((self = [super init])) { 58 | _totalSize = [initialData length]; 59 | _bytePool = (UInt8 *)malloc(_totalSize); 60 | memcpy(_bytePool, (const char *)[initialData bytes], _totalSize); 61 | numBits = _totalSize * 8; 62 | } 63 | return self; 64 | } 65 | 66 | - (id)init { 67 | if ((self = [super init])) { 68 | _totalSize = kAllocBufferSize; 69 | _bytePool = (UInt8 *)malloc(_totalSize); 70 | numBits = 0; 71 | } 72 | return self; 73 | } 74 | 75 | - (void)addBit:(BOOL)flag { 76 | LZWDataAddBit(&_bytePool, &_totalSize, &numBits, flag); 77 | } 78 | 79 | - (BOOL)getBitAtIndex:(NSUInteger)bitIndex { 80 | if (bitIndex >= numBits) { 81 | @throw [NSException exceptionWithName:BitOutOfRangeException 82 | reason:@"The specified bit index is beyond the bounds of the buffer." 83 | userInfo:nil]; 84 | } 85 | return LZWDataGetBit(_bytePool, bitIndex); 86 | } 87 | 88 | #pragma mark LZW Buffer 89 | 90 | - (void)addLZWClearCode { 91 | for (int i = 0; i < 8; i++) { 92 | LZWDataAddBit(&_bytePool, &_totalSize, &numBits, NO); 93 | } 94 | LZWDataAddBit(&_bytePool, &_totalSize, &numBits, YES); 95 | } 96 | 97 | - (void)addByte:(NSUInteger)startBit fromBuffer:(LZWSpoof *)source { 98 | for (NSUInteger bitIndex = startBit; bitIndex < startBit + 8; bitIndex++) { 99 | LZWDataAddBit(&_bytePool, &_totalSize, &numBits, [source getBitAtIndex:bitIndex]); 100 | } 101 | } 102 | 103 | #pragma mark Data 104 | 105 | - (NSData *)convertToData { 106 | NSUInteger numBytes = numBits / 8 + (numBits % 8 == 0 ? 0 : 1); 107 | return [NSData dataWithBytes:_bytePool length:numBytes]; 108 | } 109 | 110 | - (void)dealloc { 111 | free(_bytePool); 112 | #if !__has_feature(objc_arc) 113 | [super dealloc]; 114 | #endif 115 | } 116 | 117 | @end 118 | 119 | void LZWDataAddBit (UInt8 ** _bytePool, NSUInteger * _totalSize, NSUInteger * numBits, BOOL flag) { 120 | NSUInteger endNumber = *numBits + 1; 121 | if (endNumber / 8 + (endNumber % 8 == 0 ? 0 : 1) > *_totalSize) { 122 | *_totalSize += kAllocBufferSize; 123 | *_bytePool = (UInt8 *)realloc(*_bytePool, *_totalSize); 124 | } 125 | NSUInteger byteIndex = (*numBits) / 8; 126 | UInt8 byteMask = (1 << ((*numBits) % 8)); 127 | if (flag) { 128 | (*_bytePool)[byteIndex] |= byteMask; 129 | } else { 130 | (*_bytePool)[byteIndex] &= (0xff ^ byteMask); 131 | } 132 | *numBits += 1; 133 | } 134 | 135 | BOOL LZWDataGetBit (UInt8 * _bytePool, NSUInteger bitIndex) { 136 | NSUInteger byteIndex = bitIndex / 8; 137 | UInt8 byteMask = (1 << (bitIndex % 8)); 138 | return (((_bytePool[byteIndex] & byteMask) == 0) ? NO : YES); 139 | } 140 | -------------------------------------------------------------------------------- /ANImageBitmapRep/CoreGraphics/CGContextCreator.m: -------------------------------------------------------------------------------- 1 | // 2 | // CGContextCreator.m 3 | // ImageBitmapRep 4 | // 5 | // Created by Alex Nichol on 7/4/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "CGContextCreator.h" 10 | 11 | 12 | @implementation CGContextCreator 13 | 14 | - (id)init { 15 | if ((self = [super init])) { 16 | // Initialization code here. 17 | } 18 | 19 | return self; 20 | } 21 | 22 | + (CGContextRef)newARGBBitmapContextWithSize:(CGSize)size { 23 | CGContextRef context = NULL; 24 | CGColorSpaceRef colorSpace; 25 | void * bitmapData; 26 | int bitmapByteCount; 27 | int bitmapBytesPerRow; 28 | 29 | // Get image width, height. We'll use the entire image. 30 | size_t pixelsWide = round(size.width); 31 | size_t pixelsHigh = round(size.height); 32 | 33 | bitmapBytesPerRow = (int)(pixelsWide * 4); 34 | bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh); 35 | 36 | // Use the generic RGB color space. 37 | colorSpace = CGColorSpaceCreateDeviceRGB(); 38 | if (colorSpace == NULL) { 39 | fprintf(stderr, "Error allocating color space\n"); 40 | return NULL; 41 | } 42 | 43 | // allocate 44 | bitmapData = malloc(bitmapByteCount); 45 | if (bitmapData == NULL) { 46 | NSLog(@"Malloc failed which is too bad. I was hoping to use this memory."); 47 | CGColorSpaceRelease(colorSpace); 48 | // even though CGContextRef technically is not a pointer, 49 | // it's typedef probably is and it is a scalar anyway. 50 | return NULL; 51 | } 52 | 53 | // Create the bitmap context. We are 54 | // setting up the image as an ARGB (0-255 per component) 55 | // 4-byte per/pixel. 56 | context = CGBitmapContextCreate (bitmapData, 57 | pixelsWide, 58 | pixelsHigh, 59 | 8, 60 | bitmapBytesPerRow, 61 | colorSpace, 62 | kCGImageAlphaPremultipliedFirst); 63 | if (context == NULL) { 64 | free (bitmapData); 65 | NSLog(@"Failed to create bitmap!"); 66 | } 67 | 68 | CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height)); 69 | CGColorSpaceRelease(colorSpace); 70 | 71 | return context; 72 | } 73 | 74 | + (CGContextRef)newARGBBitmapContextWithImage:(CGImageRef)image { 75 | CGContextRef context = NULL; 76 | CGColorSpaceRef colorSpace; 77 | void * bitmapData; 78 | int bitmapByteCount; 79 | int bitmapBytesPerRow; 80 | 81 | // Get image width, height. We'll use the entire image. 82 | size_t pixelsWide = CGImageGetWidth(image); 83 | size_t pixelsHigh = CGImageGetHeight(image); 84 | 85 | bitmapBytesPerRow = (int)(pixelsWide * 4); 86 | bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh); 87 | 88 | // Use the generic RGB color space. 89 | colorSpace = CGColorSpaceCreateDeviceRGB(); 90 | if (colorSpace == NULL) { 91 | fprintf(stderr, "Error allocating color space\n"); 92 | return NULL; 93 | } 94 | 95 | // allocate 96 | bitmapData = malloc(bitmapByteCount); 97 | if (bitmapData == NULL) { 98 | NSLog(@"Malloc failed which is too bad. I was hoping to use this memory."); 99 | CGColorSpaceRelease(colorSpace); 100 | // even though CGContextRef technically is not a pointer, 101 | // it's typedef probably is and it is a scalar anyway. 102 | return NULL; 103 | } 104 | 105 | // Create the bitmap context. We are 106 | // setting up the image as an ARGB (0-255 per component) 107 | // 4-byte per/pixel. 108 | context = CGBitmapContextCreate (bitmapData, 109 | pixelsWide, 110 | pixelsHigh, 111 | 8, // bits per component 112 | bitmapBytesPerRow, 113 | colorSpace, 114 | kCGImageAlphaPremultipliedFirst); 115 | if (context == NULL) { 116 | free (bitmapData); 117 | NSLog(@"Failed to create bitmap!"); 118 | } 119 | 120 | // draw the image on the context. 121 | // CGContextTranslateCTM(context, 0, CGImageGetHeight(image)); 122 | // CGContextScaleCTM(context, 1.0, -1.0); 123 | CGContextClearRect(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image))); 124 | CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); 125 | 126 | CGColorSpaceRelease(colorSpace); 127 | 128 | return context; 129 | } 130 | 131 | #if __has_feature(objc_arc) != 1 132 | - (void)dealloc { 133 | [super dealloc]; 134 | } 135 | #endif 136 | 137 | @end 138 | -------------------------------------------------------------------------------- /ANGif/ANGifEncoder.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifEncoder.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANGifEncoder.h" 11 | 12 | @implementation ANGifEncoder 13 | 14 | - (id)initWithFileHandle:(NSFileHandle *)handle size:(CGSize)aSize 15 | globalColorTable:(ANColorTable *)gct { 16 | if ((self = [super init])) { 17 | if (!handle) return nil; 18 | #if __has_feature(objc_arc) 19 | globalColorTable = gct; 20 | fileHandle = handle; 21 | #else 22 | globalColorTable = [gct retain]; 23 | fileHandle = [handle retain]; 24 | #endif 25 | screenWidth = round(aSize.width); 26 | screenHeight = round(aSize.height); 27 | 28 | [handle writeData:[NSData dataWithBytes:kGifHeader length:strlen(kGifHeader)]]; 29 | 30 | // logical screen descriptor 31 | ANGifLogicalScreenDesc * screenDesc = [[ANGifLogicalScreenDesc alloc] init]; 32 | screenDesc.screenWidth = (UInt16)screenWidth; 33 | screenDesc.screenHeight = (UInt16)screenHeight; 34 | if (gct) { 35 | screenDesc.globalColorTable = YES; 36 | screenDesc.gctSize = 7; 37 | } 38 | [handle writeData:[screenDesc encodeBlock]]; 39 | #if !__has_feature(objc_arc) 40 | [screenDesc release]; 41 | #endif 42 | 43 | if (gct) { 44 | // write blank GCT, which will be re-written when the file 45 | // is closed 46 | gctOffset = [handle offsetInFile]; 47 | [handle writeData:[gct encodeRawColorTableCount:256]]; 48 | } 49 | } 50 | return self; 51 | } 52 | 53 | - (id)initWithOutputFile:(NSString *)fileName size:(CGSize)aSize 54 | globalColorTable:(ANColorTable *)gct { 55 | if (![[NSFileManager defaultManager] fileExistsAtPath:fileName]) { 56 | [[NSFileManager defaultManager] createFileAtPath:fileName contents:[NSData data] attributes:nil]; 57 | } 58 | self = [self initWithFileHandle:[NSFileHandle fileHandleForWritingAtPath:fileName] 59 | size:aSize globalColorTable:gct]; 60 | return self; 61 | } 62 | 63 | - (void)addApplicationExtension:(ANGifAppExtension *)ext { 64 | [fileHandle writeData:[ext encodeBlock]]; 65 | } 66 | 67 | - (void)addImageFrame:(ANGifImageFrame *)imageFrame { 68 | ANColorTable * colorTable = nil; 69 | NSData * imageData; 70 | 71 | if ([imageFrame localColorTable]) { 72 | colorTable = imageFrame.localColorTable; 73 | } else { 74 | colorTable = globalColorTable; 75 | } 76 | if (!colorTable) { 77 | #if __has_feature(objc_arc) 78 | imageFrame.localColorTable = [[ANAvgColorTable alloc] init]; 79 | #else 80 | imageFrame.localColorTable = [[[ANAvgColorTable alloc] init] autorelease]; 81 | #endif 82 | colorTable = imageFrame.localColorTable; 83 | } 84 | 85 | // - graphics control extension 86 | 87 | ANGifGraphicControlExt * gfxControl = [[ANGifGraphicControlExt alloc] init]; 88 | gfxControl.delayTime = imageFrame.delayTime; 89 | gfxControl.userInputFlag = NO; 90 | gfxControl.transparentColorFlag = [colorTable hasTransparentFirst]; 91 | gfxControl.transparentColorIndex = [colorTable transparentIndex]; 92 | [fileHandle writeData:[gfxControl encodeBlock]]; 93 | #if !__has_feature(objc_arc) 94 | [gfxControl release]; 95 | #endif 96 | 97 | // - image descriptor 98 | 99 | // calculate image data and re-arrange color table 100 | imageData = [imageFrame encodeImageUsingColorTable:colorTable]; 101 | 102 | ANGifImageDescriptor * descriptor = [[ANGifImageDescriptor alloc] initWithImageFrame:imageFrame]; 103 | [fileHandle writeData:[descriptor encodeBlock]]; 104 | #if !__has_feature(objc_arc) 105 | [descriptor release]; 106 | #endif 107 | 108 | // - local color table 109 | if (imageFrame.localColorTable) { 110 | // [colorTable sortByPriority]; 111 | [fileHandle writeData:[colorTable encodeRawColorTable]]; 112 | } 113 | 114 | // - and image itself 115 | UInt8 lzwSize = 8; 116 | [fileHandle writeData:[NSData dataWithBytes:&lzwSize length:1]]; 117 | 118 | NSData * lzwCompressed = [LZWSpoof lzwExpandData:imageData]; 119 | NSArray * imageBlocks = [ANGifDataSubblock dataSubblocksForData:lzwCompressed]; 120 | for (ANGifDataSubblock * subblock in imageBlocks) { 121 | [subblock writeToFileHandle:fileHandle]; 122 | } 123 | 124 | lzwSize = 0; 125 | [fileHandle writeData:[NSData dataWithBytes:&lzwSize length:1]]; // NULL terminator 126 | } 127 | 128 | - (void)finishDataStream { 129 | // write gif trailer 130 | [fileHandle writeData:[NSData dataWithBytes:kGifTrailer length:1]]; 131 | // rewrite GCT 132 | if (globalColorTable) { 133 | // [globalColorTable sortByPriority]; 134 | [fileHandle seekToFileOffset:gctOffset]; 135 | [fileHandle writeData:[globalColorTable encodeRawColorTableCount:256]]; 136 | } 137 | } 138 | 139 | - (void)closeFile { 140 | [self finishDataStream]; 141 | [fileHandle closeFile]; 142 | #if !__has_feature(objc_arc) 143 | [fileHandle release]; 144 | #endif 145 | fileHandle = nil; 146 | } 147 | 148 | #if !__has_feature(objc_arc) 149 | 150 | - (void)dealloc { 151 | [globalColorTable release]; 152 | [fileHandle release]; 153 | [super dealloc]; 154 | } 155 | 156 | #endif 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /ANGif/ColorTable/Cut/ANMutableColorArray.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANMutableColorArray.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/2/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANMutableColorArray.h" 11 | #define kColorBufferSize 256 12 | 13 | int CompareColorQSort (const void * ent1, const void * ent2); 14 | 15 | @implementation ANMutableColorArray 16 | 17 | - (id)init { 18 | if ((self = [super init])) { 19 | _colors = (ANGifColor *)malloc(sizeof(ANGifColor) * kColorBufferSize); 20 | _totalAlloced = kColorBufferSize; 21 | } 22 | return self; 23 | } 24 | 25 | - (NSUInteger)count { 26 | return _entryCount; 27 | } 28 | 29 | - (void)addColor:(ANGifColor)color { 30 | for (NSUInteger i = 0; i < _entryCount; i++) { 31 | ANGifColor aColor = [self colorAtIndex:i]; 32 | if (ANGifColorVariance(color, aColor) < 5) return; 33 | } 34 | if (_entryCount + 1 == _totalAlloced) { 35 | _totalAlloced += kColorBufferSize; 36 | _colors = (ANGifColor *)realloc(_colors, sizeof(ANGifColor) * _totalAlloced); 37 | } 38 | _colors[_entryCount++] = color; 39 | } 40 | 41 | - (void)removeAtIndex:(NSUInteger)index { 42 | NSUInteger assignIndex = 0; 43 | for (NSUInteger i = 0; i < _entryCount; i++) { 44 | if (i != index) { 45 | _colors[assignIndex++] = _colors[i]; 46 | } 47 | } 48 | _entryCount = assignIndex; 49 | if (_totalAlloced - kColorBufferSize >= _entryCount && _totalAlloced > kColorBufferSize) { 50 | _totalAlloced -= kColorBufferSize; 51 | _colors = (ANGifColor *)realloc(_colors, sizeof(ANGifColor) * _totalAlloced); 52 | } 53 | } 54 | 55 | - (ANGifColor)colorAtIndex:(NSUInteger)index { 56 | if (index >= _entryCount) { 57 | @throw [NSException exceptionWithName:ANGifColorIndexOutOfBoundsException 58 | reason:@"The specified color index is beyond the bounds of the array." 59 | userInfo:nil]; 60 | } 61 | return _colors[index]; 62 | } 63 | 64 | #pragma mark Averaging 65 | 66 | - (void)sortByBrightness { 67 | qsort(_colors, _entryCount, sizeof(ANGifColor), CompareColorQSort); 68 | } 69 | 70 | - (ANMutableColorArray *)colorArrayByAveragingSplit:(NSUInteger)numColors { 71 | ANMutableColorArray * newArray = [[ANMutableColorArray alloc] init]; 72 | 73 | // calculate number of colors per sector 74 | NSUInteger colorsPerSect = _entryCount / numColors; 75 | NSUInteger colorsRemaining = _entryCount % numColors; 76 | NSUInteger startIndex = 0; 77 | 78 | for (NSUInteger i = 0; i < numColors; i++) { 79 | NSUInteger size = colorsPerSect; 80 | if (colorsRemaining > 0) { 81 | size += 1; 82 | colorsRemaining--; 83 | } 84 | 85 | if (size == 0) break; 86 | 87 | double red = 0, green = 0, blue = 0; 88 | 89 | // average colors 90 | for (NSUInteger j = startIndex; j < startIndex + size; j++) { 91 | ANGifColor aColor = _colors[j]; 92 | red += (double)aColor.red; 93 | green += (double)aColor.green; 94 | blue += (double)aColor.blue; 95 | } 96 | 97 | red /= (double)size; 98 | green /= (double)size; 99 | blue /= (double)size; 100 | 101 | ANGifColor genColor = ANGifColorMake((UInt8)red, (UInt8)green, (UInt8)blue); 102 | [newArray addColor:genColor]; 103 | 104 | startIndex += size; 105 | } 106 | #if __has_feature(objc_arc) 107 | return newArray; 108 | #else 109 | return [newArray autorelease]; 110 | #endif 111 | } 112 | 113 | - (void)removeDuplicates { 114 | return; 115 | for (NSUInteger i = 0; i < _entryCount; i++) { 116 | ANGifColor currentColor = _colors[i]; 117 | for (NSUInteger j = i + 1; j < _entryCount; j++) { 118 | ANGifColor anotherColor = _colors[j]; 119 | if (ANGifColorIsEqual(currentColor, anotherColor)) { 120 | [self removeAtIndex:j]; 121 | j--; 122 | } 123 | } 124 | } 125 | } 126 | 127 | - (ANGifColor)averagePopFirst { 128 | if (_entryCount == 1) { 129 | ANGifColor color = [self colorAtIndex:0]; 130 | [self removeAtIndex:0]; 131 | return color; 132 | } 133 | NSUInteger bestFit = 1; 134 | NSUInteger variance = 255*3; 135 | ANGifColor firstColor = [self colorAtIndex:0]; 136 | 137 | for (NSUInteger i = 1; i < _entryCount; i++) { 138 | ANGifColor color = [self colorAtIndex:i]; 139 | NSUInteger lvariance = ANGifColorVariance(firstColor, color); 140 | if (lvariance < variance) { 141 | bestFit = i; 142 | variance = lvariance; 143 | if (variance == 0) { 144 | break; 145 | } 146 | } 147 | } 148 | 149 | ANGifColor selectedColor = [self colorAtIndex:bestFit]; 150 | [self removeAtIndex:bestFit]; 151 | [self removeAtIndex:0]; 152 | return ANGifColorAverage(selectedColor, firstColor); 153 | } 154 | 155 | #pragma mark Memory Management 156 | 157 | - (void)dealloc { 158 | free(_colors); 159 | #if !__has_feature(objc_arc) 160 | [super dealloc]; 161 | #endif 162 | } 163 | 164 | @end 165 | 166 | int CompareColorQSort (const void * ent1, const void * ent2) { 167 | ANGifColor * color1 = (ANGifColor *)ent1; 168 | ANGifColor * color2 = (ANGifColor *)ent2; 169 | return ((int)(color1->red + color1->green + color1->blue) - 170 | (int)(color2->red + color2->green + color2->blue)); 171 | } 172 | -------------------------------------------------------------------------------- /ANGif/ColorTable/ANColorTable.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANGifColorTable.m 3 | // GifPro 4 | // 5 | // Created by Alex Nichol on 11/1/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | // Converted to Non-ARC 11/4/11 9 | 10 | #import "ANColorTable.h" 11 | 12 | @implementation ANColorTable 13 | 14 | @synthesize maxColors; 15 | @synthesize hasTransparentFirst; 16 | 17 | - (id)initWithTransparentFirst:(BOOL)transparentFirst { 18 | if ((self = [self init])) { 19 | ANGifColor myColor; 20 | myColor.red = 0; 21 | myColor.green = 0; 22 | myColor.blue = 0; 23 | [self addColor:myColor]; 24 | hasTransparentFirst = transparentFirst; 25 | } 26 | return self; 27 | } 28 | 29 | - (id)init { 30 | if ((self = [super init])) { 31 | _entries = (ANGifColorTableEntry *)malloc(sizeof(ANGifColorTableEntry)); 32 | _totalAlloced = 1; 33 | maxColors = 256; 34 | } 35 | return self; 36 | } 37 | 38 | - (NSUInteger)numberOfEntries { 39 | return _entryCount; 40 | } 41 | 42 | - (void)setColor:(ANGifColor)color atIndex:(UInt8)index { 43 | if (index >= _entryCount) { 44 | @throw [NSException exceptionWithName:ANGifColorIndexOutOfBoundsException 45 | reason:@"The specified color index was beyond the bounds of the color table." 46 | userInfo:nil]; 47 | } 48 | _entries[index].color = color; 49 | _entries[index].priority = 1; 50 | } 51 | 52 | - (UInt8)addColor:(ANGifColor)aColor { 53 | for (NSUInteger i = (self.hasTransparentFirst ? 1 : 0); i < _entryCount; i++) { 54 | if (ANGifColorIsEqual(_entries[i].color, aColor)) { 55 | _entries[i].priority += 1; 56 | return (UInt8)i; 57 | } 58 | } 59 | if (_entryCount >= maxColors) { 60 | @throw [NSException exceptionWithName:ANGifColorTableFullException reason:nil userInfo:nil]; 61 | } 62 | if (_entryCount == _totalAlloced) { 63 | _totalAlloced += 3; 64 | if (_totalAlloced > maxColors) _totalAlloced = maxColors; 65 | _entries = (ANGifColorTableEntry *)realloc(_entries, sizeof(ANGifColorTableEntry) * _totalAlloced); 66 | } 67 | _entries[_entryCount].color = aColor; 68 | _entries[_entryCount].priority = 1; 69 | return _entryCount++; 70 | } 71 | 72 | - (ANGifColor)colorAtIndex:(UInt8)index { 73 | if (index >= _entryCount) { 74 | @throw [NSException exceptionWithName:ANGifColorIndexOutOfBoundsException 75 | reason:@"The specified color index was beyond the bounds of the color table." 76 | userInfo:nil]; 77 | } 78 | return _entries[index].color; 79 | } 80 | 81 | - (UInt8)transparentIndex { 82 | return 0; 83 | } 84 | 85 | - (void)dealloc { 86 | free(_entries); 87 | #if !__has_feature(objc_arc) 88 | [super dealloc]; 89 | #endif 90 | } 91 | 92 | #pragma mark - Sorting - 93 | 94 | - (void)sortByPriority { 95 | while ([self singleSortStep]); 96 | } 97 | 98 | - (BOOL)singleSortStep { 99 | if (_entryCount == (self.hasTransparentFirst ? 1 : 0)) return NO; 100 | ANGifColorTableEntry lastEntry = _entries[(self.hasTransparentFirst ? 1 : 0)]; 101 | for (NSUInteger i = (self.hasTransparentFirst ? 2 : 1); i < _entryCount; i++) { 102 | ANGifColorTableEntry entry = _entries[i]; 103 | if (entry.priority > lastEntry.priority) { 104 | // swap order 105 | _entries[i] = lastEntry; 106 | _entries[i - 1] = entry; 107 | return YES; 108 | } 109 | lastEntry = entry; 110 | } 111 | return NO; 112 | } 113 | 114 | #pragma mark Encoding 115 | 116 | - (UInt8)colorTableSizeValue { 117 | for (NSUInteger x = 0; x < 8; x++) { 118 | // test the value 119 | NSUInteger countValue = 1 << (x + 1); 120 | if (countValue >= _entryCount) { 121 | return x; 122 | } 123 | } 124 | return 7; 125 | } 126 | 127 | - (NSData *)encodeRawColorTable { 128 | UInt8 tableSize = [self colorTableSizeValue]; 129 | NSUInteger numEntries = 1 << ((NSUInteger)tableSize + 1); 130 | return [self encodeRawColorTableCount:numEntries]; 131 | } 132 | 133 | - (NSData *)encodeRawColorTableCount:(NSUInteger)numEntries { 134 | NSMutableData * encoded = [NSMutableData data]; 135 | 136 | UInt8 byte; 137 | for (NSUInteger i = 0; i < numEntries; i++) { 138 | if (i >= _entryCount) { 139 | // add empty entry 140 | byte = 0; 141 | [encoded appendBytes:&byte length:1]; 142 | [encoded appendBytes:&byte length:1]; 143 | [encoded appendBytes:&byte length:1]; 144 | } else { 145 | ANGifColor color = [self colorAtIndex:(UInt8)i]; 146 | [encoded appendBytes:&color.red length:1]; 147 | [encoded appendBytes:&color.green length:1]; 148 | [encoded appendBytes:&color.blue length:1]; 149 | } 150 | } 151 | 152 | return [NSData dataWithData:encoded]; 153 | } 154 | 155 | @end 156 | 157 | BOOL ANGifColorIsEqual (ANGifColor color1, ANGifColor color2) { 158 | if (color1.red == color2.red && color1.green == color2.green && color1.blue == color2.blue) { 159 | return YES; 160 | } 161 | return NO; 162 | } 163 | 164 | NSUInteger ANGifColorVariance (ANGifColor color1, ANGifColor color2) { 165 | NSUInteger v = 0; 166 | v += abs((int)color1.red - (int)color2.red); 167 | v += abs((int)color1.green - (int)color2.green); 168 | v += abs((int)color1.blue - (int)color2.blue); 169 | return v; 170 | } 171 | 172 | ANGifColor ANGifColorAverage (ANGifColor color1, ANGifColor color2) { 173 | ANGifColor median; 174 | median.red = (UInt8)round(((double)color1.red + (double)color2.red) / 2.0); 175 | median.green = (UInt8)round(((double)color1.green + (double)color2.green) / 2.0); 176 | median.blue = (UInt8)round(((double)color1.blue + (double)color2.blue) / 2.0); 177 | return median; 178 | } 179 | 180 | ANGifColor ANGifColorMake (UInt8 red, UInt8 green, UInt8 blue) { 181 | ANGifColor color; 182 | color.red = red; 183 | color.green = green; 184 | color.blue = blue; 185 | return color; 186 | } 187 | -------------------------------------------------------------------------------- /ANImageBitmapRep/ANImageBitmapRep.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANImageBitmapRep.m 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ANImageBitmapRep.h" 10 | 11 | BMPixel BMPixelMake (CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) { 12 | BMPixel pixel; 13 | pixel.red = red; 14 | pixel.green = green; 15 | pixel.blue = blue; 16 | pixel.alpha = alpha; 17 | return pixel; 18 | } 19 | 20 | #if TARGET_OS_IPHONE 21 | UIColor * UIColorFromBMPixel (BMPixel pixel) { 22 | return [UIColor colorWithRed:pixel.red green:pixel.green blue:pixel.blue alpha:pixel.alpha]; 23 | } 24 | #elif TARGET_OS_MAC 25 | NSColor * NSColorFromBMPixel (BMPixel pixel) { 26 | return [NSColor colorWithCalibratedRed:pixel.red green:pixel.green blue:pixel.blue alpha:pixel.alpha]; 27 | } 28 | #endif 29 | 30 | @interface ANImageBitmapRep (BaseClasses) 31 | 32 | - (void)generateBaseClasses; 33 | 34 | @end 35 | 36 | @implementation ANImageBitmapRep 37 | 38 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 39 | if (!baseClasses) [self generateBaseClasses]; 40 | for (int i = 0; i < [baseClasses count]; i++) { 41 | BitmapContextManipulator * manip = [baseClasses objectAtIndex:i]; 42 | if ([manip respondsToSelector:[anInvocation selector]]) { 43 | [anInvocation invokeWithTarget:manip]; 44 | return; 45 | } 46 | } 47 | [self doesNotRecognizeSelector:[anInvocation selector]]; 48 | } 49 | 50 | #if __has_feature(objc_arc) == 1 51 | + (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize { 52 | return [[ANImageBitmapRep alloc] initWithSize:BMPointMake(round(avgSize.width), round(avgSize.height))]; 53 | } 54 | 55 | + (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage { 56 | return [[ANImageBitmapRep alloc] initWithImage:anImage]; 57 | } 58 | #else 59 | + (ANImageBitmapRep *)imageBitmapRepWithCGSize:(CGSize)avgSize { 60 | return [[[ANImageBitmapRep alloc] initWithSize:BMPointMake(round(avgSize.width), round(avgSize.height))] autorelease]; 61 | } 62 | 63 | + (ANImageBitmapRep *)imageBitmapRepWithImage:(ANImageObj *)anImage { 64 | return [[[ANImageBitmapRep alloc] initWithImage:anImage] autorelease]; 65 | } 66 | #endif 67 | 68 | - (void)invertColors { 69 | UInt8 pixel[4]; 70 | BMPoint size = [self bitmapSize]; 71 | for (long y = 0; y < size.y; y++) { 72 | for (long x = 0; x < size.x; x++) { 73 | [self getRawPixel:pixel atPoint:BMPointMake(x, y)]; 74 | pixel[0] = 255 - pixel[0]; 75 | pixel[1] = 255 - pixel[1]; 76 | pixel[2] = 255 - pixel[2]; 77 | [self setRawPixel:pixel atPoint:BMPointMake(x, y)]; 78 | } 79 | } 80 | } 81 | 82 | - (void)setQuality:(CGFloat)quality { 83 | NSAssert(quality >= 0 && quality <= 1, @"Quality must be between 0 and 1."); 84 | if (quality == 1.0) return; 85 | CGSize cSize = CGSizeMake((CGFloat)([self bitmapSize].x) * quality, (CGFloat)([self bitmapSize].y) * quality); 86 | BMPoint oldSize = [self bitmapSize]; 87 | [self setSize:BMPointMake(round(cSize.width), round(cSize.height))]; 88 | [self setSize:oldSize]; 89 | } 90 | 91 | - (void)setBrightness:(CGFloat)brightness { 92 | NSAssert(brightness >= 0 && brightness <= 2, @"Brightness must be between 0 and 2."); 93 | BMPoint size = [self bitmapSize]; 94 | for (long y = 0; y < size.y; y++) { 95 | for (long x = 0; x < size.x; x++) { 96 | BMPoint point = BMPointMake(x, y); 97 | BMPixel pixel = [self getPixelAtPoint:point]; 98 | pixel.red *= brightness; 99 | pixel.green *= brightness; 100 | pixel.blue *= brightness; 101 | if (pixel.red > 1) pixel.red = 1; 102 | if (pixel.green > 1) pixel.green = 1; 103 | if (pixel.blue > 1) pixel.blue = 1; 104 | [self setPixel:pixel atPoint:point]; 105 | } 106 | } 107 | } 108 | 109 | - (BMPixel)getPixelAtPoint:(BMPoint)point { 110 | UInt8 rawPixel[4]; 111 | [self getRawPixel:rawPixel atPoint:point]; 112 | BMPixel pixel; 113 | pixel.alpha = (CGFloat)(rawPixel[3]) / 255.0; 114 | pixel.red = ((CGFloat)(rawPixel[0]) / 255.0) / pixel.alpha; 115 | pixel.green = ((CGFloat)(rawPixel[1]) / 255.0) / pixel.alpha; 116 | pixel.blue = ((CGFloat)(rawPixel[2]) / 255.0) / pixel.alpha; 117 | return pixel; 118 | } 119 | 120 | - (void)setPixel:(BMPixel)pixel atPoint:(BMPoint)point { 121 | NSAssert(pixel.red >= 0 && pixel.red <= 1, @"Pixel color must range from 0 to 1."); 122 | NSAssert(pixel.green >= 0 && pixel.green <= 1, @"Pixel color must range from 0 to 1."); 123 | NSAssert(pixel.blue >= 0 && pixel.blue <= 1, @"Pixel color must range from 0 to 1."); 124 | NSAssert(pixel.alpha >= 0 && pixel.alpha <= 1, @"Pixel color must range from 0 to 1."); 125 | UInt8 rawPixel[4]; 126 | rawPixel[0] = round(pixel.red * 255.0 * pixel.alpha); 127 | rawPixel[1] = round(pixel.green * 255.0 * pixel.alpha); 128 | rawPixel[2] = round(pixel.blue * 255.0 * pixel.alpha); 129 | rawPixel[3] = round(pixel.alpha * 255.0); 130 | [self setRawPixel:rawPixel atPoint:point]; 131 | } 132 | 133 | - (ANImageObj *)image { 134 | return ANImageFromCGImage([self CGImage]); 135 | } 136 | 137 | #if __has_feature(objc_arc) != 1 138 | - (void)dealloc { 139 | [baseClasses release]; 140 | [super dealloc]; 141 | } 142 | #endif 143 | 144 | #pragma mark Base Classes 145 | 146 | - (void)generateBaseClasses { 147 | BitmapCropManipulator * croppable = [[BitmapCropManipulator alloc] initWithContext:self]; 148 | BitmapScaleManipulator * scalable = [[BitmapScaleManipulator alloc] initWithContext:self]; 149 | BitmapRotationManipulator * rotatable = [[BitmapRotationManipulator alloc] initWithContext:self]; 150 | baseClasses = [[NSArray alloc] initWithObjects:croppable, scalable, rotatable, nil]; 151 | #if __has_feature(objc_arc) != 1 152 | [rotatable release]; 153 | [scalable release]; 154 | [croppable release]; 155 | #endif 156 | } 157 | 158 | #pragma mark NSCopying 159 | 160 | - (id)copyWithZone:(NSZone *)zone { 161 | BMPoint size = [self bitmapSize]; 162 | ANImageBitmapRep * rep = [[ANImageBitmapRep allocWithZone:zone] initWithSize:size]; 163 | CGContextRef newContext = [rep context]; 164 | CGContextDrawImage(newContext, CGRectMake(0, 0, size.x, size.y), [self CGImage]); 165 | [rep setNeedsUpdate:YES]; 166 | return rep; 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /Classes/ExportViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExportViewController.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 11/5/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "ExportViewController.h" 10 | 11 | @interface ExportViewController (Background) 12 | 13 | - (void)setProgressLabel:(NSString *)label; 14 | - (void)setProgressPercent:(NSNumber *)percent; 15 | - (void)informCallbackDone:(NSString *)file; 16 | 17 | - (void)exportThread:(NSString *)fileOutput; 18 | - (ANGifImageFrame *)imageFrameWithImage:(UIImage *)anImage fitting:(CGSize)imageSize; 19 | 20 | @end 21 | 22 | @implementation ExportViewController 23 | 24 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 25 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 26 | if (self) { 27 | // Custom initialization 28 | } 29 | return self; 30 | } 31 | 32 | - (id)initWithImages:(NSArray *)imageArray { 33 | if ((self = [super init])) { 34 | #if __has_feature(objc_arc) 35 | images = imageArray; 36 | #else 37 | images = [imageArray retain]; 38 | #endif 39 | self.view.backgroundColor = [UIColor whiteColor]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)encodeToFile:(NSString *)fileName callback:(void (^)(NSString * file))callback { 45 | #if __has_feature(objc_arc) 46 | doneCallback = callback; 47 | #else 48 | if (doneCallback) Block_release(doneCallback); 49 | doneCallback = Block_copy(callback); 50 | #endif 51 | [NSThread detachNewThreadSelector:@selector(exportThread:) toTarget:self withObject:fileName]; 52 | } 53 | 54 | #pragma mark - View lifecycle - 55 | 56 | - (void)didReceiveMemoryWarning { 57 | // Releases the view if it doesn't have a superview. 58 | [super didReceiveMemoryWarning]; 59 | 60 | // Release any cached data, images, etc that aren't in use. 61 | } 62 | 63 | // Implement loadView to create a view hierarchy programmatically, without using a nib. 64 | - (void)loadView { 65 | [super loadView]; 66 | // progressStatus, progressView 67 | progressStatus = [[UILabel alloc] initWithFrame:CGRectMake(10, 120, 300, 20)]; 68 | progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(10, 160, 300, 20)]; 69 | [progressStatus setBackgroundColor:[UIColor clearColor]]; 70 | [progressStatus setTextAlignment:UITextAlignmentCenter]; 71 | [self.view addSubview:progressStatus]; 72 | [self.view addSubview:progressView]; 73 | } 74 | 75 | /* 76 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 77 | - (void)viewDidLoad { 78 | [super viewDidLoad]; 79 | } 80 | */ 81 | 82 | - (void)viewDidUnload { 83 | [super viewDidUnload]; 84 | // Release any retained subviews of the main view. 85 | // e.g. self.myOutlet = nil; 86 | } 87 | 88 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 89 | // Return YES for supported orientations 90 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 91 | } 92 | 93 | #pragma mark - Background Thread - 94 | 95 | - (void)exportThread:(NSString *)fileOutput { 96 | @autoreleasepool { 97 | // statements here 98 | [self setProgressLabel:@"Opening file ..."]; 99 | [self setProgressPercent:[NSNumber numberWithFloat:0]]; 100 | UIImage * firstImage = nil; 101 | if ([images count] > 0) { 102 | firstImage = [images objectAtIndex:0]; 103 | } 104 | CGSize canvasSize = (firstImage ? firstImage.size : CGSizeZero); 105 | ANGifEncoder * encoder = [[ANGifEncoder alloc] initWithOutputFile:fileOutput size:canvasSize globalColorTable:nil]; 106 | ANGifNetscapeAppExtension * extension = [[ANGifNetscapeAppExtension alloc] init]; 107 | [encoder addApplicationExtension:extension]; 108 | #if !__has_feature(objc_arc) 109 | [extension release]; 110 | #endif 111 | [self setProgressLabel:@"Writing frames ..."]; 112 | [self setProgressPercent:[NSNumber numberWithFloat:0.1]]; 113 | float numberOfFrames = (float)[images count]; 114 | for (int i = 0; i < [images count]; i++) { 115 | float progress = 0.1 + ((0.9 / (float)numberOfFrames) * (float)i); 116 | [self setProgressPercent:[NSNumber numberWithFloat:progress]]; 117 | [self setProgressLabel:[NSString stringWithFormat:@"Resizing Frame (%d/%d)", i + 1, (int)[images count]]]; 118 | UIImage * image = [images objectAtIndex:i]; 119 | ANGifImageFrame * theFrame = [self imageFrameWithImage:image fitting:canvasSize]; 120 | [self setProgressLabel:[NSString stringWithFormat:@"Encoding Frame (%d/%d)", i + 1, (int)[images count]]]; 121 | [encoder addImageFrame:theFrame]; 122 | } 123 | [encoder closeFile]; 124 | #if !__has_feature(objc_arc) 125 | [encoder release]; 126 | #endif 127 | [self performSelectorOnMainThread:@selector(informCallbackDone:) withObject:fileOutput waitUntilDone:NO]; 128 | } 129 | } 130 | 131 | - (ANGifImageFrame *)imageFrameWithImage:(UIImage *)anImage fitting:(CGSize)imageSize { 132 | UIImage * scaledImage = anImage; 133 | if (!CGSizeEqualToSize(anImage.size, imageSize)) { 134 | scaledImage = [anImage imageFittingFrame:imageSize]; 135 | } 136 | 137 | UIImagePixelSource * pixelSource = [[UIImagePixelSource alloc] initWithImage:scaledImage]; 138 | ANCutColorTable * colorTable = [[ANCutColorTable alloc] initWithTransparentFirst:YES pixelSource:pixelSource]; 139 | ANGifImageFrame * frame = [[ANGifImageFrame alloc] initWithPixelSource:pixelSource colorTable:colorTable delayTime:1]; 140 | #if !__has_feature(objc_arc) 141 | [colorTable release]; 142 | [pixelSource release]; 143 | [frame autorelease]; 144 | #endif 145 | return frame; 146 | } 147 | 148 | #pragma mark Background Callbacks 149 | 150 | - (void)setProgressLabel:(NSString *)label { 151 | if ([[NSThread currentThread] isMainThread]) { 152 | [progressStatus setText:label]; 153 | } else { 154 | [self performSelectorOnMainThread:@selector(setProgressLabel:) 155 | withObject:label waitUntilDone:NO]; 156 | } 157 | } 158 | 159 | - (void)setProgressPercent:(NSNumber *)percent { 160 | if ([[NSThread currentThread] isMainThread]) { 161 | [progressView setProgress:[percent floatValue]]; 162 | } else { 163 | [self performSelectorOnMainThread:@selector(setProgressPercent:) 164 | withObject:percent waitUntilDone:NO]; 165 | } 166 | } 167 | 168 | - (void)informCallbackDone:(NSString *)file { 169 | if (doneCallback) doneCallback(file); 170 | } 171 | 172 | #pragma mark - Memory Management - 173 | 174 | #if !__has_feature(objc_arc) 175 | 176 | - (void)dealloc { 177 | [images release]; 178 | [progressView release]; 179 | [progressStatus release]; 180 | if (doneCallback) Block_release(doneCallback); 181 | [super dealloc]; 182 | } 183 | 184 | #endif 185 | 186 | @end 187 | -------------------------------------------------------------------------------- /ANImageBitmapRep/Manipulators/BitmapRotationManipulator.m: -------------------------------------------------------------------------------- 1 | // 2 | // RotatableBitmapRep.m 3 | // ImageManip 4 | // 5 | // Created by Alex Nichol on 7/12/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "BitmapRotationManipulator.h" 10 | 11 | #define DEGTORAD(x) (x * (M_PI / 180.0f)) 12 | 13 | static CGPoint locationForAngle (CGFloat angle, CGFloat hypotenuse) { 14 | CGPoint p; 15 | p.x = (CGFloat)cos((double)DEGTORAD(angle)) * hypotenuse; 16 | p.y = (CGFloat)sin((double)DEGTORAD(angle)) * hypotenuse; 17 | return p; 18 | } 19 | 20 | @implementation BitmapRotationManipulator 21 | 22 | - (void)rotate:(CGFloat)degrees { 23 | if (degrees == 0) return; 24 | 25 | CGSize size = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y); 26 | CGSize newSize = CGSizeZero; 27 | 28 | /* Since the corners go off to the sides, we have to use the existing hypotenuse to calculate the new size 29 | for the image. This is done using some basic trigonometry. 30 | */ 31 | CGFloat hypotenuse; 32 | hypotenuse = (CGFloat)sqrt(pow((double)size.width / 2.0, 2.0) + pow((double)size.height / 2.0, 2.0)); 33 | 34 | CGPoint minP = CGPointMake(CGFLOAT_MAX, CGFLOAT_MAX); 35 | CGPoint maxP = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN); 36 | 37 | /* Find the angle for the corners. */ 38 | float firstAngle = (float)atan2((double)size.height / 2.0, (double)size.width / 2.0); 39 | float secondAngle = (float)atan2((double)size.height / 2.0, (double)size.width / -2.0); 40 | float thirdAngle = (float)atan2((double)size.height / -2.0, (double)size.width / -2.0); 41 | float fourthAngle = (float)atan2((double)size.height / -2.0, (double)size.width / 2.0); 42 | float angles[4] = {firstAngle, secondAngle, thirdAngle, fourthAngle}; 43 | 44 | /* Rotate the corners by the new degrees, finding out how outgoing 45 | the corners will be. This will allow us to easily calculate 46 | the new size of the image. 47 | */ 48 | for (int i = 0; i < 4; i++) { 49 | // conver the angle to radians. 50 | float deg = angles[i] * (float)(180.0f / M_PI); 51 | CGPoint p1 = locationForAngle(deg + degrees, hypotenuse); 52 | if (p1.x < minP.x) minP.x = p1.x; 53 | if (p1.x > maxP.x) maxP.x = p1.x; 54 | if (p1.y < minP.y) minP.y = p1.y; 55 | if (p1.y > maxP.y) maxP.y = p1.y; 56 | } 57 | 58 | newSize.width = maxP.x - minP.x; 59 | newSize.height = maxP.y - minP.y; 60 | 61 | /* Figure out where the thing is going to go when rotated by the bottom left 62 | corner. Use that information to translate it so that it rotates from the center. 63 | */ 64 | hypotenuse = (CGFloat)sqrt((pow(newSize.width / 2.0, 2) + pow(newSize.height / 2.0, 2))); 65 | 66 | CGPoint newCenter; 67 | float addAngle = (float)atan2((double)newSize.height / 2, (double)newSize.width / 2) * (float)(180.0f / M_PI); 68 | newCenter.x = cos((float)DEGTORAD((degrees + addAngle))) * hypotenuse; 69 | newCenter.y = sin((float)DEGTORAD((degrees + addAngle))) * hypotenuse; 70 | 71 | CGPoint offsetCenter; 72 | offsetCenter.x = (float)((float)newSize.width / 2.0f) - (float)newCenter.x; 73 | offsetCenter.y = (float)((float)newSize.height / 2.0f) - (float)newCenter.y; 74 | 75 | CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:newSize]; 76 | CGContextSaveGState(newContext); 77 | CGContextTranslateCTM(newContext, (float)round((float)offsetCenter.x), (float)round((float)offsetCenter.y)); 78 | 79 | CGContextRotateCTM(newContext, (CGFloat)DEGTORAD(degrees)); 80 | CGRect drawRect; 81 | drawRect.size = size; 82 | drawRect.origin.x = (CGFloat)round((newSize.width / 2) - (size.width / 2)); 83 | drawRect.origin.y = (CGFloat)round((newSize.height / 2) - (size.height / 2)); 84 | 85 | CGContextDrawImage(newContext, drawRect, [bitmapContext CGImage]); 86 | CGContextRestoreGState(newContext); 87 | [bitmapContext setContext:newContext]; 88 | CGContextRelease(newContext); 89 | } 90 | 91 | - (CGImageRef)imageByRotating:(CGFloat)degrees { 92 | if (degrees == 0) return [bitmapContext CGImage]; 93 | 94 | CGSize size = CGSizeMake([bitmapContext bitmapSize].x, [bitmapContext bitmapSize].y); 95 | CGSize newSize = CGSizeZero; 96 | 97 | /* Since the corners go off to the sides, we have to use the existing hypotenuse to calculate the new size 98 | for the image. This is done using some basic trigonometry. 99 | */ 100 | CGFloat hypotenuse; 101 | hypotenuse = (CGFloat)sqrt(pow((double)size.width / 2.0, 2.0) + pow((double)size.height / 2.0, 2.0)); 102 | 103 | CGPoint minP = CGPointMake(CGFLOAT_MAX, CGFLOAT_MAX); 104 | CGPoint maxP = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN); 105 | 106 | /* Find the angle for the corners. */ 107 | float firstAngle = (float)atan2((double)size.height / 2.0, (double)size.width / 2.0); 108 | float secondAngle = (float)atan2((double)size.height / 2.0, (double)size.width / -2.0); 109 | float thirdAngle = (float)atan2((double)size.height / -2.0, (double)size.width / -2.0); 110 | float fourthAngle = (float)atan2((double)size.height / -2.0, (double)size.width / 2.0); 111 | float angles[4] = {firstAngle, secondAngle, thirdAngle, fourthAngle}; 112 | 113 | /* Rotate the corners by the new degrees, finding out how outgoing 114 | the corners will be. This will allow us to easily calculate 115 | the new size of the image. 116 | */ 117 | for (int i = 0; i < 4; i++) { 118 | // conver the angle to radians. 119 | float deg = angles[i] * (float)(180.0f / M_PI); 120 | CGPoint p1 = locationForAngle(deg + degrees, hypotenuse); 121 | if (p1.x < minP.x) minP.x = p1.x; 122 | if (p1.x > maxP.x) maxP.x = p1.x; 123 | if (p1.y < minP.y) minP.y = p1.y; 124 | if (p1.y > maxP.y) maxP.y = p1.y; 125 | } 126 | 127 | newSize.width = ceil(maxP.x - minP.x); 128 | newSize.height = ceil(maxP.y - minP.y); 129 | 130 | /* Figure out where the thing is going to go when rotated by the bottom left 131 | corner. Use that information to translate it so that it rotates from the center. 132 | */ 133 | hypotenuse = (CGFloat)sqrt((pow(newSize.width / 2.0, 2) + pow(newSize.height / 2.0, 2))); 134 | 135 | CGPoint newCenter; 136 | float addAngle = (float)atan2((double)newSize.height / 2, (double)newSize.width / 2) * (float)(180.0f / M_PI); 137 | newCenter.x = cos((float)DEGTORAD((degrees + addAngle))) * hypotenuse; 138 | newCenter.y = sin((float)DEGTORAD((degrees + addAngle))) * hypotenuse; 139 | 140 | CGPoint offsetCenter; 141 | offsetCenter.x = (float)((float)newSize.width / 2.0f) - (float)newCenter.x; 142 | offsetCenter.y = (float)((float)newSize.height / 2.0f) - (float)newCenter.y; 143 | 144 | CGContextRef newContext = [CGContextCreator newARGBBitmapContextWithSize:newSize]; 145 | CGContextSaveGState(newContext); 146 | CGContextTranslateCTM(newContext, (float)round((float)offsetCenter.x), (float)round((float)offsetCenter.y)); 147 | 148 | CGContextRotateCTM(newContext, (CGFloat)DEGTORAD(degrees)); 149 | CGRect drawRect; 150 | drawRect.size = size; 151 | drawRect.origin.x = (CGFloat)round((newSize.width / 2) - (size.width / 2)); 152 | drawRect.origin.y = (CGFloat)round((newSize.height / 2) - (size.height / 2)); 153 | 154 | CGContextDrawImage(newContext, drawRect, [bitmapContext CGImage]); 155 | CGContextRestoreGState(newContext); 156 | CGImageRef image = CGBitmapContextCreateImage(newContext); 157 | void * buff = CGBitmapContextGetData(newContext); 158 | CGContextRelease(newContext); 159 | free(buff); 160 | #if __has_feature(objc_arc) == 1 161 | id retainedImage = CGImageReturnAutoreleased(image); 162 | CGImageRelease(image); 163 | return (__bridge CGImageRef)retainedImage; 164 | #else 165 | CGImageContainer * container = [CGImageContainer imageContainerWithImage:image]; 166 | CGImageRelease(image); 167 | return [container image]; 168 | #endif 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /Classes/GiraffeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GiraffeViewController.m 3 | // Giraffe 4 | // 5 | // Created by Alex Nichol on 1/20/11. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "GiraffeViewController.h" 10 | 11 | @implementation GiraffeViewController 12 | 13 | // The designated initializer. Override to perform setup that is required before the view is loaded. 14 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 15 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 16 | if (self) { 17 | if (!imageFrames) { 18 | imageFrames = [[NSMutableArray alloc] init]; 19 | } 20 | } 21 | return self; 22 | } 23 | 24 | - (id)initWithCoder:(NSCoder *)aDecoder { 25 | if ((self = [super initWithCoder:aDecoder])) { 26 | if (!imageFrames) { 27 | imageFrames = [[NSMutableArray alloc] init]; 28 | } 29 | } 30 | return self; 31 | } 32 | 33 | - (id)init { 34 | if ((self = [super init])) { 35 | if (!imageFrames) { 36 | imageFrames = [[NSMutableArray alloc] init]; 37 | } 38 | } 39 | return self; 40 | } 41 | 42 | /* 43 | // Implement loadView to create a view hierarchy programmatically, without using a nib. 44 | - (void)loadView { 45 | } 46 | */ 47 | 48 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 49 | - (void)viewDidLoad { 50 | [super viewDidLoad]; 51 | } 52 | 53 | 54 | #pragma mark Actions 55 | 56 | - (IBAction)addFrame:(id)sender { 57 | if (!imagePicker) { 58 | imagePicker = [[UIImagePickerController alloc] init]; 59 | imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: 60 | UIImagePickerControllerSourceTypePhotoLibrary]; 61 | [imagePicker setDelegate:self]; 62 | [imagePicker setAllowsEditing:NO]; 63 | } 64 | [self presentModalViewController:imagePicker animated:YES]; 65 | } 66 | 67 | - (IBAction)doneEditing:(id)sender { 68 | [navItem setRightBarButtonItem:editButton animated:YES]; 69 | [tableView setEditing:NO animated:YES]; 70 | } 71 | 72 | - (IBAction)edit:(id)sender { 73 | [navItem setRightBarButtonItem:doneButton animated:YES]; 74 | [tableView setEditing:YES animated:YES]; 75 | } 76 | 77 | - (IBAction)exportVideo:(id)sender { 78 | NSString * tempFile = [NSString stringWithFormat:@"%@/%ld", NSTemporaryDirectory(), time(NULL)]; 79 | NSMutableArray * images = [NSMutableArray array]; 80 | for (PhotoEntry * entry in imageFrames) { 81 | [images addObject:entry.image]; 82 | } 83 | ExportViewController * export = [[ExportViewController alloc] initWithImages:images]; 84 | [self presentModalViewController:export animated:YES]; 85 | [export encodeToFile:tempFile callback:^(NSString * aFile) { 86 | NSData * attachmentData = [NSData dataWithContentsOfFile:aFile]; 87 | NSLog(@"Path: %@", aFile); 88 | //[[NSFileManager defaultManager] removeItemAtPath:aFile error:nil]; 89 | MFMailComposeViewController * compose = [[MFMailComposeViewController alloc] init]; 90 | [compose setSubject:@"Gif Image"]; 91 | [compose setMessageBody:@"I have kindly attached a GIF image to this E-mail. I made this GIF using ANGif, an open source Objective-C library for exporting animated GIFs." isHTML:NO]; 92 | [compose addAttachmentData:attachmentData mimeType:@"image/gif" fileName:@"image.gif"]; 93 | [compose setMailComposeDelegate:self]; 94 | [self performSelector:@selector(showViewController:) withObject:compose afterDelay:1]; 95 | #if !__has_feature(objc_arc) 96 | [compose release]; 97 | #endif 98 | [self dismissModalViewControllerAnimated:YES]; 99 | }]; 100 | #if !__has_feature(objc_arc) 101 | [export release]; 102 | #endif 103 | } 104 | 105 | - (void)showViewController:(UIViewController *)controller { 106 | [self presentModalViewController:controller animated:YES]; 107 | } 108 | 109 | #pragma mark View Lifecycle 110 | 111 | 112 | /* 113 | // Override to allow orientations other than the default portrait orientation. 114 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 115 | // Return YES for supported orientations 116 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 117 | } 118 | */ 119 | 120 | - (void)didReceiveMemoryWarning { 121 | // Releases the view if it doesn't have a superview. 122 | [super didReceiveMemoryWarning]; 123 | 124 | // Release any cached data, images, etc that aren't in use. 125 | } 126 | 127 | - (void)viewDidUnload { 128 | // Release any retained subviews of the main view. 129 | // e.g. self.myOutlet = nil; 130 | } 131 | 132 | #pragma mark - Table View - 133 | 134 | #pragma mark Data Source 135 | 136 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 137 | return 1; 138 | } 139 | 140 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 141 | return [imageFrames count]; 142 | } 143 | 144 | - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 145 | UITableViewCell * imageCell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 146 | if (!imageCell) { 147 | imageCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; 148 | #if !__has_feature(objc_arc) 149 | [imageCell autorelease]; 150 | #endif 151 | } 152 | imageCell.imageView.image = [[imageFrames objectAtIndex:indexPath.row] image]; 153 | imageCell.imageView.contentMode = UIViewContentModeScaleAspectFit; 154 | imageCell.textLabel.text = (NSString *)[[imageFrames objectAtIndex:indexPath.row] imageName]; 155 | return imageCell; 156 | } 157 | 158 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 159 | return 70; 160 | } 161 | 162 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 163 | return YES; 164 | } 165 | 166 | - (void)tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 167 | if (editingStyle == UITableViewCellEditingStyleDelete) { 168 | [imageFrames removeObjectAtIndex:indexPath.row]; 169 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 170 | withRowAnimation:UITableViewRowAnimationFade]; 171 | } 172 | } 173 | 174 | - (void)tableView:(UITableView *)aTableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { 175 | [imageFrames swapValueAtIndex:[sourceIndexPath row] withValueAtIndex:[destinationIndexPath row]]; 176 | [tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath]; 177 | } 178 | 179 | #pragma mark - Delegates - 180 | 181 | #pragma mark Image Picker 182 | 183 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 184 | PhotoEntry * entry = [[PhotoEntry alloc] initWithName:[NSString stringWithFormat:@"Image %d", ++itemID] 185 | image:[info objectForKey:UIImagePickerControllerOriginalImage]]; 186 | [imageFrames addObject:entry]; 187 | #if !__has_feature(objc_arc) 188 | [entry release]; 189 | #endif 190 | [tableView reloadData]; 191 | [self dismissModalViewControllerAnimated:YES]; 192 | } 193 | 194 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 195 | [self dismissModalViewControllerAnimated:YES]; 196 | } 197 | 198 | #pragma mark Navigation Controller 199 | 200 | - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error { 201 | [self dismissModalViewControllerAnimated:YES]; 202 | } 203 | 204 | #pragma mark - Memory Management - 205 | 206 | #if !__has_feature(objc_arc) 207 | - (void)dealloc { 208 | [imageFrames release]; 209 | [imagePicker release]; 210 | [super dealloc]; 211 | } 212 | #endif 213 | 214 | @end 215 | -------------------------------------------------------------------------------- /Giraffe.xcodeproj/alex.pbxuser: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | 1D6058900D05DD3D006BFB54 /* Giraffe */ = { 4 | activeExec = 0; 5 | executables = ( 6 | FAAA689012E8E7B300122030 /* Giraffe */, 7 | ); 8 | }; 9 | 28D7ACF60DDB3853001CB0EB /* GiraffeViewController.h */ = { 10 | uiCtxt = { 11 | sepNavIntBoundsRect = "{{0, 0}, {519, 238}}"; 12 | sepNavSelRange = "{0, 0}"; 13 | sepNavVisRange = "{85, 152}"; 14 | }; 15 | }; 16 | 28D7ACF70DDB3853001CB0EB /* GiraffeViewController.m */ = { 17 | uiCtxt = { 18 | sepNavIntBoundsRect = "{{0, 0}, {666, 1456}}"; 19 | sepNavSelRange = "{1969, 0}"; 20 | sepNavVisRange = "{1737, 456}"; 21 | }; 22 | }; 23 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 24 | activeBuildConfigurationName = Debug; 25 | activeExecutable = FAAA689012E8E7B300122030 /* Giraffe */; 26 | activeTarget = 1D6058900D05DD3D006BFB54 /* Giraffe */; 27 | addToTargets = ( 28 | 1D6058900D05DD3D006BFB54 /* Giraffe */, 29 | ); 30 | breakpoints = ( 31 | ); 32 | codeSenseManager = FAAA68A612E8E7B400122030 /* Code sense */; 33 | executables = ( 34 | FAAA689012E8E7B300122030 /* Giraffe */, 35 | ); 36 | perUserDictionary = { 37 | PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { 38 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 39 | PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; 40 | PBXFileTableDataSourceColumnWidthsKey = ( 41 | 200, 42 | 200, 43 | 151, 44 | ); 45 | PBXFileTableDataSourceColumnsKey = ( 46 | PBXBookmarksDataSource_LocationID, 47 | PBXBookmarksDataSource_NameID, 48 | PBXBookmarksDataSource_CommentsID, 49 | ); 50 | }; 51 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { 52 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 53 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 54 | PBXFileTableDataSourceColumnWidthsKey = ( 55 | 20, 56 | 341, 57 | 20, 58 | 48, 59 | 43, 60 | 43, 61 | 20, 62 | ); 63 | PBXFileTableDataSourceColumnsKey = ( 64 | PBXFileDataSource_FiletypeID, 65 | PBXFileDataSource_Filename_ColumnID, 66 | PBXFileDataSource_Built_ColumnID, 67 | PBXFileDataSource_ObjectSize_ColumnID, 68 | PBXFileDataSource_Errors_ColumnID, 69 | PBXFileDataSource_Warnings_ColumnID, 70 | PBXFileDataSource_Target_ColumnID, 71 | ); 72 | }; 73 | PBXPerProjectTemplateStateSaveDate = 322169223; 74 | PBXWorkspaceStateSaveDate = 322169223; 75 | }; 76 | perUserProjectItems = { 77 | FA2851AE12EAA39500059EF7 /* PBXTextBookmark */ = FA2851AE12EAA39500059EF7 /* PBXTextBookmark */; 78 | FA530863130EDAB40022E6D7 /* PBXTextBookmark */ = FA530863130EDAB40022E6D7 /* PBXTextBookmark */; 79 | FA530864130EDAB40022E6D7 /* PBXTextBookmark */ = FA530864130EDAB40022E6D7 /* PBXTextBookmark */; 80 | FA530865130EDAB40022E6D7 /* PBXTextBookmark */ = FA530865130EDAB40022E6D7 /* PBXTextBookmark */; 81 | FA530866130EDAB40022E6D7 /* PBXTextBookmark */ = FA530866130EDAB40022E6D7 /* PBXTextBookmark */; 82 | FA530867130EDAB40022E6D7 /* PBXTextBookmark */ = FA530867130EDAB40022E6D7 /* PBXTextBookmark */; 83 | FA5E0D3512EA9F3400892190 /* PBXTextBookmark */ = FA5E0D3512EA9F3400892190 /* PBXTextBookmark */; 84 | FA5E0D3812EA9F3400892190 /* PlistBookmark */ = FA5E0D3812EA9F3400892190 /* PlistBookmark */; 85 | FAB59F411333ED6E00DAF4FE /* PBXTextBookmark */ = FAB59F411333ED6E00DAF4FE /* PBXTextBookmark */; 86 | FAB59F421333ED6E00DAF4FE /* PBXTextBookmark */ = FAB59F421333ED6E00DAF4FE /* PBXTextBookmark */; 87 | FAB59F431333ED6E00DAF4FE /* PBXTextBookmark */ = FAB59F431333ED6E00DAF4FE /* PBXTextBookmark */; 88 | FAFD633012EB24F7007FCFBC /* PBXTextBookmark */ = FAFD633012EB24F7007FCFBC /* PBXTextBookmark */; 89 | }; 90 | sourceControlManager = FAAA68A512E8E7B400122030 /* Source Control */; 91 | userBuildSettings = { 92 | }; 93 | }; 94 | FA2851AE12EAA39500059EF7 /* PBXTextBookmark */ = { 95 | isa = PBXTextBookmark; 96 | fRef = FAAA68B412E8E85100122030 /* ANImageBitmapRep.h */; 97 | name = "ANImageBitmapRep.h: 30"; 98 | rLen = 51; 99 | rLoc = 830; 100 | rType = 0; 101 | vrLen = 486; 102 | vrLoc = 624; 103 | }; 104 | FA530863130EDAB40022E6D7 /* PBXTextBookmark */ = { 105 | isa = PBXTextBookmark; 106 | fRef = FAB9F66812EA244700DE93FB /* BitBuffer.m */; 107 | name = "BitBuffer.m: 30"; 108 | rLen = 0; 109 | rLoc = 707; 110 | rType = 0; 111 | vrLen = 187; 112 | vrLoc = 614; 113 | }; 114 | FA530864130EDAB40022E6D7 /* PBXTextBookmark */ = { 115 | isa = PBXTextBookmark; 116 | fRef = FAAA68AB12E8E81D00122030 /* ANGifBitmap.h */; 117 | name = "ANGifBitmap.h: 17"; 118 | rLen = 0; 119 | rLoc = 330; 120 | rType = 0; 121 | vrLen = 310; 122 | vrLoc = 137; 123 | }; 124 | FA530865130EDAB40022E6D7 /* PBXTextBookmark */ = { 125 | isa = PBXTextBookmark; 126 | fRef = FAAA68A812E8E7D900122030 /* ANGifEncoder.h */; 127 | name = "ANGifEncoder.h: 23"; 128 | rLen = 61; 129 | rLoc = 436; 130 | rType = 0; 131 | vrLen = 344; 132 | vrLoc = 209; 133 | }; 134 | FA530866130EDAB40022E6D7 /* PBXTextBookmark */ = { 135 | isa = PBXTextBookmark; 136 | fRef = FAAA68AC12E8E81D00122030 /* ANGifBitmap.m */; 137 | name = "ANGifBitmap.m: 65"; 138 | rLen = 0; 139 | rLoc = 1760; 140 | rType = 0; 141 | vrLen = 250; 142 | vrLoc = 1578; 143 | }; 144 | FA530867130EDAB40022E6D7 /* PBXTextBookmark */ = { 145 | isa = PBXTextBookmark; 146 | fRef = FAAA68A912E8E7D900122030 /* ANGifEncoder.m */; 147 | name = "ANGifEncoder.m: 269"; 148 | rLen = 0; 149 | rLoc = 7242; 150 | rType = 0; 151 | vrLen = 389; 152 | vrLoc = 7048; 153 | }; 154 | FA5E0D3512EA9F3400892190 /* PBXTextBookmark */ = { 155 | isa = PBXTextBookmark; 156 | fRef = 28D7ACF60DDB3853001CB0EB /* GiraffeViewController.h */; 157 | name = "GiraffeViewController.h: 1"; 158 | rLen = 0; 159 | rLoc = 0; 160 | rType = 0; 161 | vrLen = 152; 162 | vrLoc = 85; 163 | }; 164 | FA5E0D3812EA9F3400892190 /* PlistBookmark */ = { 165 | isa = PlistBookmark; 166 | fRef = 8D1107310486CEB800E47090 /* Giraffe-Info.plist */; 167 | fallbackIsa = PBXBookmark; 168 | isK = 0; 169 | kPath = ( 170 | ); 171 | name = "/Users/alex/xCode/iPhone Apps/Fails/Giraffe/Giraffe-Info.plist"; 172 | rLen = 0; 173 | rLoc = 9223372036854775808; 174 | }; 175 | FAAA689012E8E7B300122030 /* Giraffe */ = { 176 | isa = PBXExecutable; 177 | activeArgIndices = ( 178 | ); 179 | argumentStrings = ( 180 | ); 181 | autoAttachOnCrash = 1; 182 | breakpointsEnabled = 1; 183 | configStateDict = { 184 | }; 185 | customDataFormattersEnabled = 1; 186 | dataTipCustomDataFormattersEnabled = 1; 187 | dataTipShowTypeColumn = 1; 188 | dataTipSortType = 0; 189 | debuggerPlugin = GDBDebugging; 190 | disassemblyDisplayState = 0; 191 | dylibVariantSuffix = ""; 192 | enableDebugStr = 1; 193 | environmentEntries = ( 194 | ); 195 | executableSystemSymbolLevel = 0; 196 | executableUserSymbolLevel = 0; 197 | libgmallocEnabled = 0; 198 | name = Giraffe; 199 | savedGlobals = { 200 | }; 201 | showTypeColumn = 0; 202 | sourceDirectories = ( 203 | ); 204 | variableFormatDictionary = { 205 | }; 206 | }; 207 | FAAA68A512E8E7B400122030 /* Source Control */ = { 208 | isa = PBXSourceControlManager; 209 | fallbackIsa = XCSourceControlManager; 210 | isSCMEnabled = 0; 211 | scmConfiguration = { 212 | repositoryNamesForRoots = { 213 | "" = ""; 214 | }; 215 | }; 216 | }; 217 | FAAA68A612E8E7B400122030 /* Code sense */ = { 218 | isa = PBXCodeSenseManager; 219 | indexTemplatePath = ""; 220 | }; 221 | FAAA68A812E8E7D900122030 /* ANGifEncoder.h */ = { 222 | uiCtxt = { 223 | sepNavIntBoundsRect = "{{0, 0}, {519, 560}}"; 224 | sepNavSelRange = "{436, 61}"; 225 | sepNavVisRange = "{209, 344}"; 226 | }; 227 | }; 228 | FAAA68A912E8E7D900122030 /* ANGifEncoder.m */ = { 229 | uiCtxt = { 230 | sepNavIntBoundsRect = "{{0, 0}, {519, 4242}}"; 231 | sepNavSelRange = "{7242, 0}"; 232 | sepNavVisRange = "{7048, 389}"; 233 | }; 234 | }; 235 | FAAA68AB12E8E81D00122030 /* ANGifBitmap.h */ = { 236 | uiCtxt = { 237 | sepNavIntBoundsRect = "{{0, 0}, {519, 350}}"; 238 | sepNavSelRange = "{330, 0}"; 239 | sepNavVisRange = "{137, 310}"; 240 | }; 241 | }; 242 | FAAA68AC12E8E81D00122030 /* ANGifBitmap.m */ = { 243 | uiCtxt = { 244 | sepNavIntBoundsRect = "{{0, 0}, {519, 1036}}"; 245 | sepNavSelRange = "{1760, 0}"; 246 | sepNavVisRange = "{1578, 250}"; 247 | }; 248 | }; 249 | FAAA68B412E8E85100122030 /* ANImageBitmapRep.h */ = { 250 | uiCtxt = { 251 | sepNavIntBoundsRect = "{{0, 0}, {519, 644}}"; 252 | sepNavSelRange = "{830, 51}"; 253 | sepNavVisRange = "{624, 486}"; 254 | }; 255 | }; 256 | FAAA68B512E8E85100122030 /* ANImageBitmapRep.m */ = { 257 | uiCtxt = { 258 | sepNavIntBoundsRect = "{{0, 0}, {519, 4900}}"; 259 | sepNavSelRange = "{6987, 51}"; 260 | sepNavVisRange = "{6985, 268}"; 261 | }; 262 | }; 263 | FAB59F411333ED6E00DAF4FE /* PBXTextBookmark */ = { 264 | isa = PBXTextBookmark; 265 | fRef = 28D7ACF70DDB3853001CB0EB /* GiraffeViewController.m */; 266 | name = "GiraffeViewController.m: 68"; 267 | rLen = 0; 268 | rLoc = 1969; 269 | rType = 0; 270 | vrLen = 456; 271 | vrLoc = 1737; 272 | }; 273 | FAB59F421333ED6E00DAF4FE /* PBXTextBookmark */ = { 274 | isa = PBXTextBookmark; 275 | fRef = FAB9F66712EA244700DE93FB /* BitBuffer.h */; 276 | name = "BitBuffer.h: 13"; 277 | rLen = 0; 278 | rLoc = 220; 279 | rType = 0; 280 | vrLen = 220; 281 | vrLoc = 73; 282 | }; 283 | FAB59F431333ED6E00DAF4FE /* PBXTextBookmark */ = { 284 | isa = PBXTextBookmark; 285 | fRef = FAB9F66712EA244700DE93FB /* BitBuffer.h */; 286 | name = "BitBuffer.h: 13"; 287 | rLen = 0; 288 | rLoc = 220; 289 | rType = 0; 290 | vrLen = 219; 291 | vrLoc = 73; 292 | }; 293 | FAB9F66712EA244700DE93FB /* BitBuffer.h */ = { 294 | uiCtxt = { 295 | sepNavIntBoundsRect = "{{0, 0}, {519, 532}}"; 296 | sepNavSelRange = "{220, 0}"; 297 | sepNavVisRange = "{73, 219}"; 298 | sepNavWindowFrame = "{{15, 4}, {653, 601}}"; 299 | }; 300 | }; 301 | FAB9F66812EA244700DE93FB /* BitBuffer.m */ = { 302 | uiCtxt = { 303 | sepNavIntBoundsRect = "{{0, 0}, {519, 1162}}"; 304 | sepNavSelRange = "{707, 0}"; 305 | sepNavVisRange = "{614, 187}"; 306 | }; 307 | }; 308 | FAFD633012EB24F7007FCFBC /* PBXTextBookmark */ = { 309 | isa = PBXTextBookmark; 310 | fRef = FAAA68B512E8E85100122030 /* ANImageBitmapRep.m */; 311 | name = "ANImageBitmapRep.m: 235"; 312 | rLen = 51; 313 | rLoc = 6987; 314 | rType = 0; 315 | vrLen = 268; 316 | vrLoc = 6985; 317 | }; 318 | } 319 | -------------------------------------------------------------------------------- /MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1024 5 | 10D571 6 | 786 7 | 1038.29 8 | 460.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 112 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | IBCocoaTouchFramework 42 | 43 | 44 | GiraffeViewController 45 | 46 | 47 | 1 48 | 49 | IBCocoaTouchFramework 50 | NO 51 | 52 | 53 | 54 | 292 55 | {320, 480} 56 | 57 | 1 58 | MSAxIDEAA 59 | 60 | NO 61 | NO 62 | 63 | IBCocoaTouchFramework 64 | YES 65 | 66 | 67 | 68 | 69 | YES 70 | 71 | 72 | delegate 73 | 74 | 75 | 76 | 4 77 | 78 | 79 | 80 | viewController 81 | 82 | 83 | 84 | 11 85 | 86 | 87 | 88 | window 89 | 90 | 91 | 92 | 14 93 | 94 | 95 | 96 | 97 | YES 98 | 99 | 0 100 | 101 | 102 | 103 | 104 | 105 | -1 106 | 107 | 108 | File's Owner 109 | 110 | 111 | 3 112 | 113 | 114 | Giraffe App Delegate 115 | 116 | 117 | -2 118 | 119 | 120 | 121 | 122 | 10 123 | 124 | 125 | 126 | 127 | 12 128 | 129 | 130 | 131 | 132 | 133 | 134 | YES 135 | 136 | YES 137 | -1.CustomClassName 138 | -2.CustomClassName 139 | 10.CustomClassName 140 | 10.IBEditorWindowLastContentRect 141 | 10.IBPluginDependency 142 | 12.IBEditorWindowLastContentRect 143 | 12.IBPluginDependency 144 | 3.CustomClassName 145 | 3.IBPluginDependency 146 | 147 | 148 | YES 149 | UIApplication 150 | UIResponder 151 | GiraffeViewController 152 | {{234, 376}, {320, 480}} 153 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 154 | {{525, 346}, {320, 480}} 155 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 156 | GiraffeAppDelegate 157 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 158 | 159 | 160 | 161 | YES 162 | 163 | 164 | YES 165 | 166 | 167 | 168 | 169 | YES 170 | 171 | 172 | YES 173 | 174 | 175 | 176 | 15 177 | 178 | 179 | 180 | YES 181 | 182 | UIWindow 183 | UIView 184 | 185 | IBUserSource 186 | 187 | 188 | 189 | 190 | GiraffeAppDelegate 191 | NSObject 192 | 193 | YES 194 | 195 | YES 196 | viewController 197 | window 198 | 199 | 200 | YES 201 | GiraffeViewController 202 | UIWindow 203 | 204 | 205 | 206 | YES 207 | 208 | YES 209 | viewController 210 | window 211 | 212 | 213 | YES 214 | 215 | viewController 216 | GiraffeViewController 217 | 218 | 219 | window 220 | UIWindow 221 | 222 | 223 | 224 | 225 | IBProjectSource 226 | Classes/GiraffeAppDelegate.h 227 | 228 | 229 | 230 | GiraffeAppDelegate 231 | NSObject 232 | 233 | IBUserSource 234 | 235 | 236 | 237 | 238 | GiraffeViewController 239 | UIViewController 240 | 241 | IBProjectSource 242 | Classes/GiraffeViewController.h 243 | 244 | 245 | 246 | 247 | YES 248 | 249 | NSObject 250 | 251 | IBFrameworkSource 252 | Foundation.framework/Headers/NSError.h 253 | 254 | 255 | 256 | NSObject 257 | 258 | IBFrameworkSource 259 | Foundation.framework/Headers/NSFileManager.h 260 | 261 | 262 | 263 | NSObject 264 | 265 | IBFrameworkSource 266 | Foundation.framework/Headers/NSKeyValueCoding.h 267 | 268 | 269 | 270 | NSObject 271 | 272 | IBFrameworkSource 273 | Foundation.framework/Headers/NSKeyValueObserving.h 274 | 275 | 276 | 277 | NSObject 278 | 279 | IBFrameworkSource 280 | Foundation.framework/Headers/NSKeyedArchiver.h 281 | 282 | 283 | 284 | NSObject 285 | 286 | IBFrameworkSource 287 | Foundation.framework/Headers/NSObject.h 288 | 289 | 290 | 291 | NSObject 292 | 293 | IBFrameworkSource 294 | Foundation.framework/Headers/NSRunLoop.h 295 | 296 | 297 | 298 | NSObject 299 | 300 | IBFrameworkSource 301 | Foundation.framework/Headers/NSThread.h 302 | 303 | 304 | 305 | NSObject 306 | 307 | IBFrameworkSource 308 | Foundation.framework/Headers/NSURL.h 309 | 310 | 311 | 312 | NSObject 313 | 314 | IBFrameworkSource 315 | Foundation.framework/Headers/NSURLConnection.h 316 | 317 | 318 | 319 | NSObject 320 | 321 | IBFrameworkSource 322 | UIKit.framework/Headers/UIAccessibility.h 323 | 324 | 325 | 326 | NSObject 327 | 328 | IBFrameworkSource 329 | UIKit.framework/Headers/UINibLoading.h 330 | 331 | 332 | 333 | NSObject 334 | 335 | IBFrameworkSource 336 | UIKit.framework/Headers/UIResponder.h 337 | 338 | 339 | 340 | UIApplication 341 | UIResponder 342 | 343 | IBFrameworkSource 344 | UIKit.framework/Headers/UIApplication.h 345 | 346 | 347 | 348 | UIResponder 349 | NSObject 350 | 351 | 352 | 353 | UISearchBar 354 | UIView 355 | 356 | IBFrameworkSource 357 | UIKit.framework/Headers/UISearchBar.h 358 | 359 | 360 | 361 | UISearchDisplayController 362 | NSObject 363 | 364 | IBFrameworkSource 365 | UIKit.framework/Headers/UISearchDisplayController.h 366 | 367 | 368 | 369 | UIView 370 | 371 | IBFrameworkSource 372 | UIKit.framework/Headers/UITextField.h 373 | 374 | 375 | 376 | UIView 377 | UIResponder 378 | 379 | IBFrameworkSource 380 | UIKit.framework/Headers/UIView.h 381 | 382 | 383 | 384 | UIViewController 385 | 386 | IBFrameworkSource 387 | UIKit.framework/Headers/UINavigationController.h 388 | 389 | 390 | 391 | UIViewController 392 | 393 | IBFrameworkSource 394 | UIKit.framework/Headers/UIPopoverController.h 395 | 396 | 397 | 398 | UIViewController 399 | 400 | IBFrameworkSource 401 | UIKit.framework/Headers/UISplitViewController.h 402 | 403 | 404 | 405 | UIViewController 406 | 407 | IBFrameworkSource 408 | UIKit.framework/Headers/UITabBarController.h 409 | 410 | 411 | 412 | UIViewController 413 | UIResponder 414 | 415 | IBFrameworkSource 416 | UIKit.framework/Headers/UIViewController.h 417 | 418 | 419 | 420 | UIWindow 421 | UIView 422 | 423 | IBFrameworkSource 424 | UIKit.framework/Headers/UIWindow.h 425 | 426 | 427 | 428 | 429 | 0 430 | IBCocoaTouchFramework 431 | 432 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 433 | 434 | 435 | 436 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 437 | 438 | 439 | YES 440 | Giraffe.xcodeproj 441 | 3 442 | 112 443 | 444 | 445 | -------------------------------------------------------------------------------- /GiraffeViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1280 5 | 11C74 6 | 1938 7 | 1138.23 8 | 567.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 933 12 | 13 | 14 | YES 15 | IBProxyObject 16 | IBUIBarButtonItem 17 | IBUIToolbar 18 | IBUINavigationBar 19 | IBUINavigationItem 20 | IBUITableView 21 | IBUIView 22 | 23 | 24 | YES 25 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 26 | 27 | 28 | PluginDependencyRecalculationVersion 29 | 30 | 31 | 32 | YES 33 | 34 | IBFilesOwner 35 | IBCocoaTouchFramework 36 | 37 | 38 | IBFirstResponder 39 | IBCocoaTouchFramework 40 | 41 | 42 | IBCocoaTouchFramework 43 | 2 44 | 0 45 | 46 | 47 | 48 | 274 49 | 50 | YES 51 | 52 | 53 | 274 54 | {{0, 44}, {320, 372}} 55 | 56 | 57 | _NS:418 58 | 59 | 3 60 | MQA 61 | 62 | YES 63 | IBCocoaTouchFramework 64 | YES 65 | 1 66 | 0 67 | YES 68 | 44 69 | 22 70 | 22 71 | 72 | 73 | 74 | 290 75 | {320, 44} 76 | 77 | 78 | 79 | _NS:260 80 | IBCocoaTouchFramework 81 | 82 | YES 83 | 84 | 85 | Image Sequence 86 | 87 | IBCocoaTouchFramework 88 | 1 89 | 90 | 2 91 | 92 | IBCocoaTouchFramework 93 | 94 | 95 | 96 | 97 | 98 | 266 99 | {{0, 416}, {320, 44}} 100 | 101 | 102 | 103 | _NS:371 104 | NO 105 | NO 106 | IBCocoaTouchFramework 107 | 108 | YES 109 | 110 | Export 111 | IBCocoaTouchFramework 112 | 1 113 | 114 | 115 | 116 | IBCocoaTouchFramework 117 | 118 | 5 119 | 120 | 121 | IBCocoaTouchFramework 122 | 1 123 | 124 | 4 125 | 126 | 127 | 128 | 129 | {{0, 20}, {320, 460}} 130 | 131 | 132 | 133 | 134 | 1 135 | MSAxIDEAA 136 | 137 | NO 138 | 139 | IBCocoaTouchFramework 140 | 141 | 142 | 143 | 144 | YES 145 | 146 | 147 | view 148 | 149 | 150 | 151 | 7 152 | 153 | 154 | 155 | tableView 156 | 157 | 158 | 159 | 18 160 | 161 | 162 | 163 | doneButton 164 | 165 | 166 | 167 | 26 168 | 169 | 170 | 171 | editButton 172 | 173 | 174 | 175 | 27 176 | 177 | 178 | 179 | navItem 180 | 181 | 182 | 183 | 29 184 | 185 | 186 | 187 | exportVideo: 188 | 189 | 190 | 191 | 20 192 | 193 | 194 | 195 | addFrame: 196 | 197 | 198 | 199 | 19 200 | 201 | 202 | 203 | delegate 204 | 205 | 206 | 207 | 23 208 | 209 | 210 | 211 | dataSource 212 | 213 | 214 | 215 | 24 216 | 217 | 218 | 219 | edit: 220 | 221 | 222 | 223 | 22 224 | 225 | 226 | 227 | doneEditing: 228 | 229 | 230 | 231 | 28 232 | 233 | 234 | 235 | 236 | YES 237 | 238 | 0 239 | 240 | YES 241 | 242 | 243 | 244 | 245 | 246 | -1 247 | 248 | 249 | File's Owner 250 | 251 | 252 | -2 253 | 254 | 255 | 256 | 257 | 6 258 | 259 | 260 | YES 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 10 269 | 270 | 271 | YES 272 | 273 | 274 | 275 | 276 | 277 | 11 278 | 279 | 280 | YES 281 | 282 | 283 | 284 | 285 | 286 | 12 287 | 288 | 289 | YES 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 13 298 | 299 | 300 | 301 | 302 | 14 303 | 304 | 305 | 306 | 307 | 15 308 | 309 | 310 | 311 | 312 | 16 313 | 314 | 315 | 316 | 317 | 21 318 | 319 | 320 | 321 | 322 | 25 323 | 324 | 325 | 326 | 327 | 328 | 329 | YES 330 | 331 | YES 332 | -1.CustomClassName 333 | -1.IBPluginDependency 334 | -2.CustomClassName 335 | -2.IBPluginDependency 336 | 10.IBPluginDependency 337 | 11.IBPluginDependency 338 | 12.IBPluginDependency 339 | 13.IBPluginDependency 340 | 14.IBPluginDependency 341 | 15.IBPluginDependency 342 | 16.IBPluginDependency 343 | 21.IBPluginDependency 344 | 25.IBPluginDependency 345 | 6.IBPluginDependency 346 | 347 | 348 | YES 349 | GiraffeViewController 350 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 351 | UIResponder 352 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 353 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 354 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 355 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 356 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 357 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 358 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 359 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 360 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 361 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 362 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 363 | 364 | 365 | 366 | YES 367 | 368 | 369 | 370 | 371 | 372 | YES 373 | 374 | 375 | 376 | 377 | 29 378 | 379 | 380 | 381 | YES 382 | 383 | GiraffeViewController 384 | UIViewController 385 | 386 | YES 387 | 388 | YES 389 | addFrame: 390 | doneEditing: 391 | edit: 392 | exportVideo: 393 | 394 | 395 | YES 396 | id 397 | id 398 | id 399 | id 400 | 401 | 402 | 403 | YES 404 | 405 | YES 406 | addFrame: 407 | doneEditing: 408 | edit: 409 | exportVideo: 410 | 411 | 412 | YES 413 | 414 | addFrame: 415 | id 416 | 417 | 418 | doneEditing: 419 | id 420 | 421 | 422 | edit: 423 | id 424 | 425 | 426 | exportVideo: 427 | id 428 | 429 | 430 | 431 | 432 | YES 433 | 434 | YES 435 | doneButton 436 | editButton 437 | navItem 438 | tableView 439 | 440 | 441 | YES 442 | UIBarButtonItem 443 | UIBarButtonItem 444 | UINavigationItem 445 | UITableView 446 | 447 | 448 | 449 | YES 450 | 451 | YES 452 | doneButton 453 | editButton 454 | navItem 455 | tableView 456 | 457 | 458 | YES 459 | 460 | doneButton 461 | UIBarButtonItem 462 | 463 | 464 | editButton 465 | UIBarButtonItem 466 | 467 | 468 | navItem 469 | UINavigationItem 470 | 471 | 472 | tableView 473 | UITableView 474 | 475 | 476 | 477 | 478 | IBProjectSource 479 | ./Classes/GiraffeViewController.h 480 | 481 | 482 | 483 | 484 | 0 485 | IBCocoaTouchFramework 486 | 487 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 488 | 489 | 490 | 491 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 492 | 493 | 494 | YES 495 | 3 496 | 933 497 | 498 | 499 | -------------------------------------------------------------------------------- /Giraffe.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D3623260D0F684500981E51 /* GiraffeAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* GiraffeAppDelegate.m */; }; 11 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 12 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 13 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 14 | 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; 15 | 2899E5220DE3E06400AC0155 /* GiraffeViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2899E5210DE3E06400AC0155 /* GiraffeViewController.xib */; }; 16 | 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 17 | 28D7ACF80DDB3853001CB0EB /* GiraffeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* GiraffeViewController.m */; }; 18 | FA9A0BA7146572210095DA13 /* ANGifEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B88146572210095DA13 /* ANGifEncoder.m */; }; 19 | FA9A0BA8146572210095DA13 /* ANGifGraphicControlExt.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B8A146572210095DA13 /* ANGifGraphicControlExt.m */; }; 20 | FA9A0BA9146572210095DA13 /* ANGifLogicalScreenDesc.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B8C146572210095DA13 /* ANGifLogicalScreenDesc.m */; }; 21 | FA9A0BAA146572210095DA13 /* ANGifAppExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B8F146572210095DA13 /* ANGifAppExtension.m */; }; 22 | FA9A0BAB146572210095DA13 /* ANGifNetscapeAppExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B91146572210095DA13 /* ANGifNetscapeAppExtension.m */; }; 23 | FA9A0BAC146572210095DA13 /* ANAvgColorTable.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B94146572210095DA13 /* ANAvgColorTable.m */; }; 24 | FA9A0BAD146572210095DA13 /* ANColorTable.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B96146572210095DA13 /* ANColorTable.m */; }; 25 | FA9A0BAE146572210095DA13 /* ANCutColorTable.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B99146572210095DA13 /* ANCutColorTable.m */; }; 26 | FA9A0BAF146572210095DA13 /* ANMutableColorArray.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B9B146572210095DA13 /* ANMutableColorArray.m */; }; 27 | FA9A0BB0146572210095DA13 /* ANGifDataSubblock.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0B9E146572210095DA13 /* ANGifDataSubblock.m */; }; 28 | FA9A0BB1146572210095DA13 /* ANGifImageDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BA0146572210095DA13 /* ANGifImageDescriptor.m */; }; 29 | FA9A0BB2146572210095DA13 /* ANGifImageFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BA2146572210095DA13 /* ANGifImageFrame.m */; }; 30 | FA9A0BB3146572210095DA13 /* LZWSpoof.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BA6146572210095DA13 /* LZWSpoof.m */; }; 31 | FA9A0C03146574EA0095DA13 /* ANImageBitmapRep.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BEB146574EA0095DA13 /* ANImageBitmapRep.m */; }; 32 | FA9A0C04146574EA0095DA13 /* BitmapContextRep.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BED146574EA0095DA13 /* BitmapContextRep.m */; }; 33 | FA9A0C05146574EA0095DA13 /* NSImage+ANImageBitmapRep.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BF0146574EA0095DA13 /* NSImage+ANImageBitmapRep.m */; }; 34 | FA9A0C06146574EA0095DA13 /* OSCommonImage.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BF2146574EA0095DA13 /* OSCommonImage.m */; }; 35 | FA9A0C07146574EA0095DA13 /* UIImage+ANImageBitmapRep.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BF4146574EA0095DA13 /* UIImage+ANImageBitmapRep.m */; }; 36 | FA9A0C08146574EA0095DA13 /* CGContextCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BF7146574EA0095DA13 /* CGContextCreator.m */; }; 37 | FA9A0C09146574EA0095DA13 /* CGImageContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BF9146574EA0095DA13 /* CGImageContainer.m */; }; 38 | FA9A0C0A146574EA0095DA13 /* BitmapContextManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BFC146574EA0095DA13 /* BitmapContextManipulator.m */; }; 39 | FA9A0C0B146574EA0095DA13 /* BitmapCropManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0BFE146574EA0095DA13 /* BitmapCropManipulator.m */; }; 40 | FA9A0C0C146574EA0095DA13 /* BitmapRotationManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0C00146574EA0095DA13 /* BitmapRotationManipulator.m */; }; 41 | FA9A0C0D146574EA0095DA13 /* BitmapScaleManipulator.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0C02146574EA0095DA13 /* BitmapScaleManipulator.m */; }; 42 | FA9A0C111465750D0095DA13 /* UIImagePixelSource.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0C101465750D0095DA13 /* UIImagePixelSource.m */; }; 43 | FA9A0C14146594830095DA13 /* PhotoEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0C13146594830095DA13 /* PhotoEntry.m */; }; 44 | FA9A0C181465A6210095DA13 /* NSMutableArray+Move.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0C171465A6210095DA13 /* NSMutableArray+Move.m */; }; 45 | FA9A0C1B1465B3110095DA13 /* ExportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9A0C1A1465B3100095DA13 /* ExportViewController.m */; }; 46 | FA9A0C1D1465C0D70095DA13 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9A0C1C1465C0D70095DA13 /* MessageUI.framework */; }; 47 | /* End PBXBuildFile section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 51 | 1D3623240D0F684500981E51 /* GiraffeAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GiraffeAppDelegate.h; sourceTree = ""; }; 52 | 1D3623250D0F684500981E51 /* GiraffeAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GiraffeAppDelegate.m; sourceTree = ""; }; 53 | 1D6058910D05DD3D006BFB54 /* Giraffe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Giraffe.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 55 | 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 56 | 2899E5210DE3E06400AC0155 /* GiraffeViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GiraffeViewController.xib; sourceTree = ""; }; 57 | 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 58 | 28D7ACF60DDB3853001CB0EB /* GiraffeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GiraffeViewController.h; sourceTree = ""; }; 59 | 28D7ACF70DDB3853001CB0EB /* GiraffeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GiraffeViewController.m; sourceTree = ""; }; 60 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 61 | 32CA4F630368D1EE00C91783 /* Giraffe_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Giraffe_Prefix.pch; sourceTree = ""; }; 62 | 8D1107310486CEB800E47090 /* Giraffe-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Giraffe-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; 63 | FA9A0B87146572210095DA13 /* ANGifEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifEncoder.h; sourceTree = ""; }; 64 | FA9A0B88146572210095DA13 /* ANGifEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifEncoder.m; sourceTree = ""; }; 65 | FA9A0B89146572210095DA13 /* ANGifGraphicControlExt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifGraphicControlExt.h; sourceTree = ""; }; 66 | FA9A0B8A146572210095DA13 /* ANGifGraphicControlExt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifGraphicControlExt.m; sourceTree = ""; }; 67 | FA9A0B8B146572210095DA13 /* ANGifLogicalScreenDesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifLogicalScreenDesc.h; sourceTree = ""; }; 68 | FA9A0B8C146572210095DA13 /* ANGifLogicalScreenDesc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifLogicalScreenDesc.m; sourceTree = ""; }; 69 | FA9A0B8E146572210095DA13 /* ANGifAppExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifAppExtension.h; sourceTree = ""; }; 70 | FA9A0B8F146572210095DA13 /* ANGifAppExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifAppExtension.m; sourceTree = ""; }; 71 | FA9A0B90146572210095DA13 /* ANGifNetscapeAppExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifNetscapeAppExtension.h; sourceTree = ""; }; 72 | FA9A0B91146572210095DA13 /* ANGifNetscapeAppExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifNetscapeAppExtension.m; sourceTree = ""; }; 73 | FA9A0B93146572210095DA13 /* ANAvgColorTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANAvgColorTable.h; sourceTree = ""; }; 74 | FA9A0B94146572210095DA13 /* ANAvgColorTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANAvgColorTable.m; sourceTree = ""; }; 75 | FA9A0B95146572210095DA13 /* ANColorTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANColorTable.h; sourceTree = ""; }; 76 | FA9A0B96146572210095DA13 /* ANColorTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANColorTable.m; sourceTree = ""; }; 77 | FA9A0B98146572210095DA13 /* ANCutColorTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANCutColorTable.h; sourceTree = ""; }; 78 | FA9A0B99146572210095DA13 /* ANCutColorTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANCutColorTable.m; sourceTree = ""; }; 79 | FA9A0B9A146572210095DA13 /* ANMutableColorArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANMutableColorArray.h; sourceTree = ""; }; 80 | FA9A0B9B146572210095DA13 /* ANMutableColorArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANMutableColorArray.m; sourceTree = ""; }; 81 | FA9A0B9D146572210095DA13 /* ANGifDataSubblock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifDataSubblock.h; sourceTree = ""; }; 82 | FA9A0B9E146572210095DA13 /* ANGifDataSubblock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifDataSubblock.m; sourceTree = ""; }; 83 | FA9A0B9F146572210095DA13 /* ANGifImageDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifImageDescriptor.h; sourceTree = ""; }; 84 | FA9A0BA0146572210095DA13 /* ANGifImageDescriptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifImageDescriptor.m; sourceTree = ""; }; 85 | FA9A0BA1146572210095DA13 /* ANGifImageFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifImageFrame.h; sourceTree = ""; }; 86 | FA9A0BA2146572210095DA13 /* ANGifImageFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANGifImageFrame.m; sourceTree = ""; }; 87 | FA9A0BA3146572210095DA13 /* ANGifImageFramePixelSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGifImageFramePixelSource.h; sourceTree = ""; }; 88 | FA9A0BA5146572210095DA13 /* LZWSpoof.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LZWSpoof.h; sourceTree = ""; }; 89 | FA9A0BA6146572210095DA13 /* LZWSpoof.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LZWSpoof.m; sourceTree = ""; }; 90 | FA9A0BEA146574EA0095DA13 /* ANImageBitmapRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANImageBitmapRep.h; sourceTree = ""; }; 91 | FA9A0BEB146574EA0095DA13 /* ANImageBitmapRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ANImageBitmapRep.m; sourceTree = ""; }; 92 | FA9A0BEC146574EA0095DA13 /* BitmapContextRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapContextRep.h; sourceTree = ""; }; 93 | FA9A0BED146574EA0095DA13 /* BitmapContextRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapContextRep.m; sourceTree = ""; }; 94 | FA9A0BEF146574EA0095DA13 /* NSImage+ANImageBitmapRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+ANImageBitmapRep.h"; sourceTree = ""; }; 95 | FA9A0BF0146574EA0095DA13 /* NSImage+ANImageBitmapRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSImage+ANImageBitmapRep.m"; sourceTree = ""; }; 96 | FA9A0BF1146574EA0095DA13 /* OSCommonImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSCommonImage.h; sourceTree = ""; }; 97 | FA9A0BF2146574EA0095DA13 /* OSCommonImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSCommonImage.m; sourceTree = ""; }; 98 | FA9A0BF3146574EA0095DA13 /* UIImage+ANImageBitmapRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ANImageBitmapRep.h"; sourceTree = ""; }; 99 | FA9A0BF4146574EA0095DA13 /* UIImage+ANImageBitmapRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ANImageBitmapRep.m"; sourceTree = ""; }; 100 | FA9A0BF6146574EA0095DA13 /* CGContextCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGContextCreator.h; sourceTree = ""; }; 101 | FA9A0BF7146574EA0095DA13 /* CGContextCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGContextCreator.m; sourceTree = ""; }; 102 | FA9A0BF8146574EA0095DA13 /* CGImageContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGImageContainer.h; sourceTree = ""; }; 103 | FA9A0BF9146574EA0095DA13 /* CGImageContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGImageContainer.m; sourceTree = ""; }; 104 | FA9A0BFB146574EA0095DA13 /* BitmapContextManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapContextManipulator.h; sourceTree = ""; }; 105 | FA9A0BFC146574EA0095DA13 /* BitmapContextManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapContextManipulator.m; sourceTree = ""; }; 106 | FA9A0BFD146574EA0095DA13 /* BitmapCropManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapCropManipulator.h; sourceTree = ""; }; 107 | FA9A0BFE146574EA0095DA13 /* BitmapCropManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapCropManipulator.m; sourceTree = ""; }; 108 | FA9A0BFF146574EA0095DA13 /* BitmapRotationManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapRotationManipulator.h; sourceTree = ""; }; 109 | FA9A0C00146574EA0095DA13 /* BitmapRotationManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapRotationManipulator.m; sourceTree = ""; }; 110 | FA9A0C01146574EA0095DA13 /* BitmapScaleManipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapScaleManipulator.h; sourceTree = ""; }; 111 | FA9A0C02146574EA0095DA13 /* BitmapScaleManipulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitmapScaleManipulator.m; sourceTree = ""; }; 112 | FA9A0C0F1465750D0095DA13 /* UIImagePixelSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIImagePixelSource.h; sourceTree = ""; }; 113 | FA9A0C101465750D0095DA13 /* UIImagePixelSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIImagePixelSource.m; sourceTree = ""; }; 114 | FA9A0C12146594820095DA13 /* PhotoEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoEntry.h; sourceTree = ""; }; 115 | FA9A0C13146594830095DA13 /* PhotoEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoEntry.m; sourceTree = ""; }; 116 | FA9A0C161465A6210095DA13 /* NSMutableArray+Move.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+Move.h"; sourceTree = ""; }; 117 | FA9A0C171465A6210095DA13 /* NSMutableArray+Move.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+Move.m"; sourceTree = ""; }; 118 | FA9A0C191465B30F0095DA13 /* ExportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExportViewController.h; sourceTree = ""; }; 119 | FA9A0C1A1465B3100095DA13 /* ExportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExportViewController.m; sourceTree = ""; }; 120 | FA9A0C1C1465C0D70095DA13 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; 121 | /* End PBXFileReference section */ 122 | 123 | /* Begin PBXFrameworksBuildPhase section */ 124 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 125 | isa = PBXFrameworksBuildPhase; 126 | buildActionMask = 2147483647; 127 | files = ( 128 | FA9A0C1D1465C0D70095DA13 /* MessageUI.framework in Frameworks */, 129 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 130 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 131 | 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | /* End PBXFrameworksBuildPhase section */ 136 | 137 | /* Begin PBXGroup section */ 138 | 080E96DDFE201D6D7F000001 /* Classes */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | FA9A0C151465A5770095DA13 /* Utilities */, 142 | FA9A0C0E146574F50095DA13 /* Encoding */, 143 | 1D3623240D0F684500981E51 /* GiraffeAppDelegate.h */, 144 | 1D3623250D0F684500981E51 /* GiraffeAppDelegate.m */, 145 | 28D7ACF60DDB3853001CB0EB /* GiraffeViewController.h */, 146 | 28D7ACF70DDB3853001CB0EB /* GiraffeViewController.m */, 147 | FA9A0C12146594820095DA13 /* PhotoEntry.h */, 148 | FA9A0C13146594830095DA13 /* PhotoEntry.m */, 149 | FA9A0C191465B30F0095DA13 /* ExportViewController.h */, 150 | FA9A0C1A1465B3100095DA13 /* ExportViewController.m */, 151 | ); 152 | path = Classes; 153 | sourceTree = ""; 154 | }; 155 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 1D6058910D05DD3D006BFB54 /* Giraffe.app */, 159 | ); 160 | name = Products; 161 | sourceTree = ""; 162 | }; 163 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | FA9A0BE9146574EA0095DA13 /* ANImageBitmapRep */, 167 | FA9A0B86146572210095DA13 /* ANGif */, 168 | 080E96DDFE201D6D7F000001 /* Classes */, 169 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 170 | 29B97317FDCFA39411CA2CEA /* Resources */, 171 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 172 | 19C28FACFE9D520D11CA2CBB /* Products */, 173 | ); 174 | name = CustomTemplate; 175 | sourceTree = ""; 176 | }; 177 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 32CA4F630368D1EE00C91783 /* Giraffe_Prefix.pch */, 181 | 29B97316FDCFA39411CA2CEA /* main.m */, 182 | ); 183 | name = "Other Sources"; 184 | sourceTree = ""; 185 | }; 186 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 2899E5210DE3E06400AC0155 /* GiraffeViewController.xib */, 190 | 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 191 | 8D1107310486CEB800E47090 /* Giraffe-Info.plist */, 192 | ); 193 | name = Resources; 194 | sourceTree = ""; 195 | }; 196 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | FA9A0C1C1465C0D70095DA13 /* MessageUI.framework */, 200 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 201 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 202 | 288765A40DF7441C002DB57D /* CoreGraphics.framework */, 203 | ); 204 | name = Frameworks; 205 | sourceTree = ""; 206 | }; 207 | FA9A0B86146572210095DA13 /* ANGif */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | FA9A0B87146572210095DA13 /* ANGifEncoder.h */, 211 | FA9A0B88146572210095DA13 /* ANGifEncoder.m */, 212 | FA9A0B89146572210095DA13 /* ANGifGraphicControlExt.h */, 213 | FA9A0B8A146572210095DA13 /* ANGifGraphicControlExt.m */, 214 | FA9A0B8B146572210095DA13 /* ANGifLogicalScreenDesc.h */, 215 | FA9A0B8C146572210095DA13 /* ANGifLogicalScreenDesc.m */, 216 | FA9A0B8D146572210095DA13 /* App Extensions */, 217 | FA9A0B92146572210095DA13 /* ColorTable */, 218 | FA9A0B9C146572210095DA13 /* ImageFrame */, 219 | FA9A0BA4146572210095DA13 /* LZW */, 220 | ); 221 | path = ANGif; 222 | sourceTree = ""; 223 | }; 224 | FA9A0B8D146572210095DA13 /* App Extensions */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | FA9A0B8E146572210095DA13 /* ANGifAppExtension.h */, 228 | FA9A0B8F146572210095DA13 /* ANGifAppExtension.m */, 229 | FA9A0B90146572210095DA13 /* ANGifNetscapeAppExtension.h */, 230 | FA9A0B91146572210095DA13 /* ANGifNetscapeAppExtension.m */, 231 | ); 232 | path = "App Extensions"; 233 | sourceTree = ""; 234 | }; 235 | FA9A0B92146572210095DA13 /* ColorTable */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | FA9A0B93146572210095DA13 /* ANAvgColorTable.h */, 239 | FA9A0B94146572210095DA13 /* ANAvgColorTable.m */, 240 | FA9A0B95146572210095DA13 /* ANColorTable.h */, 241 | FA9A0B96146572210095DA13 /* ANColorTable.m */, 242 | FA9A0B97146572210095DA13 /* Cut */, 243 | ); 244 | path = ColorTable; 245 | sourceTree = ""; 246 | }; 247 | FA9A0B97146572210095DA13 /* Cut */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | FA9A0B98146572210095DA13 /* ANCutColorTable.h */, 251 | FA9A0B99146572210095DA13 /* ANCutColorTable.m */, 252 | FA9A0B9A146572210095DA13 /* ANMutableColorArray.h */, 253 | FA9A0B9B146572210095DA13 /* ANMutableColorArray.m */, 254 | ); 255 | path = Cut; 256 | sourceTree = ""; 257 | }; 258 | FA9A0B9C146572210095DA13 /* ImageFrame */ = { 259 | isa = PBXGroup; 260 | children = ( 261 | FA9A0B9D146572210095DA13 /* ANGifDataSubblock.h */, 262 | FA9A0B9E146572210095DA13 /* ANGifDataSubblock.m */, 263 | FA9A0B9F146572210095DA13 /* ANGifImageDescriptor.h */, 264 | FA9A0BA0146572210095DA13 /* ANGifImageDescriptor.m */, 265 | FA9A0BA1146572210095DA13 /* ANGifImageFrame.h */, 266 | FA9A0BA2146572210095DA13 /* ANGifImageFrame.m */, 267 | FA9A0BA3146572210095DA13 /* ANGifImageFramePixelSource.h */, 268 | ); 269 | path = ImageFrame; 270 | sourceTree = ""; 271 | }; 272 | FA9A0BA4146572210095DA13 /* LZW */ = { 273 | isa = PBXGroup; 274 | children = ( 275 | FA9A0BA5146572210095DA13 /* LZWSpoof.h */, 276 | FA9A0BA6146572210095DA13 /* LZWSpoof.m */, 277 | ); 278 | path = LZW; 279 | sourceTree = ""; 280 | }; 281 | FA9A0BE9146574EA0095DA13 /* ANImageBitmapRep */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | FA9A0BEA146574EA0095DA13 /* ANImageBitmapRep.h */, 285 | FA9A0BEB146574EA0095DA13 /* ANImageBitmapRep.m */, 286 | FA9A0BEC146574EA0095DA13 /* BitmapContextRep.h */, 287 | FA9A0BED146574EA0095DA13 /* BitmapContextRep.m */, 288 | FA9A0BEE146574EA0095DA13 /* Compatibility */, 289 | FA9A0BF5146574EA0095DA13 /* CoreGraphics */, 290 | FA9A0BFA146574EA0095DA13 /* Manipulators */, 291 | ); 292 | path = ANImageBitmapRep; 293 | sourceTree = ""; 294 | }; 295 | FA9A0BEE146574EA0095DA13 /* Compatibility */ = { 296 | isa = PBXGroup; 297 | children = ( 298 | FA9A0BEF146574EA0095DA13 /* NSImage+ANImageBitmapRep.h */, 299 | FA9A0BF0146574EA0095DA13 /* NSImage+ANImageBitmapRep.m */, 300 | FA9A0BF1146574EA0095DA13 /* OSCommonImage.h */, 301 | FA9A0BF2146574EA0095DA13 /* OSCommonImage.m */, 302 | FA9A0BF3146574EA0095DA13 /* UIImage+ANImageBitmapRep.h */, 303 | FA9A0BF4146574EA0095DA13 /* UIImage+ANImageBitmapRep.m */, 304 | ); 305 | path = Compatibility; 306 | sourceTree = ""; 307 | }; 308 | FA9A0BF5146574EA0095DA13 /* CoreGraphics */ = { 309 | isa = PBXGroup; 310 | children = ( 311 | FA9A0BF6146574EA0095DA13 /* CGContextCreator.h */, 312 | FA9A0BF7146574EA0095DA13 /* CGContextCreator.m */, 313 | FA9A0BF8146574EA0095DA13 /* CGImageContainer.h */, 314 | FA9A0BF9146574EA0095DA13 /* CGImageContainer.m */, 315 | ); 316 | path = CoreGraphics; 317 | sourceTree = ""; 318 | }; 319 | FA9A0BFA146574EA0095DA13 /* Manipulators */ = { 320 | isa = PBXGroup; 321 | children = ( 322 | FA9A0BFB146574EA0095DA13 /* BitmapContextManipulator.h */, 323 | FA9A0BFC146574EA0095DA13 /* BitmapContextManipulator.m */, 324 | FA9A0BFD146574EA0095DA13 /* BitmapCropManipulator.h */, 325 | FA9A0BFE146574EA0095DA13 /* BitmapCropManipulator.m */, 326 | FA9A0BFF146574EA0095DA13 /* BitmapRotationManipulator.h */, 327 | FA9A0C00146574EA0095DA13 /* BitmapRotationManipulator.m */, 328 | FA9A0C01146574EA0095DA13 /* BitmapScaleManipulator.h */, 329 | FA9A0C02146574EA0095DA13 /* BitmapScaleManipulator.m */, 330 | ); 331 | path = Manipulators; 332 | sourceTree = ""; 333 | }; 334 | FA9A0C0E146574F50095DA13 /* Encoding */ = { 335 | isa = PBXGroup; 336 | children = ( 337 | FA9A0C0F1465750D0095DA13 /* UIImagePixelSource.h */, 338 | FA9A0C101465750D0095DA13 /* UIImagePixelSource.m */, 339 | ); 340 | name = Encoding; 341 | sourceTree = ""; 342 | }; 343 | FA9A0C151465A5770095DA13 /* Utilities */ = { 344 | isa = PBXGroup; 345 | children = ( 346 | FA9A0C161465A6210095DA13 /* NSMutableArray+Move.h */, 347 | FA9A0C171465A6210095DA13 /* NSMutableArray+Move.m */, 348 | ); 349 | name = Utilities; 350 | sourceTree = ""; 351 | }; 352 | /* End PBXGroup section */ 353 | 354 | /* Begin PBXNativeTarget section */ 355 | 1D6058900D05DD3D006BFB54 /* Giraffe */ = { 356 | isa = PBXNativeTarget; 357 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Giraffe" */; 358 | buildPhases = ( 359 | 1D60588D0D05DD3D006BFB54 /* Resources */, 360 | 1D60588E0D05DD3D006BFB54 /* Sources */, 361 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 362 | ); 363 | buildRules = ( 364 | ); 365 | dependencies = ( 366 | ); 367 | name = Giraffe; 368 | productName = Giraffe; 369 | productReference = 1D6058910D05DD3D006BFB54 /* Giraffe.app */; 370 | productType = "com.apple.product-type.application"; 371 | }; 372 | /* End PBXNativeTarget section */ 373 | 374 | /* Begin PBXProject section */ 375 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 376 | isa = PBXProject; 377 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Giraffe" */; 378 | compatibilityVersion = "Xcode 3.1"; 379 | developmentRegion = English; 380 | hasScannedForEncodings = 1; 381 | knownRegions = ( 382 | English, 383 | Japanese, 384 | French, 385 | German, 386 | ); 387 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 388 | projectDirPath = ""; 389 | projectRoot = ""; 390 | targets = ( 391 | 1D6058900D05DD3D006BFB54 /* Giraffe */, 392 | ); 393 | }; 394 | /* End PBXProject section */ 395 | 396 | /* Begin PBXResourcesBuildPhase section */ 397 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 398 | isa = PBXResourcesBuildPhase; 399 | buildActionMask = 2147483647; 400 | files = ( 401 | 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 402 | 2899E5220DE3E06400AC0155 /* GiraffeViewController.xib in Resources */, 403 | ); 404 | runOnlyForDeploymentPostprocessing = 0; 405 | }; 406 | /* End PBXResourcesBuildPhase section */ 407 | 408 | /* Begin PBXSourcesBuildPhase section */ 409 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 410 | isa = PBXSourcesBuildPhase; 411 | buildActionMask = 2147483647; 412 | files = ( 413 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 414 | 1D3623260D0F684500981E51 /* GiraffeAppDelegate.m in Sources */, 415 | 28D7ACF80DDB3853001CB0EB /* GiraffeViewController.m in Sources */, 416 | FA9A0BA7146572210095DA13 /* ANGifEncoder.m in Sources */, 417 | FA9A0BA8146572210095DA13 /* ANGifGraphicControlExt.m in Sources */, 418 | FA9A0BA9146572210095DA13 /* ANGifLogicalScreenDesc.m in Sources */, 419 | FA9A0BAA146572210095DA13 /* ANGifAppExtension.m in Sources */, 420 | FA9A0BAB146572210095DA13 /* ANGifNetscapeAppExtension.m in Sources */, 421 | FA9A0BAC146572210095DA13 /* ANAvgColorTable.m in Sources */, 422 | FA9A0BAD146572210095DA13 /* ANColorTable.m in Sources */, 423 | FA9A0BAE146572210095DA13 /* ANCutColorTable.m in Sources */, 424 | FA9A0BAF146572210095DA13 /* ANMutableColorArray.m in Sources */, 425 | FA9A0BB0146572210095DA13 /* ANGifDataSubblock.m in Sources */, 426 | FA9A0BB1146572210095DA13 /* ANGifImageDescriptor.m in Sources */, 427 | FA9A0BB2146572210095DA13 /* ANGifImageFrame.m in Sources */, 428 | FA9A0BB3146572210095DA13 /* LZWSpoof.m in Sources */, 429 | FA9A0C03146574EA0095DA13 /* ANImageBitmapRep.m in Sources */, 430 | FA9A0C04146574EA0095DA13 /* BitmapContextRep.m in Sources */, 431 | FA9A0C05146574EA0095DA13 /* NSImage+ANImageBitmapRep.m in Sources */, 432 | FA9A0C06146574EA0095DA13 /* OSCommonImage.m in Sources */, 433 | FA9A0C07146574EA0095DA13 /* UIImage+ANImageBitmapRep.m in Sources */, 434 | FA9A0C08146574EA0095DA13 /* CGContextCreator.m in Sources */, 435 | FA9A0C09146574EA0095DA13 /* CGImageContainer.m in Sources */, 436 | FA9A0C0A146574EA0095DA13 /* BitmapContextManipulator.m in Sources */, 437 | FA9A0C0B146574EA0095DA13 /* BitmapCropManipulator.m in Sources */, 438 | FA9A0C0C146574EA0095DA13 /* BitmapRotationManipulator.m in Sources */, 439 | FA9A0C0D146574EA0095DA13 /* BitmapScaleManipulator.m in Sources */, 440 | FA9A0C111465750D0095DA13 /* UIImagePixelSource.m in Sources */, 441 | FA9A0C14146594830095DA13 /* PhotoEntry.m in Sources */, 442 | FA9A0C181465A6210095DA13 /* NSMutableArray+Move.m in Sources */, 443 | FA9A0C1B1465B3110095DA13 /* ExportViewController.m in Sources */, 444 | ); 445 | runOnlyForDeploymentPostprocessing = 0; 446 | }; 447 | /* End PBXSourcesBuildPhase section */ 448 | 449 | /* Begin XCBuildConfiguration section */ 450 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ALWAYS_SEARCH_USER_PATHS = NO; 454 | COPY_PHASE_STRIP = NO; 455 | GCC_DYNAMIC_NO_PIC = NO; 456 | GCC_OPTIMIZATION_LEVEL = 0; 457 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 458 | GCC_PREFIX_HEADER = Giraffe_Prefix.pch; 459 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 460 | INFOPLIST_FILE = "Giraffe-Info.plist"; 461 | PRODUCT_NAME = Giraffe; 462 | }; 463 | name = Debug; 464 | }; 465 | 1D6058950D05DD3E006BFB54 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ALWAYS_SEARCH_USER_PATHS = NO; 469 | COPY_PHASE_STRIP = YES; 470 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 471 | GCC_PREFIX_HEADER = Giraffe_Prefix.pch; 472 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 473 | INFOPLIST_FILE = "Giraffe-Info.plist"; 474 | PRODUCT_NAME = Giraffe; 475 | VALIDATE_PRODUCT = YES; 476 | }; 477 | name = Release; 478 | }; 479 | C01FCF4F08A954540054247B /* Debug */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 483 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 484 | GCC_C_LANGUAGE_STANDARD = c99; 485 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 486 | GCC_WARN_UNUSED_VARIABLE = YES; 487 | PREBINDING = NO; 488 | SDKROOT = iphoneos; 489 | }; 490 | name = Debug; 491 | }; 492 | C01FCF5008A954540054247B /* Release */ = { 493 | isa = XCBuildConfiguration; 494 | buildSettings = { 495 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 496 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 497 | GCC_C_LANGUAGE_STANDARD = c99; 498 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 499 | GCC_WARN_UNUSED_VARIABLE = YES; 500 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 501 | PREBINDING = NO; 502 | SDKROOT = iphoneos; 503 | }; 504 | name = Release; 505 | }; 506 | /* End XCBuildConfiguration section */ 507 | 508 | /* Begin XCConfigurationList section */ 509 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Giraffe" */ = { 510 | isa = XCConfigurationList; 511 | buildConfigurations = ( 512 | 1D6058940D05DD3E006BFB54 /* Debug */, 513 | 1D6058950D05DD3E006BFB54 /* Release */, 514 | ); 515 | defaultConfigurationIsVisible = 0; 516 | defaultConfigurationName = Release; 517 | }; 518 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Giraffe" */ = { 519 | isa = XCConfigurationList; 520 | buildConfigurations = ( 521 | C01FCF4F08A954540054247B /* Debug */, 522 | C01FCF5008A954540054247B /* Release */, 523 | ); 524 | defaultConfigurationIsVisible = 0; 525 | defaultConfigurationName = Release; 526 | }; 527 | /* End XCConfigurationList section */ 528 | }; 529 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 530 | } 531 | --------------------------------------------------------------------------------