From 5ddbb791dc6e7644b4d30a47cd1ceac35e268a0b Mon Sep 17 00:00:00 2001 From: alexiscatnip Date: Wed, 21 Jul 2021 01:55:43 +0800 Subject: [PATCH] simplify TGALoader. image might end up flipped or weird-colored and lose ability to decode 8-bit tga. --- .../LibreMetaverse/Imaging/BakeLayer.cs | 2 +- .../LibreMetaverse/Imaging/TGALoader.cs | 981 ++++++------------ 2 files changed, 301 insertions(+), 682 deletions(-) diff --git a/Assets/Plugins/LibreMetaverse/Imaging/BakeLayer.cs b/Assets/Plugins/LibreMetaverse/Imaging/BakeLayer.cs index 7d7af3a..ae69801 100644 --- a/Assets/Plugins/LibreMetaverse/Imaging/BakeLayer.cs +++ b/Assets/Plugins/LibreMetaverse/Imaging/BakeLayer.cs @@ -356,7 +356,7 @@ namespace OpenMetaverse.Imaging if (stream != null) { - var tex = TGALoader.LoadTGA(stream); + var tex = LoadTGAClass.LoadTGA(stream); bitmap = new Bitmap(tex); } } diff --git a/Assets/Plugins/LibreMetaverse/Imaging/TGALoader.cs b/Assets/Plugins/LibreMetaverse/Imaging/TGALoader.cs index fe8d57a..a7720a3 100644 --- a/Assets/Plugins/LibreMetaverse/Imaging/TGALoader.cs +++ b/Assets/Plugins/LibreMetaverse/Imaging/TGALoader.cs @@ -24,720 +24,339 @@ // * POSSIBILITY OF SUCH DAMAGE. // */ -//using System; -////using System.Drawing; -////using System.Drawing.Imaging; +using System; +//using System.Drawing; +//using System.Drawing.Imaging; //using Catnip.Drawing; //using Catnip.Drawing.Imaging; -//using Unity.Collections; +using Unity.Collections; +using UnityEngine; //using UnityEngine; -////using UnityEngine; -//namespace OpenMetaverse.Imaging +namespace OpenMetaverse.Imaging +{ +#if !NO_UNSAFE + + /// + /// Capability to load TGAs to Bitmap + /// + public class LoadTGAClass + { + struct tgaColorMap + { + public ushort FirstEntryIndex; + public ushort Length; + public byte EntrySize; + + public void Read(System.IO.BinaryReader br) + { + FirstEntryIndex = br.ReadUInt16(); + Length = br.ReadUInt16(); + EntrySize = br.ReadByte(); + } + } + + struct tgaImageSpec + { + public ushort XOrigin; + public ushort YOrigin; + public ushort Width; + public ushort Height; + public byte PixelDepth; + public byte Descriptor; + + public void Read(System.IO.BinaryReader br) + { + XOrigin = br.ReadUInt16(); + YOrigin = br.ReadUInt16(); + Width = br.ReadUInt16(); + Height = br.ReadUInt16(); + PixelDepth = br.ReadByte(); + Descriptor = br.ReadByte(); + } + + public byte AlphaBits + { + get + { + return (byte)(Descriptor & 0xF); + } + set + { + Descriptor = (byte)((Descriptor & ~0xF) | (value & 0xF)); + } + } + + public bool BottomUp + { + get + { + return (Descriptor & 0x20) == 0x20; + } + set + { + Descriptor = (byte)((Descriptor & ~0x20) | (value ? 0x20 : 0)); + } + } + } + + struct tgaHeader + { + public byte IdLength; + public byte ColorMapType; + public byte ImageType; + + public tgaColorMap ColorMap; + public tgaImageSpec ImageSpec; + + public void Read(System.IO.BinaryReader br) + { + this.IdLength = br.ReadByte(); + this.ColorMapType = br.ReadByte(); + this.ImageType = br.ReadByte(); + this.ColorMap = new tgaColorMap(); + this.ImageSpec = new tgaImageSpec(); + this.ColorMap.Read(br); + this.ImageSpec.Read(br); + } + + public bool RleEncoded + { + get + { + return ImageType >= 9; + } + } + } + + public static Texture2D LoadTGA(System.IO.Stream source) + { + byte[] buffer = new byte[source.Length]; + source.Read(buffer, 0, buffer.Length); + + System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer); + + using (System.IO.BinaryReader br = new System.IO.BinaryReader(ms)) + { + tgaHeader header = new tgaHeader(); + header.Read(br); + + if (header.ImageSpec.PixelDepth != 8 && + header.ImageSpec.PixelDepth != 16 && + header.ImageSpec.PixelDepth != 24 && + header.ImageSpec.PixelDepth != 32) + throw new ArgumentException("Not a supported tga file."); + + if (header.ImageSpec.PixelDepth == 8 || + header.ImageSpec.PixelDepth != 16) + throw new ArgumentException("TGA texture had either 8 or 16 bit depth."); + + if (header.ImageSpec.AlphaBits > 8) + throw new ArgumentException("Not a supported tga file."); + + if (header.ImageSpec.Width > 4096 || + header.ImageSpec.Height > 4096) + throw new ArgumentException("Image too large."); + + Texture2D b; + int width = header.ImageSpec.Width; + int height = header.ImageSpec.Height; + Color32[] pulledColors = new Color32[width * height]; + //BitmapData bd; + + // Create a bitmap for the image. + // Only include an alpha layer when the image requires one. + if (header.ImageSpec.AlphaBits > 0 || + header.ImageSpec.PixelDepth == 8 || // Assume 8 bit images are alpha only + header.ImageSpec.PixelDepth == 32) // Assume 32 bit images are ARGB + { // Image needs an alpha layer + b = new Texture2D( + header.ImageSpec.Width, + header.ImageSpec.Height, + TextureFormat.ARGB32, + false + /*PixelFormat.Format32bppArgb*/); + + //bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), + // ImageLockMode.WriteOnly, + // PixelFormat.Format32bppPArgb); + for (int i = 0; i < width * height; i++) + { + byte red = br.ReadByte(); + byte green = br.ReadByte(); + byte blue = br.ReadByte(); + byte alpha = br.ReadByte(); + + pulledColors[i] = new Color32(blue, green, red, alpha); + } + } + else + { // Image does not need an alpha layer, so do not include one. + b = new Texture2D( + header.ImageSpec.Width, + header.ImageSpec.Height, + TextureFormat.RGB24, + false + /*PixelFormat.Format32bppRgb*/); + + //bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), + // ImageLockMode.WriteOnly, + // PixelFormat.Format32bppRgb); + for (int i = 0; i < width * height; i++) + { + byte red = br.ReadByte(); + byte green = br.ReadByte(); + byte blue = br.ReadByte(); + + pulledColors[i] = new Color32(blue, green, red, 1); + } + + } + + + //switch (header.ImageSpec.PixelDepth) + //{ + // case 8: + // decodeStandard8(bd, header, br); + // break; + // case 16: + // if (header.ImageSpec.AlphaBits > 0) + // decodeSpecial16(bd, header, br); + // else + // decodeStandard16(bd, header, br); + // break; + // case 24: + // if (header.ImageSpec.AlphaBits > 0) + // decodeSpecial24(bd, header, br); + // else + // decodeStandard24(bd, header, br); + // break; + // case 32: + // decodeStandard32(bd, header, br); + // break; + // default: + // b.UnlockBits(bd); + // b.Dispose(); + // return null; + //} + + //b.UnlockBits(bd); + return b; + } + } + + public static Texture2D LoadTGA(string filename) + { + try + { + using (System.IO.FileStream f = System.IO.File.OpenRead(filename)) + { + if (f != null) + { + return LoadTGA(f); + } + } + return null; // file stream error + } + catch (System.IO.DirectoryNotFoundException) + { + return null; // file not found + } + catch (System.IO.FileNotFoundException) + { + return null; // file not found + } + } + } + +#endif +} + + +//using System; +//using System.IO; +//using UnityEngine; +//public static class TGALoader //{ -//#if !NO_UNSAFE - -// /// -// /// Capability to load TGAs to Bitmap -// /// -// public class LoadTGAClass +// // Loads 32-bit (RGBA) uncompressed TGA. Actually, due to TARGA file structure, BGRA32 is good option... +// // Disabled mipmaps. Disabled read/write option, to release texture memory copy. +// public static Texture2D LoadTGA(string fileName) // { -// struct tgaColorMap +// try // { -// public ushort FirstEntryIndex; -// public ushort Length; -// public byte EntrySize; - -// public void Read(System.IO.BinaryReader br) -// { -// FirstEntryIndex = br.ReadUInt16(); -// Length = br.ReadUInt16(); -// EntrySize = br.ReadByte(); -// } +// BinaryReader reader = new BinaryReader(File.OpenRead(fileName)); +// reader.BaseStream.Seek(12, SeekOrigin.Begin); +// short width = reader.ReadInt16(); +// short height = reader.ReadInt16(); +// reader.BaseStream.Seek(2, SeekOrigin.Current); +// byte[] source = reader.ReadBytes(width * height * 4); +// reader.Close(); +// Texture2D texture = new Texture2D(width, height, TextureFormat.BGRA32, false); +// texture.LoadRawTextureData(source); +// texture.name = Path.GetFileName(fileName); +// texture.Apply(false, true); +// return texture; // } - -// struct tgaImageSpec +// catch (Exception) // { -// public ushort XOrigin; -// public ushort YOrigin; -// public ushort Width; -// public ushort Height; -// public byte PixelDepth; -// public byte Descriptor; +// return Texture2D.blackTexture; +// } +// } -// public void Read(System.IO.BinaryReader br) -// { -// XOrigin = br.ReadUInt16(); -// YOrigin = br.ReadUInt16(); -// Width = br.ReadUInt16(); -// Height = br.ReadUInt16(); -// PixelDepth = br.ReadByte(); -// Descriptor = br.ReadByte(); -// } - -// public byte AlphaBits -// { -// get -// { -// return (byte)(Descriptor & 0xF); -// } -// set -// { -// Descriptor = (byte)((Descriptor & ~0xF) | (value & 0xF)); -// } -// } -// public bool BottomUp -// { -// get -// { -// return (Descriptor & 0x20) == 0x20; -// } -// set -// { -// Descriptor = (byte)((Descriptor & ~0x20) | (value ? 0x20 : 0)); -// } -// } -// } +// public static Texture2D LoadTGA(Stream TGAStream) +// { -// struct tgaHeader +// using (BinaryReader r = new BinaryReader(TGAStream)) // { -// public byte IdLength; -// public byte ColorMapType; -// public byte ImageType; +// // Skip some header info we don't care about. +// // Even if we did care, we have to move the stream seek point to the beginning, +// // as the previous method in the workflow left it at the end. +// r.BaseStream.Seek(12, SeekOrigin.Begin); -// public tgaColorMap ColorMap; -// public tgaImageSpec ImageSpec; +// short width = r.ReadInt16(); +// short height = r.ReadInt16(); +// int bitDepth = r.ReadByte(); -// public void Read(System.IO.BinaryReader br) -// { -// this.IdLength = br.ReadByte(); -// this.ColorMapType = br.ReadByte(); -// this.ImageType = br.ReadByte(); -// this.ColorMap = new tgaColorMap(); -// this.ImageSpec = new tgaImageSpec(); -// this.ColorMap.Read(br); -// this.ImageSpec.Read(br); -// } +// // Skip a byte of header information we don't care about. +// r.BaseStream.Seek(1, SeekOrigin.Current); -// public bool RleEncoded -// { -// get -// { -// return ImageType >= 9; -// } -// } -// } - -// struct tgaCD -// { -// public uint RMask, GMask, BMask, AMask; -// public byte RShift, GShift, BShift, AShift; -// public uint FinalOr; -// public bool NeedNoConvert; -// } +// Texture2D tex = new Texture2D(width, height); +// Color32[] pulledColors = new Color32[width * height]; -// static uint UnpackColor( -// uint sourceColor, ref tgaCD cd) -// { -// if (cd.RMask == 0xFF && cd.GMask == 0xFF && cd.BMask == 0xFF) +// if (bitDepth == 32) // { -// // Special case to deal with 8-bit TGA files that we treat as alpha masks -// return sourceColor << 24; -// } -// else -// { -// uint rpermute = (sourceColor << cd.RShift) | (sourceColor >> (32 - cd.RShift)); -// uint gpermute = (sourceColor << cd.GShift) | (sourceColor >> (32 - cd.GShift)); -// uint bpermute = (sourceColor << cd.BShift) | (sourceColor >> (32 - cd.BShift)); -// uint apermute = (sourceColor << cd.AShift) | (sourceColor >> (32 - cd.AShift)); -// uint result = -// (rpermute & cd.RMask) | (gpermute & cd.GMask) -// | (bpermute & cd.BMask) | (apermute & cd.AMask) | cd.FinalOr; - -// return result; -// } -// } - -// static unsafe void decodeLine( -// NativeArray b, -// int line, -// int byp, -// byte[] data, -// ref tgaCD cd) -// { -// if (cd.NeedNoConvert) -// { -// // fast copy - - -// //uint* linep = (uint*)((byte*)b.Scan0.ToPointer() + line * b.Stride); -// fixed (byte* ptr = data) +// for (int i = 0; i < width * height; i++) // { -// uint* sptr = (uint*)ptr; -// for (int i = 0; i < Width; ++i) -// { -// linep[i] = sptr[i]; -// } -// } -// } -// else -// { -// byte* linep = (byte*)b.Scan0.ToPointer() + line * b.Stride; - -// uint* up = (uint*)linep; +// byte red = r.ReadByte(); +// byte green = r.ReadByte(); +// byte blue = r.ReadByte(); +// byte alpha = r.ReadByte(); -// int rdi = 0; - -// fixed (byte* ptr = data) -// { -// for (int i = 0; i < b.Width; ++i) -// { -// uint x = 0; -// for (int j = 0; j < byp; ++j) -// { -// x |= ((uint)ptr[rdi]) << (j << 3); -// ++rdi; -// } -// up[i] = UnpackColor(x, ref cd); -// } +// pulledColors[i] = new Color32(blue, green, red, alpha); // } // } -// } - -// static void decodeRle( -// BitmapData b, -// int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) -// { -// try +// else if (bitDepth == 24) // { -// int w = b.Width; -// // make buffer larger, so in case of emergency I can decode -// // over line ends. -// byte[] linebuffer = new byte[(w + 128) * byp]; -// int maxindex = w * byp; -// int index = 0; - -// for (int j = 0; j < b.Height; ++j) +// for (int i = 0; i < width * height; i++) // { -// while (index < maxindex) -// { -// byte blocktype = br.ReadByte(); - -// int bytestoread; -// int bytestocopy; - -// if (blocktype >= 0x80) -// { -// bytestoread = byp; -// bytestocopy = byp * (blocktype - 0x80); -// } -// else -// { -// bytestoread = byp * (blocktype + 1); -// bytestocopy = 0; -// } - -// //if (index + bytestoread > maxindex) -// // throw new System.ArgumentException ("Corrupt TGA"); - -// br.Read(linebuffer, index, bytestoread); -// index += bytestoread; +// byte red = r.ReadByte(); +// byte green = r.ReadByte(); +// byte blue = r.ReadByte(); -// for (int i = 0; i != bytestocopy; ++i) -// { -// linebuffer[index + i] = linebuffer[index + i - bytestoread]; -// } -// index += bytestocopy; -// } -// if (!bottomUp) -// decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd); -// else -// decodeLine(b, j, byp, linebuffer, ref cd); - -// if (index > maxindex) -// { -// Array.Copy(linebuffer, maxindex, linebuffer, 0, index - maxindex); -// index -= maxindex; -// } -// else -// index = 0; - +// pulledColors[i] = new Color32(blue, green, red, 1); // } // } -// catch (System.IO.EndOfStreamException) -// { -// } -// } - -// static void decodePlain( -// BitmapData b, -// int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) -// { -// int w = b.Width; -// byte[] linebuffer = new byte[w * byp]; - -// for (int j = 0; j < b.Height; ++j) -// { -// br.Read(linebuffer, 0, w * byp); - -// if (!bottomUp) -// decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd); -// else -// decodeLine(b, j, byp, linebuffer, ref cd); -// } -// } - -// static void decodeStandard8( -// BitmapData b, -// tgaHeader hdr, -// System.IO.BinaryReader br) -// { -// tgaCD cd = new tgaCD(); -// cd.RMask = 0x000000ff; -// cd.GMask = 0x000000ff; -// cd.BMask = 0x000000ff; -// cd.AMask = 0x000000ff; -// cd.RShift = 0; -// cd.GShift = 0; -// cd.BShift = 0; -// cd.AShift = 0; -// cd.FinalOr = 0x00000000; -// if (hdr.RleEncoded) -// decodeRle(b, 1, cd, br, hdr.ImageSpec.BottomUp); -// else -// decodePlain(b, 1, cd, br, hdr.ImageSpec.BottomUp); -// } - -// static void decodeSpecial16( -// BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) -// { -// // i must convert the input stream to a sequence of uint values -// // which I then unpack. -// tgaCD cd = new tgaCD(); -// cd.RMask = 0x00f00000; -// cd.GMask = 0x0000f000; -// cd.BMask = 0x000000f0; -// cd.AMask = 0xf0000000; -// cd.RShift = 12; -// cd.GShift = 8; -// cd.BShift = 4; -// cd.AShift = 16; -// cd.FinalOr = 0; - -// if (hdr.RleEncoded) -// decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp); -// else -// decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp); -// } - -// static void decodeStandard16( -// BitmapData b, -// tgaHeader hdr, -// System.IO.BinaryReader br) -// { -// // i must convert the input stream to a sequence of uint values -// // which I then unpack. -// tgaCD cd = new tgaCD(); -// cd.RMask = 0x00f80000; // from 0xF800 -// cd.GMask = 0x0000fc00; // from 0x07E0 -// cd.BMask = 0x000000f8; // from 0x001F -// cd.AMask = 0x00000000; -// cd.RShift = 8; -// cd.GShift = 5; -// cd.BShift = 3; -// cd.AShift = 0; -// cd.FinalOr = 0xff000000; - -// if (hdr.RleEncoded) -// decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp); // else -// decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp); -// } - - -// static void decodeSpecial24(BitmapData b, -// tgaHeader hdr, System.IO.BinaryReader br) -// { -// // i must convert the input stream to a sequence of uint values -// // which I then unpack. -// tgaCD cd = new tgaCD(); -// cd.RMask = 0x00f80000; -// cd.GMask = 0x0000fc00; -// cd.BMask = 0x000000f8; -// cd.AMask = 0xff000000; -// cd.RShift = 8; -// cd.GShift = 5; -// cd.BShift = 3; -// cd.AShift = 8; -// cd.FinalOr = 0; - -// if (hdr.RleEncoded) -// decodeRle(b, 3, cd, br, hdr.ImageSpec.BottomUp); -// else -// decodePlain(b, 3, cd, br, hdr.ImageSpec.BottomUp); -// } - -// static void decodeStandard24(BitmapData b, -// tgaHeader hdr, System.IO.BinaryReader br) -// { -// // i must convert the input stream to a sequence of uint values -// // which I then unpack. -// tgaCD cd = new tgaCD(); -// cd.RMask = 0x00ff0000; -// cd.GMask = 0x0000ff00; -// cd.BMask = 0x000000ff; -// cd.AMask = 0x00000000; -// cd.RShift = 0; -// cd.GShift = 0; -// cd.BShift = 0; -// cd.AShift = 0; -// cd.FinalOr = 0xff000000; - -// if (hdr.RleEncoded) -// decodeRle(b, 3, cd, br, hdr.ImageSpec.BottomUp); -// else -// decodePlain(b, 3, cd, br, hdr.ImageSpec.BottomUp); -// } - -// static void decodeStandard32(BitmapData b, -// tgaHeader hdr, System.IO.BinaryReader br) -// { -// // i must convert the input stream to a sequence of uint values -// // which I then unpack. -// tgaCD cd = new tgaCD(); -// cd.RMask = 0x00ff0000; -// cd.GMask = 0x0000ff00; -// cd.BMask = 0x000000ff; -// cd.AMask = 0xff000000; -// cd.RShift = 0; -// cd.GShift = 0; -// cd.BShift = 0; -// cd.AShift = 0; -// cd.FinalOr = 0x00000000; -// cd.NeedNoConvert = true; - -// if (hdr.RleEncoded) -// decodeRle(b, 4, cd, br, hdr.ImageSpec.BottomUp); -// else -// decodePlain(b, 4, cd, br, hdr.ImageSpec.BottomUp); -// } - - -// public static Catnip.Drawing.Size GetTGASize(string filename) -// { -// System.IO.FileStream f = System.IO.File.OpenRead(filename); - -// System.IO.BinaryReader br = new System.IO.BinaryReader(f); - -// tgaHeader header = new tgaHeader(); -// header.Read(br); -// br.Close(); - -// return new Catnip.Drawing.Size(header.ImageSpec.Width, header.ImageSpec.Height); - -// } - -// public static Bitmap LoadTGA(System.IO.Stream source) -// { -// byte[] buffer = new byte[source.Length]; -// source.Read(buffer, 0, buffer.Length); - -// System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer); - -// using (System.IO.BinaryReader br = new System.IO.BinaryReader(ms)) // { -// tgaHeader header = new tgaHeader(); -// header.Read(br); - -// if (header.ImageSpec.PixelDepth != 8 && -// header.ImageSpec.PixelDepth != 16 && -// header.ImageSpec.PixelDepth != 24 && -// header.ImageSpec.PixelDepth != 32) -// throw new ArgumentException("Not a supported tga file."); - -// if (header.ImageSpec.AlphaBits > 8) -// throw new ArgumentException("Not a supported tga file."); - -// if (header.ImageSpec.Width > 4096 || -// header.ImageSpec.Height > 4096) -// throw new ArgumentException("Image too large."); - -// Bitmap b; -// //BitmapData bd; -// NativeArray thenativearray; - -// // Create a bitmap for the image. -// // Only include an alpha layer when the image requires one. -// if (header.ImageSpec.AlphaBits > 0 || -// header.ImageSpec.PixelDepth == 8 || // Assume 8 bit images are alpha only -// header.ImageSpec.PixelDepth == 32) // Assume 32 bit images are ARGB -// { // Image needs an alpha layer -// b = new Bitmap( -// header.ImageSpec.Width, -// header.ImageSpec.Height, -// UnityEngine.TextureFormat.ARGB32); - -// //bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), -// // ImageLockMode.WriteOnly, -// // PixelFormat.Format32bppPArgb); -// } -// else -// { // Image does not need an alpha layer, so do not include one. -// b = new Bitmap( -// header.ImageSpec.Width, -// header.ImageSpec.Height, -// UnityEngine.TextureFormat.RGB24); - -// //bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), -// // ImageLockMode.WriteOnly, -// // PixelFormat.Format32bppRgb); -// } - -// switch (header.ImageSpec.PixelDepth) -// { -// case 8: -// decodeStandard8(bd, header, br); -// break; -// case 16: -// if (header.ImageSpec.AlphaBits > 0) -// decodeSpecial16(bd, header, br); -// else -// decodeStandard16(bd, header, br); -// break; -// case 24: -// if (header.ImageSpec.AlphaBits > 0) -// decodeSpecial24(bd, header, br); -// else -// decodeStandard24(bd, header, br); -// break; -// case 32: -// decodeStandard32(bd, header, br); -// break; -// default: -// b.UnlockBits(bd); -// b.Dispose(); -// return null; -// } - -// b.UnlockBits(bd); -// return b; +// throw new Exception("TGA texture had non 32/24 bit depth."); // } -// } - -// public static unsafe ManagedImage LoadTGAImage(System.IO.Stream source) -// { -// return LoadTGAImage(source, false); -// } - -// public static unsafe ManagedImage LoadTGAImage(System.IO.Stream source, bool mask) -// { -// byte[] buffer = new byte[source.Length]; -// source.Read(buffer, 0, buffer.Length); - -// System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer); - -// using (System.IO.BinaryReader br = new System.IO.BinaryReader(ms)) -// { -// tgaHeader header = new tgaHeader(); -// header.Read(br); - -// if (header.ImageSpec.PixelDepth != 8 && -// header.ImageSpec.PixelDepth != 16 && -// header.ImageSpec.PixelDepth != 24 && -// header.ImageSpec.PixelDepth != 32) -// throw new ArgumentException("Not a supported tga file."); - -// if (header.ImageSpec.AlphaBits > 8) -// throw new ArgumentException("Not a supported tga file."); - -// if (header.ImageSpec.Width > 4096 || -// header.ImageSpec.Height > 4096) -// throw new ArgumentException("Image too large."); - -// byte[] decoded = new byte[header.ImageSpec.Width * header.ImageSpec.Height * 4]; -// BitmapData bd = new BitmapData(); - -// fixed (byte* pdecoded = &decoded[0]) -// { -// bd.Width = header.ImageSpec.Width; -// bd.Height = header.ImageSpec.Height; -// bd.PixelFormat = PixelFormat.Format32bppPArgb; -// bd.Stride = header.ImageSpec.Width * 4; -// bd.Scan0 = (IntPtr)pdecoded; - -// switch (header.ImageSpec.PixelDepth) -// { -// case 8: -// decodeStandard8(bd, header, br); -// break; -// case 16: -// if (header.ImageSpec.AlphaBits > 0) -// decodeSpecial16(bd, header, br); -// else -// decodeStandard16(bd, header, br); -// break; -// case 24: -// if (header.ImageSpec.AlphaBits > 0) -// decodeSpecial24(bd, header, br); -// else -// decodeStandard24(bd, header, br); -// break; -// case 32: -// decodeStandard32(bd, header, br); -// break; -// default: -// return null; -// } -// } -// int n = header.ImageSpec.Width * header.ImageSpec.Height; -// ManagedImage image; +// tex.SetPixels32(pulledColors); +// tex.Apply(); +// return tex; -// if (mask && header.ImageSpec.AlphaBits == 0 && header.ImageSpec.PixelDepth == 8) -// { -// image = new ManagedImage(header.ImageSpec.Width, header.ImageSpec.Height, -// ManagedImage.ImageChannels.Alpha); -// int p = 3; - -// for (int i = 0; i < n; i++) -// { -// image.Alpha[i] = decoded[p]; -// p += 4; -// } -// } -// else -// { -// image = new ManagedImage(header.ImageSpec.Width, header.ImageSpec.Height, -// ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha); -// int p = 0; - -// for (int i = 0; i < n; i++) -// { -// image.Blue[i] = decoded[p++]; -// image.Green[i] = decoded[p++]; -// image.Red[i] = decoded[p++]; -// image.Alpha[i] = decoded[p++]; -// } -// } - -// br.Close(); -// return image; -// } -// } - -// public static Bitmap LoadTGA(string filename) -// { -// try -// { -// using (System.IO.FileStream f = System.IO.File.OpenRead(filename)) -// { -// if (f != null) -// { -// return LoadTGA(f); -// } -// } -// return null; // file stream error -// } -// catch (System.IO.DirectoryNotFoundException) -// { -// return null; // file not found -// } -// catch (System.IO.FileNotFoundException) -// { -// return null; // file not found -// } // } // } -//#endif //} - - -using System; -using System.IO; -using UnityEngine; -public static class TGALoader -{ - // Loads 32-bit (RGBA) uncompressed TGA. Actually, due to TARGA file structure, BGRA32 is good option... - // Disabled mipmaps. Disabled read/write option, to release texture memory copy. - public static Texture2D LoadTGA(string fileName) - { - try - { - BinaryReader reader = new BinaryReader(File.OpenRead(fileName)); - reader.BaseStream.Seek(12, SeekOrigin.Begin); - short width = reader.ReadInt16(); - short height = reader.ReadInt16(); - reader.BaseStream.Seek(2, SeekOrigin.Current); - byte[] source = reader.ReadBytes(width * height * 4); - reader.Close(); - Texture2D texture = new Texture2D(width, height, TextureFormat.BGRA32, false); - texture.LoadRawTextureData(source); - texture.name = Path.GetFileName(fileName); - texture.Apply(false, true); - return texture; - } - catch (Exception) - { - return Texture2D.blackTexture; - } - } - - - public static Texture2D LoadTGA(Stream TGAStream) - { - - using (BinaryReader r = new BinaryReader(TGAStream)) - { - // Skip some header info we don't care about. - // Even if we did care, we have to move the stream seek point to the beginning, - // as the previous method in the workflow left it at the end. - r.BaseStream.Seek(12, SeekOrigin.Begin); - - short width = r.ReadInt16(); - short height = r.ReadInt16(); - int bitDepth = r.ReadByte(); - - // Skip a byte of header information we don't care about. - r.BaseStream.Seek(1, SeekOrigin.Current); - - Texture2D tex = new Texture2D(width, height); - Color32[] pulledColors = new Color32[width * height]; - - if (bitDepth == 32) - { - for (int i = 0; i < width * height; i++) - { - byte red = r.ReadByte(); - byte green = r.ReadByte(); - byte blue = r.ReadByte(); - byte alpha = r.ReadByte(); - - pulledColors[i] = new Color32(blue, green, red, alpha); - } - } - else if (bitDepth == 24) - { - for (int i = 0; i < width * height; i++) - { - byte red = r.ReadByte(); - byte green = r.ReadByte(); - byte blue = r.ReadByte(); - - pulledColors[i] = new Color32(blue, green, red, 1); - } - } - else - { - throw new Exception("TGA texture had non 32/24 bit depth."); - } - - tex.SetPixels32(pulledColors); - tex.Apply(); - return tex; - - } - } - -}