Skip to content

Commit f150130

Browse files
JPEG: Decoding a grayscale image hackily works..
1 parent d094566 commit f150130

File tree

1 file changed

+45
-11
lines changed

1 file changed

+45
-11
lines changed

MCGalaxy/util/Imaging/JpegDecoder.cs

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ public override SimpleBitmap Decode(byte[] src) {
4242
SimpleBitmap bmp = new SimpleBitmap();
4343

4444
ReadMarkers(src, bmp);
45-
Fail("JPEG decoder unfinished");
46-
return null;
45+
return bmp;
4746
}
4847

4948

@@ -249,7 +248,7 @@ void SetHuffTables(byte compID, byte tables) {
249248

250249
static byte[] zigzag_to_linear = new byte[64]
251250
{
252-
0, 1, 8, 16, 9, 2, 3, 10,
251+
0, 1, 8, 16, 9, 2, 3, 10,
253252
17, 24, 32, 25, 18, 11, 4, 5,
254253
12, 19, 26, 33, 40, 48, 41, 34,
255254
27, 20, 13, 6, 7, 14, 21, 28,
@@ -262,7 +261,6 @@ void SetHuffTables(byte compID, byte tables) {
262261
void DecodeMCUs(byte[] src, SimpleBitmap bmp) {
263262
int mcus_x = (bmp.Width + 7) / 8;
264263
int mcus_y = (bmp.Height + 7) / 8;
265-
bit_offset = AdvanceOffset(0);
266264

267265
JpegComponent[] comps = this.comps;
268266
int[] block = new int[64];
@@ -307,24 +305,60 @@ void DecodeMCUs(byte[] src, SimpleBitmap bmp) {
307305
}
308306
} while (idx < 64);
309307

310-
Fail("DE");
308+
float[] output = new float[64];
309+
IDCT(block, output);
310+
311+
for (int YY = 0; YY < 8; YY++)
312+
for (int XX = 0; XX < 8; XX++)
313+
{
314+
int globalX = x * 8 + XX;
315+
int globalY = y * 8 + YY;
316+
if (globalX < bmp.Width && globalY < bmp.Height) {
317+
byte rgb = (byte)output[YY*8+XX];
318+
Pixel p = new Pixel(rgb, rgb, rgb, 255);
319+
bmp.pixels[globalY * bmp.Width + globalX] = p;
320+
}
321+
}
322+
// Fail("DE");
323+
}
324+
}
325+
// Fail("MCUs");
326+
}
327+
328+
void IDCT(int[] block, float[] output) {
329+
for (int y = 0; y < 8; y++)
330+
for (int x = 0; x < 8; x++)
331+
{
332+
float sum = 0.0f;
333+
for (int v = 0; v < 8; v++)
334+
for (int u = 0; u < 8; u++)
335+
{
336+
float cu = u == 0 ? 0.70710678f : 1.0f;
337+
float cv = v == 0 ? 0.70710678f : 1.0f;
338+
339+
float suv = block[v*8+u];
340+
float cosu = (float)Math.Cos((2 * x + 1) * u * Math.PI / 16.0);
341+
float cosv = (float)Math.Cos((2 * y + 1) * v * Math.PI / 16.0);
342+
343+
sum += cu * cv * suv * cosu * cosv;
311344
}
345+
output[y*8+x] = (sum / 4.0f) + 128.0f; // undo level shift at end
312346
}
313-
Fail("MCUs");
314347
}
315348

316349
uint bit_buf;
317350
int bit_cnt;
318-
int bit_offset;
351+
bool end;
319352

320353
int ReadBits(byte[] src, int count) {
321-
while (bit_cnt <= 24) {
322-
byte next = src[bit_offset++];
354+
while (bit_cnt <= 24 && !end) {
355+
byte next = src[buf_offset++];
323356
// JPEG byte stuffing
324357
// TODO restart markers ?
325358
if (next == 0xFF) {
326-
byte type = src[bit_offset++];
327-
if (type != 0) Fail("unexpected marker");
359+
byte type = src[buf_offset++];
360+
if (type == 0xD9) { end = true; buf_offset -= 2; }
361+
else if (type != 0) Fail("unexpected marker");
328362
}
329363

330364
bit_buf <<= 8;

0 commit comments

Comments
 (0)