├── .gitignore ├── .gitmodules ├── English.lproj ├── ImageAlphaDocument.xib └── MainMenu.xib ├── IABackgroundRenderer.h ├── IABackgroundRenderer.m ├── IABackgroundRenderer.py ├── IACollectionItem.py ├── IAColorBackgroundRenderer.h ├── IAColorBackgroundRenderer.m ├── IAImage.py ├── IAImageView.py ├── IAImageViewInteractive.py ├── IAPatternBackgroundRenderer.h ├── IAPatternBackgroundRenderer.m ├── IASlider.py ├── ImageAlpha.icns ├── ImageAlpha.xcodeproj └── project.pbxproj ├── ImageAlphaApplication.h ├── ImageAlphaApplication.m ├── ImageAlphaDocument.py ├── ImageAlphaDocumentC.h ├── ImageAlphaDocumentC.m ├── ImageAlpha_Prefix.pch ├── Info.plist ├── LICENSE ├── Makefile ├── README.md ├── appcast.xml ├── debug.xcconfig ├── dsa_pub.pem ├── main.m ├── main.py ├── optimal_file_list ├── pngnq.xcodeproj └── project.pbxproj ├── pngquant.xcodeproj └── project.pbxproj ├── posterizer.xcodeproj └── project.pbxproj ├── release.xcconfig ├── textures ├── 461223185.jpg ├── 461223192.jpg ├── A_MIXRED.jpeg ├── G_IRON3.jpg ├── Rustpattern.jpeg ├── STONE4.jpeg ├── nature71.jpg ├── photoshop.png └── seawaterfull2.jpg └── zh-Hans.lproj ├── ImageAlphaDocument.xib └── MainMenu.xib /.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.pbxuser 3 | Sparkle.framework 4 | build 5 | DerivedData 6 | sign_update.rb 7 | update_appcast.php -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Sparkle"] 2 | path = Sparkle 3 | url = https://github.com/sparkle-project/Sparkle.git 4 | [submodule "mediancut-posterizer"] 5 | path = mediancut-posterizer 6 | url = git@github.com:pornel/mediancut-posterizer.git 7 | -------------------------------------------------------------------------------- /English.lproj/ImageAlphaDocument.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | NSIsNil 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | NSIsNotNil 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 150 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | NSIsNotNil 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | IABitDepthTransformer 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | NSNegateBoolean 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | NSIsNotNil 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | NSNegateBoolean 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | NSIsNotNil 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | IABitDepthNameTransformer 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | NSNegateBoolean 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | NSIsNotNil 354 | 355 | 356 | 357 | 358 | 359 | 360 | IAZoomTransformer 361 | 362 | 363 | 364 | 365 | 366 | 367 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | NSIsNil 396 | 397 | 398 | 399 | 400 | 401 | IAZoomTimesTransformer 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 462 | 463 | 464 | -------------------------------------------------------------------------------- /English.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /IABackgroundRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // IABackgroundRenderer.h 3 | // ImageAlpha 4 | // 5 | // Created by Kornel on 25.lis.12. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface IABackgroundRenderer : NSObject 12 | -(BOOL)canMove; 13 | @end 14 | -------------------------------------------------------------------------------- /IABackgroundRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // IABackgroundRenderer.m 3 | // ImageAlpha 4 | // 5 | // Created by Kornel on 25.lis.12. 6 | // 7 | // 8 | 9 | #import "IABackgroundRenderer.h" 10 | 11 | @implementation IABackgroundRenderer 12 | 13 | -(BOOL)canMove { 14 | return NO; 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /IABackgroundRenderer.py: -------------------------------------------------------------------------------- 1 | # 2 | # IABackgroundRenderer.py 3 | from objc import * 4 | from Foundation import * 5 | from AppKit import * 6 | from IAImageView import IAImageView 7 | from math import floor, ceil 8 | from Quartz.CoreGraphics import * 9 | from Quartz.QuartzCore import * 10 | 11 | IAColorBackgroundRenderer = NSClassFromString("IAColorBackgroundRenderer"); 12 | 13 | class IAImageBackgroundRenderer(NSClassFromString("IAPatternBackgroundRenderer")): 14 | backgroundOffset = (0,0) 15 | 16 | def initWithImage_(self,image): 17 | self = super(IAImageBackgroundRenderer, self).init(); 18 | if self: 19 | self.setTileImage_(image); 20 | self.moveBy_((0,0)); 21 | return self; 22 | 23 | def canMove(self): 24 | return YES 25 | 26 | def moveBy_(self,delta): 27 | self.backgroundOffset = ((self.backgroundOffset[0] + delta[0]), 28 | (self.backgroundOffset[1] + delta[1])) 29 | self.tileLayerAtX_Y_(self.backgroundOffset[0],self.backgroundOffset[1]); 30 | 31 | -------------------------------------------------------------------------------- /IACollectionItem.py: -------------------------------------------------------------------------------- 1 | # 2 | # IACollectionItem.py 3 | 4 | from Foundation import * 5 | from objc import * 6 | from AppKit import * 7 | from random import randint 8 | from IAImageView import IAImageView 9 | from IAImageViewInteractive import IAImageViewInteractive 10 | from IABackgroundRenderer import * 11 | 12 | class IACollectionViewItem(NSCollectionViewItem): 13 | def setSelected_(self, sel): 14 | NSCollectionViewItem.setSelected_(self,sel) 15 | col = self.collectionView() 16 | if sel and col is not None: 17 | col.updateSelection() 18 | 19 | def imageChangedNotification_(self,sender): 20 | view = self.view() 21 | if view is not None: 22 | subview = view.viewWithTag_(1234); 23 | if subview is not None: 24 | subview.setImage_(sender.object().image); 25 | 26 | class IACollectionImageView(IAImageView): 27 | collectionItem = None; 28 | drawBorder = False 29 | 30 | def initWithFrame_(self, frame): 31 | NSLog("col img view init"); 32 | self = super(IACollectionImageView, self).initWithFrame_(frame) 33 | assert self.layer() is not None; 34 | if self: 35 | self.registerTypes() 36 | return self 37 | 38 | def registerTypes(self): 39 | # initialization code here 40 | types = [NSFilenamesPboardType] 41 | types.append(NSImage.imagePasteboardTypes()) 42 | self.registerForDraggedTypes_(types); 43 | def draggingEntered_(self,sender): 44 | if NSImage.canInitWithPasteboard_(sender.draggingPasteboard()): 45 | self.imageFade = 0.2 46 | image = NSImage.alloc().initWithPasteboard_(sender.draggingPasteboard()) 47 | if image is not None: 48 | self.setBackgroundRenderer_(IAImageBackgroundRenderer.alloc().initWithImage_(image)) 49 | self.setNeedsDisplay_(YES) 50 | return NSDragOperationCopy | NSDragOperationGeneric | NSDragOperationMove 51 | 52 | def draggingExited_(self,sender): 53 | self.imageFade = 1.0 54 | self.setBackgroundRenderer_(self.collectionItem.representedObject()) 55 | self.setNeedsDisplay_(YES) 56 | 57 | def prepareForDragOperation_(self,sender): 58 | self.imageFade = 1.0 59 | self.setNeedsDisplay_(YES) 60 | if NSImage.canInitWithPasteboard_(sender.draggingPasteboard()): 61 | return YES 62 | else: 63 | self.draggingExited_(sender) 64 | 65 | def performDragOperation_(self,sender): 66 | image = NSImage.alloc().initWithPasteboard_(sender.draggingPasteboard()) 67 | if image is not None: 68 | self.collectionItem.setSelected_(YES) 69 | self.collectionItem.collectionView().setBackgroundImage_(image); 70 | self.setNeedsDisplay_(YES) 71 | return YES 72 | else: 73 | self.draggingExited_(sender) 74 | 75 | 76 | def tag(self): 77 | return 1234; # magic for interface builder 78 | 79 | def mouseEntered_(self,event): 80 | self.imageFade = 0.75 81 | self.drawBorder = True 82 | 83 | def mouseExited_(self,event): 84 | self.imageFade = 1 85 | pass 86 | 87 | def mouseUp_(self,event): 88 | self.drawBorder = False 89 | self.setNeedsDisplay_(YES) 90 | if self.collectionItem is not None: 91 | self.collectionItem.setSelected_(YES) 92 | 93 | def mouseDown_(self,event): 94 | self.drawBorder = True 95 | self.setNeedsDisplay_(YES) 96 | 97 | 98 | 99 | class IACollectionView(NSCollectionView): 100 | imageView = objc.IBOutlet() 101 | image = None 102 | 103 | #def frameChanged_(self,bla): 104 | # self.setMaxItemSize_((300,300)) 105 | #for i in self.content(): 106 | # i.view().setNeedsDisplay_(YES) 107 | # pass 108 | 109 | def awakeFromNib(self): 110 | self.setAllowsMultipleSelection_(NO); 111 | self.sendNotification_(u"SelectionChanged"); 112 | #self.setPostsFrameChangedNotifications_(YES) 113 | # NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self,self.frameChanged_,NSViewFrameDidChangeNotification,self); 114 | 115 | def sendNotification_(self,name): 116 | n = NSNotification.notificationWithName_object_(name,self) 117 | NSNotificationQueue.defaultQueue().enqueueNotification_postingStyle_coalesceMask_forModes_(n,NSPostWhenIdle,NSNotificationCoalescingOnName,None) 118 | 119 | 120 | def selectionChangedNotification_(self,sender): 121 | self.updateSelection(); 122 | 123 | def updateSelection(self): 124 | idx = self.selectionIndexes().firstIndex() 125 | if idx != NSNotFound: 126 | self.imageView.setBackgroundRenderer_(self.content()[idx]); 127 | 128 | def setBackgroundImage_(self,img): 129 | bgr = IAImageBackgroundRenderer.alloc().initWithImage_(img); 130 | content = NSMutableArray.arrayWithArray_(self.content()); 131 | idx = self.selectionIndexes().firstIndex() 132 | if idx != NSNotFound: 133 | content[idx] = bgr 134 | self.setContent_(content); 135 | self.sendNotification_(u"SelectionChanged"); 136 | 137 | def setImage_(self,img): 138 | self.image = img 139 | if img is not None: 140 | size = img.size() 141 | self.setMaxItemSize_((max(100,size.width*2),max(100,size.height*2))) 142 | self.setMinItemSize_((40,40)) 143 | 144 | self.sendNotification_(u"ImageChanged"); 145 | pass 146 | 147 | def newItemForRepresentedObject_(self,obj): 148 | colitem = super(IACollectionView,self).newItemForRepresentedObject_(obj); 149 | 150 | view = colitem.view().viewWithTag_(1234); 151 | #view = IACollectionImageView.alloc().initWithFrame_(((0,0),image.size())) 152 | view.setImage_(self.image) 153 | view.setBackgroundRenderer_(obj) 154 | view.zoomToFill(0.8); 155 | #colitem = IACollectionViewItem.alloc().init() 156 | #colitem.setRepresentedObject_(obj) 157 | #colitem.setView_(view) 158 | view.collectionItem = colitem 159 | 160 | # FIXME: remove from notification queue when deallocing! 161 | NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(colitem,colitem.imageChangedNotification_, u"ImageChanged", self) 162 | return colitem; 163 | 164 | 165 | -------------------------------------------------------------------------------- /IAColorBackgroundRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // IAColorBackgroundRenderer.h 3 | // ImageAlpha 4 | // 5 | // Created by (ja) xx on 16.kwi.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "IABackgroundRenderer.h" 10 | 11 | @interface IAColorBackgroundRenderer : IABackgroundRenderer { 12 | CALayer *layer; 13 | } 14 | 15 | -(id)initWithColor:(NSColor*)c; 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /IAColorBackgroundRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // IAColorBackgroundRenderer.m 3 | // ImageAlpha 4 | // 5 | // Created by (ja) xx on 16.kwi.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "IAColorBackgroundRenderer.h" 10 | 11 | @implementation IAColorBackgroundRenderer 12 | 13 | static CGColorRef CGColorCreateFromNSColor(CGColorSpaceRef colorSpace, NSColor *color) 14 | { 15 | NSColor *deviceColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; 16 | 17 | CGFloat components[4]; 18 | [deviceColor getRed: &components[0] green: &components[1] blue:&components[2] alpha: &components[3]]; 19 | 20 | return CGColorCreate(colorSpace, components); 21 | } 22 | 23 | -(id)initWithColor:(NSColor*)c 24 | { 25 | self = [super init]; 26 | if (self) { 27 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB (); 28 | CGColorRef color = CGColorCreateFromNSColor(colorSpace, c); 29 | layer = [CALayer new]; 30 | layer.backgroundColor = color; 31 | CGColorSpaceRelease (colorSpace); 32 | CGColorRelease(color); 33 | } 34 | return self; 35 | } 36 | 37 | -(CALayer *)getLayer { 38 | CALayer *newLayer = [CALayer new]; 39 | CGColorRef color = CGColorCreateCopy(layer.backgroundColor); 40 | newLayer.backgroundColor = color; 41 | CGColorRelease(color); 42 | return [newLayer autorelease]; 43 | } 44 | 45 | - (void)dealloc 46 | { 47 | 48 | [super dealloc]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /IAImage.py: -------------------------------------------------------------------------------- 1 | # 2 | # IAImage.py 3 | from objc import * 4 | from Foundation import * 5 | from AppKit import * 6 | from math import log 7 | 8 | class Quantizer(object): 9 | def qualityLabel(self): 10 | return "Colors" 11 | 12 | def supportsIeMode(self): 13 | return False 14 | 15 | def preferredDithering(self): 16 | return True 17 | 18 | def numberOfColorsToQuality(self, colors): 19 | return colors; 20 | 21 | def versionId(self, colors, dithering, ieMode): 22 | return "c%d:m%s:d%d%d" % (self.numberOfColorsToQuality(colors), self.__class__.__name__, dithering, ieMode) 23 | 24 | class Pngquant(Quantizer): 25 | def supportsIeMode(self): 26 | return True 27 | 28 | def launchArguments(self, dither, colors, ieMode): 29 | args = ["--floyd" if dither else "--nofs","%d" % colors]; 30 | if ieMode: 31 | args.insert(0,"--iebug"); 32 | return ("pngquant", args) 33 | 34 | class Pngnq(Quantizer): 35 | def launchArguments(self, dither, colors, ieMode): 36 | return ("pngnq", ["-Q","f" if dither else "n","-n","%d" % colors]) 37 | 38 | class Posterizer(Quantizer): 39 | def qualityLabel(self): 40 | return "Quality" 41 | 42 | def preferredDithering(self): 43 | return False 44 | 45 | def numberOfColorsToQuality(self, c): 46 | return round(15 + (c * 240 / 255)); 47 | 48 | def launchArguments(self, dither, colors, ieMode): 49 | args = ["%d" % self.numberOfColorsToQuality(colors)]; 50 | if dither: 51 | args.insert(0,"-d") 52 | return ("posterizer",args); 53 | 54 | class Blurizer(Quantizer): 55 | def qualityLabel(self): 56 | return "Quality" 57 | 58 | def preferredDithering(self): 59 | return True 60 | 61 | def versionId(self, colors, dithering, ieMode): 62 | return "blur%d" % self.numberOfColorsToQuality(colors) 63 | 64 | def numberOfColorsToQuality(self, c): 65 | return round(255 - 12 + 1.5*log(c, 2)); 66 | 67 | def launchArguments(self, dither, colors, ieMode): 68 | args = ["-b", "%d" % self.numberOfColorsToQuality(colors)]; 69 | return ("posterizer",args); 70 | 71 | 72 | class IAImage(NSObject): 73 | _image = None 74 | _imageData = None 75 | 76 | path = None 77 | _sourceFileSize = None 78 | 79 | versions = None 80 | 81 | _numberOfColors = 256; 82 | 83 | _quantizationMethod = 0; # 0 = pngquant; 1 = pngnq; 2 = posterizer 84 | _quantizationMethods = [ 85 | Pngquant(), 86 | Pngnq(), 87 | None, # separator 88 | Blurizer(), 89 | Posterizer(), 90 | ] 91 | _dithering = YES 92 | _ieMode = NO 93 | 94 | callbackWhenImageChanges = None 95 | 96 | def init(self): 97 | self = super(IAImage, self).init() 98 | self.versions = {}; 99 | self.updateDithering() 100 | return self 101 | 102 | def setCallbackWhenImageChanges_(self, documentToCallback): 103 | self.callbackWhenImageChanges = documentToCallback; 104 | self.update() 105 | 106 | def setImage_(self,image): 107 | self._image = image 108 | 109 | def image(self): 110 | return self._image 111 | 112 | def imageData(self): 113 | return self._imageData; 114 | 115 | def sourceFileSize(self): 116 | return self._sourceFileSize; 117 | 118 | def setPath_(self,path): 119 | self.path = path 120 | (attrs,error) = NSFileManager.defaultManager().attributesOfItemAtPath_error_(self.path,None); 121 | self._sourceFileSize = attrs.objectForKey_(NSFileSize) if attrs is not None and error is None else None; 122 | 123 | def ieMode(self): 124 | return self._ieMode 125 | 126 | def setIeMode_(self,val): 127 | self._ieMode = int(val) > 0; 128 | if self._ieMode and not self.quantizer().supportsIeMode(): 129 | self.setQuantizationMethod_(0); 130 | self.update() 131 | 132 | def dithering(self): 133 | return self._dithering 134 | 135 | def setDithering_(self,val): 136 | self._dithering = int(val) > 0 137 | self.update() 138 | 139 | def updateDithering(self): 140 | self.setDithering_(NSUserDefaults.standardUserDefaults().get("dithered", self.quantizer().preferredDithering())) 141 | 142 | def numberOfColors(self): 143 | return self._numberOfColors 144 | 145 | def qualityLabel(self): 146 | return self.quantizer().qualityLabel() 147 | 148 | def setNumberOfColors_(self,num): 149 | self._numberOfColors = int(num) 150 | self.update() 151 | 152 | def quantizationMethod(self): 153 | return self._quantizationMethod 154 | 155 | def quantizer(self): 156 | return self._quantizationMethods[self._quantizationMethod] 157 | 158 | def setQuantizationMethod_(self,num): 159 | self.willChangeValueForKey_("qualityLabel"); 160 | self._quantizationMethod = num 161 | self.didChangeValueForKey_("qualityLabel"); 162 | 163 | quantizer = self.quantizer() 164 | if not quantizer.supportsIeMode(): 165 | self.setIeMode_(False) 166 | self.updateDithering() 167 | self.update() 168 | 169 | def isBusy(self): 170 | if self.path is None: return False 171 | id = self.currentVersionId() 172 | if id not in self.versions: return False # not sure about this 173 | return not self.versions[id].isDone; 174 | 175 | def update(self): 176 | if self.path: 177 | id = self.currentVersionId() 178 | 179 | if self.numberOfColors() > 256: 180 | self._imageData = NSData.dataWithContentsOfFile_(self.path); 181 | self.setImage_(NSImage.alloc().initByReferencingFile_(self.path)); 182 | 183 | if self.callbackWhenImageChanges is not None: self.callbackWhenImageChanges.imageChanged(); 184 | 185 | elif id not in self.versions: 186 | self.versions[id] = IAImageVersion.alloc().init() 187 | self.versions[id].generateFromPath_method_dither_iemode_colors_callback_(self.path, self.quantizer(), self.dithering(), self.ieMode(), self.numberOfColors(), self) 188 | 189 | if self.callbackWhenImageChanges is not None: self.callbackWhenImageChanges.updateProgressbar(); 190 | 191 | elif self.versions[id].isDone: 192 | self._imageData = self.versions[id].imageData 193 | self.setImage_(NSImage.alloc().initWithData_(self._imageData)) 194 | 195 | if self.callbackWhenImageChanges is not None: self.callbackWhenImageChanges.imageChanged(); 196 | 197 | def currentVersionId(self): 198 | return self.quantizer().versionId(self.numberOfColors(), self.dithering(), self.ieMode()); 199 | 200 | def destroy(self): 201 | self.callbackWhenImageChanges = None 202 | for id in self.versions: 203 | self.versions[id].destroy() 204 | self.versions = {} 205 | 206 | 207 | class IAImageVersion(NSObject): 208 | imageData = None 209 | isDone = False 210 | 211 | task = None 212 | outputPipe = None 213 | callbackWhenFinished = None 214 | 215 | def generateFromPath_method_dither_iemode_colors_callback_(self,path,quantizer,dither,ieMode,colors,callbackWhenFinished): 216 | 217 | self.isDone = False 218 | self.callbackWhenFinished = callbackWhenFinished 219 | 220 | (executable, args) = quantizer.launchArguments(dither, colors, ieMode) 221 | 222 | task = NSTask.alloc().init() 223 | 224 | exePath = NSBundle.mainBundle().pathForAuxiliaryExecutable_(executable) 225 | task.setLaunchPath_(exePath) 226 | task.setCurrentDirectoryPath_(exePath.stringByDeletingLastPathComponent()) 227 | task.setArguments_(args); 228 | 229 | # pngout works best via standard input/output 230 | file = NSFileHandle.fileHandleForReadingAtPath_(path); 231 | task.setStandardInput_(file); 232 | 233 | # get output via pipe 234 | # use pipe's file handle to construct NSData object asynchronously 235 | outputPipe = NSPipe.pipe(); 236 | task.setStandardOutput_(outputPipe); 237 | 238 | # pipe *must* be read, otheriwse task will block waiting for I/O 239 | handle = outputPipe.fileHandleForReading(); 240 | NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, self.onHandleReadToEndOfFile_, NSFileHandleReadToEndOfFileCompletionNotification, handle); 241 | handle.readToEndOfFileInBackgroundAndNotify() 242 | 243 | task.launch(); 244 | return task; 245 | 246 | def onHandleReadToEndOfFile_(self,notification): 247 | self.isDone = True 248 | 249 | self.imageData = notification.userInfo().objectForKey_(NSFileHandleNotificationDataItem); 250 | if self.callbackWhenFinished is not None: 251 | self.callbackWhenFinished.update() 252 | 253 | # FIXME: use dealloc and super()? 254 | def destroy(self): 255 | NSNotificationCenter.defaultCenter().removeObserver_(self); 256 | self.callbackWhenFinished = None 257 | if self.task: 258 | self.task.terminate(); 259 | self.task = None 260 | if self.outputPipe: 261 | self.outputPipe.fileHandleForReading().closeFile() 262 | self.outputPipe = None 263 | 264 | 265 | -------------------------------------------------------------------------------- /IAImageView.py: -------------------------------------------------------------------------------- 1 | # 2 | # IAImageView.py 3 | 4 | from objc import * 5 | from Foundation import * 6 | from AppKit import * 7 | from Quartz.CoreGraphics import * 8 | from Quartz.QuartzCore import * 9 | from math import ceil, floor 10 | 11 | class IAImageView(NSView): 12 | _zoom = 2.0 13 | _lastZoom = -1 14 | _image = None 15 | _inWantsLayers = False 16 | _alternateImage = None 17 | _drawAlternateImage = NO 18 | backgroundRenderer = None 19 | _smooth = YES 20 | backgroundOffset = (0,0) 21 | imageOffset = (0,0) 22 | imageFade = 1.0 23 | zoomingToFill = 0 24 | 25 | _imageLayer = None 26 | _backgroundLayer = None 27 | 28 | def initWithFrame_(self, frame): 29 | self = super(IAImageView, self).initWithFrame_(frame) 30 | if self: 31 | self.myAddLayers() 32 | return self 33 | 34 | # existence of initWithCoder_ causes later crashes in a place 35 | # with backtrace I don't recognize, so lazy myAddLayers() 36 | # is scattered all over the place instead 37 | 38 | def myAddLayers(self): 39 | if not self._inWantsLayers: 40 | self._inWantsLayers = True; 41 | self.setWantsLayer_(YES); 42 | self._inWantsLayers = False; 43 | 44 | if self.layer() is None: self.setLayer_(CALayer.layer()); 45 | assert self.layer() is not None; 46 | 47 | self._imageLayer = CALayer.layer() 48 | self._backgroundLayer = CALayer.layer(); 49 | self._backgroundLayer.setFrame_(self.bounds()) 50 | self._backgroundLayer.setAutoresizingMask_(kCALayerWidthSizable | kCALayerHeightSizable); 51 | 52 | self._backgroundLayer.setBackgroundColor_(CGColorCreateGenericRGB(0.5,0.5,0.5,1)); 53 | self.layer().addSublayer_(self._backgroundLayer); 54 | 55 | self.layer().addSublayer_(self._imageLayer); 56 | 57 | self.addShadow(); 58 | 59 | def addShadow(self): 60 | 61 | shadowHeight = 10; 62 | shadowWidth = 12; 63 | 64 | bounds = self.layer().bounds(); 65 | NSLog("bounds %d %d %d %d",bounds.size.width, bounds.size.height, bounds.origin.x, bounds.origin.y); 66 | 67 | shadow1 = CAGradientLayer.layer(); 68 | stops = [CGColorCreateGenericRGB(0,0,0,x) for x in [0, 0.04, 0.11, 0.3]] 69 | shadow1.setColors_(stops); 70 | shadow1.setAutoresizingMask_(kCALayerWidthSizable | kCALayerMinYMargin); 71 | shadow1.setFrame_(((0,bounds.size.height-shadowHeight), (bounds.size.width, shadowHeight))); 72 | 73 | shadow2 = CAGradientLayer.layer(); 74 | stops.reverse(); 75 | shadow2.setColors_(stops); 76 | shadow2.setStartPoint_((0,0)); 77 | shadow2.setEndPoint_((1,0)); 78 | shadow2.setAutoresizingMask_(kCALayerHeightSizable | kCALayerMaxXMargin); 79 | shadow2.setFrame_(((0,0),(shadowWidth,bounds.size.height))); 80 | self.layer().addSublayer_(shadow2); 81 | self.layer().addSublayer_(shadow1); 82 | self.shadow1 = shadow1; 83 | 84 | 85 | def setFrame_(self,rect): 86 | NSView.setFrame_(self,rect) 87 | if self.zoomingToFill: self.zoomToFill(self.zoomingToFill) 88 | 89 | @objc.IBAction 90 | def zoomIn_(self, sender): 91 | self.setZoom_(self.zoom() * 2.0); 92 | 93 | @objc.IBAction 94 | def zoomOut_(self,sender): 95 | self.setZoom_(self.zoom() / 2.0); 96 | 97 | def zoomToFill(self, zoom=1.0): 98 | self.zoomingToFill = zoom 99 | if self.image() is None: return 100 | size = self.image().size() 101 | framesize = self.frame().size 102 | zoom = min(framesize.width/size.width, framesize.height/size.height)*self.zoomingToFill 103 | if zoom > 1.0: 104 | zoom = min(4.0,floor(zoom)) 105 | self._setZoom(zoom) 106 | 107 | def _limitImageOffset(self): 108 | if self.image() is None: return 109 | size = self.frame().size 110 | imgsize = self.image().size() 111 | 112 | w = (size.width + imgsize.width * self.zoom()) /2 113 | h = (size.height + imgsize.height * self.zoom()) /2 114 | 115 | self.imageOffset = (max(-w+15, min(w-15, self.imageOffset[0])), \ 116 | max(-h+15, min(h-15, self.imageOffset[1]))) 117 | 118 | def smooth(self): 119 | return self._smooth; 120 | 121 | def setSmooth_(self,smooth): 122 | self._smooth = smooth 123 | if self._imageLayer: 124 | self._imageLayer.setMagnificationFilter_(kCAFilterLinear if smooth else kCAFilterNearest) 125 | self._imageLayer.setMinificationFilter_(kCAFilterLinear if smooth else kCAFilterNearest) 126 | self.setNeedsDisplay_(YES) 127 | 128 | def zoom(self): 129 | return self._zoom; 130 | 131 | def setZoom_(self,zoom): 132 | self.zoomingToFill = 0 133 | self._setZoom(zoom); 134 | 135 | def _setZoom(self,zoom): 136 | self._zoom = min(16.0,max(1.0/128.0,zoom)) 137 | self._limitImageOffset() 138 | if self._imageLayer: 139 | if 1.0==zoom: 140 | self._imageLayer.setMagnificationFilter_(kCAFilterNearest) 141 | elif self._smooth: 142 | self.setSmooth_(YES) 143 | self.setNeedsDisplay_(YES) 144 | 145 | def image(self): 146 | return self._image; 147 | 148 | def setImage_(self,aImage): 149 | self._image=aImage 150 | if self._alternateImage and aImage: 151 | self._setScale_ofImage_(self._getScaleOfImage_(self._alternateImage), aImage); 152 | if self.zoomingToFill: 153 | self.zoomToFill(self.zoomingToFill) 154 | self.setDrawAlternateImage_(NO) 155 | 156 | 157 | def _getScaleOfImage_(self, image): 158 | w,h = image.size() 159 | rep = image.representations(); 160 | if not rep or not rep.count(): return (0,0); 161 | return (rep[0].pixelsWide()/w, rep[0].pixelsHigh()/h); 162 | 163 | def _setScale_ofImage_(self, scale, image): 164 | rep = image.representations(); 165 | if not rep or not rep.count(): return (0,0); 166 | image.setSize_((rep[0].pixelsWide()/scale[0], rep[0].pixelsHigh()/scale[1])); 167 | 168 | def alternateImage(self): 169 | return self._alternateImage; 170 | 171 | def setAlternateImage_(self,aImage): 172 | if self._image and aImage: 173 | self._setScale_ofImage_(self._getScaleOfImage_(aImage), self._image); 174 | self._alternateImage = aImage 175 | self.imageOffset = (0,0) 176 | if not self.zoomingToFill: 177 | self.setZoom_(1.0) 178 | self.setNeedsDisplay_(YES) 179 | 180 | def drawAlternateImage(self): 181 | return self._drawAlternateImage; 182 | 183 | def setDrawAlternateImage_(self,tf): 184 | self._drawAlternateImage = tf 185 | if self._imageLayer: 186 | image = self.image() if not tf else self.alternateImage() 187 | CATransaction.begin() 188 | CATransaction.setDisableActions_(True) 189 | self._imageLayer.setContents_(image); 190 | self._updateLayerZoom() 191 | CATransaction.commit() 192 | 193 | self.setNeedsDisplay_(YES) 194 | 195 | def drawAlternateImage(self): 196 | return self._drawAlternateImage == True 197 | 198 | def setBackgroundLayer_(self, layer): 199 | assert layer 200 | if self.layer() is None: 201 | self.myAddLayers() 202 | 203 | layer.setFrame_(self.bounds()); 204 | layer.setAutoresizingMask_(kCALayerWidthSizable|kCALayerHeightSizable) 205 | self.layer().replaceSublayer_with_(self._backgroundLayer, layer); 206 | self._backgroundLayer = layer; 207 | 208 | def setBackgroundRenderer_(self,renderer): 209 | assert renderer is not None; 210 | self.backgroundRenderer = renderer; 211 | if self.layer(): 212 | self.setBackgroundLayer_(renderer.getLayer()) 213 | self.setNeedsDisplay_(YES) 214 | 215 | def isOpaque(self): 216 | return self.backgroundRenderer is not None 217 | 218 | def _updateLayerZoom(self): 219 | if self._lastZoom != self._zoom: 220 | image = self.image() if not self.drawAlternateImage() else self.alternateImage(); 221 | if image is not None and self._imageLayer is not None: 222 | w,h = image.size() 223 | x,y = self.imageOffset 224 | size = self.bounds()[1] 225 | self._imageLayer.setFrame_(((x+size[0]/2-w/2,y+size[1]/2-h/2),(w*self._zoom, h*self._zoom))); 226 | self._lastZoom = self._zoom 227 | 228 | def setNeedsDisplay_(self, tf): 229 | if tf: 230 | 231 | if self.layer() is None: 232 | self.myAddLayers() 233 | 234 | image = self.image() if not self.drawAlternateImage() else self.alternateImage(); 235 | if image is not None and self._imageLayer is not None: 236 | self._updateLayerZoom() 237 | 238 | self._imageLayer.setOpacity_(self.imageFade); 239 | 240 | x,y = self.imageOffset 241 | size = self.bounds()[1] 242 | 243 | CATransaction.begin() 244 | CATransaction.setDisableActions_(True) 245 | self._imageLayer.setPosition_((x+size[0]/2,y+size[1]/2)) 246 | CATransaction.commit() 247 | 248 | super(IAImageView, self).setNeedsDisplay_(tf); 249 | 250 | -------------------------------------------------------------------------------- /IAImageViewInteractive.py: -------------------------------------------------------------------------------- 1 | # 2 | # IAImageViewInteractive.py 3 | from objc import * 4 | from Foundation import * 5 | from AppKit import * 6 | from IAImageView import IAImageView 7 | from math import floor 8 | 9 | class IAImageViewInteractive(IAImageView): 10 | def initWithFrame_(self, frame): 11 | self = super(IAImageViewInteractive, self).initWithFrame_(frame) 12 | if self: 13 | types = [NSFilenamesPboardType] 14 | types.extend(NSImage.imagePasteboardTypes()) 15 | self.registerForDraggedTypes_(types) 16 | pass 17 | return self 18 | 19 | controller = objc.IBOutlet() 20 | 21 | mouseIsDown = False 22 | dragBackground = False 23 | dragStart = (0,0) 24 | 25 | def draggingEntered_(self,sender): 26 | if self.controller.canSetDocumentImageFromPasteboard_(sender.draggingPasteboard()): 27 | self.imageFade = 0.15 28 | self.setNeedsDisplay_(YES) 29 | return NSDragOperationCopy | NSDragOperationGeneric | NSDragOperationMove 30 | 31 | def draggingExited_(self,sender): 32 | self.imageFade = 1.0 33 | self.setNeedsDisplay_(YES) 34 | 35 | def prepareForDragOperation_(self,sender): 36 | self.imageFade = 1.0 37 | self.setNeedsDisplay_(YES) 38 | return self.controller.canSetDocumentImageFromPasteboard_(sender.draggingPasteboard()) 39 | 40 | def performDragOperation_(self,sender): 41 | return self.controller.setDocumentImageFromPasteboard_(sender.draggingPasteboard()) 42 | 43 | def resetCursorRects(self): 44 | if self.image() is not None or self.backgroundRenderer is not None: 45 | curs = NSCursor.closedHandCursor() if self.mouseIsDown else NSCursor.openHandCursor() 46 | self.addCursorRect_cursor_(self.visibleRect(), curs) 47 | curs.setOnMouseEntered_(YES) 48 | 49 | def scrollWheel_(self,event): 50 | if event.deltaY() > 0: 51 | self.zoomIn_(None) 52 | elif event.deltaY() < 0: 53 | self.zoomOut_(None) 54 | 55 | def mouseExited_(self,event): 56 | self.imageFade=1.0 57 | self.setNeedsDisplay_(YES) 58 | 59 | def mouseEntered_(self,event): 60 | self.imageFade = 0.5 61 | self.setNeedsDisplay_(YES) 62 | 63 | def pointIsInImage_(self,point): 64 | if self.image() is None: return NO 65 | size = self.image().size(); 66 | 67 | fsize = self.frame().size; 68 | w = max(50,size.width * self.zoom() +15) / 2 # add "border" around image to ease dragging of small ones 69 | h = max(50,size.height * self.zoom() +15) / 2 70 | 71 | return point.x >= self.imageOffset[0]+fsize.width/2-w and point.y >= self.imageOffset[1]+fsize.height/2-h and \ 72 | point.x <= self.imageOffset[0]+fsize.width/2+w and point.y <= self.imageOffset[1]+fsize.height/2+h 73 | 74 | def mouseDragged_(self,event): 75 | point = self.convertPoint_fromView_(event.locationInWindow(), None); 76 | delta = (point.x - self.dragStart[0], point.y - self.dragStart[1]) 77 | self.dragStart = (point.x, point.y) 78 | if self.backgroundRenderer is not None and self.dragBackground: 79 | self.backgroundRenderer.moveBy_(delta) 80 | elif self.image() is not None: 81 | size = self.frame().size 82 | self.imageOffset = (self.imageOffset[0] + delta[0], 83 | self.imageOffset[1] + delta[1]) 84 | self._limitImageOffset() 85 | 86 | self.setNeedsDisplay_(YES) 87 | 88 | def mouseChange_(self, isDown): 89 | self.mouseIsDown = isDown 90 | self.window().invalidateCursorRectsForView_(self); 91 | 92 | def mouseDown_(self,event): 93 | point = self.convertPoint_fromView_(event.locationInWindow(), None) 94 | 95 | if self.backgroundRenderer is None or not self.backgroundRenderer.canMove(): 96 | self.dragBackground = False 97 | else: 98 | self.dragBackground = not self.pointIsInImage_(point) 99 | if (event.modifierFlags() & (NSShiftKeyMask | NSAlternateKeyMask | NSCommandKeyMask)): 100 | self.dragBackground = not self.dragBackground 101 | 102 | 103 | self.dragStart = (point.x,point.y) 104 | if event.clickCount()&3==2: 105 | self.imageOffset = (0,0) 106 | if self.zoomingToFill: 107 | self.setZoom_(1) 108 | else: 109 | self.zoomToFill() 110 | self.setNeedsDisplay_(YES) 111 | else: 112 | self.mouseChange_(YES); 113 | self.mouseDragged_(event) 114 | 115 | def magnifyWithEvent_(self, event): 116 | #NSLog("magnified by %f z = %f" % (event.magnification(), self.zoom())); 117 | 118 | oldzoom = self.zoom(); 119 | # zoom < 1 requires different zooming speed than > 1 120 | if (oldzoom + event.magnification() > 1): 121 | zoom = ((oldzoom / 20) + event.magnification()/4) * 20; 122 | else: 123 | zoom = 1 / (1/oldzoom - event.magnification()); 124 | 125 | # avoid crossing of the 1.0 boundary at wrong speed 126 | if (zoom > 1.0 and oldzoom < 1.0) or (zoom < 1.0 and oldzoom > 1.0): 127 | zoom = 1.0; 128 | 129 | self.setZoom_(max(0.25,zoom)); 130 | 131 | #def keyDown_(self,event): 132 | #NSLog("key! %s" % event); 133 | 134 | def mouseUp_(self,event): 135 | self.mouseChange_(NO); 136 | 137 | def updateTouches_(self,event): 138 | touches = event.touchesMatchingPhase_inView_( NSTouchPhaseStationary, self); 139 | #NSLog("touches %s" % touches.allObjects()); 140 | self.setDrawAlternateImage_((touches.count() >= 3)) 141 | 142 | def otherMouseDown_(self,event): 143 | self.setDrawAlternateImage_(YES) 144 | 145 | def otherMouseUp_(self,event): 146 | self.setDrawAlternateImage_(NO) 147 | 148 | -------------------------------------------------------------------------------- /IAPatternBackgroundRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // IAPatternBackgroundRenderer.h 3 | // ImageAlpha 4 | // 5 | // Created by (ja) xx on 12.mar.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "IABackgroundRenderer.h" 10 | 11 | @interface IAPatternBackgroundRenderer : IABackgroundRenderer { 12 | CGImageRef image; 13 | CALayer *bgLayer; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /IAPatternBackgroundRenderer.m: -------------------------------------------------------------------------------- 1 | // 2 | // IAPatternBackgroundRenderer.m 3 | // ImageAlpha 4 | // 5 | // Created by (ja) xx on 12.mar.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "IAPatternBackgroundRenderer.h" 10 | #import 11 | 12 | static void drawPatternImage(void *info, CGContextRef ctx) 13 | { 14 | CGImageRef image = (CGImageRef)info; 15 | CGContextDrawImage(ctx, CGRectMake(0,0, CGImageGetWidth(image),CGImageGetHeight(image)), image); 16 | } 17 | 18 | @implementation IAPatternBackgroundRenderer 19 | 20 | - (id)init 21 | { 22 | self = [super init]; 23 | if (self) { 24 | bgLayer = [CALayer new]; 25 | NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys: 26 | [NSNull null], @"backgroundColor", 27 | [NSNull null], @"contents", 28 | [NSNull null], @"bounds", 29 | nil]; 30 | bgLayer.actions = newActions; // non-animated scroll 31 | [newActions release]; 32 | } 33 | return self; 34 | } 35 | 36 | -(BOOL)canMove { 37 | return YES; 38 | } 39 | 40 | -(CALayer *)getLayer { 41 | CALayer *newLayer = [CALayer new]; 42 | newLayer.actions = [[bgLayer.actions copy] autorelease]; 43 | 44 | CGColorRef color = CGColorCreateCopy(bgLayer.backgroundColor); 45 | newLayer.backgroundColor = color; 46 | CGColorRelease(color); 47 | 48 | return [newLayer autorelease]; 49 | } 50 | 51 | -(void)dealloc { 52 | if (image) CGImageRelease(image); 53 | [bgLayer release]; 54 | [super dealloc]; 55 | } 56 | 57 | -(void)setTileImage:(NSImage*)nsimage { 58 | if (image) CGImageRelease(image); 59 | 60 | [NSGraphicsContext saveGraphicsState]; 61 | image = [nsimage CGImageForProposedRect:&(NSRect){.size=[nsimage size]} context:NULL hints:[NSDictionary dictionary]]; 62 | CGImageRetain(image); 63 | [NSGraphicsContext restoreGraphicsState]; 64 | } 65 | 66 | -(void)tileLayerAtX:(NSNumber*)x Y:(NSNumber *)y { 67 | 68 | CGFloat width = CGImageGetWidth(image), height = CGImageGetHeight(image); 69 | CGPatternRef pattern = CGPatternCreate( image, 70 | CGRectMake(0, 0, width, height), 71 | CGAffineTransformMake (1, 0, 0, 1, [x doubleValue], [y doubleValue]), 72 | width, height, 73 | kCGPatternTilingConstantSpacing, 74 | true, 75 | &(CGPatternCallbacks){0, &drawPatternImage, 0}); 76 | CGColorSpaceRef space = CGColorSpaceCreatePattern(NULL); 77 | CGColorRef color = CGColorCreateWithPattern(space, pattern, &(CGFloat){1.0}); 78 | CGColorSpaceRelease(space); 79 | CGPatternRelease(pattern); 80 | bgLayer.backgroundColor = color; //set your layer's background to the image 81 | CGColorRelease(color); 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /IASlider.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # IASlider.py 4 | 5 | from objc import YES, NO, IBAction, IBOutlet 6 | from Foundation import * 7 | from AppKit import * 8 | 9 | from math import pow,log 10 | 11 | class IASlider(NSSlider): 12 | zoomView = objc.IBOutlet() 13 | 14 | def scrollWheel_(self,event): 15 | if self.zoomView is not None: 16 | self.zoomView.scrollWheel_(event) 17 | 18 | 19 | class IAZoomTransformer(NSValueTransformer): 20 | def transformedValueClass(self): 21 | return NSNumber.__class__ 22 | 23 | def allowsReverseTransformation(self): 24 | return YES 25 | 26 | def reverseTransformedValue_(self,zoom): 27 | result = NSNumber.numberWithFloat_(1.0/(4.0-zoom) if zoom < 3.0 else zoom-2.0) 28 | return result 29 | 30 | def transformedValue_(self,zoom): 31 | zoom = zoom or 1.0 32 | result = NSNumber.numberWithFloat_(max(0,4.0-1.0/zoom) if zoom < 1.0 else zoom+2.0) 33 | return result 34 | 35 | class IAZoomTimesTransformer(NSValueTransformer): 36 | def transformedValue_(self,zoom): 37 | return u"%d×" % zoom if zoom >= 1.0 else [u"½×",u"⅓×",u"¼×"][min(2,int(round(1.0/zoom))-2)]; 38 | 39 | # converts numbers 0-257 to 0-9 range 40 | class IABitDepthTransformer(NSValueTransformer): 41 | def transformedValueClass(self): 42 | return NSNumber.__class__ 43 | 44 | def allowsReverseTransformation(self): 45 | return YES 46 | 47 | # colors to depth 48 | def transformedValue_(self,value): 49 | if value is None: return None; 50 | value = int(value); 51 | if (value > 256): return 9; 52 | if (value <= 2): return 1; 53 | return log(value,2); 54 | 55 | # depth to colors 56 | def reverseTransformedValue_(self,value): 57 | if value is None: return None; 58 | value = int(value); 59 | #NSLog("Reverse transforming from %d" % value); 60 | if (value > 8): return 257; 61 | if (value <= 1): return 2; 62 | return round(pow(2,value)); 63 | 64 | # displays 0-9 range as 0-256 and 2^24 65 | class IABitDepthNameTransformer(NSValueTransformer): 66 | def transformedValue_(self,value): 67 | if value is None: return None; 68 | value = int(value); 69 | if (value > 256): return u"2²⁴" 70 | return "%d" % value; 71 | 72 | 73 | # converts numbers 0-8 to 0-256 range 74 | class IABitDepthReverseTransformer(NSValueTransformer): 75 | def transformedValueClass(self): 76 | return NSNumber.__class__ 77 | 78 | # depth to colors 79 | def transformedValue_(self,value): 80 | if value is None: return None; 81 | value = int(value); 82 | if (value <= 1): return 2; 83 | return pow(2,value); 84 | 85 | 86 | -------------------------------------------------------------------------------- /ImageAlpha.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/ImageAlpha.icns -------------------------------------------------------------------------------- /ImageAlphaApplication.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface ImageAlphaApplication : NSObject 5 | @property (retain) NSString *imageOptimPath; 6 | @property (retain) IBOutlet NSMenu *ditheredMenu; 7 | @end 8 | -------------------------------------------------------------------------------- /ImageAlphaApplication.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import "ImageAlphaApplication.h" 4 | 5 | @implementation ImageAlphaApplication 6 | 7 | @synthesize imageOptimPath, ditheredMenu; 8 | 9 | -(void)applicationDidFinishLaunching:(NSApplication*)sender { 10 | self.imageOptimPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"net.pornel.imageoptim"]; 11 | 12 | id dithered = [[NSUserDefaults standardUserDefaults] objectForKey:@"dithered"]; 13 | int tag = dithered != nil ? [dithered boolValue] : -1; 14 | for (NSMenuItem *item in self.ditheredMenu.itemArray) { 15 | [item setState:item.tag == tag ? NSOnState : NSOffState]; 16 | } 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ImageAlphaDocument.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # IAController.py 4 | 5 | from objc import * 6 | from Foundation import * 7 | import IAImageView 8 | from IACollectionItem import * 9 | from IABackgroundRenderer import * 10 | from IAImage import IAImage 11 | 12 | class ImageAlphaDocument(ImageAlphaDocumentC): 13 | 14 | statusBarView = objc.IBOutlet() 15 | backgroundsView = objc.IBOutlet() 16 | progressBarView = objc.IBOutlet() 17 | savePanelView = objc.IBOutlet() 18 | 19 | def windowNibName(self): 20 | return u"ImageAlphaDocument" 21 | 22 | def windowControllerDidLoadNib_(self, aController): 23 | super(ImageAlphaDocument, self).windowControllerDidLoadNib_(aController) 24 | 25 | self._startWork(); 26 | 27 | bgs = [ 28 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/photoshop","png")), 29 | IAColorBackgroundRenderer.alloc().initWithColor_(NSColor.redColor()), 30 | IAColorBackgroundRenderer.alloc().initWithColor_(NSColor.greenColor()), 31 | IAColorBackgroundRenderer.alloc().initWithColor_(NSColor.blueColor()), 32 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/461223192","jpg")), 33 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/A_MIXRED","jpeg")), 34 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/nature71","jpg")), 35 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/seawaterfull2","jpg")), 36 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/STONE4","jpeg")), 37 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/Rustpattern","jpeg")), 38 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/461223185","jpg")), 39 | IAImageBackgroundRenderer.alloc().initWithImage_(self._getImage("textures/G_IRON3","jpg")), 40 | ] 41 | self.backgroundsView.setContent_(bgs); 42 | 43 | self.zoomedImageView().window().setAcceptsMouseMovedEvents_(YES); 44 | self.zoomedImageView().setBackgroundRenderer_(bgs[0]) 45 | 46 | if self.documentImage() is not None: 47 | self.setDisplayImage_(self.documentImage().image()) 48 | # self.setStatusMessage_("Opened " + NSFileManager.defaultManager().displayNameAtPath_(self.documentImage().path)); 49 | else: 50 | self.setStatusMessage_("To get started, drop PNG image onto main area on the right"); 51 | 52 | self.updateZoomedImageViewAlternateImage() 53 | 54 | 55 | self._endWork(); 56 | 57 | def updateZoomedImageViewAlternateImage(self, zoomToFill=False): 58 | if self.zoomedImageView() is not None and self.documentImage() is not None: 59 | self.zoomedImageView().setAlternateImage_(self.documentImage().image()) 60 | if zoomToFill: 61 | self.zoomedImageView().zoomToFill() 62 | 63 | def validateUserInterfaceItem_(self,item): 64 | # I can't find nice way to compare selectors in pyobjc, so here comes __repr__() hack (or non-hack I hope) 65 | if self.documentImage() is None and item.action().__repr__() in ["'saveDocument:'","'saveDocumentAs:'","'zoomIn:'","'zoomOut:'", "'toggleShowOriginal:'"]: 66 | return NO 67 | 68 | return super(ImageAlphaDocument, self).validateUserInterfaceItem_(item); 69 | 70 | 71 | def prepareSavePanel_(self, savePanel): 72 | delegate = NSApplication.sharedApplication().delegate() 73 | if delegate and delegate.imageOptimPath is not None: 74 | savePanel.setAccessoryView_(self.savePanelView); 75 | return YES 76 | 77 | def dataOfType_error_(self, typeName, outError): 78 | if url.isFileURL() or self.documentImage() is not None: 79 | return (self.documentImage().imageData(), None) 80 | return (None,None) 81 | 82 | def writeToURL_ofType_error_(self, url, typeName, outErorr): 83 | NSLog("write to %s type %s" % (url.path(), typeName)); 84 | 85 | if url.isFileURL() or self.documentImage() is not None: 86 | data = self.documentImage().imageData(); 87 | if data is not None: 88 | if NSFileManager.defaultManager().createFileAtPath_contents_attributes_(url.path(), data, None): 89 | self.optimizeFileIfNeeded_(url); 90 | return (True, None) 91 | 92 | return (NO,None) 93 | 94 | def readFromURL_ofType_error_(self, url, typeName, outError): 95 | NSLog("Reading file %s" % url.path()); 96 | if not url.isFileURL(): 97 | return (NO,None) 98 | return (self.setDocumentImageFromPath_(url.path()),None) 99 | 100 | def optimizeFileIfNeeded_(self,url): 101 | delegate = NSApplication.sharedApplication().delegate(); 102 | if not delegate or delegate.imageOptimPath is None or not NSUserDefaults.standardUserDefaults().boolForKey_("Optimize"): 103 | return 104 | 105 | w = NSWorkspace.sharedWorkspace(); 106 | result = w.openURLs_withAppBundleIdentifier_options_additionalEventParamDescriptor_launchIdentifiers_([url], "net.pornel.imageoptim", NSWorkspaceLaunchAsync|NSWorkspaceLaunchWithoutAddingToRecents, None, None) 107 | if (not result): 108 | result = w.openFile_withApplication_(url.path(), delegate.imageOptimPath); 109 | if (not result): 110 | NSLog("Could not launch ImageOptim for %s" % url); 111 | 112 | def setStatusMessage_(self,msg): 113 | NSLog("(status) %s", msg); 114 | if self.statusBarView is not None: self.statusBarView.setStringValue_(msg); 115 | 116 | def canSetDocumentImageFromPasteboard_(self,pboard): 117 | # disabled until in-memory image support is done 118 | # if NSImage.canInitWithPasteboard_(pboard): 119 | # NSLog("image will handle that"); 120 | # return YES 121 | 122 | type = pboard.availableTypeFromArray_([NSFilenamesPboardType]); 123 | if type is not None: 124 | # FIXME: check for PNGs here 125 | # filenames = self.filenamesFromPasteboard_(pboard) 126 | # NSLog("Filenames %s" % filenames); 127 | # for f in filenames: 128 | # NSLog("drop file %s" % f); 129 | return YES 130 | 131 | def filenamesFromPasteboard_(self,pboard): 132 | data = pboard.dataForType_(NSFilenamesPboardType) 133 | if data is None: return [] 134 | 135 | filenames, format, errorDescription = NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_( 136 | data , kCFPropertyListImmutable, None, None) 137 | return filenames; 138 | 139 | def setDocumentImageFromPasteboard_(self,pboard): 140 | type = pboard.availableTypeFromArray_([NSFilenamesPboardType]); 141 | if type is not None: 142 | filenames = self.filenamesFromPasteboard_(pboard) 143 | for file in filenames: 144 | if self.setDocumentImageFromPath_(file): 145 | return YES 146 | 147 | # disabled until in-memory image support is done 148 | # if NSImage.canInitWithPasteboard_(pboard): 149 | # image = NSImage.alloc().initWithPasteboard_(pboard); 150 | # self.setDocumentImageFromImage_(image) 151 | # return YES 152 | 153 | return NO 154 | 155 | def setDocumentImageFromPath_(self,path): 156 | image = NSImage.alloc().initWithContentsOfFile_(path) 157 | if image is None: 158 | #NSLog("img is none"); 159 | return NO 160 | 161 | docimg = IAImage.alloc().init(); 162 | self.setFileURL_(NSURL.fileURLWithPath_(path)) 163 | self.setFileType_("public.png.imagealpha"); 164 | 165 | docimg.setPath_(path); 166 | docimg.setImage_(image); 167 | self.setNewDocumentImage_(docimg) 168 | return YES 169 | 170 | def setDocumentImageFromImage_(self,image): 171 | return NO # not supported until iaimage can save temp image 172 | 173 | # if self.documentImage() is not None: 174 | # NSLog("That's not supported yet"); 175 | # return NO 176 | 177 | # docimg = IAImage.alloc().init(); 178 | # docimg.setImage_(image) 179 | # return self.setNewDocumentImage_(docimg); 180 | 181 | def setNewDocumentImage_(self,docimg): 182 | #NSLog("new dimage set"); 183 | if self.documentImage() is not None: 184 | self.documentImage().destroy(); 185 | 186 | self.setDocumentImage_(docimg); 187 | docimg.setCallbackWhenImageChanges_(self); 188 | self.setDisplayImage_(docimg.image()); 189 | 190 | self.updateZoomedImageViewAlternateImage(zoomToFill=True) 191 | 192 | def setDisplayImage_(self,image): 193 | if self.zoomedImageView() is None or self.backgroundsView is None: return; 194 | self.zoomedImageView().setImage_(image) 195 | self.backgroundsView.setImage_(image) 196 | self.backgroundsView.setSelectable_(YES if image is not None else NO); 197 | #NSLog("Set new display image %s" % image); 198 | 199 | def imageChanged(self): 200 | assert self.documentImage() is not None 201 | self.setDisplayImage_(self.documentImage().image()); 202 | data = self.documentImage().imageData() 203 | self.updateProgressbar() 204 | if data is not None: 205 | source_filesize = self.documentImage().sourceFileSize(); 206 | if source_filesize is None or source_filesize < data.length(): 207 | msg = "Image size: %d bytes" % data.length() 208 | else: 209 | percent = 100-data.length()*100/source_filesize 210 | msg = "Image size: %d bytes (saved %d%% of %d bytes)" % (data.length(), percent, source_filesize) 211 | self.setStatusMessage_(msg) 212 | 213 | def _getImage(self,name,ext="png"): 214 | path = NSBundle.mainBundle().resourcePath().stringByAppendingPathComponent_(name).stringByAppendingPathExtension_(ext); 215 | image = NSImage.alloc().initWithContentsOfFile_(path); 216 | if image is None: 217 | NSLog("Failed to load %s " % name); 218 | return image 219 | 220 | _busyLevel = 0 221 | 222 | def _startWork(self): 223 | self._busyLevel += 1 224 | self.updateProgressbar() 225 | 226 | def _endWork(self): 227 | self._busyLevel -= 1 228 | self.updateProgressbar() 229 | 230 | def updateProgressbar(self): 231 | if self.progressBarView is None: return 232 | 233 | isBusy = self._busyLevel > 0 or (self.documentImage() is not None and self.documentImage().isBusy()); 234 | 235 | if isBusy: 236 | self.progressBarView.startAnimation_(self); 237 | else: 238 | self.progressBarView.stopAnimation_(self); 239 | 240 | @objc.IBAction 241 | def toggleShowOriginal_(self,action): 242 | if self.zoomedImageView() is not None: 243 | self.zoomedImageView().setDrawAlternateImage_(not self.zoomedImageView().drawAlternateImage()); 244 | 245 | @objc.IBAction 246 | def revert_(self,action): 247 | pass 248 | 249 | @objc.IBAction 250 | def zoomIn_(self, sender): 251 | if self.zoomedImageView() is not None: 252 | self.zoomedImageView().zoomIn_(sender); 253 | 254 | @objc.IBAction 255 | def zoomOut_(self, sender): 256 | if self.zoomedImageView() is not None: 257 | self.zoomedImageView().zoomOut_(sender); 258 | -------------------------------------------------------------------------------- /ImageAlphaDocumentC.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface IAImageView : NSView 5 | -(NSNumber*)drawAlternateImage; 6 | -(void)setDrawAlternateImage:(NSNumber*)b; 7 | @end 8 | 9 | @interface IAImage : NSObject 10 | -(void)updateDithering; 11 | @end 12 | 13 | @interface ImageAlphaDocumentC : NSDocument { 14 | IAImageView* zoomedImageView; 15 | NSView *leftPaneView; 16 | } 17 | 18 | @property (assign) BOOL drawAlternateImage; 19 | @property (retain) IBOutlet IAImageView* zoomedImageView; 20 | @property (retain) IAImage* documentImage; 21 | @property (retain) IBOutlet NSView* leftPaneView; 22 | @end 23 | -------------------------------------------------------------------------------- /ImageAlphaDocumentC.m: -------------------------------------------------------------------------------- 1 | 2 | #import "ImageAlphaDocumentC.h" 3 | 4 | @implementation ImageAlphaDocumentC 5 | 6 | @synthesize zoomedImageView, documentImage, leftPaneView; 7 | 8 | static CGFloat constrain(NSInteger dividerIndex, CGFloat proposedSize) 9 | { 10 | if (dividerIndex == 0) { 11 | if (proposedSize > 300) return 300; 12 | if (proposedSize < 210) return 210; 13 | } 14 | return proposedSize; 15 | } 16 | 17 | - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedSize ofSubviewAt:(NSInteger)dividerIndex { 18 | return constrain(dividerIndex, proposedSize); 19 | } 20 | 21 | - (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedSize ofSubviewAt:(NSInteger)dividerIndex { 22 | return constrain(dividerIndex, proposedSize); 23 | } 24 | 25 | - (CGFloat)splitView:(NSSplitView *)splitView constrainSplitPosition:(CGFloat)proposedSize ofSubviewAt:(NSInteger)dividerIndex { 26 | return constrain(dividerIndex, proposedSize); 27 | } 28 | 29 | - (BOOL)splitView:(NSSplitView *)splitView shouldAdjustSizeOfSubview:(NSView *)subview { 30 | return subview != self.leftPaneView; 31 | } 32 | 33 | 34 | -(void) setDrawAlternateImage:(BOOL)val { 35 | // indirection to avoid leaks caused by xib observing itself 36 | if (self.zoomedImageView && self.documentImage) { 37 | self.zoomedImageView.drawAlternateImage = [NSNumber numberWithBool:val]; 38 | } 39 | } 40 | 41 | -(BOOL) drawAlternateImage { 42 | if (self.zoomedImageView && self.documentImage) { 43 | return [self.zoomedImageView.drawAlternateImage boolValue]; 44 | } 45 | return NO; 46 | } 47 | 48 | -(BOOL) validateMenuItem:(NSMenuItem *)sender { 49 | return self.documentImage != nil; 50 | } 51 | 52 | -(void) setDitheredPreference:(NSMenuItem *)sender { 53 | for (NSMenuItem *item in sender.menu.itemArray) { 54 | [item setState:item == sender ? NSOnState : NSOffState]; 55 | } 56 | 57 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 58 | if (sender.tag < 0) { 59 | [defaults removeObjectForKey:@"dithered"]; 60 | } else { 61 | [defaults setBool:sender.tag forKey:@"dithered"]; 62 | } 63 | [defaults synchronize]; 64 | [self.documentImage updateDithering]; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /ImageAlpha_Prefix.pch: -------------------------------------------------------------------------------- 1 | 2 | 3 | // WARNING 4 | // This file is copied from CocoaDocApp_Prefix.pch. Keep the two in sync. 5 | // --- file resumes after here --- 6 | // 7 | // Prefix header for all source files of the 'ImageAlpha' target in the 'ImageAlpha' project 8 | // 9 | 10 | #ifdef __OBJC__ 11 | #import 12 | #endif 13 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ApplePersistenceIgnoreState 6 | 7 | CFBundleAllowMixedLocalizations 8 | 9 | CFBundleDevelopmentRegion 10 | English 11 | CFBundleDocumentTypes 12 | 13 | 14 | CFBundleTypeIconFile 15 | 16 | CFBundleTypeName 17 | PNG Image 18 | CFBundleTypeRole 19 | Editor 20 | LSItemContentTypes 21 | 22 | public.png 23 | 24 | NSDocumentClass 25 | ImageAlphaDocument 26 | 27 | 28 | CFBundleExecutable 29 | ${EXECUTABLE_NAME} 30 | CFBundleIconFile 31 | ImageAlpha.icns 32 | CFBundleIdentifier 33 | $(PRODUCT_BUNDLE_IDENTIFIER) 34 | CFBundleInfoDictionaryVersion 35 | 6.0 36 | CFBundleName 37 | ${PRODUCT_NAME} 38 | CFBundlePackageType 39 | APPL 40 | CFBundleShortVersionString 41 | 1.5.1 42 | CFBundleVersion 43 | 1.5.1 44 | LSArchitecturePriority 45 | 46 | x86_64 47 | 48 | LSMinimumSystemVersion 49 | 10.8 50 | NSHumanReadableCopyright 51 | ©2017 Kornel Lesiński 52 | NSMainNibFile 53 | MainMenu 54 | NSPrincipalClass 55 | NSApplication 56 | NSSupportsAutomaticGraphicsSwitching 57 | 58 | SUFeedURL 59 | https://pngmini.com/appcast.xml 60 | SUPublicDSAKeyFile 61 | dsa_pub.pem 62 | SUShowReleaseNotes 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | Sparkle.framework: 3 | curl http://sparkle.andymatuschak.org/files/Sparkle%201.5b6.zip -o /tmp/sparkle.zip 4 | unzip /tmp/sparkle.zip 'With Garbage Collection/*' && mv 'With Garbage Collection/Sparkle.framework' ./ 5 | -rm -rf /tmp/sparkle.zip 'With Garbage Collection' 6 | -rm -rf Sparkle.framework/Versions/A/Resources/fr_CA.lproj 7 | clean: 8 | -rm -rf /tmp/sparkle.zip 'With Garbage Collection' 9 | 10 | install: 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageAlpha 2 | 3 | ImageAlpha is a Mac OS X GUI for [pngquant](http://pngquant.org), pngnq and [posterizer](https://github.com/pornel/mediancut-posterizer). These tools reduce filesize of PNG files while preserving the alpha channel. 4 | 5 | ImageAlpha is written in Python and Cocoa (PyObjC). 6 | 7 | ![Screenshot](https://pngmini.com/screenshot-1.3.png) 8 | 9 | ## Language Support 10 | * 中文简体 (Chinese Simplified) - [Pluwen](https://twitter.com/pluwen) 11 | -------------------------------------------------------------------------------- /appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ImageAlpha 4 | https://pngmini.com/appcast.xml 5 | ImageAlpha updates 6 | en 7 | 8 | 9 | 11 |
  • Upgraded to pngquant 2.10
  • 12 |
  • Compatibility with macOS High Sierra
  • 13 |
      14 | ]]> 15 | 1.5.1 16 | Thu, 27 Jul 2017 16:54:05 +0100 17 | 10.11 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "release.xcconfig" 2 | GCC_OPTIMIZATION_LEVEL = 0; 3 | DEAD_CODE_STRIPPING = NO; 4 | GCC_WARN_UNINITIALIZED_AUTOS = NO; 5 | COPY_PHASE_STRIP = NO; 6 | ONLY_ACTIVE_ARCH = YES; -------------------------------------------------------------------------------- /dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDOzCCAi0GByqGSM44BAEwggIgAoIBAQD/29U8O2QEO+QqYO0VeIuZI1gdtqS5 3 | YNVmRKZDxg6FEsQ+KvRspaH+6GD7m8wuDGVWcZBhinoOz/T046T7h75yYfgYm8i+ 4 | YI4FUK7XhwQM4gNBQ1TiyrwlvZVPkwjIlkI8uOqEAIYweNfIqWcZFM/V+KgYvqo/ 5 | cewiwY0ehKgOXY7qlQY22DlKQNzo/ccmx0aKtTpRljUu+j+6oVbX0hwH7LkPRP/l 6 | El3ifD8p0WcXC9kixFN1ns4jaOM74tzBhJay36Yg3T3dxym/IyiDC8vdiKfK4baW 7 | VYGYLbOqOIeDwTCMM59rbMY2NofXtU0hc6yf0U4lSA9dFS9toyxGSqaLAhUAoBfn 8 | GkaNya1RFlqA+FINPZ4B7LUCggEAdK/HQA/HPGLoMx+XeqlRSFymc+qMySfYnoc2 9 | PzryRWCalhXINjXmHjkcLoylsTXtRzn6ktPymf+8FhkMkDZs+DtSaYusHrPBwk2w 10 | SjHklZgIUnvnEPN4t/US29d10dHqqQYdjwROuWWJNM7E4To79XjR1AeG84yXvpMm 11 | Nrtp9XeCQLWmOvctSp5ZEhqnEjRCxBzowYM5NDLWA8h46689sM/1C3lsCOb+XQHa 12 | R9TklxRtlbpNW90cPzbPxji+xRjHUc9R8fHW4Wx6s/JRu3gHREkAGyyJ1k93T8vc 13 | p10U4qGGJTlHiBUt3fWZGnZzmz4j4Yw1MOwdoSBgrF3/wsZ6IQOCAQYAAoIBAQDt 14 | Jk3nm5uTf44d8lMLiKQVrE7QttfHFMHGPXkBzomBar3rvSV46dmOdSqKRkE+JXNU 15 | x81iA/otMDr//uBnviwPOwJCMXnli2CTZXuBITTfDqIu7/2CzlPL3sSqhpp8tpAF 16 | 7vnVOvk4TTk23P93qjil/mlqiRzyefn9NgbEKkWMrzDOnpTCajH02ZTZZxVqFtyX 17 | PLArdOfV+QMJtSIlVCsy0EwudDdK7gL2ef7+QWzzoVo2FVQFOpckvnmsC65yL/9v 18 | 4sPVDR/mNPOC0dML9fkRJr6ykD4IgOw+lwSDxBE8vgQmvy8n3U4zVPyfdgSndAKF 19 | AEjuJ8qRswZ0xG0B8D2W 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ImageAlpha 4 | 5 | #import 6 | #import 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 11 | 12 | NSBundle *mainBundle = [NSBundle mainBundle]; 13 | NSString *resourcePath = [mainBundle resourcePath]; 14 | NSArray *pythonPathArray = [NSArray arrayWithObjects: resourcePath, [resourcePath stringByAppendingPathComponent:@"PyObjC"], nil]; 15 | 16 | setenv("PYTHONPATH", [[pythonPathArray componentsJoinedByString:@":"] UTF8String], 1); 17 | 18 | NSArray *possibleMainExtensions = [NSArray arrayWithObjects: @"py", @"pyc", @"pyo", nil]; 19 | NSString *mainFilePath = nil; 20 | 21 | for (NSString *possibleMainExtension in possibleMainExtensions) { 22 | mainFilePath = [mainBundle pathForResource: @"main" ofType: possibleMainExtension]; 23 | if ( mainFilePath != nil ) break; 24 | } 25 | 26 | int result = -1; 27 | if ( mainFilePath ) { 28 | 29 | Py_SetProgramName("/usr/bin/python"); 30 | Py_Initialize(); 31 | PySys_SetArgv(argc, (char **)argv); 32 | 33 | const char *mainFilePathPtr = [mainFilePath fileSystemRepresentation]; 34 | FILE *mainFile = fopen(mainFilePathPtr, "r"); 35 | result = PyRun_SimpleFile(mainFile, (char *)[[mainFilePath lastPathComponent] UTF8String]); 36 | 37 | } 38 | if ( result != 0 ) { 39 | NSAlert *alert = [NSAlert alertWithMessageText:@"Unable to start ImageAlpha" defaultButton:@"Abort" alternateButton:nil otherButton:nil 40 | informativeTextWithFormat:@"Python/PyObjC program failed to start.\nSee Console.app for details.",nil]; 41 | [alert runModal]; 42 | } 43 | 44 | [pool drain]; 45 | 46 | return result; 47 | } 48 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # 2 | # main.py 3 | 4 | # can't avoid default encoding. Python dies in a system-initiated callback due to pretending it's still 1963. 5 | import sys 6 | reload(sys); 7 | sys.setdefaultencoding("utf8"); 8 | 9 | #import modules required by application 10 | import objc 11 | import Foundation 12 | import AppKit 13 | 14 | objc.setVerbose(1) 15 | 16 | from PyObjCTools import AppHelper 17 | 18 | # import modules containing classes required to start application and load MainMenu.nib 19 | 20 | import ImageAlphaDocument 21 | import IASlider 22 | import IACollectionItem 23 | import IAImageViewInteractive 24 | import IABackgroundRenderer 25 | import IAImageView 26 | import IAImage 27 | 28 | # pass control to AppKit 29 | AppHelper.runEventLoop() 30 | -------------------------------------------------------------------------------- /optimal_file_list: -------------------------------------------------------------------------------- 1 | ImageAlpha.app/Contents/MacOS/ImageAlpha 2 | ImageAlpha.app/Contents/MacOS/liblibpng.dylib 3 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib 4 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib 5 | ImageAlpha.app/Contents/Resources/English.lproj/ImageAlphaDocument.nib 6 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib 7 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib 8 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib 9 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib 10 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib 11 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib 12 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib 13 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib 14 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib 15 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib 16 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib 17 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib 18 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib 19 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib 20 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib 21 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib 22 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib 23 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib 24 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib 25 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib 26 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib 27 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib 28 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib 29 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib 30 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib 31 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib 32 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib 33 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib 34 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib 35 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib 36 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib 37 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib 38 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib 39 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib 40 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib 41 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib 42 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib 43 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib 44 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib 45 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib 46 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib 47 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib 48 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib 49 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib 50 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib 51 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib 52 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib 53 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib 54 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib 55 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib 56 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib 57 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib 58 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib 59 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib 60 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib 61 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib 62 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib 63 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib 64 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib 65 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib 66 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib 67 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib 68 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib 69 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib 70 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib 71 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib 72 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib 73 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib 74 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib 75 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib 76 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib 77 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib 78 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib 79 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib 80 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib 81 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib 82 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib 83 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib 84 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib 85 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib 86 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib 87 | ImageAlpha.app/Contents/Resources/English.lproj/MainMenu.nib 88 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Sparkle 89 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Sparkle 90 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate 91 | ImageAlpha.app/Contents/Resources/textures/STONE4.jpeg 92 | ImageAlpha.app/Contents/Resources/textures/A_MIXRED.jpeg 93 | ImageAlpha.app/Contents/Resources/textures/Rustpattern.jpeg 94 | ImageAlpha.app/Contents/Resources/textures/photoshop.png 95 | ImageAlpha.app/Contents/Resources/textures/nature71.jpg 96 | ImageAlpha.app/Contents/Resources/textures/461223192.jpg 97 | ImageAlpha.app/Contents/Resources/textures/seawaterfull2.jpg 98 | ImageAlpha.app/Contents/Resources/textures/G_IRON3.jpg 99 | ImageAlpha.app/Contents/Resources/textures/461223185.jpg 100 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj 101 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt.lproj 102 | ImageAlpha.app/Contents/Resources/dsa_pub.pem 103 | ImageAlpha.app/Contents/PkgInfo 104 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo 105 | ImageAlpha.app/Contents/MacOS/pngnq 106 | ImageAlpha.app/Contents/MacOS/posterizer 107 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Resources 108 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/_CodeSignature/CodeResources 109 | ImageAlpha.app/Contents/_CodeSignature/CodeResources 110 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings 111 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings 112 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings 113 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings 114 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings 115 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings 116 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings 117 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings 118 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings 119 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ca.lproj/Sparkle.strings 120 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings 121 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings 122 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings 123 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings 124 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings 125 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings 126 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings 127 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings 128 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings 129 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/he.lproj/Sparkle.strings 130 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings 131 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings 132 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings 133 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fi.lproj/Sparkle.strings 134 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings 135 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings 136 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings 137 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings 138 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings 139 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings 140 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings 141 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings 142 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings 143 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings 144 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings 145 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings 146 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings 147 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings 148 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings 149 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings 150 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings 151 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings 152 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings 153 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings 154 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings 155 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings 156 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings 157 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings 158 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings 159 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings 160 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings 161 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings 162 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings 163 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings 164 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings 165 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings 166 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings 167 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings 168 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings 169 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings 170 | ImageAlpha.app/Contents/Resources/ImageAlpha.icns 171 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns 172 | ImageAlpha.app/Contents/MacOS/pngquant 173 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/Current 174 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist 175 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist 176 | ImageAlpha.app/Contents/Info.plist 177 | ImageAlpha.app/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist 178 | ImageAlpha.app/Contents/Resources/IAImage.py 179 | ImageAlpha.app/Contents/Resources/IAImageViewInteractive.py 180 | ImageAlpha.app/Contents/Resources/IACollectionItem.py 181 | ImageAlpha.app/Contents/Resources/main.py 182 | ImageAlpha.app/Contents/Resources/IASlider.py 183 | ImageAlpha.app/Contents/Resources/IABackgroundRenderer.py 184 | ImageAlpha.app/Contents/Resources/ImageAlphaDocument.py 185 | ImageAlpha.app/Contents/Resources/IAImageView.py 186 | -------------------------------------------------------------------------------- /pngnq.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5ABD76000F0E588100515CC9 /* rwpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABD75FA0F0E588100515CC9 /* rwpng.c */; }; 11 | 5ABD76010F0E588100515CC9 /* neuquant32.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABD75FB0F0E588100515CC9 /* neuquant32.c */; }; 12 | 5ABD76030F0E588100515CC9 /* pngnq.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABD75FD0F0E588100515CC9 /* pngnq.c */; }; 13 | 5ABD774E0F0E883E00515CC9 /* rwpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABD75FA0F0E588100515CC9 /* rwpng.c */; }; 14 | 5ABD774F0F0E883E00515CC9 /* neuquant32.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABD75FB0F0E588100515CC9 /* neuquant32.c */; }; 15 | 5ABD775A0F0E886100515CC9 /* pngcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABD77590F0E886100515CC9 /* pngcomp.c */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 5ABD75FA0F0E588100515CC9 /* rwpng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rwpng.c; path = pngnq/src/rwpng.c; sourceTree = SOURCE_ROOT; }; 20 | 5ABD75FB0F0E588100515CC9 /* neuquant32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = neuquant32.c; path = pngnq/src/neuquant32.c; sourceTree = SOURCE_ROOT; }; 21 | 5ABD75FD0F0E588100515CC9 /* pngnq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngnq.c; path = pngnq/src/pngnq.c; sourceTree = SOURCE_ROOT; }; 22 | 5ABD75FE0F0E588100515CC9 /* neuquant32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = neuquant32.h; path = pngnq/src/neuquant32.h; sourceTree = SOURCE_ROOT; }; 23 | 5ABD75FF0F0E588100515CC9 /* rwpng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rwpng.h; path = pngnq/src/rwpng.h; sourceTree = SOURCE_ROOT; }; 24 | 5ABD77440F0E87ED00515CC9 /* pngcomp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pngcomp; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 5ABD77590F0E886100515CC9 /* pngcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngcomp.c; path = pngnq/src/pngcomp.c; sourceTree = SOURCE_ROOT; }; 26 | 5AED10E6139BD44B00FF5C69 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = ""; }; 27 | 5AED10E7139BD44B00FF5C69 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = ""; }; 28 | 8DD76FB20486AB0100D96B5E /* pngnq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pngnq; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 5ABD77420F0E87ED00515CC9 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | 8DD76FAD0486AB0100D96B5E /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXFrameworksBuildPhase section */ 47 | 48 | /* Begin PBXGroup section */ 49 | 08FB7794FE84155DC02AAC07 /* pngnq */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 08FB7795FE84155DC02AAC07 /* Source */, 53 | 5AED10E6139BD44B00FF5C69 /* release.xcconfig */, 54 | 5AED10E7139BD44B00FF5C69 /* debug.xcconfig */, 55 | 1AB674ADFE9D54B511CA2CBB /* Products */, 56 | ); 57 | name = pngnq; 58 | sourceTree = ""; 59 | }; 60 | 08FB7795FE84155DC02AAC07 /* Source */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 5ABD75FA0F0E588100515CC9 /* rwpng.c */, 64 | 5ABD77590F0E886100515CC9 /* pngcomp.c */, 65 | 5ABD75FB0F0E588100515CC9 /* neuquant32.c */, 66 | 5ABD75FD0F0E588100515CC9 /* pngnq.c */, 67 | 5ABD75FE0F0E588100515CC9 /* neuquant32.h */, 68 | 5ABD75FF0F0E588100515CC9 /* rwpng.h */, 69 | ); 70 | name = Source; 71 | sourceTree = ""; 72 | }; 73 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 8DD76FB20486AB0100D96B5E /* pngnq */, 77 | 5ABD77440F0E87ED00515CC9 /* pngcomp */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | /* End PBXGroup section */ 83 | 84 | /* Begin PBXNativeTarget section */ 85 | 5ABD77430F0E87ED00515CC9 /* pngcomp */ = { 86 | isa = PBXNativeTarget; 87 | buildConfigurationList = 5ABD774D0F0E881300515CC9 /* Build configuration list for PBXNativeTarget "pngcomp" */; 88 | buildPhases = ( 89 | 5ABD77410F0E87ED00515CC9 /* Sources */, 90 | 5ABD77420F0E87ED00515CC9 /* Frameworks */, 91 | ); 92 | buildRules = ( 93 | ); 94 | dependencies = ( 95 | ); 96 | name = pngcomp; 97 | productName = pngcomp; 98 | productReference = 5ABD77440F0E87ED00515CC9 /* pngcomp */; 99 | productType = "com.apple.product-type.tool"; 100 | }; 101 | 8DD76FA90486AB0100D96B5E /* pngnq */ = { 102 | isa = PBXNativeTarget; 103 | buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "pngnq" */; 104 | buildPhases = ( 105 | 8DD76FAB0486AB0100D96B5E /* Sources */, 106 | 8DD76FAD0486AB0100D96B5E /* Frameworks */, 107 | ); 108 | buildRules = ( 109 | ); 110 | dependencies = ( 111 | ); 112 | name = pngnq; 113 | productInstallPath = "$(HOME)/bin"; 114 | productName = pngnq; 115 | productReference = 8DD76FB20486AB0100D96B5E /* pngnq */; 116 | productType = "com.apple.product-type.tool"; 117 | }; 118 | /* End PBXNativeTarget section */ 119 | 120 | /* Begin PBXProject section */ 121 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 122 | isa = PBXProject; 123 | attributes = { 124 | LastUpgradeCheck = 0410; 125 | }; 126 | buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "pngnq" */; 127 | compatibilityVersion = "Xcode 3.2"; 128 | developmentRegion = English; 129 | hasScannedForEncodings = 1; 130 | knownRegions = ( 131 | English, 132 | Japanese, 133 | French, 134 | German, 135 | ); 136 | mainGroup = 08FB7794FE84155DC02AAC07 /* pngnq */; 137 | projectDirPath = ""; 138 | projectRoot = ""; 139 | targets = ( 140 | 8DD76FA90486AB0100D96B5E /* pngnq */, 141 | 5ABD77430F0E87ED00515CC9 /* pngcomp */, 142 | ); 143 | }; 144 | /* End PBXProject section */ 145 | 146 | /* Begin PBXSourcesBuildPhase section */ 147 | 5ABD77410F0E87ED00515CC9 /* Sources */ = { 148 | isa = PBXSourcesBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | 5ABD774E0F0E883E00515CC9 /* rwpng.c in Sources */, 152 | 5ABD774F0F0E883E00515CC9 /* neuquant32.c in Sources */, 153 | 5ABD775A0F0E886100515CC9 /* pngcomp.c in Sources */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | 8DD76FAB0486AB0100D96B5E /* Sources */ = { 158 | isa = PBXSourcesBuildPhase; 159 | buildActionMask = 2147483647; 160 | files = ( 161 | 5ABD76000F0E588100515CC9 /* rwpng.c in Sources */, 162 | 5ABD76010F0E588100515CC9 /* neuquant32.c in Sources */, 163 | 5ABD76030F0E588100515CC9 /* pngnq.c in Sources */, 164 | ); 165 | runOnlyForDeploymentPostprocessing = 0; 166 | }; 167 | /* End PBXSourcesBuildPhase section */ 168 | 169 | /* Begin XCBuildConfiguration section */ 170 | 1DEB928608733DD80010E9CD /* Debug */ = { 171 | isa = XCBuildConfiguration; 172 | buildSettings = { 173 | INSTALL_PATH = /usr/local/bin; 174 | KEEP_PRIVATE_EXTERNS = YES; 175 | PRODUCT_NAME = pngnq; 176 | }; 177 | name = Debug; 178 | }; 179 | 1DEB928708733DD80010E9CD /* Release */ = { 180 | isa = XCBuildConfiguration; 181 | buildSettings = { 182 | COPY_PHASE_STRIP = NO; 183 | INSTALL_PATH = /usr/local/bin; 184 | KEEP_PRIVATE_EXTERNS = YES; 185 | PRODUCT_NAME = pngnq; 186 | }; 187 | name = Release; 188 | }; 189 | 1DEB928A08733DD80010E9CD /* Debug */ = { 190 | isa = XCBuildConfiguration; 191 | baseConfigurationReference = 5AED10E7139BD44B00FF5C69 /* debug.xcconfig */; 192 | buildSettings = { 193 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; 194 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 195 | GCC_PREPROCESSOR_DEFINITIONS = ( 196 | PNG_CONFIGURE_LIBPNG, 197 | HAVE_CONFIG_H, 198 | ); 199 | LD_GENERATE_MAP_FILE = YES; 200 | LIBRARY_SEARCH_PATHS = ( 201 | /usr/X11/lib/, 202 | /usr/lib, 203 | ); 204 | OTHER_LDFLAGS = ( 205 | "-lpng", 206 | "-lz", 207 | ); 208 | STRIP_INSTALLED_PRODUCT = NO; 209 | USER_HEADER_SEARCH_PATHS = "~/ImageOptim/libpng/"; 210 | }; 211 | name = Debug; 212 | }; 213 | 1DEB928B08733DD80010E9CD /* Release */ = { 214 | isa = XCBuildConfiguration; 215 | baseConfigurationReference = 5AED10E6139BD44B00FF5C69 /* release.xcconfig */; 216 | buildSettings = { 217 | DEAD_CODE_STRIPPING = NO; 218 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; 219 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 220 | GCC_PREPROCESSOR_DEFINITIONS = ( 221 | PNG_CONFIGURE_LIBPNG, 222 | HAVE_CONFIG_H, 223 | ); 224 | LD_GENERATE_MAP_FILE = YES; 225 | LIBRARY_SEARCH_PATHS = ( 226 | /usr/X11/lib/, 227 | /usr/lib, 228 | ); 229 | OTHER_LDFLAGS = ( 230 | "-lpng", 231 | "-lz", 232 | ); 233 | STRIP_INSTALLED_PRODUCT = NO; 234 | USER_HEADER_SEARCH_PATHS = "~/ImageOptim/libpng/"; 235 | }; 236 | name = Release; 237 | }; 238 | 5ABD77460F0E87ED00515CC9 /* Debug */ = { 239 | isa = XCBuildConfiguration; 240 | buildSettings = { 241 | INSTALL_PATH = /usr/local/bin; 242 | PRODUCT_NAME = pngcomp; 243 | }; 244 | name = Debug; 245 | }; 246 | 5ABD77470F0E87ED00515CC9 /* Release */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | INSTALL_PATH = /usr/local/bin; 250 | PRODUCT_NAME = pngcomp; 251 | }; 252 | name = Release; 253 | }; 254 | /* End XCBuildConfiguration section */ 255 | 256 | /* Begin XCConfigurationList section */ 257 | 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "pngnq" */ = { 258 | isa = XCConfigurationList; 259 | buildConfigurations = ( 260 | 1DEB928608733DD80010E9CD /* Debug */, 261 | 1DEB928708733DD80010E9CD /* Release */, 262 | ); 263 | defaultConfigurationIsVisible = 0; 264 | defaultConfigurationName = Release; 265 | }; 266 | 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "pngnq" */ = { 267 | isa = XCConfigurationList; 268 | buildConfigurations = ( 269 | 1DEB928A08733DD80010E9CD /* Debug */, 270 | 1DEB928B08733DD80010E9CD /* Release */, 271 | ); 272 | defaultConfigurationIsVisible = 0; 273 | defaultConfigurationName = Release; 274 | }; 275 | 5ABD774D0F0E881300515CC9 /* Build configuration list for PBXNativeTarget "pngcomp" */ = { 276 | isa = XCConfigurationList; 277 | buildConfigurations = ( 278 | 5ABD77460F0E87ED00515CC9 /* Debug */, 279 | 5ABD77470F0E87ED00515CC9 /* Release */, 280 | ); 281 | defaultConfigurationIsVisible = 0; 282 | defaultConfigurationName = Release; 283 | }; 284 | /* End XCConfigurationList section */ 285 | }; 286 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 287 | } 288 | -------------------------------------------------------------------------------- /pngquant.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5A311AF412E3C48B00EE60BD /* pam.c in Sources */ = {isa = PBXBuildFile; fileRef = 5AFD912412E29A5200C26E0C /* pam.c */; }; 11 | 5A3345D00F22C0E900669FE0 /* pngquant.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A3345CE0F22C0E900669FE0 /* pngquant.c */; }; 12 | 5A3345D10F22C0E900669FE0 /* rwpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A3345CF0F22C0E900669FE0 /* rwpng.c */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXFileReference section */ 16 | 5A3345CD0F22C0E900669FE0 /* rwpng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = rwpng.h; path = pngquant/rwpng.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 17 | 5A3345CE0F22C0E900669FE0 /* pngquant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = pngquant.c; path = pngquant/pngquant.c; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.c; }; 18 | 5A3345CF0F22C0E900669FE0 /* rwpng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rwpng.c; path = pngquant/rwpng.c; sourceTree = SOURCE_ROOT; }; 19 | 5AED10E8139BD4C900FF5C69 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = ""; }; 20 | 5AED10E9139BD4C900FF5C69 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = ""; }; 21 | 5AFD8E9112E265DB00C26E0C /* pam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pam.h; path = pngquant/pam.h; sourceTree = ""; }; 22 | 5AFD912412E29A5200C26E0C /* pam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pam.c; path = pngquant/pam.c; sourceTree = ""; }; 23 | 8DD76FB20486AB0100D96B5E /* pngquant */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pngquant; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | /* End PBXFileReference section */ 25 | 26 | /* Begin PBXFrameworksBuildPhase section */ 27 | 8DD76FAD0486AB0100D96B5E /* Frameworks */ = { 28 | isa = PBXFrameworksBuildPhase; 29 | buildActionMask = 2147483647; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | 08FB7794FE84155DC02AAC07 /* Untitled */ = { 38 | isa = PBXGroup; 39 | children = ( 40 | 08FB7795FE84155DC02AAC07 /* Source */, 41 | 1AB674ADFE9D54B511CA2CBB /* Products */, 42 | 5AED10E8139BD4C900FF5C69 /* release.xcconfig */, 43 | 5AED10E9139BD4C900FF5C69 /* debug.xcconfig */, 44 | ); 45 | name = Untitled; 46 | sourceTree = ""; 47 | }; 48 | 08FB7795FE84155DC02AAC07 /* Source */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 5A3345CE0F22C0E900669FE0 /* pngquant.c */, 52 | 5A3345CD0F22C0E900669FE0 /* rwpng.h */, 53 | 5A3345CF0F22C0E900669FE0 /* rwpng.c */, 54 | 5AFD8E9112E265DB00C26E0C /* pam.h */, 55 | 5AFD912412E29A5200C26E0C /* pam.c */, 56 | ); 57 | name = Source; 58 | sourceTree = ""; 59 | }; 60 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 8DD76FB20486AB0100D96B5E /* pngquant */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | /* End PBXGroup section */ 69 | 70 | /* Begin PBXNativeTarget section */ 71 | 8DD76FA90486AB0100D96B5E /* pngquant */ = { 72 | isa = PBXNativeTarget; 73 | buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "pngquant" */; 74 | buildPhases = ( 75 | 8DD76FAB0486AB0100D96B5E /* Sources */, 76 | 8DD76FAD0486AB0100D96B5E /* Frameworks */, 77 | ); 78 | buildRules = ( 79 | ); 80 | dependencies = ( 81 | ); 82 | name = pngquant; 83 | productInstallPath = "$(HOME)/bin"; 84 | productName = Untitled; 85 | productReference = 8DD76FB20486AB0100D96B5E /* pngquant */; 86 | productType = "com.apple.product-type.tool"; 87 | }; 88 | /* End PBXNativeTarget section */ 89 | 90 | /* Begin PBXProject section */ 91 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 92 | isa = PBXProject; 93 | attributes = { 94 | LastUpgradeCheck = 0410; 95 | }; 96 | buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "pngquant" */; 97 | compatibilityVersion = "Xcode 3.2"; 98 | developmentRegion = English; 99 | hasScannedForEncodings = 1; 100 | knownRegions = ( 101 | English, 102 | Japanese, 103 | French, 104 | German, 105 | ); 106 | mainGroup = 08FB7794FE84155DC02AAC07 /* Untitled */; 107 | projectDirPath = ""; 108 | projectRoot = ""; 109 | targets = ( 110 | 8DD76FA90486AB0100D96B5E /* pngquant */, 111 | ); 112 | }; 113 | /* End PBXProject section */ 114 | 115 | /* Begin PBXSourcesBuildPhase section */ 116 | 8DD76FAB0486AB0100D96B5E /* Sources */ = { 117 | isa = PBXSourcesBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | 5A311AF412E3C48B00EE60BD /* pam.c in Sources */, 121 | 5A3345D00F22C0E900669FE0 /* pngquant.c in Sources */, 122 | 5A3345D10F22C0E900669FE0 /* rwpng.c in Sources */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | /* End PBXSourcesBuildPhase section */ 127 | 128 | /* Begin XCBuildConfiguration section */ 129 | 1DEB928608733DD80010E9CD /* Debug */ = { 130 | isa = XCBuildConfiguration; 131 | buildSettings = { 132 | INSTALL_PATH = /usr/local/bin; 133 | PRODUCT_NAME = pngquant; 134 | }; 135 | name = Debug; 136 | }; 137 | 1DEB928708733DD80010E9CD /* Release */ = { 138 | isa = XCBuildConfiguration; 139 | buildSettings = { 140 | INSTALL_PATH = /usr/local/bin; 141 | PRODUCT_NAME = pngquant; 142 | }; 143 | name = Release; 144 | }; 145 | 1DEB928A08733DD80010E9CD /* Debug */ = { 146 | isa = XCBuildConfiguration; 147 | baseConfigurationReference = 5AED10E9139BD4C900FF5C69 /* debug.xcconfig */; 148 | buildSettings = { 149 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 150 | GCC_PREPROCESSOR_DEFINITIONS = ""; 151 | LD_GENERATE_MAP_FILE = YES; 152 | LIBRARY_SEARCH_PATHS = ( 153 | /usr/lib/, 154 | /usr/X11/lib/, 155 | ); 156 | MACOSX_DEPLOYMENT_TARGET = 10.6; 157 | OTHER_LDFLAGS = ( 158 | "-lpng", 159 | "-lz", 160 | ); 161 | SDKROOT = macosx10.6; 162 | STRIP_INSTALLED_PRODUCT = NO; 163 | USER_HEADER_SEARCH_PATHS = /usr/X11/include/; 164 | }; 165 | name = Debug; 166 | }; 167 | 1DEB928B08733DD80010E9CD /* Release */ = { 168 | isa = XCBuildConfiguration; 169 | baseConfigurationReference = 5AED10E8139BD4C900FF5C69 /* release.xcconfig */; 170 | buildSettings = { 171 | COPY_PHASE_STRIP = NO; 172 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 173 | GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; 174 | LD_GENERATE_MAP_FILE = YES; 175 | LIBRARY_SEARCH_PATHS = ( 176 | /usr/lib/, 177 | /usr/X11/lib/, 178 | ); 179 | MACOSX_DEPLOYMENT_TARGET = 10.6; 180 | OTHER_LDFLAGS = ( 181 | "-lpng", 182 | "-lz", 183 | ); 184 | SDKROOT = macosx10.6; 185 | STRIP_INSTALLED_PRODUCT = NO; 186 | USER_HEADER_SEARCH_PATHS = /usr/X11/include/; 187 | }; 188 | name = Release; 189 | }; 190 | /* End XCBuildConfiguration section */ 191 | 192 | /* Begin XCConfigurationList section */ 193 | 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "pngquant" */ = { 194 | isa = XCConfigurationList; 195 | buildConfigurations = ( 196 | 1DEB928608733DD80010E9CD /* Debug */, 197 | 1DEB928708733DD80010E9CD /* Release */, 198 | ); 199 | defaultConfigurationIsVisible = 0; 200 | defaultConfigurationName = Release; 201 | }; 202 | 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "pngquant" */ = { 203 | isa = XCConfigurationList; 204 | buildConfigurations = ( 205 | 1DEB928A08733DD80010E9CD /* Debug */, 206 | 1DEB928B08733DD80010E9CD /* Release */, 207 | ); 208 | defaultConfigurationIsVisible = 0; 209 | defaultConfigurationName = Release; 210 | }; 211 | /* End XCConfigurationList section */ 212 | }; 213 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 214 | } 215 | -------------------------------------------------------------------------------- /posterizer.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5ABF8DCE1393C9DA0054E027 /* posterize.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABF8DCC1393C9DA0054E027 /* posterize.c */; }; 11 | 5ABF8DCF1393C9DA0054E027 /* rwpng.c in Sources */ = {isa = PBXBuildFile; fileRef = 5ABF8DCD1393C9DA0054E027 /* rwpng.c */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 5A27B9F1139B087F0095FC2F /* release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = SOURCE_ROOT; }; 16 | 5A27B9F2139B087F0095FC2F /* debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = SOURCE_ROOT; }; 17 | 5ABF8DCC1393C9DA0054E027 /* posterize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = posterize.c; path = posterizer/posterize.c; sourceTree = ""; }; 18 | 5ABF8DCD1393C9DA0054E027 /* rwpng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rwpng.c; path = posterizer/rwpng.c; sourceTree = ""; }; 19 | 8DD76FB20486AB0100D96B5E /* posterizer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = posterizer; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | /* End PBXFileReference section */ 21 | 22 | /* Begin PBXGroup section */ 23 | 08FB7794FE84155DC02AAC07 /* lossy */ = { 24 | isa = PBXGroup; 25 | children = ( 26 | 08FB7795FE84155DC02AAC07 /* Source */, 27 | 1AB674ADFE9D54B511CA2CBB /* Products */, 28 | 5A27B9F2139B087F0095FC2F /* debug.xcconfig */, 29 | 5A27B9F1139B087F0095FC2F /* release.xcconfig */, 30 | ); 31 | name = lossy; 32 | sourceTree = ""; 33 | }; 34 | 08FB7795FE84155DC02AAC07 /* Source */ = { 35 | isa = PBXGroup; 36 | children = ( 37 | 5ABF8DCC1393C9DA0054E027 /* posterize.c */, 38 | 5ABF8DCD1393C9DA0054E027 /* rwpng.c */, 39 | ); 40 | name = Source; 41 | sourceTree = ""; 42 | }; 43 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 8DD76FB20486AB0100D96B5E /* posterizer */, 47 | ); 48 | name = Products; 49 | sourceTree = ""; 50 | }; 51 | /* End PBXGroup section */ 52 | 53 | /* Begin PBXNativeTarget section */ 54 | 8DD76FA90486AB0100D96B5E /* posterizer */ = { 55 | isa = PBXNativeTarget; 56 | buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "posterizer" */; 57 | buildPhases = ( 58 | 8DD76FAB0486AB0100D96B5E /* Sources */, 59 | ); 60 | buildRules = ( 61 | ); 62 | dependencies = ( 63 | ); 64 | name = posterizer; 65 | productInstallPath = "$(HOME)/bin"; 66 | productName = lossy; 67 | productReference = 8DD76FB20486AB0100D96B5E /* posterizer */; 68 | productType = "com.apple.product-type.tool"; 69 | }; 70 | /* End PBXNativeTarget section */ 71 | 72 | /* Begin PBXProject section */ 73 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 74 | isa = PBXProject; 75 | attributes = { 76 | BuildIndependentTargetsInParallel = YES; 77 | LastUpgradeCheck = 0410; 78 | }; 79 | buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "posterizer" */; 80 | compatibilityVersion = "Xcode 3.2"; 81 | developmentRegion = English; 82 | hasScannedForEncodings = 1; 83 | knownRegions = ( 84 | English, 85 | Japanese, 86 | French, 87 | German, 88 | ); 89 | mainGroup = 08FB7794FE84155DC02AAC07 /* lossy */; 90 | projectDirPath = ""; 91 | projectRoot = ""; 92 | targets = ( 93 | 8DD76FA90486AB0100D96B5E /* posterizer */, 94 | ); 95 | }; 96 | /* End PBXProject section */ 97 | 98 | /* Begin PBXSourcesBuildPhase section */ 99 | 8DD76FAB0486AB0100D96B5E /* Sources */ = { 100 | isa = PBXSourcesBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 5ABF8DCE1393C9DA0054E027 /* posterize.c in Sources */, 104 | 5ABF8DCF1393C9DA0054E027 /* rwpng.c in Sources */, 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | /* End PBXSourcesBuildPhase section */ 109 | 110 | /* Begin XCBuildConfiguration section */ 111 | 1DEB928608733DD80010E9CD /* Debug */ = { 112 | isa = XCBuildConfiguration; 113 | buildSettings = { 114 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 115 | INSTALL_PATH = /usr/local/bin; 116 | LIBRARY_SEARCH_PATHS = ( 117 | "$(inherited)", 118 | /usr/X11/lib, 119 | /Users/porneL/ImageOptim/libpng/build/Release, 120 | ); 121 | PRODUCT_NAME = posterizer; 122 | }; 123 | name = Debug; 124 | }; 125 | 1DEB928708733DD80010E9CD /* Release */ = { 126 | isa = XCBuildConfiguration; 127 | buildSettings = { 128 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 129 | INSTALL_PATH = /usr/local/bin; 130 | LIBRARY_SEARCH_PATHS = ( 131 | "$(inherited)", 132 | /usr/X11/lib, 133 | /Users/porneL/ImageOptim/libpng/build/Release, 134 | ); 135 | PRODUCT_NAME = posterizer; 136 | }; 137 | name = Release; 138 | }; 139 | 1DEB928A08733DD80010E9CD /* Debug */ = { 140 | isa = XCBuildConfiguration; 141 | baseConfigurationReference = 5A27B9F2139B087F0095FC2F /* debug.xcconfig */; 142 | buildSettings = { 143 | GCC_C_LANGUAGE_STANDARD = gnu99; 144 | GCC_PREPROCESSOR_DEFINITIONS = ( 145 | PNG_CONFIGURE_LIBPNG, 146 | HAVE_CONFIG_H, 147 | ); 148 | HEADER_SEARCH_PATHS = "~/ImageOptim/libpng/"; 149 | OTHER_LDFLAGS = ( 150 | "-lpng", 151 | "-lz", 152 | ); 153 | }; 154 | name = Debug; 155 | }; 156 | 1DEB928B08733DD80010E9CD /* Release */ = { 157 | isa = XCBuildConfiguration; 158 | baseConfigurationReference = 5A27B9F1139B087F0095FC2F /* release.xcconfig */; 159 | buildSettings = { 160 | GCC_C_LANGUAGE_STANDARD = gnu99; 161 | GCC_PREPROCESSOR_DEFINITIONS = ( 162 | PNG_CONFIGURE_LIBPNG, 163 | HAVE_CONFIG_H, 164 | ); 165 | HEADER_SEARCH_PATHS = "~/ImageOptim/libpng/"; 166 | OTHER_LDFLAGS = ( 167 | "-lpng", 168 | "-lz", 169 | ); 170 | }; 171 | name = Release; 172 | }; 173 | /* End XCBuildConfiguration section */ 174 | 175 | /* Begin XCConfigurationList section */ 176 | 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "posterizer" */ = { 177 | isa = XCConfigurationList; 178 | buildConfigurations = ( 179 | 1DEB928608733DD80010E9CD /* Debug */, 180 | 1DEB928708733DD80010E9CD /* Release */, 181 | ); 182 | defaultConfigurationIsVisible = 0; 183 | defaultConfigurationName = Release; 184 | }; 185 | 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "posterizer" */ = { 186 | isa = XCConfigurationList; 187 | buildConfigurations = ( 188 | 1DEB928A08733DD80010E9CD /* Debug */, 189 | 1DEB928B08733DD80010E9CD /* Release */, 190 | ); 191 | defaultConfigurationIsVisible = 0; 192 | defaultConfigurationName = Release; 193 | }; 194 | /* End XCConfigurationList section */ 195 | }; 196 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 197 | } 198 | -------------------------------------------------------------------------------- /release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_SEARCH_USER_PATHS = NO; 2 | DEAD_CODE_STRIPPING = YES; 3 | DEPLOYMENT_POSTPROCESSING = YES; 4 | GCC_AUTO_VECTORIZATION = YES; 5 | GCC_C_LANGUAGE_STANDARD = c99; 6 | GCC_ENABLE_CPP_RTTI = NO; 7 | GCC_FAST_MATH = YES; 8 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 9 | GCC_INLINES_ARE_PRIVATE_EXTERN = YES; 10 | GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; 11 | GCC_STRICT_ALIASING = YES; 12 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 13 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 14 | GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; 15 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 16 | GCC_WARN_UNUSED_FUNCTION = YES; 17 | GCC_WARN_UNUSED_LABEL = YES; 18 | GCC_WARN_UNUSED_VALUE = YES; 19 | GCC_WARN_UNUSED_VARIABLE = YES; 20 | MACOSX_DEPLOYMENT_TARGET = 10.7; 21 | ONLY_ACTIVE_ARCH = NO; 22 | PLIST_FILE_OUTPUT_FORMAT = binary; 23 | STRINGS_FILE_OUTPUT_ENCODING = UTF-8; 24 | LD_RUNPATH_SEARCH_PATHS = @loader_path/../Frameworks 25 | -------------------------------------------------------------------------------- /textures/461223185.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/461223185.jpg -------------------------------------------------------------------------------- /textures/461223192.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/461223192.jpg -------------------------------------------------------------------------------- /textures/A_MIXRED.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/A_MIXRED.jpeg -------------------------------------------------------------------------------- /textures/G_IRON3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/G_IRON3.jpg -------------------------------------------------------------------------------- /textures/Rustpattern.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/Rustpattern.jpeg -------------------------------------------------------------------------------- /textures/STONE4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/STONE4.jpeg -------------------------------------------------------------------------------- /textures/nature71.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/nature71.jpg -------------------------------------------------------------------------------- /textures/photoshop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/photoshop.png -------------------------------------------------------------------------------- /textures/seawaterfull2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kornelski/ImageAlpha/ec93d2956ffea8e6534413759eee2cd88d63af2f/textures/seawaterfull2.jpg -------------------------------------------------------------------------------- /zh-Hans.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | --------------------------------------------------------------------------------