/XeeExperimentalImage1Saver.m
Objective C | 163 lines | 130 code | 27 blank | 6 comment | 10 complexity | 22c593b6bad73267dd9abdf9b65a47e7 MD5 | raw file
1#import "XeeExperimentalImage1Saver.h" 2#import "XeeBitmapImage.h" 3 4#import <XADMaster/CSFileHandle.h> 5 6static void f(int n,int *xp,int *yp); 7static int fi(int x,int y); 8 9@implementation XeeExperimentalImage1Saver 10 11+(BOOL)canSaveImage:(XeeImage *)img 12{ 13 return YES; 14/* CGImageRef cgimage=[img createCGImage]; 15 if(!img) return NO; 16 int depth=CGImageGetBitsPerComponent(cgimage); 17 int info=CGImageGetBitmapInfo(cgimage); 18 CGImageRelease(cgimage); 19 return depth==8;*/ 20} 21 22-(id)initWithImage:(XeeImage *)img 23{ 24 if(self=[super initWithImage:img]) 25 { 26 } 27 return self; 28} 29 30-(NSString *)format { return @"Xee Experimental Image Format 1"; } 31 32-(NSString *)extension { return @"xei1"; } 33 34-(BOOL)save:(NSString *)filename 35{ 36 BOOL res=NO; 37 CGImageRef cgimage=[image createCGImage]; 38 if(cgimage) 39 { 40 int pixelwidth=CGImageGetWidth(cgimage); 41 int pixelheight=CGImageGetHeight(cgimage); 42 43 XeeBitmapImage *bmimage=[[[XeeBitmapImage alloc] initWithType:XeeBitmapTypeNRGB8 width:pixelwidth height:pixelheight] autorelease]; 44 45 if(image) 46 { 47 CGContextRef cgcontext=[bmimage createCGContext]; 48 if(cgcontext) 49 { 50 CGContextDrawImage(cgcontext,CGRectMake(0,0,pixelwidth,pixelheight),cgimage); 51 CGContextRelease(cgcontext); 52 53 CSFileHandle *fh=[CSFileHandle fileHandleForWritingAtPath:filename]; 54 55 if(fh) 56 { 57 [fh writeInt32BE:'XEI1']; 58 [fh writeInt32BE:pixelwidth]; 59 [fh writeInt32BE:pixelheight]; 60 61 uint8_t *data=[bmimage data]; 62 int bpr=[bmimage bytesPerRow]; 63 int left,n,x,y; 64 uint8_t prev; 65 66 left=pixelwidth*pixelheight; 67 n=0; 68 prev=0; 69 while(left) 70 { 71 f(n++,&x,&y); 72 if(x<pixelwidth&y<pixelheight) 73 { 74 uint32_t *row=(uint32_t *)(data+y*bpr); 75 uint8_t val=XeeGetRFromNRGB8(row[x]); 76 [fh writeUInt8:(uint8_t)(val-prev)]; 77 prev=val; 78 left--; 79 } 80 } 81 82 left=pixelwidth*pixelheight; 83 n=0; 84 prev=0; 85 while(left) 86 { 87 f(n++,&x,&y); 88 if(x<pixelwidth&y<pixelheight) 89 { 90 uint32_t *row=(uint32_t *)(data+y*bpr); 91 uint8_t val=XeeGetGFromNRGB8(row[x]); 92 [fh writeUInt8:(uint8_t)(val-prev)]; 93 prev=val; 94 left--; 95 } 96 } 97 98 left=pixelwidth*pixelheight; 99 n=0; 100 prev=0; 101 while(left) 102 { 103 f(n++,&x,&y); 104 if(x<pixelwidth&y<pixelheight) 105 { 106 uint32_t *row=(uint32_t *)(data+y*bpr); 107 uint8_t val=XeeGetBFromNRGB8(row[x]); 108 [fh writeUInt8:(uint8_t)(val-prev)]; 109 prev=val; 110 left--; 111 } 112 } 113 114 res=YES; 115 } 116 } 117 } 118 119 CGImageRelease(cgimage); 120 } 121 return res; 122} 123 124@end 125 126 127static int transform_table[4][4]={{0,1,2,3},{0,2,1,3},{3,2,1,0},{3,1,2,0}}; 128static int locations[4]={0,1,3,2}; 129 130static void f(int n,int *xp,int *yp) 131{ 132 static int transforms[4]={1,0,0,3}; 133 int x=0,y=0; 134 int trans=0; 135 for(int i=30;i>=0;i-=2) 136 { 137 int m=(n>>i)&3; 138 int bits=transform_table[trans][locations[m]]; 139 140 x=(x<<1)|((bits>>1)&1); 141 y=(y<<1)|(bits&1); 142 143 trans^=transforms[m]; 144 } 145 *xp=x; *yp=y; 146} 147 148static int fi(int x,int y) 149{ 150 static int transforms[4]={1,0,3,0}; 151 int n=0; 152 int trans=0; 153 for(int i=15;i>=0;i--) 154 { 155 int m=transform_table[trans][((y>>i)&1)|(((x>>i)&1)<<1)]; 156 int bits=locations[m]; 157 158 n=(n<<2)|bits; 159 160 trans^=transforms[m]; 161 } 162 return n; 163}