Skip to content

Commit c294041

Browse files
JPEG: Little bit faster
1 parent bc4ce0a commit c294041

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

MCGalaxy/util/Imaging/JpegDecoder.cs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,12 @@ void ReadFrameStart(byte[] src, SimpleBitmap bmp) {
251251
// In most JPEG images there is chroma sub-sampling
252252
for (int i = 0; i < numComps; i++)
253253
{
254-
comps[i].BlocksPerMcuX = comps[i].SamplingHor;
255-
comps[i].BlocksPerMcuY = comps[i].SamplingVer;
254+
JpegComponent comp = comps[i];
255+
comp.BlocksPerMcuX = comp.SamplingHor;
256+
comp.BlocksPerMcuY = comp.SamplingVer;
257+
258+
comp.SamplesPerBlockX = (byte)(lowestHor / comp.BlocksPerMcuX);
259+
comp.SamplesPerBlockY = (byte)(lowestVer / comp.BlocksPerMcuY);
256260
}
257261
}
258262

@@ -311,8 +315,11 @@ void DecodeMCUs(byte[] src, SimpleBitmap bmp) {
311315
int mcus_y = Utils.CeilDiv(bmp.Height, mcu_h);
312316

313317
JpegComponent[] comps = this.comps;
314-
int[] block = new int[BLOCK_SIZE];
318+
int* block = stackalloc int[BLOCK_SIZE + 32];
315319
float* output = stackalloc float[BLOCK_SIZE];
320+
// NOTE: block has extra data at end, in case of invalid huffman code
321+
// resulting in 'num zeroes' going past limit of 64
322+
// Although there can be at most 15 extra zeroes, add 32 padding to be safe
316323

317324
YCbCr[] colors = new YCbCr[mcu_w * mcu_h];
318325

@@ -339,8 +346,8 @@ void DecodeMCUs(byte[] src, SimpleBitmap bmp) {
339346
DecodeBlock(comp, src, block);
340347
IDCT(block, output);
341348

342-
int samplesX = lowestHor / comp.SamplingHor;
343-
int samplesY = lowestVer / comp.SamplingVer;
349+
int samplesX = comp.SamplesPerBlockX;
350+
int samplesY = comp.SamplesPerBlockY;
344351

345352
for (int y = 0; y < BLOCK_SAMPLES; y++)
346353
for (int x = 0; x < BLOCK_SAMPLES; x++)
@@ -400,7 +407,7 @@ static byte ByteClamp(float v) {
400407
return (byte)v;
401408
}
402409

403-
void DecodeBlock(JpegComponent comp, byte[] src, int[] block) {
410+
void DecodeBlock(JpegComponent comp, byte[] src, int* block) {
404411
// DC value is relative to DC value from prior block
405412
var table = dc_huff_tables[comp.DCHuffTable];
406413
int dc_code = ReadHuffman(table, src);
@@ -410,7 +417,7 @@ void DecodeBlock(JpegComponent comp, byte[] src, int[] block) {
410417
comp.PredDCValue = dc_value;
411418

412419
byte[] dequant = quant_tables[comp.QuantTable];
413-
for (int j = 0; j < block.Length; j++) block[j] = 0;
420+
for (int j = 0; j < BLOCK_SIZE; j++) block[j] = 0;
414421
block[0] = dc_value * dequant[0];
415422

416423
// 63 AC values
@@ -455,7 +462,7 @@ void DecodeBlock(JpegComponent comp, byte[] src, int[] block) {
455462
const float C7 = 0.19509032201f / 4.0f; // cos(7pi/16)
456463

457464
const int DCT_SIZE = 8;
458-
static void IDCT(int[] block, float* output) {
465+
static void IDCT(int* block, float* output) {
459466
float* tmp = stackalloc float[DCT_SIZE * DCT_SIZE];
460467

461468
for (int col = 0; col < DCT_SIZE; col++)
@@ -626,16 +633,18 @@ int ReadBiasedValue(byte[] src, int bits) {
626633
class JpegComponent
627634
{
628635
public byte ID;
629-
public byte QuantTable;
636+
public byte QuantTable;
637+
public byte ACHuffTable;
638+
public byte DCHuffTable;
639+
public int PredDCValue;
630640

631-
public byte SamplingHor;
632-
public byte SamplingVer;
633641
public byte BlocksPerMcuX;
634-
public byte BlocksPerMcuY;
642+
public byte BlocksPerMcuY;
643+
public byte SamplesPerBlockX;
644+
public byte SamplesPerBlockY;
635645

636-
public byte ACHuffTable;
637-
public byte DCHuffTable;
638-
public int PredDCValue;
646+
public byte SamplingHor;
647+
public byte SamplingVer;
639648
}
640649

641650
class HuffmanTable

0 commit comments

Comments
 (0)