Mercurial > libavcodec.hg
comparison pnmdec.c @ 10465:267588850827 libavcodec
Split the decoders from pnmen.c off into their own file.
author | diego |
---|---|
date | Wed, 28 Oct 2009 06:34:00 +0000 |
parents | |
children | d6860312274c |
comparison
equal
deleted
inserted
replaced
10464:1dac7b87f3d6 | 10465:267588850827 |
---|---|
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" | |
24 #include "pnm.h" | |
25 | |
26 | |
27 static int pnm_decode_frame(AVCodecContext *avctx, void *data, | |
28 int *data_size, AVPacket *avpkt) | |
29 { | |
30 const uint8_t *buf = avpkt->data; | |
31 int buf_size = avpkt->size; | |
32 PNMContext * const s = avctx->priv_data; | |
33 AVFrame *picture = data; | |
34 AVFrame * const p = (AVFrame*)&s->picture; | |
35 int i, n, linesize, h, upgrade = 0; | |
36 unsigned char *ptr; | |
37 | |
38 s->bytestream_start = | |
39 s->bytestream = buf; | |
40 s->bytestream_end = buf + buf_size; | |
41 | |
42 if (ff_pnm_decode_header(avctx, s) < 0) | |
43 return -1; | |
44 | |
45 if (p->data[0]) | |
46 avctx->release_buffer(avctx, p); | |
47 | |
48 p->reference = 0; | |
49 if (avctx->get_buffer(avctx, p) < 0) { | |
50 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
51 return -1; | |
52 } | |
53 p->pict_type = FF_I_TYPE; | |
54 p->key_frame = 1; | |
55 | |
56 switch (avctx->pix_fmt) { | |
57 default: | |
58 return -1; | |
59 case PIX_FMT_RGB48BE: | |
60 n = avctx->width * 6; | |
61 goto do_read; | |
62 case PIX_FMT_RGB24: | |
63 n = avctx->width * 3; | |
64 goto do_read; | |
65 case PIX_FMT_GRAY8: | |
66 n = avctx->width; | |
67 if (s->maxval < 255) | |
68 upgrade = 1; | |
69 goto do_read; | |
70 case PIX_FMT_GRAY16BE: | |
71 case PIX_FMT_GRAY16LE: | |
72 n = avctx->width * 2; | |
73 if (s->maxval < 65535) | |
74 upgrade = 2; | |
75 goto do_read; | |
76 case PIX_FMT_MONOWHITE: | |
77 case PIX_FMT_MONOBLACK: | |
78 n = (avctx->width + 7) >> 3; | |
79 do_read: | |
80 ptr = p->data[0]; | |
81 linesize = p->linesize[0]; | |
82 if (s->bytestream + n * avctx->height > s->bytestream_end) | |
83 return -1; | |
84 for (i = 0; i < avctx->height; i++) { | |
85 if (!upgrade) | |
86 memcpy(ptr, s->bytestream, n); | |
87 else if (upgrade == 1) { | |
88 unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval; | |
89 for (j = 0; j < n; j++) | |
90 ptr[j] = (s->bytestream[j] * f + 64) >> 7; | |
91 } else if (upgrade == 2) { | |
92 unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval; | |
93 for (j = 0; j < n / 2; j++) { | |
94 v = be2me_16(((uint16_t *)s->bytestream)[j]); | |
95 ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; | |
96 } | |
97 } | |
98 s->bytestream += n; | |
99 ptr += linesize; | |
100 } | |
101 break; | |
102 case PIX_FMT_YUV420P: | |
103 { | |
104 unsigned char *ptr1, *ptr2; | |
105 | |
106 n = avctx->width; | |
107 ptr = p->data[0]; | |
108 linesize = p->linesize[0]; | |
109 if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end) | |
110 return -1; | |
111 for (i = 0; i < avctx->height; i++) { | |
112 memcpy(ptr, s->bytestream, n); | |
113 s->bytestream += n; | |
114 ptr += linesize; | |
115 } | |
116 ptr1 = p->data[1]; | |
117 ptr2 = p->data[2]; | |
118 n >>= 1; | |
119 h = avctx->height >> 1; | |
120 for (i = 0; i < h; i++) { | |
121 memcpy(ptr1, s->bytestream, n); | |
122 s->bytestream += n; | |
123 memcpy(ptr2, s->bytestream, n); | |
124 s->bytestream += n; | |
125 ptr1 += p->linesize[1]; | |
126 ptr2 += p->linesize[2]; | |
127 } | |
128 } | |
129 break; | |
130 case PIX_FMT_RGB32: | |
131 ptr = p->data[0]; | |
132 linesize = p->linesize[0]; | |
133 if (s->bytestream + avctx->width * avctx->height * 4 > s->bytestream_end) | |
134 return -1; | |
135 for (i = 0; i < avctx->height; i++) { | |
136 int j, r, g, b, a; | |
137 | |
138 for (j = 0; j < avctx->width; j++) { | |
139 r = *s->bytestream++; | |
140 g = *s->bytestream++; | |
141 b = *s->bytestream++; | |
142 a = *s->bytestream++; | |
143 ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; | |
144 } | |
145 ptr += linesize; | |
146 } | |
147 break; | |
148 } | |
149 *picture = *(AVFrame*)&s->picture; | |
150 *data_size = sizeof(AVPicture); | |
151 | |
152 return s->bytestream - s->bytestream_start; | |
153 } | |
154 | |
155 | |
156 #if CONFIG_PGM_DECODER | |
157 AVCodec pgm_decoder = { | |
158 "pgm", | |
159 CODEC_TYPE_VIDEO, | |
160 CODEC_ID_PGM, | |
161 sizeof(PNMContext), | |
162 ff_pnm_init, | |
163 NULL, | |
164 ff_pnm_end, | |
165 pnm_decode_frame, | |
166 CODEC_CAP_DR1, | |
167 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, PIX_FMT_NONE}, | |
168 .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), | |
169 }; | |
170 #endif | |
171 | |
172 #if CONFIG_PGMYUV_DECODER | |
173 AVCodec pgmyuv_decoder = { | |
174 "pgmyuv", | |
175 CODEC_TYPE_VIDEO, | |
176 CODEC_ID_PGMYUV, | |
177 sizeof(PNMContext), | |
178 ff_pnm_init, | |
179 NULL, | |
180 ff_pnm_end, | |
181 pnm_decode_frame, | |
182 CODEC_CAP_DR1, | |
183 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | |
184 .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), | |
185 }; | |
186 #endif | |
187 | |
188 #if CONFIG_PPM_DECODER | |
189 AVCodec ppm_decoder = { | |
190 "ppm", | |
191 CODEC_TYPE_VIDEO, | |
192 CODEC_ID_PPM, | |
193 sizeof(PNMContext), | |
194 ff_pnm_init, | |
195 NULL, | |
196 ff_pnm_end, | |
197 pnm_decode_frame, | |
198 CODEC_CAP_DR1, | |
199 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB48BE, PIX_FMT_NONE}, | |
200 .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), | |
201 }; | |
202 #endif | |
203 | |
204 #if CONFIG_PBM_DECODER | |
205 AVCodec pbm_decoder = { | |
206 "pbm", | |
207 CODEC_TYPE_VIDEO, | |
208 CODEC_ID_PBM, | |
209 sizeof(PNMContext), | |
210 ff_pnm_init, | |
211 NULL, | |
212 ff_pnm_end, | |
213 pnm_decode_frame, | |
214 CODEC_CAP_DR1, | |
215 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_MONOWHITE, PIX_FMT_NONE}, | |
216 .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), | |
217 }; | |
218 #endif | |
219 | |
220 #if CONFIG_PAM_DECODER | |
221 AVCodec pam_decoder = { | |
222 "pam", | |
223 CODEC_TYPE_VIDEO, | |
224 CODEC_ID_PAM, | |
225 sizeof(PNMContext), | |
226 ff_pnm_init, | |
227 NULL, | |
228 ff_pnm_end, | |
229 pnm_decode_frame, | |
230 CODEC_CAP_DR1, | |
231 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE}, | |
232 .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), | |
233 }; | |
234 #endif |