comparison iff.c @ 11175:30856cadb01b libavcodec

IFF bitmap n-bit color support
author pross
date Mon, 15 Feb 2010 11:26:35 +0000
parents 85a1b00a2413
children a4c6587e2c27
comparison
equal deleted inserted replaced
11174:421c6cd2fb9f 11175:30856cadb01b
24 * IFF PBM/ILBM bitmap decoder 24 * IFF PBM/ILBM bitmap decoder
25 */ 25 */
26 26
27 #include "bytestream.h" 27 #include "bytestream.h"
28 #include "avcodec.h" 28 #include "avcodec.h"
29 #include "get_bits.h"
30
31 typedef struct {
32 AVFrame frame;
33 int planesize;
34 uint8_t * planebuf;
35 } IffContext;
29 36
30 /** 37 /**
31 * Convert CMAP buffer (stored in extradata) to lavc palette format 38 * Convert CMAP buffer (stored in extradata) to lavc palette format
32 */ 39 */
33 int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) 40 int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
43 if (avctx->extradata_size < count * 3) { 50 if (avctx->extradata_size < count * 3) {
44 av_log(avctx, AV_LOG_ERROR, "palette data underflow\n"); 51 av_log(avctx, AV_LOG_ERROR, "palette data underflow\n");
45 return AVERROR_INVALIDDATA; 52 return AVERROR_INVALIDDATA;
46 } 53 }
47 for (i=0; i < count; i++) { 54 for (i=0; i < count; i++) {
48 pal[i] = AV_RB24( avctx->extradata + i*3 ); 55 pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
49 } 56 }
50 return 0; 57 return 0;
51 } 58 }
52 59
53 static av_cold int decode_init(AVCodecContext *avctx) 60 static av_cold int decode_init(AVCodecContext *avctx)
54 { 61 {
55 AVFrame *frame = avctx->priv_data; 62 IffContext *s = avctx->priv_data;
56 63
57 avctx->pix_fmt = PIX_FMT_PAL8; 64 if (avctx->bits_per_coded_sample <= 8) {
58 frame->reference = 1; 65 avctx->pix_fmt = PIX_FMT_PAL8;
59 66 } else if (avctx->bits_per_coded_sample <= 32) {
60 if (avctx->get_buffer(avctx, frame) < 0) { 67 avctx->pix_fmt = PIX_FMT_BGR32;
68 } else {
69 return AVERROR_INVALIDDATA;
70 }
71
72 s->planesize = avctx->width / 8;
73 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
74 if (!s->planebuf)
75 return AVERROR(ENOMEM);
76
77 s->frame.reference = 1;
78 if (avctx->get_buffer(avctx, &s->frame) < 0) {
61 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 79 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
62 return AVERROR_UNKNOWN; 80 return AVERROR_UNKNOWN;
63 } 81 }
64 return ff_cmap_read_palette(avctx, (uint32_t*)frame->data[1]); 82
83 return avctx->bits_per_coded_sample <= 8 ?
84 ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0;
65 } 85 }
66 86
67 /** 87 /**
68 * Interleaved memcpy 88 * Decode interleaved plane buffer
69 */ 89 * @param dst Destination buffer
70 static void imemcpy(uint8_t *dst, const uint8_t const *buf, int x, int bps, int plane, int length) 90 * @param buf Source buffer
71 { 91 * @param buf_size
72 int i, b; 92 * @param bps bits_per_coded_sample
73 for(i = 0; i < length; i++) { 93 * @param plane plane number to decode as
74 int value = buf[i]; 94 */
75 for (b = 0; b < bps; b++) { 95 #define DECLARE_DECODEPLANE(suffix, type) \
76 if (value & (1<<b)) 96 static void decodeplane##suffix(void *dst, const uint8_t const *buf, int buf_size, int bps, int plane) \
77 dst[ (x+i)*bps + 7 - b] |= 1<<plane; 97 { \
78 } 98 GetBitContext gb; \
79 } 99 int i, b; \
80 } 100 init_get_bits(&gb, buf, buf_size * 8); \
81 101 for(i = 0; i < (buf_size * 8 + bps - 1) / bps; i++) { \
82 /** 102 for (b = 0; b < bps; b++) { \
83 * Interleaved memset 103 ((type *)dst)[ i*bps + b ] |= get_bits1(&gb) << plane; \
84 */ 104 } \
85 static void imemset(uint8_t *dst, int value, int x, int bps, int plane, int length) 105 } \
86 { 106 }
87 int i, b; 107 DECLARE_DECODEPLANE(8, uint8_t)
88 for(i = 0; i < length; i++) { 108 DECLARE_DECODEPLANE(32, uint32_t)
89 for (b = 0; b < bps; b++) {
90 if (value & (1<<b))
91 dst[ (x+i)*bps + 7 - b] |= 1<<plane;
92 }
93 }
94 }
95 109
96 static int decode_frame_ilbm(AVCodecContext *avctx, 110 static int decode_frame_ilbm(AVCodecContext *avctx,
97 void *data, int *data_size, 111 void *data, int *data_size,
98 AVPacket *avpkt) 112 AVPacket *avpkt)
99 { 113 {
100 AVFrame *frame = avctx->priv_data; 114 IffContext *s = avctx->priv_data;
101 const uint8_t *buf = avpkt->data; 115 const uint8_t *buf = avpkt->data;
102 int buf_size = avpkt->size; 116 int buf_size = avpkt->size;
103 int planewidth = avctx->width / avctx->bits_per_coded_sample;
104 int y, plane; 117 int y, plane;
105 118
106 if (avctx->reget_buffer(avctx, frame) < 0){ 119 if (avctx->reget_buffer(avctx, &s->frame) < 0){
107 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 120 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
108 return -1; 121 return -1;
109 } 122 }
110 123
111 if (buf_size < avctx->width * avctx->height) { 124 if (buf_size < avctx->width * avctx->height) {
112 av_log(avctx, AV_LOG_ERROR, "buffer underflow\n"); 125 av_log(avctx, AV_LOG_ERROR, "buffer underflow\n");
113 return -1; 126 return -1;
114 } 127 }
115 128
116 for(y = 0; y < avctx->height; y++ ) { 129 for(y = 0; y < avctx->height; y++ ) {
117 uint8_t *row = &frame->data[0][ y*frame->linesize[0] ]; 130 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
118 memset(row, 0, avctx->width); 131 memset(row, 0, avctx->pix_fmt == PIX_FMT_PAL8 ? avctx->width : (avctx->width * 4));
119 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { 132 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
120 imemcpy(row, buf, 0, avctx->bits_per_coded_sample, plane, planewidth); 133 if (avctx->pix_fmt == PIX_FMT_PAL8) {
121 buf += planewidth; 134 decodeplane8(row, buf, s->planesize, avctx->bits_per_coded_sample, plane);
135 } else { // PIX_FMT_BGR32
136 decodeplane32(row, buf, s->planesize, avctx->bits_per_coded_sample, plane);
137 }
138 buf += s->planesize;
122 } 139 }
123 } 140 }
124 141
125 *data_size = sizeof(AVFrame); 142 *data_size = sizeof(AVFrame);
126 *(AVFrame*)data = *frame; 143 *(AVFrame*)data = s->frame;
127 return buf_size; 144 return buf_size;
128 } 145 }
129 146
130 static int decode_frame_byterun1(AVCodecContext *avctx, 147 static int decode_frame_byterun1(AVCodecContext *avctx,
131 void *data, int *data_size, 148 void *data, int *data_size,
132 AVPacket *avpkt) 149 AVPacket *avpkt)
133 { 150 {
134 AVFrame *frame = avctx->priv_data; 151 IffContext *s = avctx->priv_data;
135 const uint8_t *buf = avpkt->data; 152 const uint8_t *buf = avpkt->data;
136 int buf_size = avpkt->size; 153 int buf_size = avpkt->size;
137 const uint8_t *buf_end = buf+buf_size; 154 const uint8_t *buf_end = buf+buf_size;
138 int planewidth = avctx->width / avctx->bits_per_coded_sample;
139 int y, plane, x; 155 int y, plane, x;
140 156
141 if (avctx->reget_buffer(avctx, frame) < 0){ 157 if (avctx->reget_buffer(avctx, &s->frame) < 0){
142 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 158 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
143 return -1; 159 return -1;
144 } 160 }
145 161
146 for(y = 0; y < avctx->height ; y++ ) { 162 for(y = 0; y < avctx->height ; y++ ) {
147 uint8_t *row = &frame->data[0][ y*frame->linesize[0] ]; 163 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
148 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved 164 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
149 memset(row, 0, avctx->width); 165 memset(row, 0, avctx->pix_fmt == PIX_FMT_PAL8 ? avctx->width : (avctx->width * 4));
150 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { 166 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
151 for(x = 0; x < planewidth && buf < buf_end; ) { 167 for(x = 0; x < s->planesize && buf < buf_end; ) {
152 int8_t value = *buf++; 168 int8_t value = *buf++;
153 int length; 169 int length;
154 if (value >= 0) { 170 if (value >= 0) {
155 length = value + 1; 171 length = value + 1;
156 imemcpy(row, buf, x, avctx->bits_per_coded_sample, plane, FFMIN3(length, buf_end - buf, planewidth - x)); 172 memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf));
157 buf += length; 173 buf += length;
158 } else if (value > -128) { 174 } else if (value > -128) {
159 length = -value + 1; 175 length = -value + 1;
160 imemset(row, *buf++, x, avctx->bits_per_coded_sample, plane, FFMIN(length, planewidth - x)); 176 memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x));
161 } else { //noop 177 } else { //noop
162 continue; 178 continue;
163 } 179 }
164 x += length; 180 x += length;
181 }
182 if (avctx->pix_fmt == PIX_FMT_PAL8) {
183 decodeplane8(row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane);
184 } else { //PIX_FMT_BGR32
185 decodeplane32(row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane);
165 } 186 }
166 } 187 }
167 } else { 188 } else {
168 for(x = 0; x < avctx->width && buf < buf_end; ) { 189 for(x = 0; x < avctx->width && buf < buf_end; ) {
169 int8_t value = *buf++; 190 int8_t value = *buf++;
182 } 203 }
183 } 204 }
184 } 205 }
185 206
186 *data_size = sizeof(AVFrame); 207 *data_size = sizeof(AVFrame);
187 *(AVFrame*)data = *frame; 208 *(AVFrame*)data = s->frame;
188 return buf_size; 209 return buf_size;
189 } 210 }
190 211
191 static av_cold int decode_end(AVCodecContext *avctx) 212 static av_cold int decode_end(AVCodecContext *avctx)
192 { 213 {
193 AVFrame *frame = avctx->priv_data; 214 IffContext *s = avctx->priv_data;
194 if (frame->data[0]) 215 if (s->frame.data[0])
195 avctx->release_buffer(avctx, frame); 216 avctx->release_buffer(avctx, &s->frame);
217 av_freep(&s->planebuf);
196 return 0; 218 return 0;
197 } 219 }
198 220
199 AVCodec iff_ilbm_decoder = { 221 AVCodec iff_ilbm_decoder = {
200 "iff_ilbm", 222 "iff_ilbm",
201 CODEC_TYPE_VIDEO, 223 CODEC_TYPE_VIDEO,
202 CODEC_ID_IFF_ILBM, 224 CODEC_ID_IFF_ILBM,
203 sizeof(AVFrame), 225 sizeof(IffContext),
204 decode_init, 226 decode_init,
205 NULL, 227 NULL,
206 decode_end, 228 decode_end,
207 decode_frame_ilbm, 229 decode_frame_ilbm,
208 CODEC_CAP_DR1, 230 CODEC_CAP_DR1,
211 233
212 AVCodec iff_byterun1_decoder = { 234 AVCodec iff_byterun1_decoder = {
213 "iff_byterun1", 235 "iff_byterun1",
214 CODEC_TYPE_VIDEO, 236 CODEC_TYPE_VIDEO,
215 CODEC_ID_IFF_BYTERUN1, 237 CODEC_ID_IFF_BYTERUN1,
216 sizeof(AVFrame), 238 sizeof(IffContext),
217 decode_init, 239 decode_init,
218 NULL, 240 NULL,
219 decode_end, 241 decode_end,
220 decode_frame_byterun1, 242 decode_frame_byterun1,
221 CODEC_CAP_DR1, 243 CODEC_CAP_DR1,