Commits

Alex Szpakowski committed a3dc135

Added an Apple ImageIO backend to love.image as an alternative to DevIL on OSX and iOS.
Compared to DevIL, ImageIO provides a 10-50% speed increase when decoding images, and a 50-1000% speed increase when encoding - with smaller filesizes (and the same or better quality) to boot.

imageio::ImageData::load is based on rude's ImageIO iOS backend.

Comments (0)

Files changed (7)

platform/macosx/love-framework.xcodeproj/project.pbxproj

 		FA08F62C16C7541400F007B5 /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA577A8716C71CF000860150 /* wrap_Shader.cpp */; };
 		FA08F62D16C7541400F007B5 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C16FDB537A702F4D42534E /* wrap_SpriteBatch.cpp */; };
 		FA08F62E16C7542600F007B5 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 78115E763B723C0C40AD47CF /* ImageData.cpp */; };
-		FA08F62F16C7542600F007B5 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505F23A73BFE250833D650E4 /* Image.cpp */; };
-		FA08F63016C7542600F007B5 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7781A230065F346E2313A /* ImageData.cpp */; };
 		FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */; };
 		FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */; };
 		FA08F63316C7542D00F007B5 /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 677F545C76EA3B247329358D /* Joystick.cpp */; };
 		FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; };
 		FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6716C719D900860150 /* FreeType.framework */; };
 		FA577AC316C7512F00860150 /* Game_Music_Emu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6B16C719E400860150 /* Game_Music_Emu.framework */; };
-		FA577AC416C7513200860150 /* IL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6916C719DE00860150 /* IL.framework */; };
 		FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A8216C71A5300860150 /* libmodplug.framework */; };
 		FA577AC616C7513800860150 /* Lua.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6D16C719EA00860150 /* Lua.framework */; };
 		FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6F16C719F000860150 /* mpg123.framework */; };
 		FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */; };
 		FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937616DCC6C2006F2BEE /* wrap_Math.h */; };
 		FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; };
+		FAEA5A3916F8209F00E4B968 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEA5A3516F8209F00E4B968 /* Image.cpp */; };
+		FAEA5A3A16F8209F00E4B968 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEA5A3616F8209F00E4B968 /* Image.h */; };
+		FAEA5A3B16F8209F00E4B968 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEA5A3716F8209F00E4B968 /* ImageData.cpp */; };
+		FAEA5A3C16F8209F00E4B968 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEA5A3816F8209F00E4B968 /* ImageData.h */; };
+		FAEA5A5016F8312D00E4B968 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAEA5A4F16F8312D00E4B968 /* ApplicationServices.framework */; };
 		FAF272A416E3D44400CC193A /* Channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729816E3D44400CC193A /* Channel.cpp */; };
 		FAF272A516E3D44400CC193A /* Channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729916E3D44400CC193A /* Channel.h */; };
 		FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729A16E3D44400CC193A /* LuaThread.cpp */; };
 		1A95437F513E662113AC154A /* b2Rope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Rope.h; sourceTree = "<group>"; };
 		1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = "<group>"; };
 		1AA213FC158815FA77C40330 /* ChainShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChainShape.h; sourceTree = "<group>"; };
-		1AA7781A230065F346E2313A /* ImageData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
 		1B036C7C5A8832AE53BB1C06 /* b2CollideEdge.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideEdge.cpp; sourceTree = "<group>"; };
 		1B1C4E4D288A1D2F29E57B1B /* Rasterizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Rasterizer.cpp; sourceTree = "<group>"; };
 		1B4E22F1388E2B2E76E3377B /* wrap_GlyphData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_GlyphData.cpp; sourceTree = "<group>"; };
 		27F777AB188D674F30BC1829 /* wrap_World.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_World.h; sourceTree = "<group>"; };
 		28016C9B51FE1A893DC35B66 /* Variant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Variant.h; sourceTree = "<group>"; };
 		28024635525B077E08A73D9B /* Source.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = "<group>"; };
-		283342E174613897621A43F1 /* ImageData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
 		286660042F9654F61AB90D7A /* Body.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Body.h; sourceTree = "<group>"; };
 		2912092853050AF9785F39BE /* wrap_RevoluteJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_RevoluteJoint.h; sourceTree = "<group>"; };
 		295C665B1E0B6B2D03CC4937 /* wrap_Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = "<group>"; };
 		4F34010A575C02E66D400CE2 /* RopeJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RopeJoint.h; sourceTree = "<group>"; };
 		4F3E12BD4A646D0366792FC9 /* b2WorldCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = "<group>"; };
 		503971A86B7167A91B670FBA /* boot.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = boot.lua.h; sourceTree = "<group>"; };
-		505F23A73BFE250833D650E4 /* Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
 		50B67F2D0CC511706810302E /* wrap_GearJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_GearJoint.cpp; sourceTree = "<group>"; };
 		50EC67CE3ED71F5D13304FD4 /* b2Contact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = "<group>"; };
 		50F0575E16561864699E41F5 /* b2Fixture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = "<group>"; };
 		66F8479E6D2D587A592F2024 /* socket.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = socket.lua.h; sourceTree = "<group>"; };
 		677F545C76EA3B247329358D /* Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
 		678E42771C9B415628A3234D /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = "<group>"; };
-		68616BD516DB124312B47EB3 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
 		691C5C5828550E2F60754EF2 /* wrap_Event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Event.cpp; sourceTree = "<group>"; };
 		695E4ED13AA0689E64280573 /* wrap_Timer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Timer.cpp; sourceTree = "<group>"; };
 		69967D2323404E1F0ED21F11 /* wrap_DistanceJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_DistanceJoint.cpp; sourceTree = "<group>"; };
 		FA5454C016F1310000D30303 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = "<group>"; };
 		FA5454C116F1310000D30303 /* MathModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathModule.h; sourceTree = "<group>"; };
 		FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = "<absolute>"; };
-		FA577A6916C719DE00860150 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = "<absolute>"; };
 		FA577A6B16C719E400860150 /* Game_Music_Emu.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Game_Music_Emu.framework; path = /Library/Frameworks/Game_Music_Emu.framework; sourceTree = "<absolute>"; };
 		FA577A6D16C719EA00860150 /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = "<absolute>"; };
 		FA577A6F16C719F000860150 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; };
 		FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Math.cpp; sourceTree = "<group>"; };
 		FA7C937616DCC6C2006F2BEE /* wrap_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Math.h; sourceTree = "<group>"; };
 		FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
+		FAEA5A3516F8209F00E4B968 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
+		FAEA5A3616F8209F00E4B968 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
+		FAEA5A3716F8209F00E4B968 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
+		FAEA5A3816F8209F00E4B968 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
+		FAEA5A4F16F8312D00E4B968 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
 		FAF2729816E3D44400CC193A /* Channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Channel.cpp; sourceTree = "<group>"; };
 		FAF2729916E3D44400CC193A /* Channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Channel.h; sourceTree = "<group>"; };
 		FAF2729A16E3D44400CC193A /* LuaThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LuaThread.cpp; sourceTree = "<group>"; };
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				FAEA5A5016F8312D00E4B968 /* ApplicationServices.framework in Frameworks */,
 				FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */,
 				FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */,
 				FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */,
 				FA577AC316C7512F00860150 /* Game_Music_Emu.framework in Frameworks */,
-				FA577AC416C7513200860150 /* IL.framework in Frameworks */,
 				FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */,
 				FA577AC616C7513800860150 /* Lua.framework in Frameworks */,
 				FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */,
 				25C325DC2128769F6C6A54C3 /* Image.h */,
 				78115E763B723C0C40AD47CF /* ImageData.cpp */,
 				07B301984BE42246402F7D27 /* ImageData.h */,
-				13730AB030E309FF6E2961F1 /* devil */,
+				FAEA5A3416F8209F00E4B968 /* imageio */,
 				0B0728FA73B107B37A956A09 /* wrap_Image.cpp */,
 				006B015320155B4D42B43B61 /* wrap_Image.h */,
 				076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */,
 			path = libluasocket;
 			sourceTree = "<group>";
 		};
