in src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/JpegDecoder.java [214:296]
private void readMcu(final JpegInputStream is, final int[] preds, final Block[] mcu) throws ImagingException {
for (int i = 0; i < sosSegment.numberOfComponents; i++) {
final SosSegment.Component scanComponent = sosSegment.getComponents(i);
SofnSegment.Component frameComponent = null;
for (int j = 0; j < sofnSegment.numberOfComponents; j++) {
if (sofnSegment.getComponents(j).componentIdentifier == scanComponent.scanComponentSelector) {
frameComponent = sofnSegment.getComponents(j);
break;
}
}
if (frameComponent == null) {
throw new ImagingException("Invalid component");
}
final Block fullBlock = mcu[i];
for (int y = 0; y < frameComponent.verticalSamplingFactor; y++) {
for (int x = 0; x < frameComponent.horizontalSamplingFactor; x++) {
Arrays.fill(zz, 0);
// page 104 of T.81
final int t = decode(is, huffmanDCTables[scanComponent.dcCodingTableSelector]);
int diff = receive(t, is);
diff = extend(diff, t);
zz[0] = preds[i] + diff;
preds[i] = zz[0];
// "Decode_AC_coefficients", figure F.13, page 106 of T.81
int k = 1;
while (true) {
final int rs = decode(is, huffmanACTables[scanComponent.acCodingTableSelector]);
final int ssss = rs & 0xf;
final int rrrr = rs >> 4;
final int r = rrrr;
if (ssss == 0) {
if (r != 15) {
break;
}
k += 16;
} else {
k += r;
// "Decode_ZZ(k)", figure F.14, page 107 of T.81
zz[k] = receive(ssss, is);
zz[k] = extend(zz[k], ssss);
if (k == 63) {
break;
}
k++;
}
}
final int shift = 1 << sofnSegment.precision - 1;
final int max = (1 << sofnSegment.precision) - 1;
final float[] scaledQuantizationTable = scaledQuantizationTables[frameComponent.quantTabDestSelector];
ZigZag.zigZagToBlock(zz, blockInt);
for (int j = 0; j < 64; j++) {
block[j] = blockInt[j] * scaledQuantizationTable[j];
}
Dct.inverseDct8x8(block);
int dstRowOffset = 8 * y * 8 * frameComponent.horizontalSamplingFactor + 8 * x;
int srcNext = 0;
for (int yy = 0; yy < 8; yy++) {
for (int xx = 0; xx < 8; xx++) {
float sample = block[srcNext++];
sample += shift;
final int result;
if (sample < 0) {
result = 0;
} else if (sample > max) {
result = max;
} else {
result = fastRound(sample);
}
fullBlock.samples[dstRowOffset + xx] = result;
}
dstRowOffset += 8 * frameComponent.horizontalSamplingFactor;
}
}
}
}
}