瀏覽代碼

added fmt.useAsyncDecode, added FmtSupport for hl jpg

Nicolas Cannasse 9 年之前
父節點
當前提交
b7e19f6242
共有 6 個文件被更改,包括 89 次插入24 次删除
  1. 2 3
      h3d/mat/BigTexture.hx
  2. 2 3
      h3d/mat/TextureChannels.hx
  3. 4 5
      hxd/fs/LoadedBitmap.hx
  4. 2 5
      hxd/fs/LocalFileSystem.hx
  5. 48 0
      hxd/impl/FmtSupport.hx
  6. 31 8
      hxd/res/Image.hx

+ 2 - 3
h3d/mat/BigTexture.hx

@@ -209,10 +209,9 @@ class BigTexture {
 	}
 
 	function upload( t : hxd.res.Image, q : QuadTree, alphaChannel ) {
-		switch( t.getFormat() ) {
-		case Png, Gif:
+		if( !t.getFormat().useAsyncDecode )
 			uploadPixels(t.getPixels(), q.x, q.y, alphaChannel);
-		case Jpg:
+		else {
 			loadCount++;
 			var o = { t : t, q : q, alpha : alphaChannel, skip : false };
 			pending.push(o);

+ 2 - 3
h3d/mat/TextureChannels.hx

@@ -43,10 +43,9 @@ class TextureChannels extends Texture {
 
 	public function setResource( c : hxd.Pixels.Channel, res : hxd.res.Image, ?srcChannel : hxd.Pixels.Channel ) {
 		if( srcChannel == null ) srcChannel = c;
-		switch( res.getFormat() ) {
-		case Png, Gif:
+		if( !res.getFormat().useAsyncDecode )
 			setPixels(c, res.getPixels(), srcChannel);
-		case Jpg:
+		else {
 			res.entry.loadBitmap(function(bmp) {
 				var bmp = bmp.toBitmap();
 				var pix = bmp.getPixels();

+ 4 - 5
hxd/fs/LoadedBitmap.hx

@@ -4,10 +4,10 @@ package hxd.fs;
 typedef LoadedBitmapData = flash.display.BitmapData;
 #elseif lime
 typedef LoadedBitmapData = lime.graphics.Image;
-#elseif js 
+#elseif js
 typedef LoadedBitmapData = js.html.Image;
-#else 
-typedef LoadedBitmapData = Dynamic;
+#else
+typedef LoadedBitmapData = hxd.BitmapData;
 #end
 
 abstract LoadedBitmap(LoadedBitmapData) {
@@ -31,8 +31,7 @@ abstract LoadedBitmap(LoadedBitmapData) {
 		@:privateAccess bmp.ctx.drawImage(this, 0, 0);
 		return bmp;
 		#else
-		throw "TODO";
-		return null;
+		return this;
 		#end
 	}
 

+ 2 - 5
hxd/fs/LocalFileSystem.hx

@@ -209,11 +209,7 @@ private class LocalEntry extends FileEntry {
 	}
 
 	override function load( ?onReady : Void -> Void ) : Void {
-		#if air3
 		if( onReady != null ) haxe.Timer.delay(onReady, 1);
-		#else
-		throw "TODO";
-		#end
 	}
 
 	override function loadBitmap( onLoaded : hxd.fs.LoadedBitmap -> Void ) : Void {
@@ -229,7 +225,8 @@ private class LocalEntry extends FileEntry {
 		});
 		loader.load(new flash.net.URLRequest(file.url));
 		#else
-		throw "TODO";
+		var bmp = new hxd.res.Image(this).toBitmap();
+		onLoaded(new hxd.fs.LoadedBitmap(bmp));
 		#end
 	}
 

+ 48 - 0
hxd/impl/FmtSupport.hx

@@ -0,0 +1,48 @@
+package hxd.impl;
+
+#if hl
+
+@:enum private abstract PixelFormat(Int) {
+  var RGB = 0;
+  var BGR = 1;
+  var RGBX = 2;
+  var BGRX = 3;
+  var XBGR = 4;
+  var XRGB = 5;
+  var GRAY = 6;
+  var RGBA = 7;
+  var BGRA = 8;
+  var ABGR = 9;
+  var ARGB = 10;
+  var CMYK = 11;
+}
+
+@:hlNative("fmt")
+class FmtSupport {
+
+	public static function decodeJPG( src : haxe.io.Bytes, width : Int, height : Int, fmt : hxd.PixelFormat, flipY : Bool ) {
+		var ifmt : PixelFormat = switch( fmt ) {
+		case RGBA: RGBA;
+		case BGRA: BGRA;
+		case ARGB: ARGB;
+		default:
+			fmt = BGRA;
+			BGRA;
+		};
+		var dst = hxd.impl.Tmp.getBytes(width * height * 4);
+		if( !jpg_decode(src.getData(), src.length, dst.getData(), width, height, width * 4, ifmt, (flipY?1:0)) ) {
+			hxd.impl.Tmp.saveBytes(dst);
+			return null;
+		}
+		var pix = new hxd.Pixels(width, height, dst, fmt);
+		if( flipY ) pix.flags.set(FlipY);
+		pix.convert(fmt);
+		return pix;
+	}
+
+	static function jpg_decode( src : hl.types.Bytes, srcLen : Int, dst : hl.types.Bytes, width : Int, height : Int, stride : Int, format : PixelFormat, flags : Int ) : Bool {
+		return false;
+	}
+
+}
+#end

+ 31 - 8
hxd/res/Image.hx

@@ -1,9 +1,27 @@
 package hxd.res;
 
-enum ImageFormat {
-	Jpg;
-	Png;
-	Gif;
+@:enum abstract ImageFormat(Int) {
+
+	var Jpg = 0;
+	var Png = 1;
+	var Gif = 2;
+
+	/*
+		Tells if we might not be able to directly decode the image without going through a loadBitmap async call.
+		This for example occurs when we want to decode progressive JPG in JS.
+	*/
+	public var useAsyncDecode(get, never) : Bool;
+
+	inline function get_useAsyncDecode() {
+		#if hl
+		return false;
+		#else
+		return this == Jpg.toInt();
+		#end
+	}
+
+	inline function toInt() return this;
+
 }
 
 class Image extends Resource {
@@ -114,8 +132,14 @@ class Image extends Resource {
 			pixels = new Pixels(inf.width, inf.height, format.gif.Tools.extractFullBGRA(gif, 0), BGRA);
 		case Jpg:
 			var bytes = entry.getBytes();
+			#if hl
+			if( fmt == null ) fmt = BGRA;
+			pixels = hxd.impl.FmtSupport.decodeJPG(bytes, inf.width, inf.height, fmt, flipY);
+			if( pixels == null ) throw "Failed to decode JPG " + entry.path;
+			#else
 			var p = NanoJpeg.decode(bytes);
-			pixels = new Pixels(p.width,p.height,p.pixels, BGRA);
+			pixels = new Pixels(p.width, p.height, p.pixels, BGRA);
+			#end
 		}
 		if( fmt != null ) pixels.convert(fmt);
 		if( flipY != null ) pixels.setFlip(flipY);
@@ -142,8 +166,7 @@ class Image extends Resource {
 	}
 
 	function loadTexture() {
-		switch( getFormat() ) {
-		case Png, Gif:
+		if( !getFormat().useAsyncDecode ) {
 			function load() {
 				// immediately loading the PNG is faster than going through loadBitmap
 				tex.alloc();
@@ -159,7 +182,7 @@ class Image extends Resource {
 				load();
 			else
 				entry.load(load);
-		case Jpg:
+		} else {
 			// use native decoding
 			tex.flags.set(Loading);
 			entry.loadBitmap(function(bmp) {