-		13730AB030E309FF6E2961F1 /* devil */ = {
-			isa = PBXGroup;
-			children = (
-				505F23A73BFE250833D650E4 /* Image.cpp */,
-				68616BD516DB124312B47EB3 /* Image.h */,
-				1AA7781A230065F346E2313A /* ImageData.cpp */,
-				283342E174613897621A43F1 /* ImageData.h */,
-			);
-			path = devil;
-			sourceTree = "<group>";
-		};
 		153D76205F7A4ACD12FB4C0E /* window */ = {
 			isa = PBXGroup;
 			children = (
 		FA577A6616C7199700860150 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				FAEA5A4F16F8312D00E4B968 /* ApplicationServices.framework */,
 				FA577A7916C71A1700860150 /* Cocoa.framework */,
 				FA577A6716C719D900860150 /* FreeType.framework */,
 				FA577A6B16C719E400860150 /* Game_Music_Emu.framework */,
-				FA577A6916C719DE00860150 /* IL.framework */,
 				FA577A8216C71A5300860150 /* libmodplug.framework */,
 				FA577A6D16C719EA00860150 /* Lua.framework */,
 				FA577A6F16C719F000860150 /* mpg123.framework */,
 			path = math;
 			sourceTree = "<group>";
 		};
+		FAEA5A3416F8209F00E4B968 /* imageio */ = {
+			isa = PBXGroup;
+			children = (
+				FAEA5A3516F8209F00E4B968 /* Image.cpp */,
+				FAEA5A3616F8209F00E4B968 /* Image.h */,
+				FAEA5A3716F8209F00E4B968 /* ImageData.cpp */,
+				FAEA5A3816F8209F00E4B968 /* ImageData.h */,
+			);
+			path = imageio;
+			sourceTree = "<group>";
+		};
 		FAF272B016E3D46400CC193A /* sdl */ = {
 			isa = PBXGroup;
 			children = (
 				FAF272B616E3D46400CC193A /* Thread.h in Headers */,
 				FAF272B816E3D46400CC193A /* threads.h in Headers */,
 				FA5454C316F1310000D30303 /* MathModule.h in Headers */,
+				FAEA5A3A16F8209F00E4B968 /* Image.h in Headers */,
+				FAEA5A3C16F8209F00E4B968 /* ImageData.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 				FA08F62C16C7541400F007B5 /* wrap_Shader.cpp in Sources */,
 				FA08F62D16C7541400F007B5 /* wrap_SpriteBatch.cpp in Sources */,
 				FA08F62E16C7542600F007B5 /* ImageData.cpp in Sources */,
-				FA08F62F16C7542600F007B5 /* Image.cpp in Sources */,
-				FA08F63016C7542600F007B5 /* ImageData.cpp in Sources */,
 				FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */,
 				FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */,
 				FA08F63316C7542D00F007B5 /* Joystick.cpp in Sources */,
 				FAF272B516E3D46400CC193A /* Thread.cpp in Sources */,
 				FAF272B716E3D46400CC193A /* threads.cpp in Sources */,
 				FA5454C216F1310000D30303 /* MathModule.cpp in Sources */,
+				FAEA5A3916F8209F00E4B968 /* Image.cpp in Sources */,
+				FAEA5A3B16F8209F00E4B968 /* ImageData.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

platform/macosx/love.xcodeproj/project.pbxproj

 		A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; };
 		A9255DEC1043188D00BA1496 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; };
 		A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255E021043195A00BA1496 /* Vorbis.framework */; };
-		A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F421043240F00BA1496 /* IL.framework */; };
 		A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F51104324D700BA1496 /* Ogg.framework */; };
 		A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4710420B4A007D418B /* OpenGL.framework */; };
 		A93E6E5410420B57007D418B /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; };
 				A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */,
 				A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */,
 				A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */,
-				A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */,
 				A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */,
 				A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */,
 				A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */,
 		A9255DEA1043188D00BA1496 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = "<group>"; };
 		A9255DEB1043188D00BA1496 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = "<group>"; };
 		A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = "<absolute>"; };
-		A9255F421043240F00BA1496 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = "<absolute>"; };
 		A9255F51104324D700BA1496 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = "<absolute>"; };
 		A93E6A3410420AC0007D418B /* love.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = love.cpp; path = ../../src/love.cpp; sourceTree = "<group>"; };
 		A93E6E4710420B4A007D418B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
 				1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
 				A93E6E4810420B4A007D418B /* FreeType.framework */,
 				A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */,
-				A9255F421043240F00BA1496 /* IL.framework */,
 				A9F16926109E7BAD00FC83D1 /* libmodplug.framework */,
 				FA08F69116C765A200F007B5 /* love.framework */,
 				A93E6E5310420B57007D418B /* Lua.framework */,

src/modules/image/imageio/Image.cpp

