Mercurial > libavcodec.hg
comparison rtjpeg.c @ 9701:31f48c034eae libavcodec
Distinguish between non-coded blocks and decode errors in rtjpeg's get_block
| author | reimar |
|---|---|
| date | Sun, 24 May 2009 09:06:06 +0000 |
| parents | 1a8821c5d28d |
| children |
comparison
equal
deleted
inserted
replaced
| 9700:1a8821c5d28d | 9701:31f48c034eae |
|---|---|
| 36 * \brief read one block from stream | 36 * \brief read one block from stream |
| 37 * \param gb contains stream data | 37 * \param gb contains stream data |
| 38 * \param block where data is written to | 38 * \param block where data is written to |
| 39 * \param scan array containing the mapping stream address -> block position | 39 * \param scan array containing the mapping stream address -> block position |
| 40 * \param quant quantization factors | 40 * \param quant quantization factors |
| 41 * \return 0 means the block is not coded, < 0 means an error occurred. | |
| 41 * | 42 * |
| 42 * Note: GetBitContext is used to make the code simpler, since all data is | 43 * Note: GetBitContext is used to make the code simpler, since all data is |
| 43 * aligned this could be done faster in a different way, e.g. as it is done | 44 * aligned this could be done faster in a different way, e.g. as it is done |
| 44 * in MPlayer libmpcodecs/native/rtjpegn.c. | 45 * in MPlayer libmpcodecs/native/rtjpegn.c. |
| 45 */ | 46 */ |
| 54 return 0; | 55 return 0; |
| 55 | 56 |
| 56 // number of non-zero coefficients | 57 // number of non-zero coefficients |
| 57 coeff = get_bits(gb, 6); | 58 coeff = get_bits(gb, 6); |
| 58 if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) | 59 if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) |
| 59 return 0; | 60 return -1; |
| 60 | 61 |
| 61 // normally we would only need to clear the (63 - coeff) last values, | 62 // normally we would only need to clear the (63 - coeff) last values, |
| 62 // but since we do not know where they are we just clear the whole block | 63 // but since we do not know where they are we just clear the whole block |
| 63 memset(block, 0, 64 * sizeof(DCTELEM)); | 64 memset(block, 0, 64 * sizeof(DCTELEM)); |
| 64 | 65 |
| 71 } | 72 } |
| 72 | 73 |
| 73 // 4 bits per coefficient | 74 // 4 bits per coefficient |
| 74 ALIGN(4); | 75 ALIGN(4); |
| 75 if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) | 76 if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) |
| 76 return 0; | 77 return -1; |
| 77 while (coeff) { | 78 while (coeff) { |
| 78 ac = get_sbits(gb, 4); | 79 ac = get_sbits(gb, 4); |
| 79 if (ac == -8) | 80 if (ac == -8) |
| 80 break; // continue with more bits | 81 break; // continue with more bits |
| 81 PUT_COEFF(ac); | 82 PUT_COEFF(ac); |
| 82 } | 83 } |
| 83 | 84 |
| 84 // 8 bits per coefficient | 85 // 8 bits per coefficient |
| 85 ALIGN(8); | 86 ALIGN(8); |
| 86 if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) | 87 if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) |
| 87 return 0; | 88 return -1; |
| 88 while (coeff) { | 89 while (coeff) { |
| 89 ac = get_sbits(gb, 8); | 90 ac = get_sbits(gb, 8); |
| 90 PUT_COEFF(ac); | 91 PUT_COEFF(ac); |
| 91 } | 92 } |
| 92 | 93 |
| 112 uint8_t *u = f->data[1], *v = f->data[2]; | 113 uint8_t *u = f->data[1], *v = f->data[2]; |
| 113 init_get_bits(&gb, buf, buf_size * 8); | 114 init_get_bits(&gb, buf, buf_size * 8); |
| 114 for (y = 0; y < h; y++) { | 115 for (y = 0; y < h; y++) { |
| 115 for (x = 0; x < w; x++) { | 116 for (x = 0; x < w; x++) { |
| 116 DCTELEM *block = c->block; | 117 DCTELEM *block = c->block; |
| 117 if (get_block(&gb, block, c->scan, c->lquant)) | 118 if (get_block(&gb, block, c->scan, c->lquant) > 0) |
| 118 c->dsp->idct_put(y1, f->linesize[0], block); | 119 c->dsp->idct_put(y1, f->linesize[0], block); |
| 119 y1 += 8; | 120 y1 += 8; |
| 120 if (get_block(&gb, block, c->scan, c->lquant)) | 121 if (get_block(&gb, block, c->scan, c->lquant) > 0) |
| 121 c->dsp->idct_put(y1, f->linesize[0], block); | 122 c->dsp->idct_put(y1, f->linesize[0], block); |
| 122 y1 += 8; | 123 y1 += 8; |
| 123 if (get_block(&gb, block, c->scan, c->lquant)) | 124 if (get_block(&gb, block, c->scan, c->lquant) > 0) |
| 124 c->dsp->idct_put(y2, f->linesize[0], block); | 125 c->dsp->idct_put(y2, f->linesize[0], block); |
| 125 y2 += 8; | 126 y2 += 8; |
| 126 if (get_block(&gb, block, c->scan, c->lquant)) | 127 if (get_block(&gb, block, c->scan, c->lquant) > 0) |
| 127 c->dsp->idct_put(y2, f->linesize[0], block); | 128 c->dsp->idct_put(y2, f->linesize[0], block); |
| 128 y2 += 8; | 129 y2 += 8; |
| 129 if (get_block(&gb, block, c->scan, c->cquant)) | 130 if (get_block(&gb, block, c->scan, c->cquant) > 0) |
| 130 c->dsp->idct_put(u, f->linesize[1], block); | 131 c->dsp->idct_put(u, f->linesize[1], block); |
| 131 u += 8; | 132 u += 8; |
| 132 if (get_block(&gb, block, c->scan, c->cquant)) | 133 if (get_block(&gb, block, c->scan, c->cquant) > 0) |
| 133 c->dsp->idct_put(v, f->linesize[2], block); | 134 c->dsp->idct_put(v, f->linesize[2], block); |
| 134 v += 8; | 135 v += 8; |
| 135 } | 136 } |
| 136 y1 += 2 * 8 * (f->linesize[0] - w); | 137 y1 += 2 * 8 * (f->linesize[0] - w); |
| 137 y2 += 2 * 8 * (f->linesize[0] - w); | 138 y2 += 2 * 8 * (f->linesize[0] - w); |
