Compare commits
No commits in common. "354155db200738d5d0ed0e7d5f48451ffd78f515" and "3e4230e46f4516b700783d67511b56e43bb7faff" have entirely different histories.
354155db20
...
3e4230e46f
|
@ -35,9 +35,11 @@ public class GifDecoder
|
|||
LogicalScreenHeight = reader.ReadUInt16();
|
||||
var flags = reader.ReadByte();
|
||||
HasGlobalColorTable = ((flags >> 7) & 0x1) != 0;
|
||||
// Godot.GD.Print($"HALLO WE HAVE GLOBAL TABLE? {HasGlobalColorTable}");
|
||||
BitsPerColorChannel = (byte)(((flags >> 4) & 0x7) + 1);
|
||||
IsGlobalColorTableSorted = ((flags >> 3) & 0x1) != 0;
|
||||
GlobalColorTableSize = (int)Math.Pow(2, (flags & 0x7) + 1);
|
||||
// Godot.GD.Print($"Global colour size? {GlobalColorTableSize}");
|
||||
BackgroundColorIndex = reader.ReadByte();
|
||||
var rawAspectRatio = reader.ReadByte();
|
||||
if (rawAspectRatio == 0)
|
||||
|
@ -84,7 +86,6 @@ public class GifDecoder
|
|||
private byte[] _colors;
|
||||
private byte[] _pixelIndices;
|
||||
private int _transparentIndex;
|
||||
private readonly bool _interlaced;
|
||||
|
||||
public ImageData(BinaryReader reader, byte[] globalColors, int transparentIndex)
|
||||
{
|
||||
|
@ -94,7 +95,7 @@ public class GifDecoder
|
|||
var height = reader.ReadUInt16();
|
||||
var flags = reader.ReadByte();
|
||||
var hasLocalColorTable = ((flags >> 7) & 0x1) != 0;
|
||||
_interlaced = ((flags >> 6) & 0x1) != 0; // See appendix E for interlacing
|
||||
var interlaced = ((flags >> 6) & 0x1) != 0; // See appendix E for interlacing
|
||||
var isLocalColorTableSorted = ((flags >> 5) & 0x1) != 0;
|
||||
var sizeOfLocalColorTable = (byte)Math.Pow(2, (flags & 0x7) + 1);
|
||||
byte[] colors;
|
||||
|
@ -139,6 +140,7 @@ public class GifDecoder
|
|||
compressedBytes.AddRange(bytes);
|
||||
blockSize = reader.ReadByte();
|
||||
}
|
||||
// Godot.GD.Print($"End of image data: {reader.BaseStream.Position}");
|
||||
|
||||
using MemoryStream compressedStream = new(compressedBytes.ToArray());
|
||||
using BinaryReader compressedReader = new(compressedStream, Encoding.UTF8, false);
|
||||
|
@ -178,6 +180,7 @@ public class GifDecoder
|
|||
}
|
||||
else if (code == endCode)
|
||||
{
|
||||
// Godot.GD.Print($"CompressedBytesLeft: {compressedReader.BaseStream.Length - compressedReader.BaseStream.Position}");
|
||||
break;
|
||||
}
|
||||
else if (code < codeCount)
|
||||
|
@ -253,47 +256,15 @@ public class GifDecoder
|
|||
{
|
||||
var bytesIdx = 0;
|
||||
var bytes = new byte[Width * Height * 4];
|
||||
|
||||
void WritePixelBytes(int bytesOffset, int colorIndex)
|
||||
foreach (var colorIndex in _pixelIndices)
|
||||
{
|
||||
bytes[bytesOffset] = _colors[colorIndex * 3];
|
||||
bytes[bytesOffset + 1] = _colors[colorIndex * 3 + 1];
|
||||
bytes[bytesOffset + 2] = _colors[colorIndex * 3 + 2];
|
||||
bytes[bytesOffset + 3] = (byte)((colorIndex == _transparentIndex) ? 0 : 255);
|
||||
bytes[bytesIdx++] = _colors[colorIndex * 3];
|
||||
bytes[bytesIdx++] = _colors[colorIndex * 3 + 1];
|
||||
bytes[bytesIdx++] = _colors[colorIndex * 3 + 2];
|
||||
// Fuck you LGS hardcoding the transparent index suck my balls
|
||||
// bytes[bytesIdx++] = (byte)((colorIndex == _transparentIndex) ? 0 : 255);
|
||||
bytes[bytesIdx++] = (byte)((colorIndex == 0) ? 0 : 255);
|
||||
}
|
||||
|
||||
if (!_interlaced)
|
||||
{
|
||||
foreach (var colorIndex in _pixelIndices)
|
||||
{
|
||||
WritePixelBytes(bytesIdx, colorIndex);
|
||||
bytesIdx += 4;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
var pass = 0;
|
||||
var inc = 8;
|
||||
var y = 0;
|
||||
var indicesOffset = 0;
|
||||
var bytesPerRow = Width * 4;
|
||||
for (var i = 0; i < Height; i++)
|
||||
{
|
||||
bytesIdx = y * bytesPerRow;
|
||||
for (var x = 0; x < Width; x++)
|
||||
{
|
||||
WritePixelBytes(bytesIdx + x * 4, _pixelIndices[indicesOffset++]);
|
||||
}
|
||||
|
||||
y += inc;
|
||||
if (y >= Height)
|
||||
{
|
||||
pass += 1;
|
||||
y = (int)(8 / Math.Pow(2, pass));
|
||||
inc = y * 2;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
@ -309,12 +280,15 @@ public class GifDecoder
|
|||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
// Godot.GD.Print($"Decoding image at: {path}");
|
||||
|
||||
using MemoryStream stream = new(File.ReadAllBytes(path));
|
||||
using BinaryReader reader = new(stream, Encoding.UTF8, false);
|
||||
|
||||
_header = new Header(reader);
|
||||
_globalColors = ReadColorTable(reader, _header.HasGlobalColorTable ? _header.GlobalColorTableSize : 0);
|
||||
var images = new List<ImageData>();
|
||||
var transparentIndex = -1;
|
||||
while (true)
|
||||
{
|
||||
var id = reader.ReadByte();
|
||||
|
@ -322,18 +296,22 @@ public class GifDecoder
|
|||
switch (id)
|
||||
{
|
||||
case 0x2C: // Image
|
||||
images.Add(new ImageData(reader, _globalColors, 0));
|
||||
// Godot.GD.Print("Adding new image!!");
|
||||
images.Add(new ImageData(reader, _globalColors, transparentIndex));
|
||||
transparentIndex = -1;
|
||||
break;
|
||||
case 0x21: // Extension
|
||||
// We don't need to actually handle any extensions. The only one that's
|
||||
// potentially relevant is GraphicsControl, but Dark uses a hardcoded
|
||||
// transparency palette index and doesn't use multi-frame GIFs with timing.
|
||||
reader.ReadByte();
|
||||
var blockSize = reader.ReadByte();
|
||||
while (blockSize != 0)
|
||||
var extId = reader.ReadByte();
|
||||
if (extId == 0xF9)
|
||||
{
|
||||
reader.ReadBytes(blockSize);
|
||||
blockSize = reader.ReadByte();
|
||||
var graphicsControl = new GraphicsControl(reader);
|
||||
transparentIndex = graphicsControl.TransparencyIndex;
|
||||
// Godot.GD.Print($"We set the transparent index: {transparentIndex} for {path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't support Comment (0xFE), Text (0x01), or Application (0xFF) extensions
|
||||
throw new InvalidDataException($"Unknown or unsupported extension identifier in GIF file: {extId}");
|
||||
}
|
||||
break;
|
||||
case 0x3B:
|
||||
|
|
Loading…
Reference in New Issue