Mercurial > libavcodec.hg
annotate iff.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | ad4ac2a6373f |
children | 5b9d41da4152 |
rev | line source |
---|---|
11074 | 1 /* |
2 * IFF PBM/ILBM bitmap decoder | |
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org> | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
23 * @file libavcodec/iff.c | |
24 * IFF PBM/ILBM bitmap decoder | |
25 */ | |
26 | |
27 #include "bytestream.h" | |
28 #include "avcodec.h" | |
11175 | 29 #include "get_bits.h" |
30 | |
31 typedef struct { | |
32 AVFrame frame; | |
33 int planesize; | |
34 uint8_t * planebuf; | |
35 } IffContext; | |
11074 | 36 |
37 /** | |
38 * Convert CMAP buffer (stored in extradata) to lavc palette format | |
39 */ | |
40 int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) | |
41 { | |
42 int count, i; | |
43 | |
44 if (avctx->bits_per_coded_sample > 8) { | |
45 av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n"); | |
46 return AVERROR_INVALIDDATA; | |
47 } | |
48 | |
49 count = 1 << avctx->bits_per_coded_sample; | |
50 if (avctx->extradata_size < count * 3) { | |
51 av_log(avctx, AV_LOG_ERROR, "palette data underflow\n"); | |
52 return AVERROR_INVALIDDATA; | |
53 } | |
54 for (i=0; i < count; i++) { | |
11175 | 55 pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 ); |
11074 | 56 } |
57 return 0; | |
58 } | |
59 | |
60 static av_cold int decode_init(AVCodecContext *avctx) | |
61 { | |
11175 | 62 IffContext *s = avctx->priv_data; |
11074 | 63 |
11175 | 64 if (avctx->bits_per_coded_sample <= 8) { |
65 avctx->pix_fmt = PIX_FMT_PAL8; | |
66 } else if (avctx->bits_per_coded_sample <= 32) { | |
67 avctx->pix_fmt = PIX_FMT_BGR32; | |
68 } else { | |
69 return AVERROR_INVALIDDATA; | |
70 } | |
11074 | 71 |
11175 | 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) { | |
11074 | 79 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
80 return AVERROR_UNKNOWN; | |
81 } | |
11175 | 82 |
83 return avctx->bits_per_coded_sample <= 8 ? | |
84 ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0; | |
11074 | 85 } |
86 | |
87 /** | |
11175 | 88 * Decode interleaved plane buffer |
89 * @param dst Destination buffer | |
90 * @param buf Source buffer | |
91 * @param buf_size | |
92 * @param bps bits_per_coded_sample | |
93 * @param plane plane number to decode as | |
11074 | 94 */ |
11175 | 95 #define DECLARE_DECODEPLANE(suffix, type) \ |
11336 | 96 static void decodeplane##suffix(void *dst, const uint8_t *const buf, int buf_size, int bps, int plane) \ |
11175 | 97 { \ |
98 GetBitContext gb; \ | |
99 int i, b; \ | |
100 init_get_bits(&gb, buf, buf_size * 8); \ | |
101 for(i = 0; i < (buf_size * 8 + bps - 1) / bps; i++) { \ | |
102 for (b = 0; b < bps; b++) { \ | |
103 ((type *)dst)[ i*bps + b ] |= get_bits1(&gb) << plane; \ | |
104 } \ | |
105 } \ | |
11074 | 106 } |
11175 | 107 DECLARE_DECODEPLANE(8, uint8_t) |
108 DECLARE_DECODEPLANE(32, uint32_t) | |
11074 | 109 |
110 static int decode_frame_ilbm(AVCodecContext *avctx, | |
111 void *data, int *data_size, | |
112 AVPacket *avpkt) | |
113 { | |
11175 | 114 IffContext *s = avctx->priv_data; |
11074 | 115 const uint8_t *buf = avpkt->data; |
116 int buf_size = avpkt->size; | |
11187 | 117 const uint8_t *buf_end = buf+buf_size; |
11074 | 118 int y, plane; |
119 | |
11175 | 120 if (avctx->reget_buffer(avctx, &s->frame) < 0){ |
11074 | 121 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
122 return -1; | |
123 } | |
124 | |
125 for(y = 0; y < avctx->height; y++ ) { | |
11175 | 126 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; |
127 memset(row, 0, avctx->pix_fmt == PIX_FMT_PAL8 ? avctx->width : (avctx->width * 4)); | |
11187 | 128 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { |
11175 | 129 if (avctx->pix_fmt == PIX_FMT_PAL8) { |
11187 | 130 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), avctx->bits_per_coded_sample, plane); |
11175 | 131 } else { // PIX_FMT_BGR32 |
11187 | 132 decodeplane32(row, buf, FFMIN(s->planesize, buf_end - buf), avctx->bits_per_coded_sample, plane); |
11175 | 133 } |
134 buf += s->planesize; | |
11074 | 135 } |
136 } | |
137 | |
138 *data_size = sizeof(AVFrame); | |
11175 | 139 *(AVFrame*)data = s->frame; |
11074 | 140 return buf_size; |
141 } | |
142 | |
143 static int decode_frame_byterun1(AVCodecContext *avctx, | |
144 void *data, int *data_size, | |
145 AVPacket *avpkt) | |
146 { | |
11175 | 147 IffContext *s = avctx->priv_data; |
11074 | 148 const uint8_t *buf = avpkt->data; |
149 int buf_size = avpkt->size; | |
150 const uint8_t *buf_end = buf+buf_size; | |
151 int y, plane, x; | |
152 | |
11175 | 153 if (avctx->reget_buffer(avctx, &s->frame) < 0){ |
11074 | 154 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
155 return -1; | |
156 } | |
157 | |
158 for(y = 0; y < avctx->height ; y++ ) { | |
11175 | 159 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; |
11074 | 160 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved |
11175 | 161 memset(row, 0, avctx->pix_fmt == PIX_FMT_PAL8 ? avctx->width : (avctx->width * 4)); |
11074 | 162 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { |
11175 | 163 for(x = 0; x < s->planesize && buf < buf_end; ) { |
11124
85a1b00a2413
Use int8_t instead of char, the signedness of char can differ between systems.
reimar
parents:
11074
diff
changeset
|
164 int8_t value = *buf++; |
11074 | 165 int length; |
166 if (value >= 0) { | |
167 length = value + 1; | |
11175 | 168 memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf)); |
11074 | 169 buf += length; |
170 } else if (value > -128) { | |
171 length = -value + 1; | |
11175 | 172 memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x)); |
11074 | 173 } else { //noop |
174 continue; | |
175 } | |
176 x += length; | |
177 } | |
11175 | 178 if (avctx->pix_fmt == PIX_FMT_PAL8) { |
179 decodeplane8(row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane); | |
180 } else { //PIX_FMT_BGR32 | |
181 decodeplane32(row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane); | |
182 } | |
11074 | 183 } |
184 } else { | |
185 for(x = 0; x < avctx->width && buf < buf_end; ) { | |
11124
85a1b00a2413
Use int8_t instead of char, the signedness of char can differ between systems.
reimar
parents:
11074
diff
changeset
|
186 int8_t value = *buf++; |
11074 | 187 int length; |
188 if (value >= 0) { | |
189 length = value + 1; | |
190 memcpy(row + x, buf, FFMIN3(length, buf_end - buf, avctx->width - x)); | |
191 buf += length; | |
192 } else if (value > -128) { | |
193 length = -value + 1; | |
194 memset(row + x, *buf++, FFMIN(length, avctx->width - x)); | |
195 } else { //noop | |
196 continue; | |
197 } | |
198 x += length; | |
199 } | |
200 } | |
201 } | |
202 | |
203 *data_size = sizeof(AVFrame); | |
11175 | 204 *(AVFrame*)data = s->frame; |
11074 | 205 return buf_size; |
206 } | |
207 | |
208 static av_cold int decode_end(AVCodecContext *avctx) | |
209 { | |
11175 | 210 IffContext *s = avctx->priv_data; |
211 if (s->frame.data[0]) | |
212 avctx->release_buffer(avctx, &s->frame); | |
213 av_freep(&s->planebuf); | |
11074 | 214 return 0; |
215 } | |
216 | |
217 AVCodec iff_ilbm_decoder = { | |
218 "iff_ilbm", | |
219 CODEC_TYPE_VIDEO, | |
220 CODEC_ID_IFF_ILBM, | |
11175 | 221 sizeof(IffContext), |
11074 | 222 decode_init, |
223 NULL, | |
224 decode_end, | |
225 decode_frame_ilbm, | |
226 CODEC_CAP_DR1, | |
227 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"), | |
228 }; | |
229 | |
230 AVCodec iff_byterun1_decoder = { | |
231 "iff_byterun1", | |
232 CODEC_TYPE_VIDEO, | |
233 CODEC_ID_IFF_BYTERUN1, | |
11175 | 234 sizeof(IffContext), |
11074 | 235 decode_init, |
236 NULL, | |
237 decode_end, | |
238 decode_frame_byterun1, | |
239 CODEC_CAP_DR1, | |
240 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"), | |
241 }; |