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