Skip to content

Commit 7633b96

Browse files
committed
Fix RLE image decoding, thanks @duncanspumpkin. Fixes #29
1 parent ad0da46 commit 7633b96

File tree

3 files changed

+21
-36
lines changed

3 files changed

+21
-36
lines changed

AvaGui/Assets/palette.png

20 Bytes
Loading

Dat/FileParsing/SawyerStreamReader.cs

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -346,72 +346,60 @@ static uint GetNextNonDuplicateOffset(List<G1Element32> elements, int currentEle
346346

347347
public static byte[] DecodeRLEImageData(G1Element32 img)
348348
{
349-
// not sure why this happens, but this seems 'legit'; airport files have these
350-
if (img.ImageData.Length == 0)
351-
{
352-
return [];
353-
}
354-
355349
var width = img.Width;
356350
var height = img.Height;
357351

358352
var dstLineWidth = img.Width;
359-
var dst0Index = 0; // dstLineWidth * img.yOffset + img.xOffset;
353+
var dst0Index = 0;
360354

361355
var srcBuf = img.ImageData;
362356
var dstBuf = new byte[img.Width * img.Height]; // Assuming a single byte per pixel
363357

364358
var srcY = 0;
365359

360+
// Move up to the first line of the image if source_y_start is negative. Why does this even occur?
366361
if (srcY < 0)
367362
{
368363
srcY++;
369364
height--;
370365
dst0Index += dstLineWidth;
371366
}
372367

368+
// For every line in the image
373369
for (var i = 0; i < height; i++)
374370
{
375371
var y = srcY + i;
376372

377-
var lineOffset = srcBuf[y * 2] | (srcBuf[(y * 2) + 1] << 8);
378-
379-
var nextRunIndex = lineOffset;
373+
// The first part of the source pointer is a list of offsets to different lines
374+
// This will move the pointer to the correct source line.
375+
var nextRunIndex = srcBuf[y * 2] | (srcBuf[(y * 2) + 1] << 8);
380376
var dstLineStartIndex = dst0Index + (dstLineWidth * i);
381377

382-
while (true)
378+
// For every data chunk in the line
379+
var isEndOfLine = false;
380+
while (!isEndOfLine)
383381
{
384382
var srcIndex = nextRunIndex;
385-
386-
var rleInfoByte = srcBuf[srcIndex++];
387-
var dataSize = rleInfoByte & 0x7F;
388-
var isEndOfLine = (rleInfoByte & 0x80) != 0;
389-
383+
var dataSize = srcBuf[srcIndex++];
390384
var firstPixelX = srcBuf[srcIndex++];
391-
nextRunIndex = srcIndex + dataSize;
385+
isEndOfLine = (dataSize & 0x80) != 0;
386+
dataSize &= 0x7F;
392387

393-
var x = firstPixelX - 0; // img.xOffset;
394-
var numPixels = dataSize;
388+
// Have our next source pointer point to the next data section
389+
nextRunIndex = srcIndex + dataSize;
395390

396-
if (x > 0)
397-
{
398-
x++;
399-
srcIndex++;
400-
numPixels--;
401-
}
402-
else if (x < 0)
403-
{
404-
srcIndex += -x;
405-
numPixels += x;
406-
x = 0;
407-
}
391+
var x = firstPixelX;
392+
int numPixels = dataSize;
408393

394+
// If the end position is further out than the whole image
395+
// end position then we need to shorten the line again
409396
numPixels = Math.Min(numPixels, width - x);
410397

411398
var dstIndex = dstLineStartIndex + x;
412399

413400
if (numPixels > 0)
414401
{
402+
// Since we're sampling each pixel at this zoom level, just do a straight std::memcpy
415403
Array.Copy(srcBuf, srcIndex, dstBuf, dstIndex, numPixels);
416404
}
417405

Dat/PaletteMap.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,17 @@ public PaletteMap(Color[] _palette)
4848
public (Color Color, byte Index)[] PrimaryRemapColours
4949
=> [.. Palette[7..10], .. Palette[246..255]];
5050

51-
public (Color Color, byte Index)[] UnkReserved
52-
=> Palette[154..166];
53-
5451
public (Color Color, byte Index)[] SecondaryRemapColours
5552
=> Palette[202..214];
5653

5754
public (Color Color, byte Index) ChunkedTransparent
5855
=> Palette[255];
5956

6057
public (Color Color, byte Index)[] ValidColours
61-
=> [.. Palette[10..154], .. Palette[166..202], .. Palette[214..246]];
58+
=> [.. Palette[10..202], .. Palette[214..246]];
6259

6360
public (Color Color, byte Index)[] ReservedColours
64-
=> [Transparent, .. DirectXReserved, .. PrimaryRemapColours, .. UnkReserved, .. SecondaryRemapColours, ChunkedTransparent];
61+
=> [Transparent, .. DirectXReserved, .. PrimaryRemapColours, .. SecondaryRemapColours, ChunkedTransparent];
6562

6663
public byte[] ConvertRgba32ImageToG1Data(Image<Rgba32> img, G1ElementFlags flags)
6764
{

0 commit comments

Comments
 (0)