+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Image.h"
+#include "ImageData.h"
+
+namespace love
+{
+namespace image
+{
+namespace imageio
+{
+
+Image::Image()
+{
+}
+
+Image::~Image()
+{
+}
+
+const char *Image::getName() const
+{
+	return "love.image.imageio";
+}
+
+love::image::ImageData *Image::newImageData(love::filesystem::File *file)
+{
+	return new ImageData(file);
+}
+
+love::image::ImageData *Image::newImageData(Data *data)
+{
+	return new ImageData(data);
+}
+
+love::image::ImageData *Image::newImageData(int width, int height)
+{
+	return new ImageData(width, height);
+}
+
+love::image::ImageData *Image::newImageData(int width, int height, void *data)
+{
+	return new ImageData(width, height, data);
+}
+
+} // imageio
+} // image
+} // love

src/modules/image/imageio/Image.h

+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_IMAGE_IMAGEIO_IMAGE_H
+#define LOVE_IMAGE_IMAGEIO_IMAGE_H
+
+// LOVE
+#include "image/Image.h"
+
+namespace love
+{
+namespace image
+{
+namespace imageio
+{
+
+class Image : public love::image::Image
+{
+public:
+
+	Image();
+	~Image();
+
+	// Implements Module.
+	const char *getName() const;
+
+	love::image::ImageData *newImageData(love::filesystem::File *file);
+	love::image::ImageData *newImageData(Data *data);
+	love::image::ImageData *newImageData(int width, int height);
+	love::image::ImageData *newImageData(int width, int height, void *data);
+
+}; // Image
+
+} // imageio
+} // image
+} // love
+
+#endif // LOVE_IMAGE_IMAGEIO_IMAGE_H

src/modules/image/imageio/ImageData.cpp

