|
|
|
@ -38,6 +38,7 @@ |
|
|
|
|
* \param block where data is written to |
|
|
|
|
* \param scan array containing the mapping stream address -> block position |
|
|
|
|
* \param quant quantization factors |
|
|
|
|
* \return 0 means the block is not coded, < 0 means an error occurred. |
|
|
|
|
* |
|
|
|
|
* Note: GetBitContext is used to make the code simpler, since all data is |
|
|
|
|
* aligned this could be done faster in a different way, e.g. as it is done |
|
|
|
@ -56,7 +57,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc |
|
|
|
|
// number of non-zero coefficients
|
|
|
|
|
coeff = get_bits(gb, 6); |
|
|
|
|
if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) |
|
|
|
|
return 0; |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
// normally we would only need to clear the (63 - coeff) last values,
|
|
|
|
|
// but since we do not know where they are we just clear the whole block
|
|
|
|
@ -73,7 +74,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc |
|
|
|
|
// 4 bits per coefficient
|
|
|
|
|
ALIGN(4); |
|
|
|
|
if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) |
|
|
|
|
return 0; |
|
|
|
|
return -1; |
|
|
|
|
while (coeff) { |
|
|
|
|
ac = get_sbits(gb, 4); |
|
|
|
|
if (ac == -8) |
|
|
|
@ -84,7 +85,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc |
|
|
|
|
// 8 bits per coefficient
|
|
|
|
|
ALIGN(8); |
|
|
|
|
if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) |
|
|
|
|
return 0; |
|
|
|
|
return -1; |
|
|
|
|
while (coeff) { |
|
|
|
|
ac = get_sbits(gb, 8); |
|
|
|
|
PUT_COEFF(ac); |
|
|
|
@ -114,22 +115,22 @@ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, |
|
|
|
|
for (y = 0; y < h; y++) { |
|
|
|
|
for (x = 0; x < w; x++) { |
|
|
|
|
DCTELEM *block = c->block; |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant)) |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant) > 0) |
|
|
|
|
c->dsp->idct_put(y1, f->linesize[0], block); |
|
|
|
|
y1 += 8; |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant)) |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant) > 0) |
|
|
|
|
c->dsp->idct_put(y1, f->linesize[0], block); |
|
|
|
|
y1 += 8; |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant)) |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant) > 0) |
|
|
|
|
c->dsp->idct_put(y2, f->linesize[0], block); |
|
|
|
|
y2 += 8; |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant)) |
|
|
|
|
if (get_block(&gb, block, c->scan, c->lquant) > 0) |
|
|
|
|
c->dsp->idct_put(y2, f->linesize[0], block); |
|
|
|
|
y2 += 8; |
|
|
|
|
if (get_block(&gb, block, c->scan, c->cquant)) |
|
|
|
|
if (get_block(&gb, block, c->scan, c->cquant) > 0) |
|
|
|
|
c->dsp->idct_put(u, f->linesize[1], block); |
|
|
|
|
u += 8; |
|
|
|
|
if (get_block(&gb, block, c->scan, c->cquant)) |
|
|
|
|
if (get_block(&gb, block, c->scan, c->cquant) > 0) |
|
|
|
|
c->dsp->idct_put(v, f->linesize[2], block); |
|
|
|
|
v += 8; |
|
|
|
|
} |
|
|
|
|