Skip to content

Commit 8b2c9c9

Browse files
Fix GIF decoder not handling deferred clear codes properly
1 parent 3e95dc3 commit 8b2c9c9

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

MCGalaxy/util/Imaging/GifDecoder.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ void ReadMarkers(byte[] src, SimpleBitmap bmp) {
103103
case MARKER_IMAGE_END:
104104
return;
105105
default:
106-
Fail("unknown marker");
106+
Fail("unknown marker:" + marker.ToString("X2"));
107107
break;
108108
}
109109
}
@@ -251,9 +251,7 @@ void ReadImage(byte[] src, SimpleBitmap bmp) {
251251
break;
252252
}
253253

254-
if (code > availCode) {
255-
Fail("invalid code");
256-
}
254+
if (code > availCode) Fail("invalid code");
257255

258256
// Add new entry to code table unless it's full
259257
// GIF spec allows this as per 'deferred clear codes'
@@ -268,15 +266,14 @@ void ReadImage(byte[] src, SimpleBitmap bmp) {
268266

269267
// Check if inserted code was last free entry of table
270268
// If this is the case, then the table is immediately expanded
271-
if ((availCode & codeMask) == 0 && availCode != (MAX_CODES - 1)) {
269+
if ((availCode & codeMask) == 0 && availCode != MAX_CODES) {
272270
codeLen++;
273271
codeMask = (1 << codeLen) - 1;
274272
Array.Resize(ref dict, 1 << codeLen);
275273
}
276274
}
277275

278276
prevCode = code;
279-
// TODO output code
280277

281278
// "top" entry is actually last entry in chain
282279
int chain_len = dict[code].len;

MCGalaxy/util/Imaging/JpegDecoder.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,50 @@ public static bool DetectHeader(byte[] data) {
3131
}
3232

3333
public override SimpleBitmap Decode(byte[] src) {
34+
SetBuffer(src);
35+
SimpleBitmap bmp = new SimpleBitmap();
36+
37+
ReadMarkers(src, bmp);
3438
Fail("JPEG decoder unfinished");
3539
return null;
3640
}
41+
42+
const ushort MARKER_IMAGE_BEG = 0xFFD8;
43+
const ushort MARKER_IMAGE_END = 0xFFD9;
44+
const ushort MARKER_APP0 = 0xFFE0;
45+
const ushort MARKER_TBL_QUANT = 0xFFDB;
46+
const ushort MARKER_TBL_HUFF = 0xFFC4;
47+
48+
void ReadMarkers(byte[] src, SimpleBitmap bmp) {
49+
for (;;)
50+
{
51+
int offset = AdvanceOffset(2);
52+
ushort marker = MemUtils.ReadU16_BE(src, offset);
53+
54+
switch (marker)
55+
{
56+
case MARKER_IMAGE_BEG:
57+
break; // Nothing to do
58+
case MARKER_IMAGE_END:
59+
return;
60+
case MARKER_APP0:
61+
case MARKER_TBL_QUANT:
62+
case MARKER_TBL_HUFF:
63+
SkipMarker(src);
64+
break;
65+
66+
default:
67+
Fail("unknown marker:" + marker.ToString("X4"));
68+
break;
69+
}
70+
}
71+
}
72+
73+
void SkipMarker(byte[] src) {
74+
int offset = AdvanceOffset(2);
75+
ushort len = MemUtils.ReadU16_BE(src, offset);
76+
// length *includes* 2 bytes of length
77+
AdvanceOffset(len - 2);
78+
}
3779
}
3880
}

0 commit comments

Comments
 (0)