Mercurial > libavcodec.hg
annotate pnmdec.c @ 12266:48d6738904a9 libavcodec
Fix SPLATB_REG mess. Used to be a if/elseif/elseif/elseif spaghetti, so this
splits it into small optimization-specific macros which are selected for each
DSP function. The advantage of this approach is that the sse4 functions now
use the ssse3 codepath also without needing an explicit sse4 codepath.
author | rbultje |
---|---|
date | Sat, 24 Jul 2010 19:33:05 +0000 |
parents | 8b28e74de2c0 |
children |
rev | line source |
---|---|
10465 | 1 /* |
2 * PNM image format | |
3 * Copyright (c) 2002, 2003 Fabrice Bellard | |
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 #include "avcodec.h" | |
23 #include "bytestream.h" | |
10612 | 24 #include "put_bits.h" |
10465 | 25 #include "pnm.h" |
26 | |
27 | |
28 static int pnm_decode_frame(AVCodecContext *avctx, void *data, | |
29 int *data_size, AVPacket *avpkt) | |
30 { | |
31 const uint8_t *buf = avpkt->data; | |
32 int buf_size = avpkt->size; | |
33 PNMContext * const s = avctx->priv_data; | |
34 AVFrame *picture = data; | |
35 AVFrame * const p = (AVFrame*)&s->picture; | |
10612 | 36 int i, j, n, linesize, h, upgrade = 0; |
10465 | 37 unsigned char *ptr; |
10612 | 38 int components, sample_len; |
10465 | 39 |
40 s->bytestream_start = | |
41 s->bytestream = buf; | |
42 s->bytestream_end = buf + buf_size; | |
43 | |
44 if (ff_pnm_decode_header(avctx, s) < 0) | |
45 return -1; | |
46 | |
47 if (p->data[0]) | |
48 avctx->release_buffer(avctx, p); | |
49 | |
50 p->reference = 0; | |
51 if (avctx->get_buffer(avctx, p) < 0) { | |
52 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
53 return -1; | |
54 } | |
55 p->pict_type = FF_I_TYPE; | |
56 p->key_frame = 1; | |
57 | |
58 switch (avctx->pix_fmt) { | |
59 default: | |
60 return -1; | |
61 case PIX_FMT_RGB48BE: | |
62 n = avctx->width * 6; | |
10612 | 63 components=3; |
64 sample_len=16; | |
10465 | 65 goto do_read; |
66 case PIX_FMT_RGB24: | |
67 n = avctx->width * 3; | |
10612 | 68 components=3; |
69 sample_len=8; | |
10465 | 70 goto do_read; |
71 case PIX_FMT_GRAY8: | |
72 n = avctx->width; | |
10612 | 73 components=1; |
74 sample_len=8; | |
10465 | 75 if (s->maxval < 255) |
76 upgrade = 1; | |
77 goto do_read; | |
78 case PIX_FMT_GRAY16BE: | |
79 case PIX_FMT_GRAY16LE: | |
80 n = avctx->width * 2; | |
10612 | 81 components=1; |
82 sample_len=16; | |
10465 | 83 if (s->maxval < 65535) |
84 upgrade = 2; | |
85 goto do_read; | |
86 case PIX_FMT_MONOWHITE: | |
87 case PIX_FMT_MONOBLACK: | |
88 n = (avctx->width + 7) >> 3; | |
10612 | 89 components=1; |
90 sample_len=1; | |
10465 | 91 do_read: |
92 ptr = p->data[0]; | |
93 linesize = p->linesize[0]; | |
94 if (s->bytestream + n * avctx->height > s->bytestream_end) | |
95 return -1; | |
10612 | 96 if(s->type < 4){ |
97 for (i=0; i<avctx->height; i++) { | |
98 PutBitContext pb; | |
99 init_put_bits(&pb, ptr, linesize); | |
100 for(j=0; j<avctx->width * components; j++){ | |
101 unsigned int c=0; | |
102 int v=0; | |
103 while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' )) | |
104 s->bytestream++; | |
105 if(s->bytestream >= s->bytestream_end) | |
106 return -1; | |
107 do{ | |
108 v= 10*v + c; | |
109 c= (*s->bytestream++) - '0'; | |
110 }while(c <= 9); | |
111 put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval); | |
112 } | |
113 flush_put_bits(&pb); | |
114 ptr+= linesize; | |
115 } | |
116 }else{ | |
10465 | 117 for (i = 0; i < avctx->height; i++) { |
118 if (!upgrade) | |
119 memcpy(ptr, s->bytestream, n); | |
120 else if (upgrade == 1) { | |
121 unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval; | |
122 for (j = 0; j < n; j++) | |
123 ptr[j] = (s->bytestream[j] * f + 64) >> 7; | |
124 } else if (upgrade == 2) { | |
125 unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval; | |
126 for (j = 0; j < n / 2; j++) { | |
12129 | 127 v = av_be2ne16(((uint16_t *)s->bytestream)[j]); |
10465 | 128 ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; |
129 } | |
130 } | |
131 s->bytestream += n; | |
132 ptr += linesize; | |
133 } | |
10612 | 134 } |
10465 | 135 break; |
136 case PIX_FMT_YUV420P: | |
137 { | |
138 unsigned char *ptr1, *ptr2; | |
139 | |
140 n = avctx->width; | |
141 ptr = p->data[0]; | |
142 linesize = p->linesize[0]; | |
143 if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end) | |
144 return -1; | |
145 for (i = 0; i < avctx->height; i++) { | |
146 memcpy(ptr, s->bytestream, n); | |
147 s->bytestream += n; | |
148 ptr += linesize; | |
149 } | |
150 ptr1 = p->data[1]; | |
151 ptr2 = p->data[2]; | |
152 n >>= 1; | |
153 h = avctx->height >> 1; | |
154 for (i = 0; i < h; i++) { | |
155 memcpy(ptr1, s->bytestream, n); | |
156 s->bytestream += n; | |
157 memcpy(ptr2, s->bytestream, n); | |
158 s->bytestream += n; | |
159 ptr1 += p->linesize[1]; | |
160 ptr2 += p->linesize[2]; | |
161 } | |
162 } | |
163 break; | |
164 case PIX_FMT_RGB32: | |
165 ptr = p->data[0]; | |
166 linesize = p->linesize[0]; | |
167 if (s->bytestream + avctx->width * avctx->height * 4 > s->bytestream_end) | |
168 return -1; | |
169 for (i = 0; i < avctx->height; i++) { | |
170 int j, r, g, b, a; | |
171 | |
172 for (j = 0; j < avctx->width; j++) { | |
173 r = *s->bytestream++; | |
174 g = *s->bytestream++; | |
175 b = *s->bytestream++; | |
176 a = *s->bytestream++; | |
177 ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; | |
178 } | |
179 ptr += linesize; | |
180 } | |
181 break; | |
182 } | |
183 *picture = *(AVFrame*)&s->picture; | |
184 *data_size = sizeof(AVPicture); | |
185 | |
186 return s->bytestream - s->bytestream_start; | |
187 } | |
188 | |
189 | |
190 #if CONFIG_PGM_DECODER | |
191 AVCodec pgm_decoder = { | |
192 "pgm", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10612
diff
changeset
|
193 AVMEDIA_TYPE_VIDEO, |
10465 | 194 CODEC_ID_PGM, |
195 sizeof(PNMContext), | |
196 ff_pnm_init, | |
197 NULL, | |
198 ff_pnm_end, | |
199 pnm_decode_frame, | |
200 CODEC_CAP_DR1, | |
201 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, PIX_FMT_NONE}, | |
12108
c35d7bc64882
Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents:
11560
diff
changeset
|
202 .max_lowres = 5, |
10465 | 203 .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), |
204 }; | |
205 #endif | |
206 | |
207 #if CONFIG_PGMYUV_DECODER | |
208 AVCodec pgmyuv_decoder = { | |
209 "pgmyuv", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10612
diff
changeset
|
210 AVMEDIA_TYPE_VIDEO, |
10465 | 211 CODEC_ID_PGMYUV, |
212 sizeof(PNMContext), | |
213 ff_pnm_init, | |
214 NULL, | |
215 ff_pnm_end, | |
216 pnm_decode_frame, | |
217 CODEC_CAP_DR1, | |
218 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | |
12108
c35d7bc64882
Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents:
11560
diff
changeset
|
219 .max_lowres = 5, |
10465 | 220 .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), |
221 }; | |
222 #endif | |
223 | |
224 #if CONFIG_PPM_DECODER | |
225 AVCodec ppm_decoder = { | |
226 "ppm", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10612
diff
changeset
|
227 AVMEDIA_TYPE_VIDEO, |
10465 | 228 CODEC_ID_PPM, |
229 sizeof(PNMContext), | |
230 ff_pnm_init, | |
231 NULL, | |
232 ff_pnm_end, | |
233 pnm_decode_frame, | |
234 CODEC_CAP_DR1, | |
235 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB48BE, PIX_FMT_NONE}, | |
12108
c35d7bc64882
Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents:
11560
diff
changeset
|
236 .max_lowres = 5, |
10465 | 237 .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), |
238 }; | |
239 #endif | |
240 | |
241 #if CONFIG_PBM_DECODER | |
242 AVCodec pbm_decoder = { | |
243 "pbm", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10612
diff
changeset
|
244 AVMEDIA_TYPE_VIDEO, |
10465 | 245 CODEC_ID_PBM, |
246 sizeof(PNMContext), | |
247 ff_pnm_init, | |
248 NULL, | |
249 ff_pnm_end, | |
250 pnm_decode_frame, | |
251 CODEC_CAP_DR1, | |
252 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_MONOWHITE, PIX_FMT_NONE}, | |
12108
c35d7bc64882
Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents:
11560
diff
changeset
|
253 .max_lowres = 5, |
10465 | 254 .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), |
255 }; | |
256 #endif | |
257 | |
258 #if CONFIG_PAM_DECODER | |
259 AVCodec pam_decoder = { | |
260 "pam", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10612
diff
changeset
|
261 AVMEDIA_TYPE_VIDEO, |
10465 | 262 CODEC_ID_PAM, |
263 sizeof(PNMContext), | |
264 ff_pnm_init, | |
265 NULL, | |
266 ff_pnm_end, | |
267 pnm_decode_frame, | |
268 CODEC_CAP_DR1, | |
269 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE}, | |
12108
c35d7bc64882
Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents:
11560
diff
changeset
|
270 .max_lowres = 5, |
10465 | 271 .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), |
272 }; | |
273 #endif |