Signed-off-by: Paras Chadha <paraschadha18@gmail.com>
Paras Chadha authored on 2017/03/12 06:01:23... | ... |
@@ -609,6 +609,8 @@ following image formats are supported: |
609 | 609 |
@tab X BitMap image format |
610 | 610 |
@item XFace @tab X @tab X |
611 | 611 |
@tab X-Face image format |
612 |
+@item XPM @tab @tab X |
|
613 |
+ @tab X PixMap image format |
|
612 | 614 |
@item XWD @tab X @tab X |
613 | 615 |
@tab X Window Dump image format |
614 | 616 |
@end multitable |
... | ... |
@@ -650,6 +650,7 @@ OBJS-$(CONFIG_XFACE_ENCODER) += xfaceenc.o xface.o |
650 | 650 |
OBJS-$(CONFIG_XL_DECODER) += xl.o |
651 | 651 |
OBJS-$(CONFIG_XMA1_DECODER) += wmaprodec.o wma.o wma_common.o |
652 | 652 |
OBJS-$(CONFIG_XMA2_DECODER) += wmaprodec.o wma.o wma_common.o |
653 |
+OBJS-$(CONFIG_XPM_DECODER) += xpmdec.o |
|
653 | 654 |
OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o |
654 | 655 |
OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o |
655 | 656 |
OBJS-$(CONFIG_XWD_DECODER) += xwddec.o |
... | ... |
@@ -378,6 +378,7 @@ static void register_all(void) |
378 | 378 |
REGISTER_ENCDEC (XBM, xbm); |
379 | 379 |
REGISTER_ENCDEC (XFACE, xface); |
380 | 380 |
REGISTER_DECODER(XL, xl); |
381 |
+ REGISTER_DECODER(XPM, xpm); |
|
381 | 382 |
REGISTER_ENCDEC (XWD, xwd); |
382 | 383 |
REGISTER_ENCDEC (Y41P, y41p); |
383 | 384 |
REGISTER_DECODER(YLC, ylc); |
... | ... |
@@ -1591,6 +1591,13 @@ static const AVCodecDescriptor codec_descriptors[] = { |
1591 | 1591 |
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, |
1592 | 1592 |
}, |
1593 | 1593 |
{ |
1594 |
+ .id = AV_CODEC_ID_XPM, |
|
1595 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
1596 |
+ .name = "xpm", |
|
1597 |
+ .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image"), |
|
1598 |
+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, |
|
1599 |
+ }, |
|
1600 |
+ { |
|
1594 | 1601 |
.id = AV_CODEC_ID_XWD, |
1595 | 1602 |
.type = AVMEDIA_TYPE_VIDEO, |
1596 | 1603 |
.name = "xwd", |
... | ... |
@@ -28,8 +28,8 @@ |
28 | 28 |
#include "libavutil/version.h" |
29 | 29 |
|
30 | 30 |
#define LIBAVCODEC_VERSION_MAJOR 57 |
31 |
-#define LIBAVCODEC_VERSION_MINOR 82 |
|
32 |
-#define LIBAVCODEC_VERSION_MICRO 102 |
|
31 |
+#define LIBAVCODEC_VERSION_MINOR 83 |
|
32 |
+#define LIBAVCODEC_VERSION_MICRO 100 |
|
33 | 33 |
|
34 | 34 |
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |
35 | 35 |
LIBAVCODEC_VERSION_MINOR, \ |
36 | 36 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,425 @@ |
0 |
+/* |
|
1 |
+ * XPM image format |
|
2 |
+ * |
|
3 |
+ * Copyright (c) 2012 Paul B Mahol |
|
4 |
+ * Copyright (c) 2017 Paras Chadha |
|
5 |
+ * |
|
6 |
+ * This file is part of FFmpeg. |
|
7 |
+ * |
|
8 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
9 |
+ * modify it under the terms of the GNU Lesser General Public |
|
10 |
+ * License as published by the Free Software Foundation; either |
|
11 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
12 |
+ * |
|
13 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
16 |
+ * Lesser General Public License for more details. |
|
17 |
+ * |
|
18 |
+ * You should have received a copy of the GNU Lesser General Public |
|
19 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
20 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
21 |
+ */ |
|
22 |
+ |
|
23 |
+#include "libavutil/parseutils.h" |
|
24 |
+#include "libavutil/avstring.h" |
|
25 |
+#include "avcodec.h" |
|
26 |
+#include "internal.h" |
|
27 |
+ |
|
28 |
+typedef struct XPMContext { |
|
29 |
+ uint32_t *pixels; |
|
30 |
+ int pixels_size; |
|
31 |
+} XPMDecContext; |
|
32 |
+ |
|
33 |
+typedef struct ColorEntry { |
|
34 |
+ const char *name; ///< a string representing the name of the color |
|
35 |
+ uint32_t rgb_color; ///< RGB values for the color |
|
36 |
+} ColorEntry; |
|
37 |
+ |
|
38 |
+static int color_table_compare(const void *lhs, const void *rhs) |
|
39 |
+{ |
|
40 |
+ return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name); |
|
41 |
+} |
|
42 |
+ |
|
43 |
+static const ColorEntry color_table[] = { |
|
44 |
+ { "AliceBlue", 0xFFF0F8FF }, |
|
45 |
+ { "AntiqueWhite", 0xFFFAEBD7 }, |
|
46 |
+ { "Aqua", 0xFF00FFFF }, |
|
47 |
+ { "Aquamarine", 0xFF7FFFD4 }, |
|
48 |
+ { "Azure", 0xFFF0FFFF }, |
|
49 |
+ { "Beige", 0xFFF5F5DC }, |
|
50 |
+ { "Bisque", 0xFFFFE4C4 }, |
|
51 |
+ { "Black", 0xFF000000 }, |
|
52 |
+ { "BlanchedAlmond", 0xFFFFEBCD }, |
|
53 |
+ { "Blue", 0xFF0000FF }, |
|
54 |
+ { "BlueViolet", 0xFF8A2BE2 }, |
|
55 |
+ { "Brown", 0xFFA52A2A }, |
|
56 |
+ { "BurlyWood", 0xFFDEB887 }, |
|
57 |
+ { "CadetBlue", 0xFF5F9EA0 }, |
|
58 |
+ { "Chartreuse", 0xFF7FFF00 }, |
|
59 |
+ { "Chocolate", 0xFFD2691E }, |
|
60 |
+ { "Coral", 0xFFFF7F50 }, |
|
61 |
+ { "CornflowerBlue", 0xFF6495ED }, |
|
62 |
+ { "Cornsilk", 0xFFFFF8DC }, |
|
63 |
+ { "Crimson", 0xFFDC143C }, |
|
64 |
+ { "Cyan", 0xFF00FFFF }, |
|
65 |
+ { "DarkBlue", 0xFF00008B }, |
|
66 |
+ { "DarkCyan", 0xFF008B8B }, |
|
67 |
+ { "DarkGoldenRod", 0xFFB8860B }, |
|
68 |
+ { "DarkGray", 0xFFA9A9A9 }, |
|
69 |
+ { "DarkGreen", 0xFF006400 }, |
|
70 |
+ { "DarkKhaki", 0xFFBDB76B }, |
|
71 |
+ { "DarkMagenta", 0xFF8B008B }, |
|
72 |
+ { "DarkOliveGreen", 0xFF556B2F }, |
|
73 |
+ { "Darkorange", 0xFFFF8C00 }, |
|
74 |
+ { "DarkOrchid", 0xFF9932CC }, |
|
75 |
+ { "DarkRed", 0xFF8B0000 }, |
|
76 |
+ { "DarkSalmon", 0xFFE9967A }, |
|
77 |
+ { "DarkSeaGreen", 0xFF8FBC8F }, |
|
78 |
+ { "DarkSlateBlue", 0xFF483D8B }, |
|
79 |
+ { "DarkSlateGray", 0xFF2F4F4F }, |
|
80 |
+ { "DarkTurquoise", 0xFF00CED1 }, |
|
81 |
+ { "DarkViolet", 0xFF9400D3 }, |
|
82 |
+ { "DeepPink", 0xFFFF1493 }, |
|
83 |
+ { "DeepSkyBlue", 0xFF00BFFF }, |
|
84 |
+ { "DimGray", 0xFF696969 }, |
|
85 |
+ { "DodgerBlue", 0xFF1E90FF }, |
|
86 |
+ { "FireBrick", 0xFFB22222 }, |
|
87 |
+ { "FloralWhite", 0xFFFFFAF0 }, |
|
88 |
+ { "ForestGreen", 0xFF228B22 }, |
|
89 |
+ { "Fuchsia", 0xFFFF00FF }, |
|
90 |
+ { "Gainsboro", 0xFFDCDCDC }, |
|
91 |
+ { "GhostWhite", 0xFFF8F8FF }, |
|
92 |
+ { "Gold", 0xFFFFD700 }, |
|
93 |
+ { "GoldenRod", 0xFFDAA520 }, |
|
94 |
+ { "Gray", 0xFF808080 }, |
|
95 |
+ { "Green", 0xFF008000 }, |
|
96 |
+ { "GreenYellow", 0xFFADFF2F }, |
|
97 |
+ { "HoneyDew", 0xFFF0FFF0 }, |
|
98 |
+ { "HotPink", 0xFFFF69B4 }, |
|
99 |
+ { "IndianRed", 0xFFCD5C5C }, |
|
100 |
+ { "Indigo", 0xFF4B0082 }, |
|
101 |
+ { "Ivory", 0xFFFFFFF0 }, |
|
102 |
+ { "Khaki", 0xFFF0E68C }, |
|
103 |
+ { "Lavender", 0xFFE6E6FA }, |
|
104 |
+ { "LavenderBlush", 0xFFFFF0F5 }, |
|
105 |
+ { "LawnGreen", 0xFF7CFC00 }, |
|
106 |
+ { "LemonChiffon", 0xFFFFFACD }, |
|
107 |
+ { "LightBlue", 0xFFADD8E6 }, |
|
108 |
+ { "LightCoral", 0xFFF08080 }, |
|
109 |
+ { "LightCyan", 0xFFE0FFFF }, |
|
110 |
+ { "LightGoldenRodYellow", 0xFFFAFAD2 }, |
|
111 |
+ { "LightGreen", 0xFF90EE90 }, |
|
112 |
+ { "LightGrey", 0xFFD3D3D3 }, |
|
113 |
+ { "LightPink", 0xFFFFB6C1 }, |
|
114 |
+ { "LightSalmon", 0xFFFFA07A }, |
|
115 |
+ { "LightSeaGreen", 0xFF20B2AA }, |
|
116 |
+ { "LightSkyBlue", 0xFF87CEFA }, |
|
117 |
+ { "LightSlateGray", 0xFF778899 }, |
|
118 |
+ { "LightSteelBlue", 0xFFB0C4DE }, |
|
119 |
+ { "LightYellow", 0xFFFFFFE0 }, |
|
120 |
+ { "Lime", 0xFF00FF00 }, |
|
121 |
+ { "LimeGreen", 0xFF32CD32 }, |
|
122 |
+ { "Linen", 0xFFFAF0E6 }, |
|
123 |
+ { "Magenta", 0xFFFF00FF }, |
|
124 |
+ { "Maroon", 0xFF800000 }, |
|
125 |
+ { "MediumAquaMarine", 0xFF66CDAA }, |
|
126 |
+ { "MediumBlue", 0xFF0000CD }, |
|
127 |
+ { "MediumOrchid", 0xFFBA55D3 }, |
|
128 |
+ { "MediumPurple", 0xFF9370D8 }, |
|
129 |
+ { "MediumSeaGreen", 0xFF3CB371 }, |
|
130 |
+ { "MediumSlateBlue", 0xFF7B68EE }, |
|
131 |
+ { "MediumSpringGreen", 0xFF00FA9A }, |
|
132 |
+ { "MediumTurquoise", 0xFF48D1CC }, |
|
133 |
+ { "MediumVioletRed", 0xFFC71585 }, |
|
134 |
+ { "MidnightBlue", 0xFF191970 }, |
|
135 |
+ { "MintCream", 0xFFF5FFFA }, |
|
136 |
+ { "MistyRose", 0xFFFFE4E1 }, |
|
137 |
+ { "Moccasin", 0xFFFFE4B5 }, |
|
138 |
+ { "NavajoWhite", 0xFFFFDEAD }, |
|
139 |
+ { "Navy", 0xFF000080 }, |
|
140 |
+ { "None", 0x00000000 }, |
|
141 |
+ { "OldLace", 0xFFFDF5E6 }, |
|
142 |
+ { "Olive", 0xFF808000 }, |
|
143 |
+ { "OliveDrab", 0xFF6B8E23 }, |
|
144 |
+ { "Orange", 0xFFFFA500 }, |
|
145 |
+ { "OrangeRed", 0xFFFF4500 }, |
|
146 |
+ { "Orchid", 0xFFDA70D6 }, |
|
147 |
+ { "PaleGoldenRod", 0xFFEEE8AA }, |
|
148 |
+ { "PaleGreen", 0xFF98FB98 }, |
|
149 |
+ { "PaleTurquoise", 0xFFAFEEEE }, |
|
150 |
+ { "PaleVioletRed", 0xFFD87093 }, |
|
151 |
+ { "PapayaWhip", 0xFFFFEFD5 }, |
|
152 |
+ { "PeachPuff", 0xFFFFDAB9 }, |
|
153 |
+ { "Peru", 0xFFCD853F }, |
|
154 |
+ { "Pink", 0xFFFFC0CB }, |
|
155 |
+ { "Plum", 0xFFDDA0DD }, |
|
156 |
+ { "PowderBlue", 0xFFB0E0E6 }, |
|
157 |
+ { "Purple", 0xFF800080 }, |
|
158 |
+ { "Red", 0xFFFF0000 }, |
|
159 |
+ { "RosyBrown", 0xFFBC8F8F }, |
|
160 |
+ { "RoyalBlue", 0xFF4169E1 }, |
|
161 |
+ { "SaddleBrown", 0xFF8B4513 }, |
|
162 |
+ { "Salmon", 0xFFFA8072 }, |
|
163 |
+ { "SandyBrown", 0xFFF4A460 }, |
|
164 |
+ { "SeaGreen", 0xFF2E8B57 }, |
|
165 |
+ { "SeaShell", 0xFFFFF5EE }, |
|
166 |
+ { "Sienna", 0xFFA0522D }, |
|
167 |
+ { "Silver", 0xFFC0C0C0 }, |
|
168 |
+ { "SkyBlue", 0xFF87CEEB }, |
|
169 |
+ { "SlateBlue", 0xFF6A5ACD }, |
|
170 |
+ { "SlateGray", 0xFF708090 }, |
|
171 |
+ { "Snow", 0xFFFFFAFA }, |
|
172 |
+ { "SpringGreen", 0xFF00FF7F }, |
|
173 |
+ { "SteelBlue", 0xFF4682B4 }, |
|
174 |
+ { "Tan", 0xFFD2B48C }, |
|
175 |
+ { "Teal", 0xFF008080 }, |
|
176 |
+ { "Thistle", 0xFFD8BFD8 }, |
|
177 |
+ { "Tomato", 0xFFFF6347 }, |
|
178 |
+ { "Turquoise", 0xFF40E0D0 }, |
|
179 |
+ { "Violet", 0xFFEE82EE }, |
|
180 |
+ { "Wheat", 0xFFF5DEB3 }, |
|
181 |
+ { "White", 0xFFFFFFFF }, |
|
182 |
+ { "WhiteSmoke", 0xFFF5F5F5 }, |
|
183 |
+ { "Yellow", 0xFFFFFF00 }, |
|
184 |
+ { "YellowGreen", 0xFF9ACD32 } |
|
185 |
+}; |
|
186 |
+ |
|
187 |
+static int convert(uint8_t x) |
|
188 |
+{ |
|
189 |
+ if (x >= 'a') { |
|
190 |
+ x -= 87; |
|
191 |
+ } else if (x >= 'A') { |
|
192 |
+ x -= 55; |
|
193 |
+ } else { |
|
194 |
+ x -= '0'; |
|
195 |
+ } |
|
196 |
+ return x; |
|
197 |
+} |
|
198 |
+ |
|
199 |
+/* |
|
200 |
+** functions same as strcspn but ignores characters in reject if they are inside a C style comment... |
|
201 |
+** @param string, reject - same as that of strcspn |
|
202 |
+** @return length till any character in reject does not occur in string |
|
203 |
+*/ |
|
204 |
+static size_t mod_strcspn(const char *string, const char *reject) |
|
205 |
+{ |
|
206 |
+ int i, j; |
|
207 |
+ |
|
208 |
+ for (i = 0; string && string[i]; i++) { |
|
209 |
+ if (string[i] == '/' && string[i+1] == '*') { |
|
210 |
+ i += 2; |
|
211 |
+ while ( string && string[i] && (string[i] != '*' || string[i+1] != '/') ) |
|
212 |
+ i++; |
|
213 |
+ i++; |
|
214 |
+ } else if (string[i] == '/' && string[i+1] == '/') { |
|
215 |
+ i += 2; |
|
216 |
+ while ( string && string[i] && string[i] != '\n' ) |
|
217 |
+ i++; |
|
218 |
+ } else { |
|
219 |
+ for (j = 0; reject && reject[j]; j++) { |
|
220 |
+ if (string[i] == reject[j]) |
|
221 |
+ break; |
|
222 |
+ } |
|
223 |
+ if (reject && reject[j]) |
|
224 |
+ break; |
|
225 |
+ } |
|
226 |
+ } |
|
227 |
+ return i; |
|
228 |
+} |
|
229 |
+ |
|
230 |
+static uint32_t hexstring_to_rgba(const char *p, int len) |
|
231 |
+{ |
|
232 |
+ uint32_t ret = 0xFF000000; |
|
233 |
+ const ColorEntry *entry; |
|
234 |
+ char color_name[100]; |
|
235 |
+ |
|
236 |
+ if (*p == '#') { |
|
237 |
+ p++; |
|
238 |
+ len--; |
|
239 |
+ if (len == 3) { |
|
240 |
+ ret |= (convert(p[2]) << 4) | |
|
241 |
+ (convert(p[1]) << 12) | |
|
242 |
+ (convert(p[0]) << 20); |
|
243 |
+ } else if (len == 4) { |
|
244 |
+ ret = (convert(p[3]) << 4) | |
|
245 |
+ (convert(p[2]) << 12) | |
|
246 |
+ (convert(p[1]) << 20) | |
|
247 |
+ (convert(p[0]) << 28); |
|
248 |
+ } else if (len == 6) { |
|
249 |
+ ret |= convert(p[5]) | |
|
250 |
+ (convert(p[4]) << 4) | |
|
251 |
+ (convert(p[3]) << 8) | |
|
252 |
+ (convert(p[2]) << 12) | |
|
253 |
+ (convert(p[1]) << 16) | |
|
254 |
+ (convert(p[0]) << 20); |
|
255 |
+ } else if (len == 8) { |
|
256 |
+ ret = convert(p[7]) | |
|
257 |
+ (convert(p[6]) << 4) | |
|
258 |
+ (convert(p[5]) << 8) | |
|
259 |
+ (convert(p[4]) << 12) | |
|
260 |
+ (convert(p[3]) << 16) | |
|
261 |
+ (convert(p[2]) << 20) | |
|
262 |
+ (convert(p[1]) << 24) | |
|
263 |
+ (convert(p[0]) << 28); |
|
264 |
+ } |
|
265 |
+ } else { |
|
266 |
+ strncpy(color_name, p, len); |
|
267 |
+ color_name[len] = '\0'; |
|
268 |
+ |
|
269 |
+ entry = bsearch(color_name, |
|
270 |
+ color_table, |
|
271 |
+ FF_ARRAY_ELEMS(color_table), |
|
272 |
+ sizeof(ColorEntry), |
|
273 |
+ color_table_compare); |
|
274 |
+ |
|
275 |
+ if (!entry) |
|
276 |
+ return ret; |
|
277 |
+ |
|
278 |
+ ret = entry->rgb_color; |
|
279 |
+ } |
|
280 |
+ return ret; |
|
281 |
+} |
|
282 |
+ |
|
283 |
+static int ascii2index(const uint8_t *cpixel, int cpp) |
|
284 |
+{ |
|
285 |
+ const uint8_t *p = cpixel; |
|
286 |
+ int n = 0, m = 1, i; |
|
287 |
+ |
|
288 |
+ for (i = 0; i < cpp; i++) { |
|
289 |
+ if (*p < ' ' || *p > '~') |
|
290 |
+ return AVERROR_INVALIDDATA; |
|
291 |
+ n += (*p++ - ' ') * m; |
|
292 |
+ m *= 95; |
|
293 |
+ } |
|
294 |
+ return n; |
|
295 |
+} |
|
296 |
+ |
|
297 |
+static int xpm_decode_frame(AVCodecContext *avctx, void *data, |
|
298 |
+ int *got_frame, AVPacket *avpkt) |
|
299 |
+{ |
|
300 |
+ XPMDecContext *x = avctx->priv_data; |
|
301 |
+ AVFrame *p=data; |
|
302 |
+ const uint8_t *end, *ptr = avpkt->data; |
|
303 |
+ int ncolors, cpp, ret, i, j; |
|
304 |
+ int64_t size; |
|
305 |
+ uint32_t *dst; |
|
306 |
+ |
|
307 |
+ avctx->pix_fmt = AV_PIX_FMT_BGRA; |
|
308 |
+ |
|
309 |
+ end = avpkt->data + avpkt->size; |
|
310 |
+ if (memcmp(ptr, "/* XPM */", 9)) { |
|
311 |
+ av_log(avctx, AV_LOG_ERROR, "missing signature\n"); |
|
312 |
+ return AVERROR_INVALIDDATA; |
|
313 |
+ } |
|
314 |
+ |
|
315 |
+ ptr += mod_strcspn(ptr, "\""); |
|
316 |
+ if (sscanf(ptr, "\"%u %u %u %u\",", |
|
317 |
+ &avctx->width, &avctx->height, &ncolors, &cpp) != 4) { |
|
318 |
+ av_log(avctx, AV_LOG_ERROR, "missing image parameters\n"); |
|
319 |
+ return AVERROR_INVALIDDATA; |
|
320 |
+ } |
|
321 |
+ |
|
322 |
+ if ((ret = ff_set_dimensions(avctx, avctx->width, avctx->height)) < 0) |
|
323 |
+ return ret; |
|
324 |
+ |
|
325 |
+ if ((ret = ff_get_buffer(avctx, p, 0)) < 0) |
|
326 |
+ return ret; |
|
327 |
+ |
|
328 |
+ if (ncolors <= 0) { |
|
329 |
+ av_log(avctx, AV_LOG_ERROR, "invalid number of colors: %d\n", ncolors); |
|
330 |
+ return AVERROR_INVALIDDATA; |
|
331 |
+ } |
|
332 |
+ |
|
333 |
+ if (cpp <= 0) { |
|
334 |
+ av_log(avctx, AV_LOG_ERROR, "invalid number of chars per pixel: %d\n", cpp); |
|
335 |
+ return AVERROR_INVALIDDATA; |
|
336 |
+ } |
|
337 |
+ |
|
338 |
+ size = 1; |
|
339 |
+ j = 1; |
|
340 |
+ for (i = 0; i < cpp; i++) { |
|
341 |
+ size += j * 94; |
|
342 |
+ j *= 95; |
|
343 |
+ } |
|
344 |
+ size *= 4; |
|
345 |
+ |
|
346 |
+ if (size < 0) { |
|
347 |
+ av_log(avctx, AV_LOG_ERROR, "unsupported number of chars per pixel: %d\n", cpp); |
|
348 |
+ return AVERROR(ENOMEM); |
|
349 |
+ } |
|
350 |
+ |
|
351 |
+ av_fast_padded_malloc(&x->pixels, &x->pixels_size, size); |
|
352 |
+ if (!x->pixels) |
|
353 |
+ return AVERROR(ENOMEM); |
|
354 |
+ |
|
355 |
+ ptr += mod_strcspn(ptr, ",") + 1; |
|
356 |
+ for (i = 0; i < ncolors; i++) { |
|
357 |
+ const uint8_t *index; |
|
358 |
+ int len; |
|
359 |
+ |
|
360 |
+ ptr += mod_strcspn(ptr, "\"") + 1; |
|
361 |
+ if (ptr + cpp > end) |
|
362 |
+ return AVERROR_INVALIDDATA; |
|
363 |
+ index = ptr; |
|
364 |
+ ptr += cpp; |
|
365 |
+ |
|
366 |
+ ptr = strstr(ptr, "c "); |
|
367 |
+ if (ptr) { |
|
368 |
+ ptr += 2; |
|
369 |
+ } else { |
|
370 |
+ return AVERROR_INVALIDDATA; |
|
371 |
+ } |
|
372 |
+ |
|
373 |
+ len = strcspn(ptr, "\" "); |
|
374 |
+ |
|
375 |
+ if ((ret = ascii2index(index, cpp)) < 0) |
|
376 |
+ return ret; |
|
377 |
+ |
|
378 |
+ x->pixels[ret] = hexstring_to_rgba(ptr, len); |
|
379 |
+ ptr += mod_strcspn(ptr, ",") + 1; |
|
380 |
+ } |
|
381 |
+ |
|
382 |
+ for (i = 0; i < avctx->height; i++) { |
|
383 |
+ dst = (uint32_t *)(p->data[0] + i * p->linesize[0]); |
|
384 |
+ ptr += mod_strcspn(ptr, "\"") + 1; |
|
385 |
+ |
|
386 |
+ for (j = 0; j < avctx->width; j++) { |
|
387 |
+ if (ptr + cpp > end) |
|
388 |
+ return AVERROR_INVALIDDATA; |
|
389 |
+ |
|
390 |
+ if ((ret = ascii2index(ptr, cpp)) < 0) |
|
391 |
+ return ret; |
|
392 |
+ |
|
393 |
+ *dst++ = x->pixels[ret]; |
|
394 |
+ ptr += cpp; |
|
395 |
+ } |
|
396 |
+ ptr += mod_strcspn(ptr, ",") + 1; |
|
397 |
+ } |
|
398 |
+ |
|
399 |
+ p->key_frame = 1; |
|
400 |
+ p->pict_type = AV_PICTURE_TYPE_I; |
|
401 |
+ |
|
402 |
+ *got_frame = 1; |
|
403 |
+ |
|
404 |
+ return avpkt->size; |
|
405 |
+} |
|
406 |
+ |
|
407 |
+static av_cold int xpm_decode_close(AVCodecContext *avctx) |
|
408 |
+{ |
|
409 |
+ XPMDecContext *x = avctx->priv_data; |
|
410 |
+ av_freep(&x->pixels); |
|
411 |
+ |
|
412 |
+ return 0; |
|
413 |
+} |
|
414 |
+ |
|
415 |
+AVCodec ff_xpm_decoder = { |
|
416 |
+ .name = "xpm", |
|
417 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
418 |
+ .id = AV_CODEC_ID_XPM, |
|
419 |
+ .priv_data_size = sizeof(XPMDecContext), |
|
420 |
+ .close = xpm_decode_close, |
|
421 |
+ .decode = xpm_decode_frame, |
|
422 |
+ .capabilities = CODEC_CAP_DR1, |
|
423 |
+ .long_name = NULL_IF_CONFIG_SMALL("XPM (X PixMap) image") |
|
424 |
+}; |
... | ... |
@@ -241,6 +241,7 @@ OBJS-$(CONFIG_IMAGE_SGI_PIPE_DEMUXER) += img2dec.o img2.o |
241 | 241 |
OBJS-$(CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER) += img2dec.o img2.o |
242 | 242 |
OBJS-$(CONFIG_IMAGE_TIFF_PIPE_DEMUXER) += img2dec.o img2.o |
243 | 243 |
OBJS-$(CONFIG_IMAGE_WEBP_PIPE_DEMUXER) += img2dec.o img2.o |
244 |
+OBJS-$(CONFIG_IMAGE_XPM_PIPE_DEMUXER) += img2dec.o img2.o |
|
244 | 245 |
OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o |
245 | 246 |
OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o |
246 | 247 |
OBJS-$(CONFIG_IRCAM_DEMUXER) += ircamdec.o ircam.o pcm.o |
... | ... |
@@ -372,6 +372,7 @@ static void register_all(void) |
372 | 372 |
REGISTER_DEMUXER (IMAGE_SUNRAST_PIPE, image_sunrast_pipe); |
373 | 373 |
REGISTER_DEMUXER (IMAGE_TIFF_PIPE, image_tiff_pipe); |
374 | 374 |
REGISTER_DEMUXER (IMAGE_WEBP_PIPE, image_webp_pipe); |
375 |
+ REGISTER_DEMUXER (IMAGE_XPM_PIPE, image_xpm_pipe); |
|
375 | 376 |
|
376 | 377 |
/* external libraries */ |
377 | 378 |
REGISTER_MUXER (CHROMAPRINT, chromaprint); |
... | ... |
@@ -75,6 +75,7 @@ const IdStrMap ff_img_tags[] = { |
75 | 75 |
{ AV_CODEC_ID_V210X, "yuv10" }, |
76 | 76 |
{ AV_CODEC_ID_WEBP, "webp" }, |
77 | 77 |
{ AV_CODEC_ID_XBM, "xbm" }, |
78 |
+ { AV_CODEC_ID_XPM, "xpm" }, |
|
78 | 79 |
{ AV_CODEC_ID_XFACE, "xface" }, |
79 | 80 |
{ AV_CODEC_ID_XWD, "xwd" }, |
80 | 81 |
{ AV_CODEC_ID_NONE, NULL } |
... | ... |
@@ -943,6 +943,15 @@ static int pam_probe(AVProbeData *p) |
943 | 943 |
return pnm_magic_check(p, 7) ? pnm_probe(p) : 0; |
944 | 944 |
} |
945 | 945 |
|
946 |
+static int xpm_probe(AVProbeData *p) |
|
947 |
+{ |
|
948 |
+ const uint8_t *b = p->buf; |
|
949 |
+ |
|
950 |
+ if (AV_RB64(b) == 0x2f2a2058504d202a && *(b+8) == '/') |
|
951 |
+ return AVPROBE_SCORE_MAX - 1; |
|
952 |
+ return 0; |
|
953 |
+} |
|
954 |
+ |
|
946 | 955 |
#define IMAGEAUTO_DEMUXER(imgname, codecid)\ |
947 | 956 |
static const AVClass imgname ## _class = {\ |
948 | 957 |
.class_name = AV_STRINGIFY(imgname) " demuxer",\ |
... | ... |
@@ -983,3 +992,4 @@ IMAGEAUTO_DEMUXER(sgi, AV_CODEC_ID_SGI) |
983 | 983 |
IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST) |
984 | 984 |
IMAGEAUTO_DEMUXER(tiff, AV_CODEC_ID_TIFF) |
985 | 985 |
IMAGEAUTO_DEMUXER(webp, AV_CODEC_ID_WEBP) |
986 |
+IMAGEAUTO_DEMUXER(xpm, AV_CODEC_ID_XPM) |