Mercurial > libavcodec.hg
comparison iff.c @ 11725:e9537b2d70ce libavcodec
Grayscale support. Patch by Sebastian Vater <cdgs basty googlemail com>.
author | rbultje |
---|---|
date | Thu, 13 May 2010 19:16:03 +0000 |
parents | 92f4ca7a4002 |
children | 7c35c611faa4 |
comparison
equal
deleted
inserted
replaced
11724:5b64cfa35e9c | 11725:e9537b2d70ce |
---|---|
108 LUT32(20), LUT32(21), LUT32(22), LUT32(23), | 108 LUT32(20), LUT32(21), LUT32(22), LUT32(23), |
109 LUT32(24), LUT32(25), LUT32(26), LUT32(27), | 109 LUT32(24), LUT32(25), LUT32(26), LUT32(27), |
110 LUT32(28), LUT32(29), LUT32(30), LUT32(31), | 110 LUT32(28), LUT32(29), LUT32(30), LUT32(31), |
111 }; | 111 }; |
112 | 112 |
113 // Gray to RGB, required for palette table of grayscale images with bpp < 8 | |
114 static av_always_inline uint32_t gray2rgb(const uint32_t x) { | |
115 return x << 16 | x << 8 | x; | |
116 } | |
117 | |
113 /** | 118 /** |
114 * Convert CMAP buffer (stored in extradata) to lavc palette format | 119 * Convert CMAP buffer (stored in extradata) to lavc palette format |
115 */ | 120 */ |
116 int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) | 121 int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) |
117 { | 122 { |
123 } | 128 } |
124 | 129 |
125 count = 1 << avctx->bits_per_coded_sample; | 130 count = 1 << avctx->bits_per_coded_sample; |
126 // If extradata is smaller than actually needed, fill the remaining with black. | 131 // If extradata is smaller than actually needed, fill the remaining with black. |
127 count = FFMIN(avctx->extradata_size / 3, count); | 132 count = FFMIN(avctx->extradata_size / 3, count); |
133 if (count) { | |
128 for (i=0; i < count; i++) { | 134 for (i=0; i < count; i++) { |
129 pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 ); | 135 pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 ); |
130 } | 136 } |
137 } else { // Create gray-scale color palette for bps < 8 | |
138 count = 1 << avctx->bits_per_coded_sample; | |
139 | |
140 for (i=0; i < count; i++) { | |
141 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample); | |
142 } | |
143 } | |
131 return 0; | 144 return 0; |
132 } | 145 } |
133 | 146 |
134 static av_cold int decode_init(AVCodecContext *avctx) | 147 static av_cold int decode_init(AVCodecContext *avctx) |
135 { | 148 { |
136 IffContext *s = avctx->priv_data; | 149 IffContext *s = avctx->priv_data; |
137 int err; | 150 int err; |
138 | 151 |
139 if (avctx->bits_per_coded_sample <= 8) { | 152 if (avctx->bits_per_coded_sample <= 8) { |
140 avctx->pix_fmt = PIX_FMT_PAL8; | 153 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 || |
154 avctx->extradata_size) ? PIX_FMT_PAL8 | |
155 : PIX_FMT_GRAY8; | |
141 } else if (avctx->bits_per_coded_sample <= 32) { | 156 } else if (avctx->bits_per_coded_sample <= 32) { |
142 avctx->pix_fmt = PIX_FMT_BGR32; | 157 avctx->pix_fmt = PIX_FMT_BGR32; |
143 } else { | 158 } else { |
144 return AVERROR_INVALIDDATA; | 159 return AVERROR_INVALIDDATA; |
145 } | 160 } |
155 if ((err = avctx->get_buffer(avctx, &s->frame) < 0)) { | 170 if ((err = avctx->get_buffer(avctx, &s->frame) < 0)) { |
156 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 171 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
157 return err; | 172 return err; |
158 } | 173 } |
159 | 174 |
160 return avctx->bits_per_coded_sample <= 8 ? | 175 return (avctx->bits_per_coded_sample <= 8 && |
176 avctx->pix_fmt != PIX_FMT_GRAY8) ? | |
161 ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0; | 177 ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0; |
162 } | 178 } |
163 | 179 |
164 /** | 180 /** |
165 * Decode interleaved plane buffer up to 8bpp | 181 * Decode interleaved plane buffer up to 8bpp |
217 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 233 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
218 return -1; | 234 return -1; |
219 } | 235 } |
220 | 236 |
221 if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved | 237 if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved |
222 if (avctx->pix_fmt == PIX_FMT_PAL8) { | 238 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { |
223 for(y = 0; y < avctx->height; y++ ) { | 239 for(y = 0; y < avctx->height; y++ ) { |
224 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; | 240 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; |
225 memset(row, 0, avctx->width); | 241 memset(row, 0, avctx->width); |
226 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { | 242 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { |
227 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane); | 243 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane); |
236 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane); | 252 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane); |
237 buf += s->planesize; | 253 buf += s->planesize; |
238 } | 254 } |
239 } | 255 } |
240 } | 256 } |
241 } else if (avctx->pix_fmt == PIX_FMT_PAL8) { // IFF-PBM | 257 } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM |
242 for(y = 0; y < avctx->height; y++ ) { | 258 for(y = 0; y < avctx->height; y++ ) { |
243 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]]; | 259 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]]; |
244 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf)); | 260 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf)); |
245 buf += avctx->width; | 261 buf += avctx->width; |
246 } | 262 } |
265 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 281 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
266 return -1; | 282 return -1; |
267 } | 283 } |
268 | 284 |
269 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved | 285 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved |
270 if (avctx->pix_fmt == PIX_FMT_PAL8) { | 286 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { |
271 for(y = 0; y < avctx->height ; y++ ) { | 287 for(y = 0; y < avctx->height ; y++ ) { |
272 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; | 288 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; |
273 memset(row, 0, avctx->width); | 289 memset(row, 0, avctx->width); |
274 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { | 290 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { |
275 for(x = 0; x < s->planesize && buf < buf_end; ) { | 291 for(x = 0; x < s->planesize && buf < buf_end; ) { |