in Support/STBImage/include/stb_image.h [2834:2956]
static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
{
stbi__jpeg_reset(z);
if (!z->progressive) {
if (z->scan_n == 1) {
int i,j;
STBI_SIMD_ALIGN(short, data[64]);
int n = z->order[0];
// non-interleaved data, we just need to process one block at a time,
// in trivial scanline order
// number of blocks to do just depends on how many actual "pixels" this
// component has, independent of interleaved MCU blocking and such
int w = (z->img_comp[n].x+7) >> 3;
int h = (z->img_comp[n].y+7) >> 3;
for (j=0; j < h; ++j) {
for (i=0; i < w; ++i) {
int ha = z->img_comp[n].ha;
if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
// every data block is an MCU, so countdown the restart interval
if (--z->todo <= 0) {
if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
// if it's NOT a restart, then just bail, so we get corrupt data
// rather than no data
if (!STBI__RESTART(z->marker)) return 1;
stbi__jpeg_reset(z);
}
}
}
return 1;
} else { // interleaved
int i,j,k,x,y;
STBI_SIMD_ALIGN(short, data[64]);
for (j=0; j < z->img_mcu_y; ++j) {
for (i=0; i < z->img_mcu_x; ++i) {
// scan an interleaved mcu... process scan_n components in order
for (k=0; k < z->scan_n; ++k) {
int n = z->order[k];
// scan out an mcu's worth of this component; that's just determined
// by the basic H and V specified for the component
for (y=0; y < z->img_comp[n].v; ++y) {
for (x=0; x < z->img_comp[n].h; ++x) {
int x2 = (i*z->img_comp[n].h + x)*8;
int y2 = (j*z->img_comp[n].v + y)*8;
int ha = z->img_comp[n].ha;
if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data);
}
}
}
// after all interleaved components, that's an interleaved MCU,
// so now count down the restart interval
if (--z->todo <= 0) {
if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
if (!STBI__RESTART(z->marker)) return 1;
stbi__jpeg_reset(z);
}
}
}
return 1;
}
} else {
if (z->scan_n == 1) {
int i,j;
int n = z->order[0];
// non-interleaved data, we just need to process one block at a time,
// in trivial scanline order
// number of blocks to do just depends on how many actual "pixels" this
// component has, independent of interleaved MCU blocking and such
int w = (z->img_comp[n].x+7) >> 3;
int h = (z->img_comp[n].y+7) >> 3;
for (j=0; j < h; ++j) {
for (i=0; i < w; ++i) {
short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
if (z->spec_start == 0) {
if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
return 0;
} else {
int ha = z->img_comp[n].ha;
if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha]))
return 0;
}
// every data block is an MCU, so countdown the restart interval
if (--z->todo <= 0) {
if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
if (!STBI__RESTART(z->marker)) return 1;
stbi__jpeg_reset(z);
}
}
}
return 1;
} else { // interleaved
int i,j,k,x,y;
for (j=0; j < z->img_mcu_y; ++j) {
for (i=0; i < z->img_mcu_x; ++i) {
// scan an interleaved mcu... process scan_n components in order
for (k=0; k < z->scan_n; ++k) {
int n = z->order[k];
// scan out an mcu's worth of this component; that's just determined
// by the basic H and V specified for the component
for (y=0; y < z->img_comp[n].v; ++y) {
for (x=0; x < z->img_comp[n].h; ++x) {
int x2 = (i*z->img_comp[n].h + x);
int y2 = (j*z->img_comp[n].v + y);
short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
return 0;
}
}
}
// after all interleaved components, that's an interleaved MCU,
// so now count down the restart interval
if (--z->todo <= 0) {
if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
if (!STBI__RESTART(z->marker)) return 1;
stbi__jpeg_reset(z);
}
}
}
return 1;
}
}
}