Mercurial > libavcodec.hg
annotate pnm.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 | d6860312274c |
children | 914f484bb476 |
rev | line source |
---|---|
4978 | 1 /* |
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 | 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 */ | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
21 |
4978 | 22 #include "avcodec.h" |
23 #include "pnm.h" | |
24 | |
25 static inline int pnm_space(int c) | |
26 { | |
6750 | 27 return c == ' ' || c == '\n' || c == '\r' || c == '\t'; |
4978 | 28 } |
29 | |
30 static void pnm_get(PNMContext *sc, char *str, int buf_size) | |
31 { | |
32 char *s; | |
33 int c; | |
34 | |
35 /* skip spaces and comments */ | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
36 for (;;) { |
4978 | 37 c = *sc->bytestream++; |
38 if (c == '#') { | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
39 do { |
4978 | 40 c = *sc->bytestream++; |
41 } while (c != '\n' && sc->bytestream < sc->bytestream_end); | |
42 } else if (!pnm_space(c)) { | |
43 break; | |
44 } | |
45 } | |
46 | |
47 s = str; | |
48 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) { | |
49 if ((s - str) < buf_size - 1) | |
50 *s++ = c; | |
51 c = *sc->bytestream++; | |
52 } | |
53 *s = '\0'; | |
54 } | |
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 | 58 char buf1[32], tuple_type[32]; |
59 int h, w, depth, maxval; | |
60 | |
61 pnm_get(s, buf1, sizeof(buf1)); | |
10612 | 62 s->type= buf1[1]-'0'; |
63 if(buf1[0] != 'P') | |
64 return -1; | |
65 | |
66 if (s->type==1 || s->type==4) { | |
4978 | 67 avctx->pix_fmt = PIX_FMT_MONOWHITE; |
10612 | 68 } else if (s->type==2 || s->type==5) { |
4978 | 69 if (avctx->codec_id == CODEC_ID_PGMYUV) |
70 avctx->pix_fmt = PIX_FMT_YUV420P; | |
71 else | |
72 avctx->pix_fmt = PIX_FMT_GRAY8; | |
10612 | 73 } else if (s->type==3 || s->type==6) { |
4978 | 74 avctx->pix_fmt = PIX_FMT_RGB24; |
10612 | 75 } else if (s->type==7) { |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
76 w = -1; |
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
77 h = -1; |
4978 | 78 maxval = -1; |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
79 depth = -1; |
4978 | 80 tuple_type[0] = '\0'; |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
81 for (;;) { |
4978 | 82 pnm_get(s, buf1, sizeof(buf1)); |
83 if (!strcmp(buf1, "WIDTH")) { | |
84 pnm_get(s, buf1, sizeof(buf1)); | |
85 w = strtol(buf1, NULL, 10); | |
86 } else if (!strcmp(buf1, "HEIGHT")) { | |
87 pnm_get(s, buf1, sizeof(buf1)); | |
88 h = strtol(buf1, NULL, 10); | |
89 } else if (!strcmp(buf1, "DEPTH")) { | |
90 pnm_get(s, buf1, sizeof(buf1)); | |
91 depth = strtol(buf1, NULL, 10); | |
92 } else if (!strcmp(buf1, "MAXVAL")) { | |
93 pnm_get(s, buf1, sizeof(buf1)); | |
94 maxval = strtol(buf1, NULL, 10); | |
95 } else if (!strcmp(buf1, "TUPLETYPE")) { | |
96 pnm_get(s, tuple_type, sizeof(tuple_type)); | |
97 } else if (!strcmp(buf1, "ENDHDR")) { | |
98 break; | |
99 } else { | |
100 return -1; | |
101 } | |
102 } | |
103 /* check that all tags are present */ | |
104 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h)) | |
105 return -1; | |
106 | |
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
107 avctx->width = w; |
4978 | 108 avctx->height = h; |
109 if (depth == 1) { | |
110 if (maxval == 1) | |
111 avctx->pix_fmt = PIX_FMT_MONOWHITE; | |
112 else | |
113 avctx->pix_fmt = PIX_FMT_GRAY8; | |
114 } else if (depth == 3) { | |
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
115 if (maxval < 256) { |
4978 | 116 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
|
117 } else { |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
118 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
|
119 avctx->pix_fmt = PIX_FMT_NONE; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
120 return -1; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
121 } |
4978 | 122 } else if (depth == 4) { |
123 avctx->pix_fmt = PIX_FMT_RGB32; | |
124 } else { | |
125 return -1; | |
126 } | |
127 return 0; | |
128 } else { | |
129 return -1; | |
130 } | |
131 pnm_get(s, buf1, sizeof(buf1)); | |
132 avctx->width = atoi(buf1); | |
133 if (avctx->width <= 0) | |
134 return -1; | |
135 pnm_get(s, buf1, sizeof(buf1)); | |
136 avctx->height = atoi(buf1); | |
137 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) | |
138 return -1; | |
139 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { | |
140 pnm_get(s, buf1, sizeof(buf1)); | |
141 s->maxval = atoi(buf1); | |
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
142 if (s->maxval >= 256) { |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
143 if (avctx->pix_fmt == PIX_FMT_GRAY8) { |
7865 | 144 avctx->pix_fmt = PIX_FMT_GRAY16BE; |
145 if (s->maxval != 65535) | |
146 avctx->pix_fmt = PIX_FMT_GRAY16; | |
9145
de31b10455cc
pnm: Add missing 'else'. Fixes decoding for 16-bit pgm.
jbr
parents:
9002
diff
changeset
|
147 } else if (avctx->pix_fmt == PIX_FMT_RGB24) { |
9002 | 148 if (s->maxval > 255) |
149 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
|
150 } else { |
9002 | 151 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
|
152 avctx->pix_fmt = PIX_FMT_NONE; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
153 return -1; |
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
154 } |
4978 | 155 } |
10612 | 156 }else |
157 s->maxval=1; | |
4978 | 158 /* more check if YUV420 */ |
159 if (avctx->pix_fmt == PIX_FMT_YUV420P) { | |
160 if ((avctx->width & 1) != 0) | |
161 return -1; | |
162 h = (avctx->height * 2); | |
163 if ((h % 3) != 0) | |
164 return -1; | |
165 h /= 3; | |
166 avctx->height = h; | |
167 } | |
168 return 0; | |
169 } | |
10460
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
170 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
171 av_cold int ff_pnm_end(AVCodecContext *avctx) |
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 PNMContext *s = avctx->priv_data; |
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 if (s->picture.data[0]) |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
176 avctx->release_buffer(avctx, &s->picture); |
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 return 0; |
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 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
181 av_cold int ff_pnm_init(AVCodecContext *avctx) |
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 PNMContext *s = avctx->priv_data; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
184 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
185 avcodec_get_frame_defaults((AVFrame*)&s->picture); |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
186 avctx->coded_frame = (AVFrame*)&s->picture; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
187 |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
188 return 0; |
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
189 } |