/* Shim functions */ public static byte[] Decompress(EndianBinaryReader reader, int width, int height, PixelDataFormat inputFormat, long readLength) { byte[] outPixels = new byte[readLength * 8]; PixelOrderingDelegate pixelOrderingFunc = ImageBinary.GetPixelOrderingFunction(inputFormat & PixelDataFormat.MaskPixelOrdering); for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4) { ushort[] decompressedBlock = new ushort[(4 * 4) * 4]; if ((inputFormat & PixelDataFormat.MaskSpecial) == PixelDataFormat.SpecialFormatBPTC_Float) { DecompressBlockBPTCFloatShared(reader, false, ref decompressedBlock); } else if ((inputFormat & PixelDataFormat.MaskSpecial) == PixelDataFormat.SpecialFormatBPTC_SignedFloat) { DecompressBlockBPTCFloatShared(reader, true, ref decompressedBlock); } else { throw new Exception("Trying to decode BPTC Float/SignedFloat with format set to non-BPTC"); } int rx, ry; pixelOrderingFunc(x / 4, y / 4, width / 4, height / 4, inputFormat, out rx, out ry); rx *= 4; ry *= 4; for (int py = 0; py < 4; py++) { for (int px = 0; px < 4; px++) { int ix = (rx + px); int iy = (ry + py); if (ix >= width || iy >= height) { continue; } for (int c = 0; c < 4; c++) { float value = Float16toFloat32(decompressedBlock[(((py * 4) + px) * 4) + c]); outPixels[(((iy * width) + ix) * 4) + c] = (byte)(value * 255); } } } } } return(outPixels); }
public static byte[] Decompress(EndianBinaryReader reader, int width, int height, PixelDataFormat inputFormat, long readLength) { byte[] outPixels = new byte[readLength * 8]; PixelOrderingDelegate pixelOrderingFunc = ImageBinary.GetPixelOrderingFunction(inputFormat & PixelDataFormat.MaskPixelOrdering); DXTxRGTCBlockDecoderDelegate blockDecoder; DXTxRGTCBlockLayout blockLayout; DXTxRGTCSignedness signedness; PixelDataFormat specialFormat = (inputFormat & PixelDataFormat.MaskSpecial); switch (specialFormat) { case PixelDataFormat.SpecialFormatDXT1: blockDecoder = DecodeDXT1Block; blockLayout = DXTxRGTCBlockLayout.Normal; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatDXT3: blockDecoder = DecodeDXT3Block; blockLayout = DXTxRGTCBlockLayout.Normal; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatDXT5: blockDecoder = DecodeDXT5Block; blockLayout = DXTxRGTCBlockLayout.Normal; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatRGTC1: blockDecoder = DecodeRGTC1Block; blockLayout = DXTxRGTCBlockLayout.Normal; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatRGTC1_Signed: blockDecoder = DecodeRGTC1Block; blockLayout = DXTxRGTCBlockLayout.PSP; signedness = DXTxRGTCSignedness.Signed; break; case PixelDataFormat.SpecialFormatRGTC2: blockDecoder = DecodeRGTC2Block; blockLayout = DXTxRGTCBlockLayout.Normal; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatRGTC2_Signed: blockDecoder = DecodeRGTC2Block; blockLayout = DXTxRGTCBlockLayout.PSP; signedness = DXTxRGTCSignedness.Signed; break; case PixelDataFormat.SpecialFormatDXT1_PSP: blockDecoder = DecodeDXT1Block; blockLayout = DXTxRGTCBlockLayout.PSP; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatDXT3_PSP: blockDecoder = DecodeDXT3Block; blockLayout = DXTxRGTCBlockLayout.PSP; signedness = DXTxRGTCSignedness.Unsigned; break; case PixelDataFormat.SpecialFormatDXT5_PSP: blockDecoder = DecodeDXT5Block; blockLayout = DXTxRGTCBlockLayout.PSP; signedness = DXTxRGTCSignedness.Unsigned; break; default: throw new Exception("Trying to decode DXT/RGTC with format set to non-DXT/RGTC"); } for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4) { byte[] decompressedBlock = blockDecoder(reader, inputFormat, blockLayout, signedness); int rx, ry; pixelOrderingFunc(x / 4, y / 4, width / 4, height / 4, inputFormat, out rx, out ry); rx *= 4; ry *= 4; for (int py = 0; py < 4; py++) { for (int px = 0; px < 4; px++) { int ix = (rx + px); int iy = (ry + py); if (ix >= width || iy >= height) { continue; } for (int c = 0; c < 4; c++) { outPixels[(((iy * width) + ix) * 4) + c] = decompressedBlock[(((py * 4) + px) * 4) + c]; } } } } } return(outPixels); }