public static unsafe libsecondlife.Image 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); 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]; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); fixed (byte* pdecoded = &decoded[0]) { bd.Width = header.ImageSpec.Width; bd.Height = header.ImageSpec.Height; bd.PixelFormat = System.Drawing.Imaging.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; libsecondlife.Image image; if (mask && header.ImageSpec.AlphaBits == 0 && header.ImageSpec.PixelDepth == 8) { image = new libsecondlife.Image(header.ImageSpec.Width, header.ImageSpec.Height, libsecondlife.ImageChannels.Alpha); int p = 3; for (int i = 0; i < n; i++) { image.Alpha[i] = decoded[p]; p += 4; } } else { image = new libsecondlife.Image(header.ImageSpec.Width, header.ImageSpec.Height, libsecondlife.ImageChannels.Color | libsecondlife.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 unsafe libsecondlife.Image 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); 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]; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); fixed(byte *pdecoded = &decoded[0]) { bd.Width = header.ImageSpec.Width; bd.Height = header.ImageSpec.Height; bd.PixelFormat = System.Drawing.Imaging.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; libsecondlife.Image image; if (mask && header.ImageSpec.AlphaBits == 0 && header.ImageSpec.PixelDepth == 8) { image = new libsecondlife.Image(header.ImageSpec.Width, header.ImageSpec.Height, libsecondlife.ImageChannels.Alpha); int p = 3; for (int i = 0; i < n; i++) { image.Alpha[i] = decoded[p]; p += 4; } } else { image = new libsecondlife.Image(header.ImageSpec.Width, header.ImageSpec.Height, libsecondlife.ImageChannels.Color | libsecondlife.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); }