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); |