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;