annotate pnm.c @ 10483:afad312b9989 libavcodec

Implement AMR gain function that is used by both AMR and SIPR. Based on AMR SoC code by Robert Swain and Colin McQuillan.
author vitor
date Sat, 31 Oct 2009 02:02:30 +0000
parents 059265d3cc65
children d6860312274c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
1 /*
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
2 * PNM image format
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 7865
diff changeset
3 * Copyright (c) 2002, 2003 Fabrice Bellard
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
4 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
5 * This file is part of FFmpeg.
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
6 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
11 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
15 * Lesser General Public License for more details.
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
16 *
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
20 */
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
21
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
22 #include "avcodec.h"
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
23 #include "pnm.h"
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
24
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
25 static inline int pnm_space(int c)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
26 {
6750
c93570aeb3eb Remove unnecessary parentheses from return calls.
diego
parents: 4985
diff changeset
27 return c == ' ' || c == '\n' || c == '\r' || c == '\t';
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
28 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
29
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
30 static void pnm_get(PNMContext *sc, char *str, int buf_size)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
31 {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
32 char *s;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
33 int c;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
34
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
35 /* skip spaces and comments */
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
36 for (;;) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
37 c = *sc->bytestream++;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
38 if (c == '#') {
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
39 do {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
40 c = *sc->bytestream++;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
41 } while (c != '\n' && sc->bytestream < sc->bytestream_end);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
42 } else if (!pnm_space(c)) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
43 break;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
44 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
45 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
46
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
47 s = str;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
48 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
49 if ((s - str) < buf_size - 1)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
50 *s++ = c;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
51 c = *sc->bytestream++;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
52 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
53 *s = '\0';
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
54 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
55
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
56 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
57 {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
58 char buf1[32], tuple_type[32];
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
59 int h, w, depth, maxval;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
60
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
61 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
62 if (!strcmp(buf1, "P4")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
63 avctx->pix_fmt = PIX_FMT_MONOWHITE;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
64 } else if (!strcmp(buf1, "P5")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
65 if (avctx->codec_id == CODEC_ID_PGMYUV)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
66 avctx->pix_fmt = PIX_FMT_YUV420P;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
67 else
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
68 avctx->pix_fmt = PIX_FMT_GRAY8;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
69 } else if (!strcmp(buf1, "P6")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
70 avctx->pix_fmt = PIX_FMT_RGB24;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
71 } else if (!strcmp(buf1, "P7")) {
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
72 w = -1;
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
73 h = -1;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
74 maxval = -1;
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
75 depth = -1;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
76 tuple_type[0] = '\0';
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
77 for (;;) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
78 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
79 if (!strcmp(buf1, "WIDTH")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
80 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
81 w = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
82 } else if (!strcmp(buf1, "HEIGHT")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
83 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
84 h = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
85 } else if (!strcmp(buf1, "DEPTH")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
86 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
87 depth = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
88 } else if (!strcmp(buf1, "MAXVAL")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
89 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
90 maxval = strtol(buf1, NULL, 10);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
91 } else if (!strcmp(buf1, "TUPLETYPE")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
92 pnm_get(s, tuple_type, sizeof(tuple_type));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
93 } else if (!strcmp(buf1, "ENDHDR")) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
94 break;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
95 } else {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
96 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
97 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
98 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
99 /* check that all tags are present */
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
100 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h))
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
101 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
102
10459
a6bb56636f90 whitespace cosmetics: K&R coding style, prettyprinting
diego
parents: 9145
diff changeset
103 avctx->width = w;
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
104 avctx->height = h;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
105 if (depth == 1) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
106 if (maxval == 1)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
107 avctx->pix_fmt = PIX_FMT_MONOWHITE;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
108 else
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
109 avctx->pix_fmt = PIX_FMT_GRAY8;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
110 } else if (depth == 3) {
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
111 if (maxval < 256) {
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
112 avctx->pix_fmt = PIX_FMT_RGB24;
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
113 } else {
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
114 av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n");
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
115 avctx->pix_fmt = PIX_FMT_NONE;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
116 return -1;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
117 }
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
118 } else if (depth == 4) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
119 avctx->pix_fmt = PIX_FMT_RGB32;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
120 } else {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
121 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
122 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
123 return 0;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
124 } else {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
125 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
126 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
127 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
128 avctx->width = atoi(buf1);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
129 if (avctx->width <= 0)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
130 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
131 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
132 avctx->height = atoi(buf1);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
133 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
134 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
135 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
136 pnm_get(s, buf1, sizeof(buf1));
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
137 s->maxval = atoi(buf1);
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
138 if (s->maxval >= 256) {
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
139 if (avctx->pix_fmt == PIX_FMT_GRAY8) {
7865
c7420b070961 cosmetics: fix indentation after r15321
jbr
parents: 7859
diff changeset
140 avctx->pix_fmt = PIX_FMT_GRAY16BE;
c7420b070961 cosmetics: fix indentation after r15321
jbr
parents: 7859
diff changeset
141 if (s->maxval != 65535)
c7420b070961 cosmetics: fix indentation after r15321
jbr
parents: 7859
diff changeset
142 avctx->pix_fmt = PIX_FMT_GRAY16;
9145
de31b10455cc pnm: Add missing 'else'. Fixes decoding for 16-bit pgm.
jbr
parents: 9002
diff changeset
143 } else if (avctx->pix_fmt == PIX_FMT_RGB24) {
9002
eb98d61af310 Support 48-bit RGB PPM image.
pross
parents: 8629
diff changeset
144 if (s->maxval > 255)
eb98d61af310 Support 48-bit RGB PPM image.
pross
parents: 8629
diff changeset
145 avctx->pix_fmt = PIX_FMT_RGB48BE;
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
146 } else {
9002
eb98d61af310 Support 48-bit RGB PPM image.
pross
parents: 8629
diff changeset
147 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
7859
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
148 avctx->pix_fmt = PIX_FMT_NONE;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
149 return -1;
48d00b406a26 Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents: 6750
diff changeset
150 }
4978
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
151 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
152 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
153 /* more check if YUV420 */
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
154 if (avctx->pix_fmt == PIX_FMT_YUV420P) {
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
155 if ((avctx->width & 1) != 0)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
156 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
157 h = (avctx->height * 2);
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
158 if ((h % 3) != 0)
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
159 return -1;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
160 h /= 3;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
161 avctx->height = h;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
162 }
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
163 return 0;
95934eef9589 move pnm parser in its own file
aurel
parents:
diff changeset
164 }
10460
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
165
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
166 av_cold int ff_pnm_end(AVCodecContext *avctx)
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
167 {
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
168 PNMContext *s = avctx->priv_data;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
169
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
170 if (s->picture.data[0])
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
171 avctx->release_buffer(avctx, &s->picture);
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
172
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
173 return 0;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
174 }
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
175
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
176 av_cold int ff_pnm_init(AVCodecContext *avctx)
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
177 {
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
178 PNMContext *s = avctx->priv_data;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
179
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
180 avcodec_get_frame_defaults((AVFrame*)&s->picture);
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
181 avctx->coded_frame = (AVFrame*)&s->picture;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
182
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
183 return 0;
059265d3cc65 Move PNM init/end functions to the PNM common code.
diego
parents: 10459
diff changeset
184 }