From 0255b8be1e45afc1e302f873606636e3890f17e5 Mon Sep 17 00:00:00 2001 From: Peter Truchly <7407641+VasilijP@users.noreply.github.com> Date: Fri, 18 Oct 2024 12:35:39 -0500 Subject: [PATCH] TgaFileFormat decoupled from TgaImage which allows saving another image sources and also provides simplified interface for loading TgaImage somewhere else using the same IImage interface. --- tgalib-core/IImage.cs | 28 ++++++++++++++++++++++++++++ tgalib-core/TgaFileFormat.cs | 30 +++++++++++++++--------------- tgalib-core/TgaHeader.cs | 6 +++--- tgalib-core/TgaImage.cs | 4 ++-- 4 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 tgalib-core/IImage.cs diff --git a/tgalib-core/IImage.cs b/tgalib-core/IImage.cs new file mode 100644 index 0000000..22dfb7f --- /dev/null +++ b/tgalib-core/IImage.cs @@ -0,0 +1,28 @@ +namespace tgalib_core; + +/// +/// Abstraction of the image usable for simplified loading and saving routines. +/// +public interface IImage +{ + /// + /// Width of the image in pixels. + /// + int Width { get; } + + /// + /// Height of the image in pixels. + /// + int Height { get; } + + /// + /// Pixel access. + /// + /// X coordinate of a pixel within the image. + /// Y coordinate of a pixel within the image. Note: TGA coordinate [0, 0] is a bottom left corner. + /// Red component (8 bit). + /// Green component (8 bit). + /// Blue component (8 bit). + /// Alpha component (8 bit). + void GetPixelRgba(int x, int y, out int r, out int g, out int b, out int a); +} \ No newline at end of file diff --git a/tgalib-core/TgaFileFormat.cs b/tgalib-core/TgaFileFormat.cs index ed562e8..59729d0 100644 --- a/tgalib-core/TgaFileFormat.cs +++ b/tgalib-core/TgaFileFormat.cs @@ -44,7 +44,7 @@ public static class TgaFileFormat { // Common save routine. - public static void CommonSave(TgaMode curTgaMode, Stream stream, TgaImage g) + public static void CommonSave(TgaMode curTgaMode, Stream stream, IImage g) { // ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault switch (curTgaMode) @@ -58,10 +58,10 @@ public static void CommonSave(TgaMode curTgaMode, Stream stream, TgaImage g) } // TGA RGB 24 RLE save code. - private static void TgaRgb24RleSave(Stream tgaFile, TgaImage image) + private static void TgaRgb24RleSave(Stream tgaFile, IImage image) { - int width = image.TgaHeader.Width; - int height = image.TgaHeader.Height; + int width = image.Width; + int height = image.Height; // 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12| 13| 14| 15| 16|17|18 byte[] header = [ 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte)(width&255),(byte)((width>>8)&255),(byte)(height&255),(byte)((height>>8)&255),24, 0]; @@ -84,10 +84,10 @@ private static void TgaRgb24RleSave(Stream tgaFile, TgaImage image) // Stops when entire image is searched or palette is full (max 256 colors) // Colors which are not in palette are written as color 0 (there should be no more than 256 colors in image) // Performs RLE compression - private static void TgaPal8RleSave(Stream tgaFile, TgaImage image) + private static void TgaPal8RleSave(Stream tgaFile, IImage image) { - int width = image.TgaHeader.Width; - int height = image.TgaHeader.Height; + int width = image.Width; + int height = image.Height; const int maxColors = 256; //palette (BGR) @@ -130,11 +130,11 @@ private static void TgaPal8RleSave(Stream tgaFile, TgaImage image) // Seraches image for unique colors. // Stops when entire image is searched or palette is full (max 256 colors) // Colors which are not in palette are written as color 0 (there should be no more than 256 colors in image) - private static void TgaPal8UncSave(Stream tgaFile, TgaImage image) + private static void TgaPal8UncSave(Stream tgaFile, IImage image) { //header - int width = image.TgaHeader.Width; - int height = image.TgaHeader.Height; + int width = image.Width; + int height = image.Height; const int maxColors = 256; //palette ( colors are stored as BGR in file ) @@ -172,10 +172,10 @@ private static void TgaPal8UncSave(Stream tgaFile, TgaImage image) } // TGA RGB 24 UNC save code. - private static void TgaRgb24UncSave(Stream tgaFile, TgaImage image) + private static void TgaRgb24UncSave(Stream tgaFile, IImage image) { - int width = image.TgaHeader.Width; - int height = image.TgaHeader.Height; + int width = image.Width; + int height = image.Height; // 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12| 13| 14| 15| 16|17|18 byte[] header = [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte)(width&255),(byte)((width>>8)&255),(byte)(height&255),(byte)((height>>8)&255),24, 0]; @@ -185,9 +185,9 @@ private static void TgaRgb24UncSave(Stream tgaFile, TgaImage image) for (int x = 0; x < width; ++x) { image.GetPixelRgba(x, y, out int r, out int g, out int b, out int a); - tgaFile.Write([(byte)(r & 255), (byte)(g & 255), (byte)(b & 255)]); // TODO: check if byte order is correct + tgaFile.Write([(byte)(r & 255), (byte)(g & 255), (byte)(b & 255)]); } tgaFile.Close(); } -} +} \ No newline at end of file diff --git a/tgalib-core/TgaHeader.cs b/tgalib-core/TgaHeader.cs index aefa41e..19cf016 100644 --- a/tgalib-core/TgaHeader.cs +++ b/tgalib-core/TgaHeader.cs @@ -10,7 +10,7 @@ public class TgaHeader /// /// Gets or sets a length of Image ID field. /// - public byte IDLength { get; set; } + public byte IdLength { get; set; } /// /// Gets or sets a Color Map type(). @@ -83,7 +83,7 @@ public class TgaHeader /// A binary reader that contains TGA file. Caller must dipose the binary reader. public TgaHeader(BinaryReader reader) { - IDLength = reader.ReadByte(); + IdLength = reader.ReadByte(); ColorMapType = reader.ReadByte(); ImageType = (TgaMode)reader.ReadByte(); ColorMapStart = reader.ReadUInt16(); @@ -104,7 +104,7 @@ public TgaHeader(BinaryReader reader) public override string ToString() { StringBuilder sb = new StringBuilder(); - sb.Append($"IDLength : {IDLength}\r\n"); + sb.Append($"IDLength : {IdLength}\r\n"); sb.Append($"ColorMapType : {ColorMapType}({ColorMapTypes.ToFormattedText(ColorMapType)})\r\n"); sb.Append($"ImageType : {ImageType}({ImageTypes.ToFormattedText(ImageType)})\r\n"); sb.Append($"ColorMapStart : {ColorMapStart}\r\n"); diff --git a/tgalib-core/TgaImage.cs b/tgalib-core/TgaImage.cs index 7ef1e46..585130b 100644 --- a/tgalib-core/TgaImage.cs +++ b/tgalib-core/TgaImage.cs @@ -5,7 +5,7 @@ namespace tgalib_core /// /// Represents TGA image. /// - public class TgaImage + public class TgaImage : IImage { /// /// Use the alpha channel forcefully, if true. @@ -72,7 +72,7 @@ private void Init(BinaryReader reader) { TgaHeader = new TgaHeader(reader); - ImageId = new byte[TgaHeader.IDLength]; + ImageId = new byte[TgaHeader.IdLength]; reader.Read(ImageId, 0, ImageId.Length); PixelFormat = DecodePixelFormat(); imageWidth = TgaHeader.Width;