Initial handling of interlaced GIFs
This commit is contained in:
parent
3e4230e46f
commit
a9a16f88e9
|
@ -86,6 +86,7 @@ public class GifDecoder
|
||||||
private byte[] _colors;
|
private byte[] _colors;
|
||||||
private byte[] _pixelIndices;
|
private byte[] _pixelIndices;
|
||||||
private int _transparentIndex;
|
private int _transparentIndex;
|
||||||
|
private readonly bool _interlaced;
|
||||||
|
|
||||||
public ImageData(BinaryReader reader, byte[] globalColors, int transparentIndex)
|
public ImageData(BinaryReader reader, byte[] globalColors, int transparentIndex)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +96,7 @@ public class GifDecoder
|
||||||
var height = reader.ReadUInt16();
|
var height = reader.ReadUInt16();
|
||||||
var flags = reader.ReadByte();
|
var flags = reader.ReadByte();
|
||||||
var hasLocalColorTable = ((flags >> 7) & 0x1) != 0;
|
var hasLocalColorTable = ((flags >> 7) & 0x1) != 0;
|
||||||
var interlaced = ((flags >> 6) & 0x1) != 0; // See appendix E for interlacing
|
_interlaced = ((flags >> 6) & 0x1) != 0; // See appendix E for interlacing
|
||||||
var isLocalColorTableSorted = ((flags >> 5) & 0x1) != 0;
|
var isLocalColorTableSorted = ((flags >> 5) & 0x1) != 0;
|
||||||
var sizeOfLocalColorTable = (byte)Math.Pow(2, (flags & 0x7) + 1);
|
var sizeOfLocalColorTable = (byte)Math.Pow(2, (flags & 0x7) + 1);
|
||||||
byte[] colors;
|
byte[] colors;
|
||||||
|
@ -256,14 +257,65 @@ public class GifDecoder
|
||||||
{
|
{
|
||||||
var bytesIdx = 0;
|
var bytesIdx = 0;
|
||||||
var bytes = new byte[Width * Height * 4];
|
var bytes = new byte[Width * Height * 4];
|
||||||
|
|
||||||
|
void WritePixelBytes(int bytesOffset, int colorIndex)
|
||||||
|
{
|
||||||
|
bytes[bytesOffset] = _colors[colorIndex * 3];
|
||||||
|
bytes[bytesOffset + 1] = _colors[colorIndex * 3 + 1];
|
||||||
|
bytes[bytesOffset + 2] = _colors[colorIndex * 3 + 2];
|
||||||
|
// Fuck you LGS hardcoding the transparent index suck my balls
|
||||||
|
// bytes[bytesOffset++] = (byte)((colorIndex == _transparentIndex) ? 0 : 255);
|
||||||
|
bytes[bytesOffset + 3] = (byte)((colorIndex == 0) ? 0 : 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_interlaced)
|
||||||
|
{
|
||||||
foreach (var colorIndex in _pixelIndices)
|
foreach (var colorIndex in _pixelIndices)
|
||||||
{
|
{
|
||||||
bytes[bytesIdx++] = _colors[colorIndex * 3];
|
WritePixelBytes(bytesIdx, colorIndex);
|
||||||
bytes[bytesIdx++] = _colors[colorIndex * 3 + 1];
|
bytesIdx += 4;
|
||||||
bytes[bytesIdx++] = _colors[colorIndex * 3 + 2];
|
}
|
||||||
// Fuck you LGS hardcoding the transparent index suck my balls
|
return bytes;
|
||||||
// bytes[bytesIdx++] = (byte)((colorIndex == _transparentIndex) ? 0 : 255);
|
}
|
||||||
bytes[bytesIdx++] = (byte)((colorIndex == 0) ? 0 : 255);
|
|
||||||
|
var pass1Count = (int)Math.Ceiling(Height / 8.0f);
|
||||||
|
var pass2Count = (int)Math.Ceiling((Height - 4) / 8.0f);
|
||||||
|
var pass3Count = (int)Math.Ceiling((Height - 2) / 4.0f);
|
||||||
|
var pass4Count = (int)Math.Ceiling((Height - 1) / 2.0f);
|
||||||
|
|
||||||
|
var indicesOffset = 0;
|
||||||
|
var bytesPerRow = Width * 4;
|
||||||
|
for (var i = 0; i < pass1Count; i++)
|
||||||
|
{
|
||||||
|
bytesIdx = 8 * i * bytesPerRow;
|
||||||
|
for (var x = 0; x < Width; x++)
|
||||||
|
{
|
||||||
|
WritePixelBytes(bytesIdx + x * 4, _pixelIndices[indicesOffset++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < pass2Count; i++)
|
||||||
|
{
|
||||||
|
bytesIdx = (4 + 8 * i) * bytesPerRow;
|
||||||
|
for (var x = 0; x < Width; x++)
|
||||||
|
{
|
||||||
|
WritePixelBytes(bytesIdx + x * 4, _pixelIndices[indicesOffset++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < pass3Count; i++)
|
||||||
|
{
|
||||||
|
bytesIdx = (2 + 4 * i) * bytesPerRow;
|
||||||
|
for (var x = 0; x < Width; x++)
|
||||||
|
{
|
||||||
|
WritePixelBytes(bytesIdx + x * 4, _pixelIndices[indicesOffset++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < pass4Count; i++)
|
||||||
|
{
|
||||||
|
bytesIdx = (1 + 2 * i) * bytesPerRow;
|
||||||
|
for (var x = 0; x < Width; x++)
|
||||||
|
{
|
||||||
|
WritePixelBytes(bytesIdx + x * 4, _pixelIndices[indicesOffset++]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue