unsigned num_components;
unsigned hsample[256], vsample[256], qtable[256];
unsigned max_hsample, max_vsample;
+ unsigned stride[256];
unsigned num_blocks_horizontal, num_blocks_vertical;
uint32_t qvalues[256][DCTSIZE2];
void* idct_data[256];
uint8_t* pixel_data[256];
+ uint8_t* pixel_write_pointer[256];
};
ssize_t stdio_read(void* userdata, uint8_t* buf, size_t count)
unsigned width = image->num_blocks_horizontal * image->hsample[c] * DCTSIZE;
unsigned height = image->num_blocks_vertical * image->vsample[c] * DCTSIZE;
+ image->stride[c] = width;
image->pixel_data[c] = (uint8_t*)malloc(width * height);
assert(image->pixel_data[c] != NULL);
+ image->pixel_write_pointer[c] = image->pixel_data[c];
fprintf(stderr, "Component %u: allocating %d x %d\n", c, width, height);
}
while (!bits.source_eof) {
for (unsigned c = 0; c < num_components; ++c) {
unsigned cn = component_num[c];
- unsigned stride = image->num_blocks_horizontal * image->hsample[cn] * DCTSIZE;
assert(image->idct_data[image->qtable[cn]] != NULL);
-
- for (unsigned local_yb = 0; local_yb < image->vsample[cn]; ++local_yb) {
- for (unsigned local_xb = 0; local_xb < image->hsample[cn]; ++local_xb) {
+
+ uint8_t* pixel_write_pointer_y = image->pixel_write_pointer[cn];
+ for (unsigned local_yb = 0; local_yb < image->vsample[cn]; ++local_yb, pixel_write_pointer_y += image->stride[cn] * DCTSIZE) {
+ uint8_t* pixel_write_pointer = pixel_write_pointer_y;
+ for (unsigned local_xb = 0; local_xb < image->hsample[cn]; ++local_xb, pixel_write_pointer += DCTSIZE) {
const struct huffman_table* dc_table = &((*tables)[DC_CLASS][dc_huffman_table[c]]);
const struct huffman_table* ac_table = &((*tables)[AC_CLASS][ac_huffman_table[c]]);
// decode DC component
unsigned dc_category = read_huffman_symbol(dc_table, &bits);
- possibly_refill(&bits, dc_category);
+ possibly_refill(&bits, dc_category + DEHUF_TABLE_BITS);
last_dc[c] += extend(read_bits(&bits, dc_category), dc_category);
int16_t coeff[DCTSIZE2] = { 0 };
// decode AC components
for (unsigned i = 1; i < DCTSIZE2; ++i) {
- unsigned rs = read_huffman_symbol(ac_table, &bits);
+ unsigned rs = read_huffman_symbol_no_refill(ac_table, &bits);
unsigned r = rs >> 4;
unsigned s = rs & 0xf;
}
if (rs == 0xf0) {
/* 16 zero coefficients */
+ possibly_refill(&bits, DEHUF_TABLE_BITS);
i += 15;
continue;
}
i += r;
- possibly_refill(&bits, s);
+ possibly_refill(&bits, s + DEHUF_TABLE_BITS);
coeff[unzigzag[i]] = extend(read_bits(&bits, s), s);
}
uint8_t pixdata[DCTSIZE2];
idct_choice(coeff, image->idct_data[image->qtable[cn]], pixdata);
- unsigned real_x = (mcu_x * image->hsample[cn] + local_xb) * DCTSIZE;
- unsigned real_y = (mcu_y * image->vsample[cn] + local_yb) * DCTSIZE;
- uint8_t* dest_pixdata = image->pixel_data[cn] + real_y * stride + real_x;
- for (unsigned y = 0; y < DCTSIZE; ++y, dest_pixdata += stride) {
+ uint8_t* dest_pixdata = pixel_write_pointer;
+ for (unsigned y = 0; y < DCTSIZE; ++y, dest_pixdata += image->stride[cn]) {
memcpy(dest_pixdata, pixdata + y * DCTSIZE, DCTSIZE);
}
}
}
+ image->pixel_write_pointer[cn] += DCTSIZE * image->hsample[cn];
}
-
+
if (++mcu_x == image->num_blocks_horizontal) {
++mcu_y;
mcu_x = 0;
+
+ for (unsigned c = 0; c < num_components; ++c) {
+ unsigned cn = component_num[c];
+ image->pixel_write_pointer[cn] += (image->vsample[cn] * DCTSIZE - 1) * image->stride[cn];
+ }
// Some debug code.
const int c = 1;