diff --git a/Libraries/formatlib/Sources/arm/format/JpgWriter.hx b/Libraries/formatlib/Sources/arm/format/JpgWriter.hx index 87597d19..9d066ace 100644 --- a/Libraries/formatlib/Sources/arm/format/JpgWriter.hx +++ b/Libraries/formatlib/Sources/arm/format/JpgWriter.hx @@ -531,7 +531,7 @@ class JpgWriter { var UDU: Array; var VDU: Array; - function RGB2YUV(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int) { + function ARGB2YUV(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int) { var pos = 0; for( y in 0...8 ) { var offset = ((y + ypos) * width + xpos) << 2; @@ -587,7 +587,7 @@ class JpgWriter { initCategoryNumber(); } - public function write( image : JpgData, type = 0, off = 0 ) { + public function write( image : JpgData, type = 0, off = 0, swapRG = false ) { // init quality table var quality = image.quality; if( quality <= 0 ) quality = 1; @@ -622,7 +622,7 @@ class JpgWriter { while( ypos < height ) { var xpos = 0; while( xpos < width ) { - RGB2YUV(image.pixels, width, xpos, ypos); + ARGB2YUV(image.pixels, width, xpos, ypos); DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); @@ -631,7 +631,20 @@ class JpgWriter { ypos += 8; } } - else if (type == 1) { + else if (type == 1 && !swapRG) { + while( ypos < height ) { + var xpos = 0; + while( xpos < width ) { + RGBA2YUV(image.pixels, width, xpos, ypos); + DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + xpos += 8; + } + ypos += 8; + } + } + else if (type == 1 && swapRG) { while( ypos < height ) { var xpos = 0; while( xpos < width ) { @@ -648,7 +661,7 @@ class JpgWriter { while( ypos < height ) { var xpos = 0; while( xpos < width ) { - BGRA2YUV_(image.pixels, width, xpos, ypos, off); + RRR2YUV(image.pixels, width, xpos, ypos, off); DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); @@ -668,7 +681,7 @@ class JpgWriter { } // armory - function BGRA2YUV(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int) { + function RGBA2YUV(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int) { var pos = 0; for( y in 0...8 ) { var offset = ((y + ypos) * width + xpos) << 2; @@ -684,7 +697,23 @@ class JpgWriter { } } } - function BGRA2YUV_(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int, off: Int) { + function BGRA2YUV(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int) { + var pos = 0; + for( y in 0...8 ) { + var offset = ((y + ypos) * width + xpos) << 2; + for( x in 0...8 ) { + var B = img.get(offset++); + var G = img.get(offset++); + var R = img.get(offset++); + offset++; // skip alpha + YDU[pos] = ((( 0.29900) * R + ( 0.58700) * G + ( 0.11400) * B)) -128; + UDU[pos] = (((-0.16874) * R + (-0.33126) * G + ( 0.50000) * B)); + VDU[pos] = ((( 0.50000) * R + (-0.41869) * G + (-0.08131) * B)); + pos++; + } + } + } + function RRR2YUV(img: haxe.io.Bytes, width : Int, xpos: Int, ypos: Int, off: Int) { var pos = 0; for( y in 0...8 ) { var offset = ((y + ypos) * width + xpos) << 2; diff --git a/Libraries/formatlib/Sources/arm/format/PngTools.hx b/Libraries/formatlib/Sources/arm/format/PngTools.hx index b47f59dd..660d3f77 100644 --- a/Libraries/formatlib/Sources/arm/format/PngTools.hx +++ b/Libraries/formatlib/Sources/arm/format/PngTools.hx @@ -140,6 +140,26 @@ class PngTools { } // armory + public static function build32BGR1( width : Int, height : Int, data : haxe.io.Bytes, ?level = 9 ) : PngData { + var rgba = haxe.io.Bytes.alloc(width * height * 4 + height); + var w = 0, r = 0; + for( y in 0...height ) { + rgba.set(w++,0); // no filter for this scanline + for( x in 0...width ) { + rgba.set(w++,data.get(r+2)); // r + rgba.set(w++,data.get(r+1)); // g + rgba.set(w++,data.get(r)); // b + rgba.set(w++,255); // 1 + r += 4; + } + } + var l = new List(); + l.add(CHeader({ width : width, height : height, colbits : 8, color : ColTrue(true), interlaced : false })); + l.add(CData(deflate(rgba,level))); + l.add(CEnd); + return l; + } + public static function build32RGB1( width : Int, height : Int, data : haxe.io.Bytes, ?level = 9 ) : PngData { var rgba = haxe.io.Bytes.alloc(width * height * 4 + height); var w = 0, r = 0; diff --git a/Sources/arm/io/ExportTexture.hx b/Sources/arm/io/ExportTexture.hx index 94bed44e..186c396e 100644 --- a/Sources/arm/io/ExportTexture.hx +++ b/Sources/arm/io/ExportTexture.hx @@ -271,20 +271,41 @@ class ExportTexture { var writer = new PngWriter(out); var data = type == 1 ? + #if kha_metal + PngTools.build32BGR1(res, res, pixels) : + #else PngTools.build32RGB1(res, res, pixels) : + #end type == 2 ? + #if kha_metal + PngTools.build32RRR1(res, res, pixels, 2 - off) : + #else PngTools.build32RRR1(res, res, pixels, off) : + #end + + #if kha_metal + PngTools.build32BGRA(res, res, pixels); + #else PngTools.build32RGBA(res, res, pixels); + #end writer.write(data); } else { var writer = new JpgWriter(out); - writer.write({ - width: res, - height: res, - quality: Context.formatQuality, - pixels: pixels - }, type, off); + writer.write( + { + width: res, + height: res, + quality: Context.formatQuality, + pixels: pixels + }, + type, + #if kha_metal + 2 - off, true + #else + off, false + #end + ); } Krom.fileSaveBytes(file, out.getBytes().getData()); }