/XeeExperimentalImage1Saver.m

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