diff --git a/SRC/Aura_OS/Aura_OS.csproj b/SRC/Aura_OS/Aura_OS.csproj
index 00a2748f..aaa9ed34 100644
--- a/SRC/Aura_OS/Aura_OS.csproj
+++ b/SRC/Aura_OS/Aura_OS.csproj
@@ -24,11 +24,16 @@
True
+
+
+
+
+
diff --git a/SRC/Aura_OS/Files.cs b/SRC/Aura_OS/Files.cs
index 34c3bd92..2505915c 100644
--- a/SRC/Aura_OS/Files.cs
+++ b/SRC/Aura_OS/Files.cs
@@ -19,6 +19,9 @@ public class Files
[ManifestResourceStream(ResourceName = "Aura_OS.Resources.wallpaper-1.bmp")]
public static byte[] Wallpaper;
+ [ManifestResourceStream(ResourceName = "Aura_OS.Resources.wallpaper-1.png")]
+ public static byte[] WallpaperPng;
+
[ManifestResourceStream(ResourceName = "Aura_OS.Resources.wallpaper-2.bmp")]
public static byte[] Wallpaper2;
@@ -52,6 +55,9 @@ public static void LoadFiles()
Kernel.wallpaper1 = new Bitmap(Files.Wallpaper);
CustomConsole.WriteLineOK("wallpaper-1.bmp wallpaper loaded.");
+ Kernel.wallpaper1png = new Png(Files.WallpaperPng);
+ CustomConsole.WriteLineOK("wallpaper-1.png wallpaper loaded.");
+
Kernel.wallpaper2 = new Bitmap(Files.Wallpaper2);
CustomConsole.WriteLineOK("wallpaper-2.bmp wallpaper loaded.");
diff --git a/SRC/Aura_OS/Kernel.cs b/SRC/Aura_OS/Kernel.cs
index 1066e410..481e2775 100644
--- a/SRC/Aura_OS/Kernel.cs
+++ b/SRC/Aura_OS/Kernel.cs
@@ -85,6 +85,7 @@ public static bool NetworkConnected
public static Bitmap CosmosLogo;
public static Bitmap wallpaper1;
+ public static Png wallpaper1png;
public static Bitmap wallpaper2;
public static Bitmap auralogo_white;
diff --git a/SRC/Aura_OS/Properties/VersionInfo.cs b/SRC/Aura_OS/Properties/VersionInfo.cs
index 881edc93..a84f2bcc 100644
--- a/SRC/Aura_OS/Properties/VersionInfo.cs
+++ b/SRC/Aura_OS/Properties/VersionInfo.cs
@@ -2,6 +2,6 @@ namespace Aura_OS
{
public class VersionInfo
{
- public static string revision = "130320241316";
+ public static string revision = "130320241712";
}
}
diff --git a/SRC/Aura_OS/Resources/wallpaper-1.png b/SRC/Aura_OS/Resources/wallpaper-1.png
new file mode 100644
index 00000000..7471466c
Binary files /dev/null and b/SRC/Aura_OS/Resources/wallpaper-1.png differ
diff --git a/SRC/Aura_OS/Resources/wallpaper-1.png.bak b/SRC/Aura_OS/Resources/wallpaper-1.png.bak
new file mode 100644
index 00000000..2763c385
Binary files /dev/null and b/SRC/Aura_OS/Resources/wallpaper-1.png.bak differ
diff --git a/SRC/Aura_OS/System/Compression/BinaryReader.cs b/SRC/Aura_OS/System/Compression/BinaryReader.cs
new file mode 100644
index 00000000..5bce5ec5
--- /dev/null
+++ b/SRC/Aura_OS/System/Compression/BinaryReader.cs
@@ -0,0 +1,98 @@
+namespace CosmosGL.System
+{
+ public class BinaryReader
+ {
+ private int _pos = 0;
+ private byte[] _data;
+
+ public BinaryReader(byte[] data)
+ {
+ _data = data;
+ }
+
+ public int Seek(int pos)
+ {
+ var oldPos = _pos;
+ _pos = pos;
+ return oldPos;
+ }
+
+ public int Tell()
+ {
+ return _pos;
+ }
+
+ public byte GetUint8()
+ {
+ return _data[_pos++];
+ }
+
+ public ushort GetUint16()
+ {
+ return (ushort)(((GetUint8() << 8) | GetUint8()) >> 0);
+ }
+
+ public uint GetUint32()
+ {
+ return (uint)GetInt32();
+ }
+
+ public short GetInt16()
+ {
+ // var result = GetUint16();
+ // if ((result & 0x8000) == 1)
+ // {
+ // result -= (1 << 16);
+ // }
+ // return result;
+
+ return (short)GetUint16();
+ }
+
+ public int GetInt32()
+ {
+ return ((GetUint8() << 24) |
+ (GetUint8() << 16) |
+ (GetUint8() << 8) |
+ (GetUint8()));
+ }
+
+ public short GetFword()
+ {
+ return GetInt16();
+ }
+
+ public int Get2Dot14()
+ {
+ return GetInt16() / (1 << 14);
+ }
+
+ public int GetFixed()
+ {
+ return GetInt32() / (1 << 16);
+ }
+
+ public string GetString(int length)
+ {
+ var result = "";
+ for (var i = 0; i < length; i++)
+ {
+ result += (char)GetUint8();
+ }
+ return result;
+ }
+
+ public void GetDate()
+ {
+ GetUint32();
+ GetUint32();
+ /* var macTime = GetUint32() * 0x100000000 + GetUint32();
+ return new DateTime(macTime, DateTimeKind.Utc);*/
+ }
+
+ public char GetChar()
+ {
+ return (char)GetUint8();
+ }
+ }
+}
\ No newline at end of file
diff --git a/SRC/Aura_OS/System/Compression/Deflate.cs b/SRC/Aura_OS/System/Compression/Deflate.cs
new file mode 100644
index 00000000..6a7f7917
--- /dev/null
+++ b/SRC/Aura_OS/System/Compression/Deflate.cs
@@ -0,0 +1,368 @@
+using System;
+using System.Collections.Generic;
+
+namespace CosmosGL.System
+{
+ ///
+ /// public domain zlib decode
+ /// original: v0.2 Sean Barrett 2006-11-18
+ /// ported to C# by Tammo Hinrichs, 2012-08-02
+ /// simple implementation
+ /// - all input must be provided in an upfront buffer
+ /// - all output is written to a single output buffer
+ /// - Warning: This is SLOW. It's no miracle .NET as well as Mono implement DeflateStream natively.
+ ///
+ public class ZlibDecoder
+ {
+ ///
+ /// Decode deflated data
+ ///
+ /// deflated input data
+ /// uncompressed output
+ public static List Inflate(IList compressed)
+ {
+ return new ZlibDecoder { In = compressed }.Inflate();
+ }
+
+ #region internal
+
+ // fast-way is faster to check than jpeg huffman, but slow way is slower
+ private const int FastBits = 9; // accelerate all cases in default tables
+ private const int FastMask = ((1 << FastBits) - 1);
+
+ private static readonly int[] DistExtra = new[]
+ {
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
+ 10, 10, 11, 11, 12, 12, 13, 13
+ };
+
+ private static readonly int[] LengthBase = new[]
+ {
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
+ 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
+ 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+ };
+
+ private static readonly int[] LengthExtra = new[]
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4,
+ 4, 4, 4, 5, 5, 5, 5, 0, 0, 0
+ };
+
+ private static readonly int[] DistBase = new[]
+ {
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193,
+ 12289, 16385, 24577, 0, 0
+ };
+
+ private static readonly int[] LengthDezigzag = new[]
+ {
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2,
+ 14,
+ 1, 15
+ };
+
+ // @TODO: should statically initialize these for optimal thread safety
+ private static readonly byte[] DefaultLength = new byte[288];
+ private static readonly byte[] DefaultDistance = new byte[32];
+
+ private List Out;
+ private UInt32 CodeBuffer;
+ private int NumBits;
+
+ private Huffman Distance;
+ private Huffman Length;
+
+ private int InPos;
+ private IList In;
+
+ private static void InitDefaults()
+ {
+ int i; // use <= to match clearly with spec
+ for (i = 0; i <= 143; ++i) DefaultLength[i] = 8;
+ for (; i <= 255; ++i) DefaultLength[i] = 9;
+ for (; i <= 279; ++i) DefaultLength[i] = 7;
+ for (; i <= 287; ++i) DefaultLength[i] = 8;
+
+ for (i = 0; i <= 31; ++i) DefaultDistance[i] = 5;
+ }
+
+ private static int BitReverse16(int n)
+ {
+ n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1);
+ n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
+ n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4);
+ n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8);
+ return n;
+ }
+
+ private static int BitReverse(int v, int bits)
+ {
+ // Debug.Assert(bits <= 16);
+ // to bit reverse n bits, reverse 16 and shift
+ // e.g. 11 bits, bit reverse and shift away 5
+ return BitReverse16(v) >> (16 - bits);
+ }
+
+ private int Get8()
+ {
+ return InPos >= In.Count ? 0 : In[InPos++];
+ }
+
+ private void FillBits()
+ {
+ do
+ {
+ // Debug.Assert(CodeBuffer < (1U << NumBits));
+ CodeBuffer |= (uint)(Get8() << NumBits);
+ NumBits += 8;
+ } while (NumBits <= 24);
+ }
+
+ private uint Receive(int n)
+ {
+ if (NumBits < n) FillBits();
+ var k = (uint)(CodeBuffer & ((1 << n) - 1));
+ CodeBuffer >>= n;
+ NumBits -= n;
+ return k;
+ }
+
+ private int HuffmanDecode(Huffman z)
+ {
+ int s;
+ if (NumBits < 16) FillBits();
+ int b = z.Fast[CodeBuffer & FastMask];
+ if (b < 0xffff)
+ {
+ s = z.Size[b];
+ CodeBuffer >>= s;
+ NumBits -= s;
+ return z.Value[b];
+ }
+
+ // not resolved by fast table, so compute it the slow way
+ // use jpeg approach, which requires MSbits at top
+ int k = BitReverse((int)CodeBuffer, 16);
+ for (s = FastBits + 1; ; ++s)
+ if (k < z.MaxCode[s])
+ break;
+ if (s == 16) return -1; // invalid code!
+ // code size is s, so:
+ b = (k >> (16 - s)) - z.FirstCode[s] + z.FirstSymbol[s];
+ // Debug.Assert(z.Size[b] == s);
+ CodeBuffer >>= s;
+ NumBits -= s;
+ return z.Value[b];
+ }
+
+ private void ParseHuffmanBlock()
+ {
+ for (; ; )
+ {
+ int z = HuffmanDecode(Length);
+ if (z < 256)
+ {
+ if (z < 0) throw new Exception("bad huffman code"); // error in huffman codes
+ Out.Add((byte)z);
+ }
+ else
+ {
+ if (z == 256) return;
+ z -= 257;
+ int len = LengthBase[z];
+ if (LengthExtra[z] != 0) len += (int)Receive(LengthExtra[z]);
+ z = HuffmanDecode(Distance);
+ if (z < 0) throw new Exception("bad huffman code");
+ int dist = DistBase[z];
+ if (DistExtra[z] != 0) dist += (int)Receive(DistExtra[z]);
+ dist = Out.Count - dist;
+ if (dist < 0) throw new Exception("bad dist");
+ for (int i = 0; i < len; i++, dist++)
+ Out.Add(Out[dist]);
+ }
+ }
+ }
+
+ private void ComputeHuffmanCodes()
+ {
+ var lenCodes = new byte[286 + 32 + 137]; //padding for maximum single op
+ var codeLengthSizes = new byte[19];
+
+ uint hlit = Receive(5) + 257;
+ uint hdist = Receive(5) + 1;
+ uint hclen = Receive(4) + 4;
+
+ for (int i = 0; i < hclen; ++i)
+ codeLengthSizes[LengthDezigzag[i]] = (byte)Receive(3);
+
+ var codeLength = new Huffman(new ArraySegment(codeLengthSizes));
+
+ int n = 0;
+ while (n < hlit + hdist)
+ {
+ int c = HuffmanDecode(codeLength);
+ // Debug.Assert(c >= 0 && c < 19);
+ if (c < 16)
+ lenCodes[n++] = (byte)c;
+ else if (c == 16)
+ {
+ c = (int)Receive(2) + 3;
+ for (int i = 0; i < c; i++) lenCodes[n + i] = lenCodes[n - 1];
+ n += c;
+ }
+ else if (c == 17)
+ {
+ c = (int)Receive(3) + 3;
+ for (int i = 0; i < c; i++) lenCodes[n + i] = 0;
+ n += c;
+ }
+ else
+ {
+ //Debug.Assert(c == 18);
+ c = (int)Receive(7) + 11;
+ for (int i = 0; i < c; i++) lenCodes[n + i] = 0;
+ n += c;
+ }
+ }
+ if (n != hlit + hdist) throw new Exception("bad codelengths");
+ Length = new Huffman(new ArraySegment(lenCodes, 0, (int)hlit));
+ Distance = new Huffman(new ArraySegment(lenCodes, (int)hlit, (int)hdist));
+ }
+
+ private void ParseUncompressedBlock()
+ {
+ var header = new byte[4];
+ if ((NumBits & 7) != 0)
+ Receive(NumBits & 7); // discard
+ // drain the bit-packed data into header
+ int k = 0;
+ while (NumBits > 0)
+ {
+ header[k++] = (byte)(CodeBuffer & 255); // wtf this warns?
+ CodeBuffer >>= 8;
+ NumBits -= 8;
+ }
+ //Debug.Assert(NumBits == 0);
+ // now fill header the normal way
+ while (k < 4)
+ header[k++] = (byte)Get8();
+ int len = header[1] * 256 + header[0];
+ int nlen = header[3] * 256 + header[2];
+ if (nlen != (len ^ 0xffff)) throw new Exception("zlib corrupt");
+ if (InPos + len > In.Count) throw new Exception("read past buffer");
+
+ // TODO: this sucks. DON'T USE LINQ.
+ var tmp = new List();
+
+ for (int i = InPos; i < InPos + len; i++)
+ {
+ Out.Add(In[i]);
+ }
+ InPos += len;
+ }
+
+ private List Inflate()
+ {
+ Out = new List();
+ NumBits = 0;
+ CodeBuffer = 0;
+
+ bool final;
+ do
+ {
+ final = Receive(1) != 0;
+ var type = (int)Receive(2);
+ if (type == 0)
+ {
+ ParseUncompressedBlock();
+ }
+ else if (type == 3)
+ {
+ throw new Exception("invalid block type");
+ }
+ else
+ {
+ if (type == 1)
+ {
+ // use fixed code lengths
+ if (DefaultDistance[31] == 0) InitDefaults();
+ Length = new Huffman(new ArraySegment(DefaultLength));
+ Distance = new Huffman(new ArraySegment(DefaultDistance));
+ }
+ else
+ {
+ ComputeHuffmanCodes();
+ }
+ ParseHuffmanBlock();
+ }
+ } while (!final);
+
+ return Out;
+ }
+
+
+ private class Huffman
+ {
+ public readonly UInt16[] Fast = new UInt16[1 << FastBits];
+ public readonly UInt16[] FirstCode = new UInt16[16];
+ public readonly UInt16[] FirstSymbol = new UInt16[16];
+ public readonly int[] MaxCode = new int[17];
+ public readonly Byte[] Size = new Byte[288];
+ public readonly UInt16[] Value = new UInt16[288];
+
+ public Huffman(ArraySegment sizeList)
+ {
+ int i;
+ int k = 0;
+ var nextCode = new int[16];
+ var sizes = new int[17];
+
+ // DEFLATE spec for generating codes
+ for (i = 0; i < Fast.Length; i++) Fast[i] = 0xffff;
+ for (i = 0; i < sizeList.Count; ++i)
+ ++sizes[sizeList.Array[i + sizeList.Offset]];
+ sizes[0] = 0;
+ /* for (i = 1; i < 16; ++i)
+ Debug.Assert(sizes[i] <= (1 << i));*/
+ int code = 0;
+ for (i = 1; i < 16; ++i)
+ {
+ nextCode[i] = code;
+ FirstCode[i] = (UInt16)code;
+ FirstSymbol[i] = (UInt16)k;
+ code = (code + sizes[i]);
+ if (sizes[i] != 0)
+ if (code - 1 >= (1 << i)) throw new Exception("bad codelengths");
+ MaxCode[i] = code << (16 - i); // preshift for inner loop
+ code <<= 1;
+ k += sizes[i];
+ }
+ MaxCode[16] = 0x10000; // sentinel
+ for (i = 0; i < sizeList.Count; ++i)
+ {
+ int s = sizeList.Array[i + sizeList.Offset];
+ if (s != 0)
+ {
+ int c = nextCode[s] - FirstCode[s] + FirstSymbol[s];
+ Size[c] = (byte)s;
+ Value[c] = (UInt16)i;
+ if (s <= FastBits)
+ {
+ int j = BitReverse(nextCode[s], s);
+ while (j < (1 << FastBits))
+ {
+ Fast[j] = (UInt16)c;
+ j += (1 << s);
+ }
+ }
+ ++nextCode[s];
+ }
+ }
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/SRC/Aura_OS/System/Graphics/UI/GUI/Components/Component.cs b/SRC/Aura_OS/System/Graphics/UI/GUI/Components/Component.cs
index b1868a8e..1e38b92d 100644
--- a/SRC/Aura_OS/System/Graphics/UI/GUI/Components/Component.cs
+++ b/SRC/Aura_OS/System/Graphics/UI/GUI/Components/Component.cs
@@ -533,7 +533,12 @@ public void DrawLine(Color color, int xStart, int yStart, int width, int height)
_buffer.DrawLine(color.ToArgb(), xStart, yStart, width, height);
}
- public void DrawImage(Bitmap image, int x, int y)
+ public void DrawImageNoAlpha(Image image, int x, int y)
+ {
+ _buffer.DrawImage(image, x, y);
+ }
+
+ public void DrawImage(Image image, int x, int y)
{
_buffer.DrawImageAlpha(image, x, y);
}
diff --git a/SRC/Aura_OS/System/Graphics/UI/GUI/Desktop.cs b/SRC/Aura_OS/System/Graphics/UI/GUI/Desktop.cs
index 7cfedaae..73cdc697 100644
--- a/SRC/Aura_OS/System/Graphics/UI/GUI/Desktop.cs
+++ b/SRC/Aura_OS/System/Graphics/UI/GUI/Desktop.cs
@@ -16,7 +16,7 @@ public class Desktop : Component
{
public FilesystemPanel MainPanel;
private string _wallpaperPath;
- private Bitmap _wallpaper;
+ private Image _wallpaper;
public Desktop(int x, int y, int width, int height) : base(x, y, width, height)
{
@@ -29,7 +29,7 @@ public Desktop(int x, int y, int width, int height) : base(x, y, width, height)
else
{
_wallpaperPath = "Embedded";
- _wallpaper = new Bitmap(Files.Wallpaper);
+ _wallpaper = Kernel.wallpaper1png;
MarkDirty();
}
@@ -47,7 +47,7 @@ public override void Draw()
{
base.Draw();
- DrawImage(_wallpaper, X, Y);
+ DrawImageNoAlpha(_wallpaper, X, Y);
MainPanel.UpdateCurrentFolder();
MainPanel.Draw(this);
diff --git a/SRC/Aura_OS/System/Graphics/UI/GUI/DirectBitmap.cs b/SRC/Aura_OS/System/Graphics/UI/GUI/DirectBitmap.cs
index a8e2947d..7525a5e6 100644
--- a/SRC/Aura_OS/System/Graphics/UI/GUI/DirectBitmap.cs
+++ b/SRC/Aura_OS/System/Graphics/UI/GUI/DirectBitmap.cs
@@ -339,7 +339,7 @@ protected void TrimLine(ref int x1, ref int y1, ref int x2, ref int y2)
y2 = (int)num4;
}
- public void DrawImage(Bitmap image, int x, int y)
+ public void DrawImage(Image image, int x, int y)
{
for (int yi = 0; yi < image.Height; yi++)
{
@@ -381,7 +381,7 @@ public static void OpacitySSE(uint* pixelPtr, int w, int h, int bpl, uint a)
// PLUGGED
}
- public void DrawImageAlpha(Bitmap image, int x, int y, byte alpha = 0xFF)
+ public void DrawImageAlpha(Image image, int x, int y, byte alpha = 0xFF)
{
if (image.RawData.Length > Bitmap.RawData.Length)
{
diff --git a/SRC/Aura_OS/System/Graphics/UI/GUI/Images/Png.cs b/SRC/Aura_OS/System/Graphics/UI/GUI/Images/Png.cs
new file mode 100644
index 00000000..8073d07b
--- /dev/null
+++ b/SRC/Aura_OS/System/Graphics/UI/GUI/Images/Png.cs
@@ -0,0 +1,386 @@
+//#define COSMOSDEBUG
+using Aura_OS.System;
+using Aura_OS.System.Graphics.UI.GUI;
+using CosmosGL.System;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection.PortableExecutable;
+using System.Security;
+using System.Text;
+
+namespace Cosmos.System.Graphics
+{
+ ///
+ /// Represents a png image.
+ ///
+ public class Png : Image
+ {
+ ///
+ /// Initializes a new instance of class.
+ ///
+ /// The width of the image.
+ /// The height of the image.
+ /// The color depth.
+ /// Thrown when either the width or height is lower than 0.
+ public Png(uint width, uint height, ColorDepth colorDepth) : base(width, height, colorDepth)
+ {
+ if (width < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(width));
+ }
+
+ if (height < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(height));
+ }
+
+ RawData = new int[width * height];
+ }
+
+ ///
+ /// Initializes a new instance of class from a byte array
+ /// representing the pixels.
+ ///
+ /// The width of the png.
+ /// The height of the png.
+ /// A byte array which includes the values for each pixel.
+ /// The format of the pixel data.
+ /// Thrown if color depth is not 32.
+ /// Thrown if png size is bigger than Int32.MaxValue.
+ /// Thrown on fatal error.
+ /// Thrown on memory error.
+ /// Thrown on fatal error.
+ public Png(uint width, uint height, byte[] pixelData, ColorDepth colorDepth) : base(width, height, colorDepth)
+ {
+ RawData = new int[width * height];
+ if (colorDepth != ColorDepth.ColorDepth32 && colorDepth != ColorDepth.ColorDepth24)
+ {
+ Global.Debugger.Send("Only color depths 24 and 32 are supported!");
+ throw new NotImplementedException("Only color depths 24 and 32 are supported!");
+ }
+
+ for (int i = 0; i < RawData.Length; i++)
+ {
+ if (colorDepth == ColorDepth.ColorDepth32)
+ {
+ RawData[i] = BitConverter.ToInt32(new byte[] { pixelData[i * 4], pixelData[i * 4 + 1], pixelData[i * 4 + 2], pixelData[i * 4 + 3] }, 0);
+ }
+ else
+ {
+ RawData[i] = BitConverter.ToInt32(new byte[] { 0, pixelData[i * 3], pixelData[i * 3 + 1], pixelData[i * 3 + 2] }, 0);
+ }
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class, using the specified path to a BMP file.
+ ///
+ /// Path to file.
+ ///
+ ///
+ /// - Thrown if path is invalid.
+ /// - Memory error.
+ ///
+ ///
+ ///
+ ///
+ /// - Thrown if path is null.
+ /// - Memory error.
+ ///
+ ///
+ /// Thrown on fatal error.
+ /// Thrown on IO error.
+ ///
+ ///
+ /// - Thrown on fatal error.
+ /// - The path refers to non-file.
+ ///
+ ///
+ /// Thrown if the stream is closed.
+ ///
+ ///
+ /// - Thrown if header is not from a BMP.
+ /// - Info header size has the wrong value.
+ /// - Number of planes is not 1. Can not read file.
+ /// - Total Image Size is smaller than pure image size.
+ ///
+ ///
+ /// Thrown if pixelsize is other then 32 / 24 or the file compressed.
+ /// Thrown if the caller does not have permissions to read / write the file.
+ /// Thrown if the file cannot be found.
+ /// Thrown if the specified path is invalid.
+ /// Thrown if the specified path is exceed the system-defined max length.
+ public Png(string path) : this(path, ColorOrder.BGR)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class, with a specified path to a BMP file.
+ ///
+ /// Path to file.
+ /// Order of colors in each pixel.
+ ///
+ ///
+ /// - Thrown if path is invalid.
+ /// - Memory error.
+ ///
+ ///
+ ///
+ ///
+ /// - Thrown if path is null.
+ /// - Memory error.
+ ///
+ ///
+ /// Thrown on fatal error.
+ /// Thrown on IO error.
+ ///
+ ///
+ /// - Thrown on fatal error.
+ /// - The path refers to non-file.
+ ///
+ ///
+ /// Thrown if the stream is closed.
+ ///
+ ///
+ /// - Thrown if header is not from a BMP.
+ /// - Info header size has the wrong value.
+ /// - Number of planes is not 1. Can not read file.
+ /// - Total Image Size is smaller than pure image size.
+ ///
+ ///
+ /// Thrown if pixelsize is other then 32 / 24 or the file compressed.
+ /// Thrown if the caller does not have permissions to read / write the file.
+ /// Thrown if the file cannot be found.
+ /// Thrown if the specified path is invalid.
+ /// Thrown if the specified path is exceed the system-defined max length.
+ public Png(string path, ColorOrder colorOrder = ColorOrder.BGR) : base(0, 0, ColorDepth.ColorDepth32) //Call the image constructor with wrong values
+ {
+ CreatePng(File.ReadAllBytes(path), colorOrder);
+ }
+
+ ///
+ /// Initializes a new instance of the class, with the specified image data byte array.
+ ///
+ /// byte array.
+ /// Thrown if imageData is null / memory error.
+ /// Thrown on memory error.
+ /// Thrown on fatal error.
+ /// Thrown on IO error.
+ /// Thrown on fatal error.
+ /// Thrown on fatal error.
+ ///
+ ///
+ /// - Thrown if header is not from a BMP.
+ /// - Info header size has the wrong value.
+ /// - Number of planes is not 1.
+ /// - Total Image Size is smaller than pure image size.
+ ///
+ ///
+ /// Thrown if pixelsize is other then 32 / 24 or the file compressed.
+ public Png(byte[] imageData) : this(imageData, ColorOrder.BGR) //Call the image constructor with wrong values
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class, with the specified image data byte array.
+ ///
+ /// byte array.
+ /// Order of colors in each pixel.
+ /// Thrown if imageData is null / memory error.
+ /// Thrown on memory error.
+ /// Thrown on fatal error.
+ /// Thrown on IO error.
+ /// Thrown on fatal error.
+ /// Thrown on fatal error.
+ ///
+ ///
+ /// - Thrown if header is not from a BMP.
+ /// - Info header size has the wrong value.
+ /// - Number of planes is not 1.
+ /// - Total Image Size is smaller than pure image size.
+ ///
+ ///
+ /// Thrown if pixelsize is other then 32 / 24 or the file compressed.
+ public Png(byte[] imageData, ColorOrder colorOrder = ColorOrder.BGR) : base(0, 0, ColorDepth.ColorDepth32) //Call the image constructor with wrong values
+ {
+ CreatePng(imageData, colorOrder);
+ }
+
+
+ // For more information about the format: https://docs.microsoft.com/en-us/previous-versions/ms969901(v=msdn.10)?redirectedfrom=MSDN
+ ///
+ /// Creates a png from the given I/O stream.
+ ///
+ /// Stream.
+ /// Order of colors in each pixel.
+ /// Thrown on memory error.
+ /// Thrown on memory error.
+ /// Thrown on fatal error.
+ /// Thrown on IO error.
+ ///
+ ///
+ /// - Thrown on fatal error.
+ /// - The stream does not support seeking.
+ ///
+ ///
+ /// Thrown if the stream is closed.
+ ///
+ ///
+ /// - Thrown if header is not from a BMP.
+ /// - Info header size has the wrong value.
+ /// - Number of planes is not 1. Can not read file.
+ /// - Total Image Size is smaller than pure image size.
+ ///
+ ///
+ /// Thrown if pixelsize is other then 32 / 24 or the file compressed.
+ private void CreatePng(byte[] bytes, ColorOrder colorOrder)
+ {
+ var reader = new CosmosGL.System.BinaryReader(bytes);
+
+ if (reader.GetUint8() != 137) return ;
+ if (reader.GetUint8() != 80) return ;
+ if (reader.GetUint8() != 78) return ;
+ if (reader.GetUint8() != 71) return ;
+ if (reader.GetUint8() != 13) return ;
+ if (reader.GetUint8() != 10) return ;
+ if (reader.GetUint8() != 26) return ;
+ if (reader.GetUint8() != 10) return ;
+
+
+ DirectBitmap re = null;
+
+ while (reader.Tell() < bytes.Length)
+ {
+ var len = reader.GetUint32();
+ var name = reader.GetString(4);
+
+ var pos = reader.Tell();
+
+ bool done = false;
+
+ switch (name)
+ {
+ case "IHDR":
+ re = new DirectBitmap((int)reader.GetUint32(), (int)reader.GetUint32());
+ var bitdepth = reader.GetUint8();
+ var colortype = reader.GetUint8();
+ var compression = reader.GetUint8();
+ var filtermethod = reader.GetUint8();
+ var interlace = reader.GetUint8();
+ CustomConsole.WriteLineInfo("IHDR");
+ break;
+ case "PLTE":
+ CustomConsole.WriteLineInfo("PLTE");
+ break;
+ case "IDAT":
+ CustomConsole.WriteLineInfo("IDAT in");
+ var buf = new List();
+ reader.GetUint8();
+ reader.GetUint8();
+ for (int i = 2; i < len; i++)
+ {
+ buf.Add(reader.GetUint8());
+ }
+
+ var data = ZlibDecoder.Inflate(buf);
+
+ var d = new CosmosGL.System.BinaryReader(data.ToArray());
+
+ var totalScanlines = data.Count / (re.Width + 1) / 4;
+
+ var prevScanline = new List();
+
+ for (int y = 0; y < totalScanlines; y++)
+ {
+ var filter = d.GetUint8();
+
+ var dat = new List();
+
+ for (int x = 0; x < re.Width * 4; x++)
+ {
+ dat.Add(d.GetUint8());
+ }
+ var scanline = new List();
+
+ if (filter == 1)
+ {
+ scanline.Add(dat[0]);
+ for (var index = 1; index < dat.Count; index++)
+ {
+ scanline.Add((byte) ((scanline[index - 4 > 0 ? index - 4 : 0] + dat[index - 1]) % 256));
+ //scanline.Add((byte) (255));
+ }
+ }
+ else if (filter == 2)
+ {
+ for (var index = 0; index < dat.Count; index++)
+ {
+ scanline.Add((byte) ((prevScanline[index] + dat[index]) % 256));
+ //scanline.Add((byte) (255));
+ }
+ }
+ else
+ {
+ }
+
+ var line = new CosmosGL.System.BinaryReader(scanline.ToArray());
+ prevScanline.Clear();
+ prevScanline.AddRange(scanline);
+
+ for (int x = 0; x < re.Width; x++)
+ {
+ var a = line.GetUint8();
+
+ var r = line.GetUint8();
+ var g = line.GetUint8();
+ var b = line.GetUint8();
+
+
+ // if (b == 55 || r == 55 || g == 55) Debugger.Break();
+
+ var argb = (a << 24) | (r << 16) | (g << 8) | b;
+
+ re.SetPixel(x, y, argb);
+ }
+
+ /* //re.SetPixel(x, y, d.GetUint32());
+
+ var b = UnSub(d, x, decoded);
+ var g = UnSub(d, x, decoded);
+ var r = UnSub(d, x, decoded);
+ var a = UnSub(d, x, decoded);
+
+ var c = new Color(r, g, b);
+
+ if (c.ToHex() == 0) c = new Color(prev);
+
+ prev = c.ToHex();
+
+
+ //if(b == 55 || r == 55 || g == 55) Debugger.Break();
+
+ re.SetPixel(x, y, c);*/
+ }
+
+ CustomConsole.WriteLineInfo("IDAT out");
+ break;
+ case "IEND":
+ CustomConsole.WriteLineInfo("IEND");
+ done = true;
+ break;
+ }
+
+ if (done) break;
+
+ reader.Seek((int) (pos + len));
+ var crc = reader.GetUint32();
+ }
+
+ CustomConsole.WriteLineInfo("oe");
+
+ global::System.Console.ReadKey();
+ }
+ }
+}