tModLoader v0.11.8.9
A mod to make and play Terraria mods
ImageIO.cs
Go to the documentation of this file.
1using Microsoft.Xna.Framework.Graphics;
2using System;
3using System.Drawing;
4using System.Drawing.Imaging;
5using System.IO;
6using System.Runtime.InteropServices;
7using System.Text;
8using System.Threading.Tasks;
9using Terraria.ModLoader.Engine;
10
12{
13 public class ImageIO
14 {
15 public const int VERSION = 1;
16
17 public static bool ToRaw(Stream src, Stream dst) {
18 using (var img = new Bitmap(src)) {
19 // now that the hi-def profile is always enabled, the max texture size is 4096
20 // if we get bug reports with old graphics cards forcing fallback to Reach and failing to load
21 // large textures, we can implement a slower path where the rawimg is converted to png before loading
22
23 //if (img.Width > 2048 || img.Height > 2048)
24 // return false;
25
26 var bitmapData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
27 var rawdata = new int[img.Width * img.Height];
28 Marshal.Copy(bitmapData.Scan0, rawdata, 0, rawdata.Length);
29 var w = new BinaryWriter(dst);
30 w.Write(VERSION);
31 w.Write(img.Width);
32 w.Write(img.Height);
33 foreach (int c in rawdata) {
34 //Bitmap is in ABGR
35 int a = c >> 24 & 0xFF;
36 int b = c >> 16 & 0xFF;
37 int g = c >> 8 & 0xFF;
38 int r = c >> 0 & 0xFF;
39
40 //special note, mirror XNA behaviour of zeroing out textures with full alpha zero
41 //this means that an author doesn't have to set their fully transparent pixels to black
42 //if they want additive blending they need to use alpha 1/255
43 if (a == 0) {
44 w.Write(0);
45 continue;
46 }
47
48 //write ARGB, note that the texture is assumed pre-multiplied, allowing for extra blending effects
49 w.Write((byte)b);
50 w.Write((byte)g);
51 w.Write((byte)r);
52 w.Write((byte)a);
53 }
54
55 return true;
56 }
57 }
58
59 public static byte[] ToRawBytes(Stream src) {
60 using (var ms = new MemoryStream()) {
61 return ToRaw(src, ms) ? ms.ToArray() : null;
62 }
63 }
64
65 public static Texture2D RawToTexture2D(GraphicsDevice graphicsDevice, Stream src) =>
66 RawToTexture2D(graphicsDevice, new BinaryReader(src, Encoding.UTF8));
67
68 public static void RawToPng(Stream src, Stream dst) {
69 using (var img = RawToTexture2D(Main.instance.GraphicsDevice, src))
70 img.SaveAsPng(dst, img.Width, img.Height);
71 }
72
73 public static Tuple<int, int, byte[]> ReadRaw(Stream src) =>
74 ReadRaw(new BinaryReader(src, Encoding.UTF8));
75
76 public static Tuple<int, int, byte[]> ReadRaw(BinaryReader r) {
77 int v = r.ReadInt32();
78 if (v != VERSION)
79 throw new Exception("Unknown RawImg Format Version: " + v);
80
81 int width = r.ReadInt32();
82 int height = r.ReadInt32();
83 var rawdata = r.ReadBytes(width * height * 4);
84 return new Tuple<int, int, byte[]>(width, height, rawdata);
85 }
86
87 public static Texture2D RawToTexture2D(GraphicsDevice graphicsDevice, BinaryReader r) {
88 var rawData = ReadRaw(r);
89 var tex = new Texture2D(graphicsDevice, rawData.Item1, rawData.Item2);
90 tex.SetData(rawData.Item3);
91 return tex;
92 }
93
94 public static Task<Texture2D> RawToTexture2DAsync(GraphicsDevice graphicsDevice, BinaryReader r) {
95 var rawData = ReadRaw(r);
96 return GLCallLocker.InvokeAsync(() => {
97 var tex = new Texture2D(graphicsDevice, rawData.Item1, rawData.Item2);
98 tex.SetData(rawData.Item3);
99 return tex;
100 });
101 }
102
103 public static Task<Texture2D> PngToTexture2DAsync(GraphicsDevice graphicsDevice, Stream stream) {
104#if XNA
105 if (!(stream is MemoryStream)) {
106 var ms = new MemoryStream((int)stream.Length);
107 stream.CopyTo(ms);
108 ms.Position = 0;
109 stream = ms;
110 }
111 return GLCallLocker.InvokeAsync(() => Texture2D.FromStream(graphicsDevice, stream));
112#else
113 Texture2D.TextureDataFromStreamEXT(stream, out int width, out int height, out byte[] rawdata, -1, -1, false);
114 return GLCallLocker.InvokeAsync(() => {
115 var tex = new Texture2D(graphicsDevice, width, height);
116 tex.SetData(rawdata);
117 return tex;
118 });
119#endif
120 }
121 }
122}
static bool ToRaw(Stream src, Stream dst)
Definition: ImageIO.cs:17
static Tuple< int, int, byte[]> ReadRaw(Stream src)
static void RawToPng(Stream src, Stream dst)
Definition: ImageIO.cs:68
static Task< Texture2D > RawToTexture2DAsync(GraphicsDevice graphicsDevice, BinaryReader r)
Definition: ImageIO.cs:94
static byte[] ToRawBytes(Stream src)
Definition: ImageIO.cs:59
static Texture2D RawToTexture2D(GraphicsDevice graphicsDevice, Stream src)
static Tuple< int, int, byte[]> ReadRaw(BinaryReader r)
Definition: ImageIO.cs:76
static Texture2D RawToTexture2D(GraphicsDevice graphicsDevice, BinaryReader r)
Definition: ImageIO.cs:87
static Task< Texture2D > PngToTexture2DAsync(GraphicsDevice graphicsDevice, Stream stream)
Definition: ImageIO.cs:103