+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#include "ImageData.h"
+
+// STD
+#include <cstring>
+#include <iostream>
+
+// LOVE
+#include "common/Exception.h"
+#include "common/math.h"
+#include "filesystem/File.h"
+
+// Image I/O
+#include <ImageIO/ImageIO.h>
+
+using love::thread::Lock;
+
+static Mutex *ioMutex = 0;
+
+namespace love
+{
+namespace image
+{
+namespace imageio
+{
+
+ImageData::ImageData(Data *data)
+{
+	load(data);
+}
+
+ImageData::ImageData(filesystem::File *file)
+{
+	Data *data = file->read();
+	load(data);
+	data->release();
+}
+
+ImageData::ImageData(int width, int height)
+{
+	this->width = width;
+	this->height = height;
+	create(width, height);
+
+	// Set to black.
+	memset(data, 0, width*height*4);
+}
+
+ImageData::ImageData(int width, int height, void *data)
+{
+	this->width = width;
+	this->height = height;
+	create(width, height, data);
+}
+
+ImageData::~ImageData()
+{
+	delete[] data;
+}
+
+void ImageData::create(int width, int height, void *data)
+{
+	try
+	{
+		this->data = new unsigned char[width*height*sizeof(pixel)];
+	}
+	catch(std::bad_alloc &)
+	{
+		throw love::Exception("Out of memory");
+	}
+
+	if (data)
+		memcpy(this->data, data, width*height*sizeof(pixel));
+}
+
+void ImageData::load(Data *data)
+{
+	if (!ioMutex)
+		ioMutex = thread::newMutex();
+
+	Lock lock(ioMutex);
+
+	CFDataRef cfdata = CFDataCreate(NULL, (const UInt8 *) data->getData(), data->getSize());
+	CGImageSourceRef source = CGImageSourceCreateWithData(cfdata, NULL);
+	CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
+
+	CFRelease(cfdata);
+	CFRelease(source);
+
+	if (!image)
+		throw love::Exception("Could not decode image!");
+
+	width = CGImageGetWidth(image);
+	height = CGImageGetHeight(image);
+
+	size_t bpp = CGImageGetBitsPerPixel(image) / 8;
+
+	if (bpp != 4)
+		throw love::Exception("ImageIO decoding error: image is not 4 bytes per pixel!");
+
+	cfdata = CGDataProviderCopyData(CGImageGetDataProvider(image));
+	CGImageRelease(image);
+
+	try
+	{
+		create(width, height);
+	}
+	catch (love::Exception &)
+	{
+		CFRelease(cfdata);
+		throw;
+	}
+
+	CFDataGetBytes(cfdata, CFRangeMake(0, CFDataGetLength(cfdata)), (UInt8 *) this->data);
+	CFRelease(cfdata);
+}
+
+void ImageData::encode(love::filesystem::File *f, ImageData::Format format)
+{
+	if (!ioMutex)
+		ioMutex = thread::newMutex();
+
+	Lock lock1(ioMutex);
+	Lock lock2(mutex);
+
+	CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, getData(), getSize(), NULL);
+
+	size_t pixsize = sizeof(pixel);
+	size_t bitspp = 8;
+	CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
+	CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
+
+	CGImageRef image = CGImageCreate(width, height, bitspp, bitspp*pixsize, width*pixsize, space, bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault);
+
+	CGColorSpaceRelease(space);
+	CGDataProviderRelease(provider);
+
+	CFMutableDataRef mutabledata = CFDataCreateMutable(NULL, 0);
+	if (!mutabledata)
+	{
+		CFRelease(image);
+		throw love::Exception("Could not create image for encoding!");
+	}
+
+	CFStringRef type;
+	switch (format)
+	{
+		case FORMAT_BMP:
+			type = CFStringCreateWithCString(NULL, "com.microsoft.bmp", kCFStringEncodingASCII);
+			break;
+		case FORMAT_TGA:
+			type = CFStringCreateWithCString(NULL, "com.truevision.tga-image", kCFStringEncodingASCII);
+			break;
+		case FORMAT_GIF:
+			type = CFStringCreateWithCString(NULL, "com.compuserve.gif", kCFStringEncodingASCII);
+			break;
+		case FORMAT_JPG:
+			type = CFStringCreateWithCString(NULL, "public.jpeg", kCFStringEncodingASCII);
+			break;
+		case FORMAT_PNG:
+		default:
+			type = CFStringCreateWithCString(NULL, "public.png", kCFStringEncodingASCII);
+			break;
+	}
+
+	CGImageDestinationRef dest = CGImageDestinationCreateWithData(mutabledata, type, 1, NULL);
+	CFRelease(type);
+
+	CGImageDestinationAddImage(dest, image, NULL);
+	
+	bool success = CGImageDestinationFinalize(dest);
+
+	CFRelease(image);
+	CFRelease(dest);
+
+	CFIndex encodedsize = CFDataGetLength(mutabledata);
+
+	if (!success || encodedsize == 0)
+	{
+		CFRelease(mutabledata);
+		throw love::Exception("Could not encode image!");
+	}
+
+	try
+	{
+		f->open(love::filesystem::File::WRITE);
+		f->write(CFDataGetMutableBytePtr(mutabledata), encodedsize);
+		f->close();
+	}
+	catch (love::Exception &)
+	{
+		CFRelease(mutabledata);
+		throw;
+	}
+
+	CFRelease(mutabledata);
+}
+
+} // imageio
+} // image
+} // love

src/modules/image/imageio/ImageData.h

+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_IMAGEIO_IMAGE_DATA_H
+#define LOVE_IMAGEIO_IMAGE_DATA_H
+
+// LOVE
+#include "filesystem/File.h"
+#include "image/ImageData.h"
+
+namespace love
+{
+namespace image
+{
+namespace imageio
+{
+
+class ImageData : public love::image::ImageData
+{
+private:
+
+	// Create imagedata. Initialize with data if not null.
+	void create(int width, int height, void *data = 0);
+
+	// Load an encoded format.
+	void load(Data *data);
+
+public:
+
+	ImageData(Data *data);
+	ImageData(love::filesystem::File *file);
+	ImageData(int width, int height);
+	ImageData(int width, int height, void *data);
+	virtual ~ImageData();
+
+	// Implements ImageData.
+	void encode(love::filesystem::File *f, Format format);
+
+}; // ImageData
+
+} // imageio
+} // image
+} // love
+
+#endif // LOVE_IMAGEIO_IMAGE_DATA_H

src/modules/image/wrap_Image.cpp

 #include "common/Data.h"
 #include "common/StringMap.h"
 
-#include "devil/Image.h"
+#ifdef LOVE_MACOSX
+	#include "imageio/Image.h"
+#else
+	#include "devil/Image.h"
+#endif
 
 namespace love
 {
 	{
 		try
 		{
+#ifdef LOVE_MACOSX
+			instance = new love::image::imageio::Image();
+#else
 			instance = new love::image::devil::Image();
+#endif
 		}
 		catch(Exception &e)
 		{