a78b454a678e0eb7659d57dd7b54a0da2815ad79
[libav.git] / libavcodec / imgconvert.c
1 /*
2 * Misc image conversion routines
3 * Copyright (c) 2001, 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 /**
23 * @file libavcodec/imgconvert.c
24 * misc image conversion routines
25 */
26
27 /* TODO:
28 * - write 'ffimg' program to test all the image related stuff
29 * - move all api to slice based system
30 * - integrate deinterlacing, postprocessing and scaling in the conversion process
31 */
32
33 #include "avcodec.h"
34 #include "dsputil.h"
35 #include "colorspace.h"
36
37 #if HAVE_MMX
38 #include "x86/mmx.h"
39 #include "x86/dsputil_mmx.h"
40 #endif
41
42 #define xglue(x, y) x ## y
43 #define glue(x, y) xglue(x, y)
44
45 #define FF_COLOR_RGB 0 /**< RGB color space */
46 #define FF_COLOR_GRAY 1 /**< gray color space */
47 #define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
48 #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
49
50 #define FF_PIXEL_PLANAR 0 /**< each channel has one component in AVPicture */
51 #define FF_PIXEL_PACKED 1 /**< only one components containing all the channels */
52 #define FF_PIXEL_PALETTE 2 /**< one components containing indexes for a palette */
53
54 typedef struct PixFmtInfo {
55 const char *name;
56 uint8_t nb_channels; /**< number of channels (including alpha) */
57 uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */
58 uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */
59 uint8_t is_alpha : 1; /**< true if alpha can be specified */
60 uint8_t x_chroma_shift; /**< X chroma subsampling factor is 2 ^ shift */
61 uint8_t y_chroma_shift; /**< Y chroma subsampling factor is 2 ^ shift */
62 uint8_t depth; /**< bit depth of the color components */
63 } PixFmtInfo;
64
65 /* this table gives more information about formats */
66 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
67 /* YUV formats */
68 [PIX_FMT_YUV420P] = {
69 .name = "yuv420p",
70 .nb_channels = 3,
71 .color_type = FF_COLOR_YUV,
72 .pixel_type = FF_PIXEL_PLANAR,
73 .depth = 8,
74 .x_chroma_shift = 1, .y_chroma_shift = 1,
75 },
76 [PIX_FMT_YUV422P] = {
77 .name = "yuv422p",
78 .nb_channels = 3,
79 .color_type = FF_COLOR_YUV,
80 .pixel_type = FF_PIXEL_PLANAR,
81 .depth = 8,
82 .x_chroma_shift = 1, .y_chroma_shift = 0,
83 },
84 [PIX_FMT_YUV444P] = {
85 .name = "yuv444p",
86 .nb_channels = 3,
87 .color_type = FF_COLOR_YUV,
88 .pixel_type = FF_PIXEL_PLANAR,
89 .depth = 8,
90 .x_chroma_shift = 0, .y_chroma_shift = 0,
91 },
92 [PIX_FMT_YUYV422] = {
93 .name = "yuyv422",
94 .nb_channels = 1,
95 .color_type = FF_COLOR_YUV,
96 .pixel_type = FF_PIXEL_PACKED,
97 .depth = 8,
98 .x_chroma_shift = 1, .y_chroma_shift = 0,
99 },
100 [PIX_FMT_UYVY422] = {
101 .name = "uyvy422",
102 .nb_channels = 1,
103 .color_type = FF_COLOR_YUV,
104 .pixel_type = FF_PIXEL_PACKED,
105 .depth = 8,
106 .x_chroma_shift = 1, .y_chroma_shift = 0,
107 },
108 [PIX_FMT_YUV410P] = {
109 .name = "yuv410p",
110 .nb_channels = 3,
111 .color_type = FF_COLOR_YUV,
112 .pixel_type = FF_PIXEL_PLANAR,
113 .depth = 8,
114 .x_chroma_shift = 2, .y_chroma_shift = 2,
115 },
116 [PIX_FMT_YUV411P] = {
117 .name = "yuv411p",
118 .nb_channels = 3,
119 .color_type = FF_COLOR_YUV,
120 .pixel_type = FF_PIXEL_PLANAR,
121 .depth = 8,
122 .x_chroma_shift = 2, .y_chroma_shift = 0,
123 },
124 [PIX_FMT_YUV440P] = {
125 .name = "yuv440p",
126 .nb_channels = 3,
127 .color_type = FF_COLOR_YUV,
128 .pixel_type = FF_PIXEL_PLANAR,
129 .depth = 8,
130 .x_chroma_shift = 0, .y_chroma_shift = 1,
131 },
132
133 /* YUV formats with alpha plane */
134 [PIX_FMT_YUVA420P] = {
135 .name = "yuva420p",
136 .nb_channels = 4,
137 .color_type = FF_COLOR_YUV,
138 .pixel_type = FF_PIXEL_PLANAR,
139 .depth = 8,
140 .x_chroma_shift = 1, .y_chroma_shift = 1,
141 },
142
143 /* JPEG YUV */
144 [PIX_FMT_YUVJ420P] = {
145 .name = "yuvj420p",
146 .nb_channels = 3,
147 .color_type = FF_COLOR_YUV_JPEG,
148 .pixel_type = FF_PIXEL_PLANAR,
149 .depth = 8,
150 .x_chroma_shift = 1, .y_chroma_shift = 1,
151 },
152 [PIX_FMT_YUVJ422P] = {
153 .name = "yuvj422p",
154 .nb_channels = 3,
155 .color_type = FF_COLOR_YUV_JPEG,
156 .pixel_type = FF_PIXEL_PLANAR,
157 .depth = 8,
158 .x_chroma_shift = 1, .y_chroma_shift = 0,
159 },
160 [PIX_FMT_YUVJ444P] = {
161 .name = "yuvj444p",
162 .nb_channels = 3,
163 .color_type = FF_COLOR_YUV_JPEG,
164 .pixel_type = FF_PIXEL_PLANAR,
165 .depth = 8,
166 .x_chroma_shift = 0, .y_chroma_shift = 0,
167 },
168 [PIX_FMT_YUVJ440P] = {
169 .name = "yuvj440p",
170 .nb_channels = 3,
171 .color_type = FF_COLOR_YUV_JPEG,
172 .pixel_type = FF_PIXEL_PLANAR,
173 .depth = 8,
174 .x_chroma_shift = 0, .y_chroma_shift = 1,
175 },
176
177 /* RGB formats */
178 [PIX_FMT_RGB24] = {
179 .name = "rgb24",
180 .nb_channels = 3,
181 .color_type = FF_COLOR_RGB,
182 .pixel_type = FF_PIXEL_PACKED,
183 .depth = 8,
184 .x_chroma_shift = 0, .y_chroma_shift = 0,
185 },
186 [PIX_FMT_BGR24] = {
187 .name = "bgr24",
188 .nb_channels = 3,
189 .color_type = FF_COLOR_RGB,
190 .pixel_type = FF_PIXEL_PACKED,
191 .depth = 8,
192 .x_chroma_shift = 0, .y_chroma_shift = 0,
193 },
194 [PIX_FMT_RGB32] = {
195 .name = "rgb32",
196 .nb_channels = 4, .is_alpha = 1,
197 .color_type = FF_COLOR_RGB,
198 .pixel_type = FF_PIXEL_PACKED,
199 .depth = 8,
200 .x_chroma_shift = 0, .y_chroma_shift = 0,
201 },
202 [PIX_FMT_RGB565] = {
203 .name = "rgb565",
204 .nb_channels = 3,
205 .color_type = FF_COLOR_RGB,
206 .pixel_type = FF_PIXEL_PACKED,
207 .depth = 5,
208 .x_chroma_shift = 0, .y_chroma_shift = 0,
209 },
210 [PIX_FMT_RGB555] = {
211 .name = "rgb555",
212 .nb_channels = 3,
213 .color_type = FF_COLOR_RGB,
214 .pixel_type = FF_PIXEL_PACKED,
215 .depth = 5,
216 .x_chroma_shift = 0, .y_chroma_shift = 0,
217 },
218
219 /* gray / mono formats */
220 [PIX_FMT_GRAY16BE] = {
221 .name = "gray16be",
222 .nb_channels = 1,
223 .color_type = FF_COLOR_GRAY,
224 .pixel_type = FF_PIXEL_PLANAR,
225 .depth = 16,
226 },
227 [PIX_FMT_GRAY16LE] = {
228 .name = "gray16le",
229 .nb_channels = 1,
230 .color_type = FF_COLOR_GRAY,
231 .pixel_type = FF_PIXEL_PLANAR,
232 .depth = 16,
233 },
234 [PIX_FMT_GRAY8] = {
235 .name = "gray",
236 .nb_channels = 1,
237 .color_type = FF_COLOR_GRAY,
238 .pixel_type = FF_PIXEL_PLANAR,
239 .depth = 8,
240 },
241 [PIX_FMT_MONOWHITE] = {
242 .name = "monow",
243 .nb_channels = 1,
244 .color_type = FF_COLOR_GRAY,
245 .pixel_type = FF_PIXEL_PLANAR,
246 .depth = 1,
247 },
248 [PIX_FMT_MONOBLACK] = {
249 .name = "monob",
250 .nb_channels = 1,
251 .color_type = FF_COLOR_GRAY,
252 .pixel_type = FF_PIXEL_PLANAR,
253 .depth = 1,
254 },
255
256 /* paletted formats */
257 [PIX_FMT_PAL8] = {
258 .name = "pal8",
259 .nb_channels = 4, .is_alpha = 1,
260 .color_type = FF_COLOR_RGB,
261 .pixel_type = FF_PIXEL_PALETTE,
262 .depth = 8,
263 },
264 [PIX_FMT_XVMC_MPEG2_MC] = {
265 .name = "xvmcmc",
266 },
267 [PIX_FMT_XVMC_MPEG2_IDCT] = {
268 .name = "xvmcidct",
269 },
270 [PIX_FMT_VDPAU_MPEG1] = {
271 .name = "vdpau_mpeg1",
272 },
273 [PIX_FMT_VDPAU_MPEG2] = {
274 .name = "vdpau_mpeg2",
275 },
276 [PIX_FMT_VDPAU_H264] = {
277 .name = "vdpau_h264",
278 },
279 [PIX_FMT_VDPAU_WMV3] = {
280 .name = "vdpau_wmv3",
281 },
282 [PIX_FMT_VDPAU_VC1] = {
283 .name = "vdpau_vc1",
284 },
285 [PIX_FMT_UYYVYY411] = {
286 .name = "uyyvyy411",
287 .nb_channels = 1,
288 .color_type = FF_COLOR_YUV,
289 .pixel_type = FF_PIXEL_PACKED,
290 .depth = 8,
291 .x_chroma_shift = 2, .y_chroma_shift = 0,
292 },
293 [PIX_FMT_BGR32] = {
294 .name = "bgr32",
295 .nb_channels = 4, .is_alpha = 1,
296 .color_type = FF_COLOR_RGB,
297 .pixel_type = FF_PIXEL_PACKED,
298 .depth = 8,
299 .x_chroma_shift = 0, .y_chroma_shift = 0,
300 },
301 [PIX_FMT_BGR565] = {
302 .name = "bgr565",
303 .nb_channels = 3,
304 .color_type = FF_COLOR_RGB,
305 .pixel_type = FF_PIXEL_PACKED,
306 .depth = 5,
307 .x_chroma_shift = 0, .y_chroma_shift = 0,
308 },
309 [PIX_FMT_BGR555] = {
310 .name = "bgr555",
311 .nb_channels = 3,
312 .color_type = FF_COLOR_RGB,
313 .pixel_type = FF_PIXEL_PACKED,
314 .depth = 5,
315 .x_chroma_shift = 0, .y_chroma_shift = 0,
316 },
317 [PIX_FMT_RGB8] = {
318 .name = "rgb8",
319 .nb_channels = 1,
320 .color_type = FF_COLOR_RGB,
321 .pixel_type = FF_PIXEL_PACKED,
322 .depth = 8,
323 .x_chroma_shift = 0, .y_chroma_shift = 0,
324 },
325 [PIX_FMT_RGB4] = {
326 .name = "rgb4",
327 .nb_channels = 1,
328 .color_type = FF_COLOR_RGB,
329 .pixel_type = FF_PIXEL_PACKED,
330 .depth = 4,
331 .x_chroma_shift = 0, .y_chroma_shift = 0,
332 },
333 [PIX_FMT_RGB4_BYTE] = {
334 .name = "rgb4_byte",
335 .nb_channels = 1,
336 .color_type = FF_COLOR_RGB,
337 .pixel_type = FF_PIXEL_PACKED,
338 .depth = 8,
339 .x_chroma_shift = 0, .y_chroma_shift = 0,
340 },
341 [PIX_FMT_BGR8] = {
342 .name = "bgr8",
343 .nb_channels = 1,
344 .color_type = FF_COLOR_RGB,
345 .pixel_type = FF_PIXEL_PACKED,
346 .depth = 8,
347 .x_chroma_shift = 0, .y_chroma_shift = 0,
348 },
349 [PIX_FMT_BGR4] = {
350 .name = "bgr4",
351 .nb_channels = 1,
352 .color_type = FF_COLOR_RGB,
353 .pixel_type = FF_PIXEL_PACKED,
354 .depth = 4,
355 .x_chroma_shift = 0, .y_chroma_shift = 0,
356 },
357 [PIX_FMT_BGR4_BYTE] = {
358 .name = "bgr4_byte",
359 .nb_channels = 1,
360 .color_type = FF_COLOR_RGB,
361 .pixel_type = FF_PIXEL_PACKED,
362 .depth = 8,
363 .x_chroma_shift = 0, .y_chroma_shift = 0,
364 },
365 [PIX_FMT_NV12] = {
366 .name = "nv12",
367 .nb_channels = 2,
368 .color_type = FF_COLOR_YUV,
369 .pixel_type = FF_PIXEL_PLANAR,
370 .depth = 8,
371 .x_chroma_shift = 1, .y_chroma_shift = 1,
372 },
373 [PIX_FMT_NV21] = {
374 .name = "nv12",
375 .nb_channels = 2,
376 .color_type = FF_COLOR_YUV,
377 .pixel_type = FF_PIXEL_PLANAR,
378 .depth = 8,
379 .x_chroma_shift = 1, .y_chroma_shift = 1,
380 },
381
382 [PIX_FMT_BGR32_1] = {
383 .name = "bgr32_1",
384 .nb_channels = 4, .is_alpha = 1,
385 .color_type = FF_COLOR_RGB,
386 .pixel_type = FF_PIXEL_PACKED,
387 .depth = 8,
388 .x_chroma_shift = 0, .y_chroma_shift = 0,
389 },
390 [PIX_FMT_RGB32_1] = {
391 .name = "rgb32_1",
392 .nb_channels = 4, .is_alpha = 1,
393 .color_type = FF_COLOR_RGB,
394 .pixel_type = FF_PIXEL_PACKED,
395 .depth = 8,
396 .x_chroma_shift = 0, .y_chroma_shift = 0,
397 },
398 };
399
400 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
401 {
402 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
403 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
404 }
405
406 const char *avcodec_get_pix_fmt_name(int pix_fmt)
407 {
408 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
409 return NULL;
410 else
411 return pix_fmt_info[pix_fmt].name;
412 }
413
414 enum PixelFormat avcodec_get_pix_fmt(const char* name)
415 {
416 int i;
417
418 for (i=0; i < PIX_FMT_NB; i++)
419 if (!strcmp(pix_fmt_info[i].name, name))
420 return i;
421 return PIX_FMT_NONE;
422 }
423
424 void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
425 {
426 /* print header */
427 if (pix_fmt < 0)
428 snprintf (buf, buf_size,
429 "name " " nb_channels" " depth" " is_alpha"
430 );
431 else{
432 PixFmtInfo info= pix_fmt_info[pix_fmt];
433
434 char is_alpha_char= info.is_alpha ? 'y' : 'n';
435
436 snprintf (buf, buf_size,
437 "%-10s" " %1d " " %2d " " %c ",
438 info.name,
439 info.nb_channels,
440 info.depth,
441 is_alpha_char
442 );
443 }
444 }
445
446 int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
447 {
448 int w2;
449 const PixFmtInfo *pinfo;
450
451 memset(picture->linesize, 0, sizeof(picture->linesize));
452
453 pinfo = &pix_fmt_info[pix_fmt];
454 switch(pix_fmt) {
455 case PIX_FMT_YUV420P:
456 case PIX_FMT_YUV422P:
457 case PIX_FMT_YUV444P:
458 case PIX_FMT_YUV410P:
459 case PIX_FMT_YUV411P:
460 case PIX_FMT_YUV440P:
461 case PIX_FMT_YUVJ420P:
462 case PIX_FMT_YUVJ422P:
463 case PIX_FMT_YUVJ444P:
464 case PIX_FMT_YUVJ440P:
465 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
466 picture->linesize[0] = width;
467 picture->linesize[1] = w2;
468 picture->linesize[2] = w2;
469 break;
470 case PIX_FMT_YUVA420P:
471 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
472 picture->linesize[0] = width;
473 picture->linesize[1] = w2;
474 picture->linesize[2] = w2;
475 picture->linesize[3] = width;
476 break;
477 case PIX_FMT_NV12:
478 case PIX_FMT_NV21:
479 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
480 picture->linesize[0] = width;
481 picture->linesize[1] = w2;
482 break;
483 case PIX_FMT_RGB24:
484 case PIX_FMT_BGR24:
485 picture->linesize[0] = width * 3;
486 break;
487 case PIX_FMT_RGB32:
488 case PIX_FMT_BGR32:
489 case PIX_FMT_RGB32_1:
490 case PIX_FMT_BGR32_1:
491 picture->linesize[0] = width * 4;
492 break;
493 case PIX_FMT_GRAY16BE:
494 case PIX_FMT_GRAY16LE:
495 case PIX_FMT_BGR555:
496 case PIX_FMT_BGR565:
497 case PIX_FMT_RGB555:
498 case PIX_FMT_RGB565:
499 case PIX_FMT_YUYV422:
500 picture->linesize[0] = width * 2;
501 break;
502 case PIX_FMT_UYVY422:
503 picture->linesize[0] = width * 2;
504 break;
505 case PIX_FMT_UYYVYY411:
506 picture->linesize[0] = width + width/2;
507 break;
508 case PIX_FMT_RGB8:
509 case PIX_FMT_BGR8:
510 case PIX_FMT_RGB4_BYTE:
511 case PIX_FMT_BGR4_BYTE:
512 case PIX_FMT_GRAY8:
513 picture->linesize[0] = width;
514 break;
515 case PIX_FMT_RGB4:
516 case PIX_FMT_BGR4:
517 picture->linesize[0] = width / 2;
518 break;
519 case PIX_FMT_MONOWHITE:
520 case PIX_FMT_MONOBLACK:
521 picture->linesize[0] = (width + 7) >> 3;
522 break;
523 case PIX_FMT_PAL8:
524 picture->linesize[0] = width;
525 picture->linesize[1] = 4;
526 break;
527 default:
528 return -1;
529 }
530 return 0;
531 }
532
533 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
534 int height)
535 {
536 int size, h2, size2;
537 const PixFmtInfo *pinfo;
538
539 pinfo = &pix_fmt_info[pix_fmt];
540 size = picture->linesize[0] * height;
541 switch(pix_fmt) {
542 case PIX_FMT_YUV420P:
543 case PIX_FMT_YUV422P:
544 case PIX_FMT_YUV444P:
545 case PIX_FMT_YUV410P:
546 case PIX_FMT_YUV411P:
547 case PIX_FMT_YUV440P:
548 case PIX_FMT_YUVJ420P:
549 case PIX_FMT_YUVJ422P:
550 case PIX_FMT_YUVJ444P:
551 case PIX_FMT_YUVJ440P:
552 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
553 size2 = picture->linesize[1] * h2;
554 picture->data[0] = ptr;
555 picture->data[1] = picture->data[0] + size;
556 picture->data[2] = picture->data[1] + size2;
557 picture->data[3] = NULL;
558 return size + 2 * size2;
559 case PIX_FMT_YUVA420P:
560 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
561 size2 = picture->linesize[1] * h2;
562 picture->data[0] = ptr;
563 picture->data[1] = picture->data[0] + size;
564 picture->data[2] = picture->data[1] + size2;
565 picture->data[3] = picture->data[1] + size2 + size2;
566 return 2 * size + 2 * size2;
567 case PIX_FMT_NV12:
568 case PIX_FMT_NV21:
569 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
570 size2 = picture->linesize[1] * h2 * 2;
571 picture->data[0] = ptr;
572 picture->data[1] = picture->data[0] + size;
573 picture->data[2] = NULL;
574 picture->data[3] = NULL;
575 return size + 2 * size2;
576 case PIX_FMT_RGB24:
577 case PIX_FMT_BGR24:
578 case PIX_FMT_RGB32:
579 case PIX_FMT_BGR32:
580 case PIX_FMT_RGB32_1:
581 case PIX_FMT_BGR32_1:
582 case PIX_FMT_GRAY16BE:
583 case PIX_FMT_GRAY16LE:
584 case PIX_FMT_BGR555:
585 case PIX_FMT_BGR565:
586 case PIX_FMT_RGB555:
587 case PIX_FMT_RGB565:
588 case PIX_FMT_YUYV422:
589 case PIX_FMT_UYVY422:
590 case PIX_FMT_UYYVYY411:
591 case PIX_FMT_RGB8:
592 case PIX_FMT_BGR8:
593 case PIX_FMT_RGB4_BYTE:
594 case PIX_FMT_BGR4_BYTE:
595 case PIX_FMT_GRAY8:
596 case PIX_FMT_RGB4:
597 case PIX_FMT_BGR4:
598 case PIX_FMT_MONOWHITE:
599 case PIX_FMT_MONOBLACK:
600 picture->data[0] = ptr;
601 picture->data[1] = NULL;
602 picture->data[2] = NULL;
603 picture->data[3] = NULL;
604 return size;
605 case PIX_FMT_PAL8:
606 size2 = (size + 3) & ~3;
607 picture->data[0] = ptr;
608 picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
609 picture->data[2] = NULL;
610 picture->data[3] = NULL;
611 return size2 + 256 * 4;
612 default:
613 picture->data[0] = NULL;
614 picture->data[1] = NULL;
615 picture->data[2] = NULL;
616 picture->data[3] = NULL;
617 return -1;
618 }
619 }
620
621 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
622 int pix_fmt, int width, int height)
623 {
624
625 if(avcodec_check_dimensions(NULL, width, height))
626 return -1;
627
628 if (ff_fill_linesize(picture, pix_fmt, width))
629 return -1;
630
631 return ff_fill_pointer(picture, ptr, pix_fmt, height);
632 }
633
634 int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
635 unsigned char *dest, int dest_size)
636 {
637 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
638 int i, j, w, h, data_planes;
639 const unsigned char* s;
640 int size = avpicture_get_size(pix_fmt, width, height);
641
642 if (size > dest_size || size < 0)
643 return -1;
644
645 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
646 if (pix_fmt == PIX_FMT_YUYV422 ||
647 pix_fmt == PIX_FMT_UYVY422 ||
648 pix_fmt == PIX_FMT_BGR565 ||
649 pix_fmt == PIX_FMT_BGR555 ||
650 pix_fmt == PIX_FMT_RGB565 ||
651 pix_fmt == PIX_FMT_RGB555)
652 w = width * 2;
653 else if (pix_fmt == PIX_FMT_UYYVYY411)
654 w = width + width/2;
655 else if (pix_fmt == PIX_FMT_PAL8)
656 w = width;
657 else
658 w = width * (pf->depth * pf->nb_channels / 8);
659
660 data_planes = 1;
661 h = height;
662 } else {
663 data_planes = pf->nb_channels;
664 w = (width*pf->depth + 7)/8;
665 h = height;
666 }
667
668 for (i=0; i<data_planes; i++) {
669 if (i == 1) {
670 w = width >> pf->x_chroma_shift;
671 h = height >> pf->y_chroma_shift;
672 }
673 s = src->data[i];
674 for(j=0; j<h; j++) {
675 memcpy(dest, s, w);
676 dest += w;
677 s += src->linesize[i];
678 }
679 }
680
681 if (pf->pixel_type == FF_PIXEL_PALETTE)
682 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
683
684 return size;
685 }
686
687 int avpicture_get_size(int pix_fmt, int width, int height)
688 {
689 AVPicture dummy_pict;
690 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
691 }
692
693 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
694 int has_alpha)
695 {
696 const PixFmtInfo *pf, *ps;
697 int loss;
698
699 ps = &pix_fmt_info[src_pix_fmt];
700 pf = &pix_fmt_info[dst_pix_fmt];
701
702 /* compute loss */
703 loss = 0;
704 pf = &pix_fmt_info[dst_pix_fmt];
705 if (pf->depth < ps->depth ||
706 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
707 loss |= FF_LOSS_DEPTH;
708 if (pf->x_chroma_shift > ps->x_chroma_shift ||
709 pf->y_chroma_shift > ps->y_chroma_shift)
710 loss |= FF_LOSS_RESOLUTION;
711 switch(pf->color_type) {
712 case FF_COLOR_RGB:
713 if (ps->color_type != FF_COLOR_RGB &&
714 ps->color_type != FF_COLOR_GRAY)
715 loss |= FF_LOSS_COLORSPACE;
716 break;
717 case FF_COLOR_GRAY:
718 if (ps->color_type != FF_COLOR_GRAY)
719 loss |= FF_LOSS_COLORSPACE;
720 break;
721 case FF_COLOR_YUV:
722 if (ps->color_type != FF_COLOR_YUV)
723 loss |= FF_LOSS_COLORSPACE;
724 break;
725 case FF_COLOR_YUV_JPEG:
726 if (ps->color_type != FF_COLOR_YUV_JPEG &&
727 ps->color_type != FF_COLOR_YUV &&
728 ps->color_type != FF_COLOR_GRAY)
729 loss |= FF_LOSS_COLORSPACE;
730 break;
731 default:
732 /* fail safe test */
733 if (ps->color_type != pf->color_type)
734 loss |= FF_LOSS_COLORSPACE;
735 break;
736 }
737 if (pf->color_type == FF_COLOR_GRAY &&
738 ps->color_type != FF_COLOR_GRAY)
739 loss |= FF_LOSS_CHROMA;
740 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
741 loss |= FF_LOSS_ALPHA;
742 if (pf->pixel_type == FF_PIXEL_PALETTE &&
743 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
744 loss |= FF_LOSS_COLORQUANT;
745 return loss;
746 }
747
748 static int avg_bits_per_pixel(int pix_fmt)
749 {
750 int bits;
751 const PixFmtInfo *pf;
752
753 pf = &pix_fmt_info[pix_fmt];
754 switch(pf->pixel_type) {
755 case FF_PIXEL_PACKED:
756 switch(pix_fmt) {
757 case PIX_FMT_YUYV422:
758 case PIX_FMT_UYVY422:
759 case PIX_FMT_RGB565:
760 case PIX_FMT_RGB555:
761 case PIX_FMT_BGR565:
762 case PIX_FMT_BGR555:
763 bits = 16;
764 break;
765 case PIX_FMT_UYYVYY411:
766 bits = 12;
767 break;
768 default:
769 bits = pf->depth * pf->nb_channels;
770 break;
771 }
772 break;
773 case FF_PIXEL_PLANAR:
774 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
775 bits = pf->depth * pf->nb_channels;
776 } else {
777 bits = pf->depth + ((2 * pf->depth) >>
778 (pf->x_chroma_shift + pf->y_chroma_shift));
779 }
780 break;
781 case FF_PIXEL_PALETTE:
782 bits = 8;
783 break;
784 default:
785 bits = -1;
786 break;
787 }
788 return bits;
789 }
790
791 static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
792 int src_pix_fmt,
793 int has_alpha,
794 int loss_mask)
795 {
796 int dist, i, loss, min_dist, dst_pix_fmt;
797
798 /* find exact color match with smallest size */
799 dst_pix_fmt = -1;
800 min_dist = 0x7fffffff;
801 for(i = 0;i < PIX_FMT_NB; i++) {
802 if (pix_fmt_mask & (1ULL << i)) {
803 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
804 if (loss == 0) {
805 dist = avg_bits_per_pixel(i);
806 if (dist < min_dist) {
807 min_dist = dist;
808 dst_pix_fmt = i;
809 }
810 }
811 }
812 }
813 return dst_pix_fmt;
814 }
815
816 int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
817 int has_alpha, int *loss_ptr)
818 {
819 int dst_pix_fmt, loss_mask, i;
820 static const int loss_mask_order[] = {
821 ~0, /* no loss first */
822 ~FF_LOSS_ALPHA,
823 ~FF_LOSS_RESOLUTION,
824 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
825 ~FF_LOSS_COLORQUANT,
826 ~FF_LOSS_DEPTH,
827 0,
828 };
829
830 /* try with successive loss */
831 i = 0;
832 for(;;) {
833 loss_mask = loss_mask_order[i++];
834 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
835 has_alpha, loss_mask);
836 if (dst_pix_fmt >= 0)
837 goto found;
838 if (loss_mask == 0)
839 break;
840 }
841 return -1;
842 found:
843 if (loss_ptr)
844 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
845 return dst_pix_fmt;
846 }
847
848 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
849 const uint8_t *src, int src_wrap,
850 int width, int height)
851 {
852 if((!dst) || (!src))
853 return;
854 for(;height > 0; height--) {
855 memcpy(dst, src, width);
856 dst += dst_wrap;
857 src += src_wrap;
858 }
859 }
860
861 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
862 {
863 int bits;
864 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
865
866 pf = &pix_fmt_info[pix_fmt];
867 switch(pf->pixel_type) {
868 case FF_PIXEL_PACKED:
869 switch(pix_fmt) {
870 case PIX_FMT_YUYV422:
871 case PIX_FMT_UYVY422:
872 case PIX_FMT_RGB565:
873 case PIX_FMT_RGB555:
874 case PIX_FMT_BGR565:
875 case PIX_FMT_BGR555:
876 bits = 16;
877 break;
878 case PIX_FMT_UYYVYY411:
879 bits = 12;
880 break;
881 default:
882 bits = pf->depth * pf->nb_channels;
883 break;
884 }
885 return (width * bits + 7) >> 3;
886 break;
887 case FF_PIXEL_PLANAR:
888 if (plane == 1 || plane == 2)
889 width= -((-width)>>pf->x_chroma_shift);
890
891 return (width * pf->depth + 7) >> 3;
892 break;
893 case FF_PIXEL_PALETTE:
894 if (plane == 0)
895 return width;
896 break;
897 }
898
899 return -1;
900 }
901
902 void av_picture_copy(AVPicture *dst, const AVPicture *src,
903 int pix_fmt, int width, int height)
904 {
905 int i;
906 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
907
908 pf = &pix_fmt_info[pix_fmt];
909 switch(pf->pixel_type) {
910 case FF_PIXEL_PACKED:
911 case FF_PIXEL_PLANAR:
912 for(i = 0; i < pf->nb_channels; i++) {
913 int h;
914 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
915 h = height;
916 if (i == 1 || i == 2) {
917 h= -((-height)>>pf->y_chroma_shift);
918 }
919 ff_img_copy_plane(dst->data[i], dst->linesize[i],
920 src->data[i], src->linesize[i],
921 bwidth, h);
922 }
923 break;
924 case FF_PIXEL_PALETTE:
925 ff_img_copy_plane(dst->data[0], dst->linesize[0],
926 src->data[0], src->linesize[0],
927 width, height);
928 /* copy the palette */
929 ff_img_copy_plane(dst->data[1], dst->linesize[1],
930 src->data[1], src->linesize[1],
931 4, 256);
932 break;
933 }
934 }
935
936 /* XXX: totally non optimized */
937
938 static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
939 int width, int height)
940 {
941 const uint8_t *p, *p1;
942 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
943 int w;
944
945 p1 = src->data[0];
946 lum1 = dst->data[0];
947 cb1 = dst->data[1];
948 cr1 = dst->data[2];
949
950 for(;height >= 1; height -= 2) {
951 p = p1;
952 lum = lum1;
953 cb = cb1;
954 cr = cr1;
955 for(w = width; w >= 2; w -= 2) {
956 lum[0] = p[0];
957 cb[0] = p[1];
958 lum[1] = p[2];
959 cr[0] = p[3];
960 p += 4;
961 lum += 2;
962 cb++;
963 cr++;
964 }
965 if (w) {
966 lum[0] = p[0];
967 cb[0] = p[1];
968 cr[0] = p[3];
969 cb++;
970 cr++;
971 }
972 p1 += src->linesize[0];
973 lum1 += dst->linesize[0];
974 if (height>1) {
975 p = p1;
976 lum = lum1;
977 for(w = width; w >= 2; w -= 2) {
978 lum[0] = p[0];
979 lum[1] = p[2];
980 p += 4;
981 lum += 2;
982 }
983 if (w) {
984 lum[0] = p[0];
985 }
986 p1 += src->linesize[0];
987 lum1 += dst->linesize[0];
988 }
989 cb1 += dst->linesize[1];
990 cr1 += dst->linesize[2];
991 }
992 }
993
994 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
995 int width, int height)
996 {
997 const uint8_t *p, *p1;
998 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
999 int w;
1000
1001 p1 = src->data[0];
1002
1003 lum1 = dst->data[0];
1004 cb1 = dst->data[1];
1005 cr1 = dst->data[2];
1006
1007 for(;height >= 1; height -= 2) {
1008 p = p1;
1009 lum = lum1;
1010 cb = cb1;
1011 cr = cr1;
1012 for(w = width; w >= 2; w -= 2) {
1013 lum[0] = p[1];
1014 cb[0] = p[0];
1015 lum[1] = p[3];
1016 cr[0] = p[2];
1017 p += 4;
1018 lum += 2;
1019 cb++;
1020 cr++;
1021 }
1022 if (w) {
1023 lum[0] = p[1];
1024 cb[0] = p[0];
1025 cr[0] = p[2];
1026 cb++;
1027 cr++;
1028 }
1029 p1 += src->linesize[0];
1030 lum1 += dst->linesize[0];
1031 if (height>1) {
1032 p = p1;
1033 lum = lum1;
1034 for(w = width; w >= 2; w -= 2) {
1035 lum[0] = p[1];
1036 lum[1] = p[3];
1037 p += 4;
1038 lum += 2;
1039 }
1040 if (w) {
1041 lum[0] = p[1];
1042 }
1043 p1 += src->linesize[0];
1044 lum1 += dst->linesize[0];
1045 }
1046 cb1 += dst->linesize[1];
1047 cr1 += dst->linesize[2];
1048 }
1049 }
1050
1051
1052 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1053 int width, int height)
1054 {
1055 const uint8_t *p, *p1;
1056 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1057 int w;
1058
1059 p1 = src->data[0];
1060 lum1 = dst->data[0];
1061 cb1 = dst->data[1];
1062 cr1 = dst->data[2];
1063 for(;height > 0; height--) {
1064 p = p1;
1065 lum = lum1;
1066 cb = cb1;
1067 cr = cr1;
1068 for(w = width; w >= 2; w -= 2) {
1069 lum[0] = p[1];
1070 cb[0] = p[0];
1071 lum[1] = p[3];
1072 cr[0] = p[2];
1073 p += 4;
1074 lum += 2;
1075 cb++;
1076 cr++;
1077 }
1078 p1 += src->linesize[0];
1079 lum1 += dst->linesize[0];
1080 cb1 += dst->linesize[1];
1081 cr1 += dst->linesize[2];
1082 }
1083 }
1084
1085
1086 static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1087 int width, int height)
1088 {
1089 const uint8_t *p, *p1;
1090 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1091 int w;
1092
1093 p1 = src->data[0];
1094 lum1 = dst->data[0];
1095 cb1 = dst->data[1];
1096 cr1 = dst->data[2];
1097 for(;height > 0; height--) {
1098 p = p1;
1099 lum = lum1;
1100 cb = cb1;
1101 cr = cr1;
1102 for(w = width; w >= 2; w -= 2) {
1103 lum[0] = p[0];
1104 cb[0] = p[1];
1105 lum[1] = p[2];
1106 cr[0] = p[3];
1107 p += 4;
1108 lum += 2;
1109 cb++;
1110 cr++;
1111 }
1112 p1 += src->linesize[0];
1113 lum1 += dst->linesize[0];
1114 cb1 += dst->linesize[1];
1115 cr1 += dst->linesize[2];
1116 }
1117 }
1118
1119 static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1120 int width, int height)
1121 {
1122 uint8_t *p, *p1;
1123 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1124 int w;
1125
1126 p1 = dst->data[0];
1127 lum1 = src->data[0];
1128 cb1 = src->data[1];
1129 cr1 = src->data[2];
1130 for(;height > 0; height--) {
1131 p = p1;
1132 lum = lum1;
1133 cb = cb1;
1134 cr = cr1;
1135 for(w = width; w >= 2; w -= 2) {
1136 p[0] = lum[0];
1137 p[1] = cb[0];
1138 p[2] = lum[1];
1139 p[3] = cr[0];
1140 p += 4;
1141 lum += 2;
1142 cb++;
1143 cr++;
1144 }
1145 p1 += dst->linesize[0];
1146 lum1 += src->linesize[0];
1147 cb1 += src->linesize[1];
1148 cr1 += src->linesize[2];
1149 }
1150 }
1151
1152 static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1153 int width, int height)
1154 {
1155 uint8_t *p, *p1;
1156 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1157 int w;
1158
1159 p1 = dst->data[0];
1160 lum1 = src->data[0];
1161 cb1 = src->data[1];
1162 cr1 = src->data[2];
1163 for(;height > 0; height--) {
1164 p = p1;
1165 lum = lum1;
1166 cb = cb1;
1167 cr = cr1;
1168 for(w = width; w >= 2; w -= 2) {
1169 p[1] = lum[0];
1170 p[0] = cb[0];
1171 p[3] = lum[1];
1172 p[2] = cr[0];
1173 p += 4;
1174 lum += 2;
1175 cb++;
1176 cr++;
1177 }
1178 p1 += dst->linesize[0];
1179 lum1 += src->linesize[0];
1180 cb1 += src->linesize[1];
1181 cr1 += src->linesize[2];
1182 }
1183 }
1184
1185 static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1186 int width, int height)
1187 {
1188 const uint8_t *p, *p1;
1189 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1190 int w;
1191
1192 p1 = src->data[0];
1193 lum1 = dst->data[0];
1194 cb1 = dst->data[1];
1195 cr1 = dst->data[2];
1196 for(;height > 0; height--) {
1197 p = p1;
1198 lum = lum1;
1199 cb = cb1;
1200 cr = cr1;
1201 for(w = width; w >= 4; w -= 4) {
1202 cb[0] = p[0];
1203 lum[0] = p[1];
1204 lum[1] = p[2];
1205 cr[0] = p[3];
1206 lum[2] = p[4];
1207 lum[3] = p[5];
1208 p += 6;
1209 lum += 4;
1210 cb++;
1211 cr++;
1212 }
1213 p1 += src->linesize[0];
1214 lum1 += dst->linesize[0];
1215 cb1 += dst->linesize[1];
1216 cr1 += dst->linesize[2];
1217 }
1218 }
1219
1220
1221 static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1222 int width, int height)
1223 {
1224 int w, h;
1225 uint8_t *line1, *line2, *linesrc = dst->data[0];
1226 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1227 uint8_t *cb1, *cb2 = src->data[1];
1228 uint8_t *cr1, *cr2 = src->data[2];
1229
1230 for(h = height / 2; h--;) {
1231 line1 = linesrc;
1232 line2 = linesrc + dst->linesize[0];
1233
1234 lum1 = lumsrc;
1235 lum2 = lumsrc + src->linesize[0];
1236
1237 cb1 = cb2;
1238 cr1 = cr2;
1239
1240 for(w = width / 2; w--;) {
1241 *line1++ = *lum1++; *line2++ = *lum2++;
1242 *line1++ = *line2++ = *cb1++;
1243 *line1++ = *lum1++; *line2++ = *lum2++;
1244 *line1++ = *line2++ = *cr1++;
1245 }
1246
1247 linesrc += dst->linesize[0] * 2;
1248 lumsrc += src->linesize[0] * 2;
1249 cb2 += src->linesize[1];
1250 cr2 += src->linesize[2];
1251 }
1252 }
1253
1254 static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1255 int width, int height)
1256 {
1257 int w, h;
1258 uint8_t *line1, *line2, *linesrc = dst->data[0];
1259 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1260 uint8_t *cb1, *cb2 = src->data[1];
1261 uint8_t *cr1, *cr2 = src->data[2];
1262
1263 for(h = height / 2; h--;) {
1264 line1 = linesrc;
1265 line2 = linesrc + dst->linesize[0];
1266
1267 lum1 = lumsrc;
1268 lum2 = lumsrc + src->linesize[0];
1269
1270 cb1 = cb2;
1271 cr1 = cr2;
1272
1273 for(w = width / 2; w--;) {
1274 *line1++ = *line2++ = *cb1++;
1275 *line1++ = *lum1++; *line2++ = *lum2++;
1276 *line1++ = *line2++ = *cr1++;
1277 *line1++ = *lum1++; *line2++ = *lum2++;
1278 }
1279
1280 linesrc += dst->linesize[0] * 2;
1281 lumsrc += src->linesize[0] * 2;
1282 cb2 += src->linesize[1];
1283 cr2 += src->linesize[2];
1284 }
1285 }
1286
1287 /* 2x2 -> 1x1 */
1288 void ff_shrink22(uint8_t *dst, int dst_wrap,
1289 const uint8_t *src, int src_wrap,
1290 int width, int height)
1291 {
1292 int w;
1293 const uint8_t *s1, *s2;
1294 uint8_t *d;
1295
1296 for(;height > 0; height--) {
1297 s1 = src;
1298 s2 = s1 + src_wrap;
1299 d = dst;
1300 for(w = width;w >= 4; w-=4) {
1301 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1302 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1303 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1304 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1305 s1 += 8;
1306 s2 += 8;
1307 d += 4;
1308 }
1309 for(;w > 0; w--) {
1310 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1311 s1 += 2;
1312 s2 += 2;
1313 d++;
1314 }
1315 src += 2 * src_wrap;
1316 dst += dst_wrap;
1317 }
1318 }
1319
1320 /* 4x4 -> 1x1 */
1321 void ff_shrink44(uint8_t *dst, int dst_wrap,
1322 const uint8_t *src, int src_wrap,
1323 int width, int height)
1324 {
1325 int w;
1326 const uint8_t *s1, *s2, *s3, *s4;
1327 uint8_t *d;
1328
1329 for(;height > 0; height--) {
1330 s1 = src;
1331 s2 = s1 + src_wrap;
1332 s3 = s2 + src_wrap;
1333 s4 = s3 + src_wrap;
1334 d = dst;
1335 for(w = width;w > 0; w--) {
1336 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1337 s2[0] + s2[1] + s2[2] + s2[3] +
1338 s3[0] + s3[1] + s3[2] + s3[3] +
1339 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1340 s1 += 4;
1341 s2 += 4;
1342 s3 += 4;
1343 s4 += 4;
1344 d++;
1345 }
1346 src += 4 * src_wrap;
1347 dst += dst_wrap;
1348 }
1349 }
1350
1351 /* 8x8 -> 1x1 */
1352 void ff_shrink88(uint8_t *dst, int dst_wrap,
1353 const uint8_t *src, int src_wrap,
1354 int width, int height)
1355 {
1356 int w, i;
1357
1358 for(;height > 0; height--) {
1359 for(w = width;w > 0; w--) {
1360 int tmp=0;
1361 for(i=0; i<8; i++){
1362 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1363 src += src_wrap;
1364 }
1365 *(dst++) = (tmp + 32)>>6;
1366 src += 8 - 8*src_wrap;
1367 }
1368 src += 8*src_wrap - 8*width;
1369 dst += dst_wrap - width;
1370 }
1371 }
1372
1373 /* XXX: add jpeg quantize code */
1374
1375 #define TRANSP_INDEX (6*6*6)
1376
1377 /* this is maybe slow, but allows for extensions */
1378 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1379 {
1380 return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
1381 }
1382
1383 static void build_rgb_palette(uint8_t *palette, int has_alpha)
1384 {
1385 uint32_t *pal;
1386 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1387 int i, r, g, b;
1388
1389 pal = (uint32_t *)palette;
1390 i = 0;
1391 for(r = 0; r < 6; r++) {
1392 for(g = 0; g < 6; g++) {
1393 for(b = 0; b < 6; b++) {
1394 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1395 (pal_value[g] << 8) | pal_value[b];
1396 }
1397 }
1398 }
1399 if (has_alpha)
1400 pal[i++] = 0;
1401 while (i < 256)
1402 pal[i++] = 0xff000000;
1403 }
1404
1405 /* copy bit n to bits 0 ... n - 1 */
1406 static inline unsigned int bitcopy_n(unsigned int a, int n)
1407 {
1408 int mask;
1409 mask = (1 << n) - 1;
1410 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1411 }
1412
1413 /* rgb555 handling */
1414
1415 #define RGB_NAME rgb555
1416
1417 #define RGB_IN(r, g, b, s)\
1418 {\
1419 unsigned int v = ((const uint16_t *)(s))[0];\
1420 r = bitcopy_n(v >> (10 - 3), 3);\
1421 g = bitcopy_n(v >> (5 - 3), 3);\
1422 b = bitcopy_n(v << 3, 3);\
1423 }
1424
1425
1426 #define RGB_OUT(d, r, g, b)\
1427 {\
1428 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1429 }
1430
1431 #define BPP 2
1432
1433 #include "imgconvert_template.c"
1434
1435 /* rgb565 handling */
1436
1437 #define RGB_NAME rgb565
1438
1439 #define RGB_IN(r, g, b, s)\
1440 {\
1441 unsigned int v = ((const uint16_t *)(s))[0];\
1442 r = bitcopy_n(v >> (11 - 3), 3);\
1443 g = bitcopy_n(v >> (5 - 2), 2);\
1444 b = bitcopy_n(v << 3, 3);\
1445 }
1446
1447 #define RGB_OUT(d, r, g, b)\
1448 {\
1449 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1450 }
1451
1452 #define BPP 2
1453
1454 #include "imgconvert_template.c"
1455
1456 /* bgr24 handling */
1457
1458 #define RGB_NAME bgr24
1459
1460 #define RGB_IN(r, g, b, s)\
1461 {\
1462 b = (s)[0];\
1463 g = (s)[1];\
1464 r = (s)[2];\
1465 }
1466
1467 #define RGB_OUT(d, r, g, b)\
1468 {\
1469 (d)[0] = b;\
1470 (d)[1] = g;\
1471 (d)[2] = r;\
1472 }
1473
1474 #define BPP 3
1475
1476 #include "imgconvert_template.c"
1477
1478 #undef RGB_IN
1479 #undef RGB_OUT
1480 #undef BPP
1481
1482 /* rgb24 handling */
1483
1484 #define RGB_NAME rgb24
1485 #define FMT_RGB24
1486
1487 #define RGB_IN(r, g, b, s)\
1488 {\
1489 r = (s)[0];\
1490 g = (s)[1];\
1491 b = (s)[2];\
1492 }
1493
1494 #define RGB_OUT(d, r, g, b)\
1495 {\
1496 (d)[0] = r;\
1497 (d)[1] = g;\
1498 (d)[2] = b;\
1499 }
1500
1501 #define BPP 3
1502
1503 #include "imgconvert_template.c"
1504
1505 /* rgb32 handling */
1506
1507 #define RGB_NAME rgb32
1508 #define FMT_RGB32
1509
1510 #define RGB_IN(r, g, b, s)\
1511 {\
1512 unsigned int v = ((const uint32_t *)(s))[0];\
1513 r = (v >> 16) & 0xff;\
1514 g = (v >> 8) & 0xff;\
1515 b = v & 0xff;\
1516 }
1517
1518 #define RGBA_IN(r, g, b, a, s)\
1519 {\
1520 unsigned int v = ((const uint32_t *)(s))[0];\
1521 a = (v >> 24) & 0xff;\
1522 r = (v >> 16) & 0xff;\
1523 g = (v >> 8) & 0xff;\
1524 b = v & 0xff;\
1525 }
1526
1527 #define RGBA_OUT(d, r, g, b, a)\
1528 {\
1529 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1530 }
1531
1532 #define BPP 4
1533
1534 #include "imgconvert_template.c"
1535
1536 static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1537 int width, int height, int xor_mask)
1538 {
1539 const unsigned char *p;
1540 unsigned char *q;
1541 int v, dst_wrap, src_wrap;
1542 int y, w;
1543
1544 p = src->data[0];
1545 src_wrap = src->linesize[0] - ((width + 7) >> 3);
1546
1547 q = dst->data[0];
1548 dst_wrap = dst->linesize[0] - width;
1549 for(y=0;y<height;y++) {
1550 w = width;
1551 while (w >= 8) {
1552 v = *p++ ^ xor_mask;
1553 q[0] = -(v >> 7);
1554 q[1] = -((v >> 6) & 1);
1555 q[2] = -((v >> 5) & 1);
1556 q[3] = -((v >> 4) & 1);
1557 q[4] = -((v >> 3) & 1);
1558 q[5] = -((v >> 2) & 1);
1559 q[6] = -((v >> 1) & 1);
1560 q[7] = -((v >> 0) & 1);
1561 w -= 8;
1562 q += 8;
1563 }
1564 if (w > 0) {
1565 v = *p++ ^ xor_mask;
1566 do {
1567 q[0] = -((v >> 7) & 1);
1568 q++;
1569 v <<= 1;
1570 } while (--w);
1571 }
1572 p += src_wrap;
1573 q += dst_wrap;
1574 }
1575 }
1576
1577 static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1578 int width, int height)
1579 {
1580 mono_to_gray(dst, src, width, height, 0xff);
1581 }
1582
1583 static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1584 int width, int height)
1585 {
1586 mono_to_gray(dst, src, width, height, 0x00);
1587 }
1588
1589 static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1590 int width, int height, int xor_mask)
1591 {
1592 int n;
1593 const uint8_t *s;
1594 uint8_t *d;
1595 int j, b, v, n1, src_wrap, dst_wrap, y;
1596
1597 s = src->data[0];
1598 src_wrap = src->linesize[0] - width;
1599
1600 d = dst->data[0];
1601 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1602
1603 for(y=0;y<height;y++) {
1604 n = width;
1605 while (n >= 8) {
1606 v = 0;
1607 for(j=0;j<8;j++) {
1608 b = s[0];
1609 s++;
1610 v = (v << 1) | (b >> 7);
1611 }
1612 d[0] = v ^ xor_mask;
1613 d++;
1614 n -= 8;
1615 }
1616 if (n > 0) {
1617 n1 = n;
1618 v = 0;
1619 while (n > 0) {
1620 b = s[0];
1621 s++;
1622 v = (v << 1) | (b >> 7);
1623 n--;
1624 }
1625 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1626 d++;
1627 }
1628 s += src_wrap;
1629 d += dst_wrap;
1630 }
1631 }
1632
1633 static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1634 int width, int height)
1635 {
1636 gray_to_mono(dst, src, width, height, 0xff);
1637 }
1638
1639 static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1640 int width, int height)
1641 {
1642 gray_to_mono(dst, src, width, height, 0x00);
1643 }
1644
1645 static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1646 int width, int height)
1647 {
1648 int x, y, src_wrap, dst_wrap;
1649 uint8_t *s, *d;
1650 s = src->data[0];
1651 src_wrap = src->linesize[0] - width;
1652 d = dst->data[0];
1653 dst_wrap = dst->linesize[0] - width * 2;
1654 for(y=0; y<height; y++){
1655 for(x=0; x<width; x++){
1656 *d++ = *s;
1657 *d++ = *s++;
1658 }
1659 s += src_wrap;
1660 d += dst_wrap;
1661 }
1662 }
1663
1664 static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1665 int width, int height)
1666 {
1667 int x, y, src_wrap, dst_wrap;
1668 uint8_t *s, *d;
1669 s = src->data[0];
1670 src_wrap = src->linesize[0] - width * 2;
1671 d = dst->data[0];
1672 dst_wrap = dst->linesize[0] - width;
1673 for(y=0; y<height; y++){
1674 for(x=0; x<width; x++){
1675 *d++ = *s;
1676 s += 2;
1677 }
1678 s += src_wrap;
1679 d += dst_wrap;
1680 }
1681 }
1682
1683 static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1684 int width, int height)
1685 {
1686 gray16_to_gray(dst, src, width, height);
1687 }
1688
1689 static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1690 int width, int height)
1691 {
1692 AVPicture tmpsrc = *src;
1693 tmpsrc.data[0]++;
1694 gray16_to_gray(dst, &tmpsrc, width, height);
1695 }
1696
1697 static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1698 int width, int height)
1699 {
1700 int x, y, src_wrap, dst_wrap;
1701 uint16_t *s, *d;
1702 s = (uint16_t*)src->data[0];
1703 src_wrap = (src->linesize[0] - width * 2)/2;
1704 d = (uint16_t*)dst->data[0];
1705 dst_wrap = (dst->linesize[0] - width * 2)/2;
1706 for(y=0; y<height; y++){
1707 for(x=0; x<width; x++){
1708 *d++ = bswap_16(*s++);
1709 }
1710 s += src_wrap;
1711 d += dst_wrap;
1712 }
1713 }
1714
1715
1716 typedef struct ConvertEntry {
1717 void (*convert)(AVPicture *dst,
1718 const AVPicture *src, int width, int height);
1719 } ConvertEntry;
1720
1721 /* Add each new conversion function in this table. In order to be able
1722 to convert from any format to any format, the following constraints
1723 must be satisfied:
1724
1725 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1726
1727 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1728
1729 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
1730
1731 - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1732 PIX_FMT_RGB24.
1733
1734 - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1735
1736 The other conversion functions are just optimizations for common cases.
1737 */
1738 static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1739 [PIX_FMT_YUV420P] = {
1740 [PIX_FMT_YUYV422] = {
1741 .convert = yuv420p_to_yuyv422,
1742 },
1743 [PIX_FMT_RGB555] = {
1744 .convert = yuv420p_to_rgb555
1745 },
1746 [PIX_FMT_RGB565] = {
1747 .convert = yuv420p_to_rgb565
1748 },
1749 [PIX_FMT_BGR24] = {
1750 .convert = yuv420p_to_bgr24
1751 },
1752 [PIX_FMT_RGB24] = {
1753 .convert = yuv420p_to_rgb24
1754 },
1755 [PIX_FMT_RGB32] = {
1756 .convert = yuv420p_to_rgb32
1757 },
1758 [PIX_FMT_UYVY422] = {
1759 .convert = yuv420p_to_uyvy422,
1760 },
1761 },
1762 [PIX_FMT_YUV422P] = {
1763 [PIX_FMT_YUYV422] = {
1764 .convert = yuv422p_to_yuyv422,
1765 },
1766 [PIX_FMT_UYVY422] = {
1767 .convert = yuv422p_to_uyvy422,
1768 },
1769 },
1770 [PIX_FMT_YUV444P] = {
1771 [PIX_FMT_RGB24] = {
1772 .convert = yuv444p_to_rgb24
1773 },
1774 },
1775 [PIX_FMT_YUVJ420P] = {
1776 [PIX_FMT_RGB555] = {
1777 .convert = yuvj420p_to_rgb555
1778 },
1779 [PIX_FMT_RGB565] = {
1780 .convert = yuvj420p_to_rgb565
1781 },
1782 [PIX_FMT_BGR24] = {
1783 .convert = yuvj420p_to_bgr24
1784 },
1785 [PIX_FMT_RGB24] = {
1786 .convert = yuvj420p_to_rgb24
1787 },
1788 [PIX_FMT_RGB32] = {
1789 .convert = yuvj420p_to_rgb32
1790 },
1791 },
1792 [PIX_FMT_YUVJ444P] = {
1793 [PIX_FMT_RGB24] = {
1794 .convert = yuvj444p_to_rgb24
1795 },
1796 },
1797 [PIX_FMT_YUYV422] = {
1798 [PIX_FMT_YUV420P] = {
1799 .convert = yuyv422_to_yuv420p,
1800 },
1801 [PIX_FMT_YUV422P] = {
1802 .convert = yuyv422_to_yuv422p,
1803 },
1804 },
1805 [PIX_FMT_UYVY422] = {
1806 [PIX_FMT_YUV420P] = {
1807 .convert = uyvy422_to_yuv420p,
1808 },
1809 [PIX_FMT_YUV422P] = {
1810 .convert = uyvy422_to_yuv422p,
1811 },
1812 },
1813 [PIX_FMT_RGB24] = {
1814 [PIX_FMT_YUV420P] = {
1815 .convert = rgb24_to_yuv420p
1816 },
1817 [PIX_FMT_RGB565] = {
1818 .convert = rgb24_to_rgb565
1819 },
1820 [PIX_FMT_RGB555] = {
1821 .convert = rgb24_to_rgb555
1822 },
1823 [PIX_FMT_RGB32] = {
1824 .convert = rgb24_to_rgb32
1825 },
1826 [PIX_FMT_BGR24] = {
1827 .convert = rgb24_to_bgr24
1828 },
1829 [PIX_FMT_GRAY8] = {
1830 .convert = rgb24_to_gray
1831 },
1832 [PIX_FMT_PAL8] = {
1833 .convert = rgb24_to_pal8
1834 },
1835 [PIX_FMT_YUV444P] = {
1836 .convert = rgb24_to_yuv444p
1837 },
1838 [PIX_FMT_YUVJ420P] = {
1839 .convert = rgb24_to_yuvj420p
1840 },
1841 [PIX_FMT_YUVJ444P] = {
1842 .convert = rgb24_to_yuvj444p
1843 },
1844 },
1845 [PIX_FMT_RGB32] = {
1846 [PIX_FMT_RGB24] = {
1847 .convert = rgb32_to_rgb24
1848 },
1849 [PIX_FMT_BGR24] = {
1850 .convert = rgb32_to_bgr24
1851 },
1852 [PIX_FMT_RGB565] = {
1853 .convert = rgb32_to_rgb565
1854 },
1855 [PIX_FMT_RGB555] = {
1856 .convert = rgb32_to_rgb555
1857 },
1858 [PIX_FMT_PAL8] = {
1859 .convert = rgb32_to_pal8
1860 },
1861 [PIX_FMT_YUV420P] = {
1862 .convert = rgb32_to_yuv420p
1863 },
1864 [PIX_FMT_GRAY8] = {
1865 .convert = rgb32_to_gray
1866 },
1867 },
1868 [PIX_FMT_BGR24] = {
1869 [PIX_FMT_RGB32] = {
1870 .convert = bgr24_to_rgb32
1871 },
1872 [PIX_FMT_RGB24] = {
1873 .convert = bgr24_to_rgb24
1874 },
1875 [PIX_FMT_YUV420P] = {
1876 .convert = bgr24_to_yuv420p
1877 },
1878 [PIX_FMT_GRAY8] = {
1879 .convert = bgr24_to_gray
1880 },
1881 },
1882 [PIX_FMT_RGB555] = {
1883 [PIX_FMT_RGB24] = {
1884 .convert = rgb555_to_rgb24
1885 },
1886 [PIX_FMT_RGB32] = {
1887 .convert = rgb555_to_rgb32
1888 },
1889 [PIX_FMT_YUV420P] = {
1890 .convert = rgb555_to_yuv420p
1891 },
1892 [PIX_FMT_GRAY8] = {
1893 .convert = rgb555_to_gray
1894 },
1895 },
1896 [PIX_FMT_RGB565] = {
1897 [PIX_FMT_RGB32] = {
1898 .convert = rgb565_to_rgb32
1899 },
1900 [PIX_FMT_RGB24] = {
1901 .convert = rgb565_to_rgb24
1902 },
1903 [PIX_FMT_YUV420P] = {
1904 .convert = rgb565_to_yuv420p
1905 },
1906 [PIX_FMT_GRAY8] = {
1907 .convert = rgb565_to_gray
1908 },
1909 },
1910 [PIX_FMT_GRAY16BE] = {
1911 [PIX_FMT_GRAY8] = {
1912 .convert = gray16be_to_gray
1913 },
1914 [PIX_FMT_GRAY16LE] = {
1915 .convert = gray16_to_gray16
1916 },
1917 },
1918 [PIX_FMT_GRAY16LE] = {
1919 [PIX_FMT_GRAY8] = {
1920 .convert = gray16le_to_gray
1921 },
1922 [PIX_FMT_GRAY16BE] = {
1923 .convert = gray16_to_gray16
1924 },
1925 },
1926 [PIX_FMT_GRAY8] = {
1927 [PIX_FMT_RGB555] = {
1928 .convert = gray_to_rgb555
1929 },
1930 [PIX_FMT_RGB565] = {
1931 .convert = gray_to_rgb565
1932 },
1933 [PIX_FMT_RGB24] = {
1934 .convert = gray_to_rgb24
1935 },
1936 [PIX_FMT_BGR24] = {
1937 .convert = gray_to_bgr24
1938 },
1939 [PIX_FMT_RGB32] = {
1940 .convert = gray_to_rgb32
1941 },
1942 [PIX_FMT_MONOWHITE] = {
1943 .convert = gray_to_monowhite
1944 },
1945 [PIX_FMT_MONOBLACK] = {
1946 .convert = gray_to_monoblack
1947 },
1948 [PIX_FMT_GRAY16LE] = {
1949 .convert = gray_to_gray16
1950 },
1951 [PIX_FMT_GRAY16BE] = {
1952 .convert = gray_to_gray16
1953 },
1954 },
1955 [PIX_FMT_MONOWHITE] = {
1956 [PIX_FMT_GRAY8] = {
1957 .convert = monowhite_to_gray
1958 },
1959 },
1960 [PIX_FMT_MONOBLACK] = {
1961 [PIX_FMT_GRAY8] = {
1962 .convert = monoblack_to_gray
1963 },
1964 },
1965 [PIX_FMT_PAL8] = {
1966 [PIX_FMT_RGB555] = {
1967 .convert = pal8_to_rgb555
1968 },
1969 [PIX_FMT_RGB565] = {
1970 .convert = pal8_to_rgb565
1971 },
1972 [PIX_FMT_BGR24] = {
1973 .convert = pal8_to_bgr24
1974 },
1975 [PIX_FMT_RGB24] = {
1976 .convert = pal8_to_rgb24
1977 },
1978 [PIX_FMT_RGB32] = {
1979 .convert = pal8_to_rgb32
1980 },
1981 },
1982 [PIX_FMT_UYYVYY411] = {
1983 [PIX_FMT_YUV411P] = {
1984 .convert = uyyvyy411_to_yuv411p,
1985 },
1986 },
1987
1988 };
1989
1990 int avpicture_alloc(AVPicture *picture,
1991 int pix_fmt, int width, int height)
1992 {
1993 int size;
1994 void *ptr;
1995
1996 size = avpicture_get_size(pix_fmt, width, height);
1997 if(size<0)
1998 goto fail;
1999 ptr = av_malloc(size);
2000 if (!ptr)
2001 goto fail;
2002 avpicture_fill(picture, ptr, pix_fmt, width, height);
2003 return 0;
2004 fail:
2005 memset(picture, 0, sizeof(AVPicture));
2006 return -1;
2007 }
2008
2009 void avpicture_free(AVPicture *picture)
2010 {
2011 av_free(picture->data[0]);
2012 }
2013
2014 /* return true if yuv planar */
2015 static inline int is_yuv_planar(const PixFmtInfo *ps)
2016 {
2017 return (ps->color_type == FF_COLOR_YUV ||
2018 ps->color_type == FF_COLOR_YUV_JPEG) &&
2019 ps->pixel_type == FF_PIXEL_PLANAR;
2020 }
2021
2022 int av_picture_crop(AVPicture *dst, const AVPicture *src,
2023 int pix_fmt, int top_band, int left_band)
2024 {
2025 int y_shift;
2026 int x_shift;
2027
2028 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2029 return -1;
2030
2031 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2032 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2033
2034 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2035 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2036 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2037
2038 dst->linesize[0] = src->linesize[0];
2039 dst->linesize[1] = src->linesize[1];
2040 dst->linesize[2] = src->linesize[2];
2041 return 0;
2042 }
2043
2044 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2045 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2046 int *color)
2047 {
2048 uint8_t *optr;
2049 int y_shift;
2050 int x_shift;
2051 int yheight;
2052 int i, y;
2053
2054 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2055 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
2056
2057 for (i = 0; i < 3; i++) {
2058 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2059 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2060
2061 if (padtop || padleft) {
2062 memset(dst->data[i], color[i],
2063 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2064 }
2065
2066 if (padleft || padright) {
2067 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2068 (dst->linesize[i] - (padright >> x_shift));
2069 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2070 for (y = 0; y < yheight; y++) {
2071 memset(optr, color[i], (padleft + padright) >> x_shift);
2072 optr += dst->linesize[i];
2073 }
2074 }
2075
2076 if (src) { /* first line */
2077 uint8_t *iptr = src->data[i];
2078 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2079 (padleft >> x_shift);
2080 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
2081 iptr += src->linesize[i];
2082 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2083 (dst->linesize[i] - (padright >> x_shift));
2084 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2085 for (y = 0; y < yheight; y++) {
2086 memset(optr, color[i], (padleft + padright) >> x_shift);
2087 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2088 (width - padleft - padright) >> x_shift);
2089 iptr += src->linesize[i];
2090 optr += dst->linesize[i];
2091 }
2092 }
2093
2094 if (padbottom || padright) {
2095 optr = dst->data[i] + dst->linesize[i] *
2096 ((height - padbottom) >> y_shift) - (padright >> x_shift);
2097 memset(optr, color[i],dst->linesize[i] *
2098 (padbottom >> y_shift) + (padright >> x_shift));
2099 }
2100 }
2101 return 0;
2102 }
2103
2104 #if !CONFIG_SWSCALE
2105 static uint8_t y_ccir_to_jpeg[256];
2106 static uint8_t y_jpeg_to_ccir[256];
2107 static uint8_t c_ccir_to_jpeg[256];
2108 static uint8_t c_jpeg_to_ccir[256];
2109
2110 /* init various conversion tables */
2111 static void img_convert_init(void)
2112 {
2113 int i;
2114 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2115
2116 for(i = 0;i < 256; i++) {
2117 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
2118 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
2119 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
2120 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
2121 }
2122 }
2123
2124 /* apply to each pixel the given table */
2125 static void img_apply_table(uint8_t *dst, int dst_wrap,
2126 const uint8_t *src, int src_wrap,
2127 int width, int height, const uint8_t *table1)
2128 {
2129 int n;
2130 const uint8_t *s;
2131 uint8_t *d;
2132 const uint8_t *table;
2133
2134 table = table1;
2135 for(;height > 0; height--) {
2136 s = src;
2137 d = dst;
2138 n = width;
2139 while (n >= 4) {
2140 d[0] = table[s[0]];
2141 d[1] = table[s[1]];
2142 d[2] = table[s[2]];
2143 d[3] = table[s[3]];
2144 d += 4;
2145 s += 4;
2146 n -= 4;
2147 }
2148 while (n > 0) {
2149 d[0] = table[s[0]];
2150 d++;
2151 s++;
2152 n--;
2153 }
2154 dst += dst_wrap;
2155 src += src_wrap;
2156 }
2157 }
2158
2159 /* XXX: use generic filter ? */
2160 /* XXX: in most cases, the sampling position is incorrect */
2161
2162 /* 4x1 -> 1x1 */
2163 static void shrink41(uint8_t *dst, int dst_wrap,
2164 const uint8_t *src, int src_wrap,
2165 int width, int height)
2166 {
2167 int w;
2168 const uint8_t *s;
2169 uint8_t *d;
2170
2171 for(;height > 0; height--) {
2172 s = src;
2173 d = dst;
2174 for(w = width;w > 0; w--) {
2175 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
2176 s += 4;
2177 d++;
2178 }
2179 src += src_wrap;
2180 dst += dst_wrap;
2181 }
2182 }
2183
2184 /* 2x1 -> 1x1 */
2185 static void shrink21(uint8_t *dst, int dst_wrap,
2186 const uint8_t *src, int src_wrap,
2187 int width, int height)
2188 {
2189 int w;
2190 const uint8_t *s;
2191 uint8_t *d;
2192
2193 for(;height > 0; height--) {
2194 s = src;
2195 d = dst;
2196 for(w = width;w > 0; w--) {
2197 d[0] = (s[0] + s[1]) >> 1;
2198 s += 2;
2199 d++;
2200 }
2201 src += src_wrap;
2202 dst += dst_wrap;
2203 }
2204 }
2205
2206 /* 1x2 -> 1x1 */
2207 static void shrink12(uint8_t *dst, int dst_wrap,
2208 const uint8_t *src, int src_wrap,
2209 int width, int height)
2210 {
2211 int w;
2212 uint8_t *d;
2213 const uint8_t *s1, *s2;
2214
2215 for(;height > 0; height--) {
2216 s1 = src;
2217 s2 = s1 + src_wrap;
2218 d = dst;
2219 for(w = width;w >= 4; w-=4) {
2220 d[0] = (s1[0] + s2[0]) >> 1;
2221 d[1] = (s1[1] + s2[1]) >> 1;
2222 d[2] = (s1[2] + s2[2]) >> 1;
2223 d[3] = (s1[3] + s2[3]) >> 1;
2224 s1 += 4;
2225 s2 += 4;
2226 d += 4;
2227 }
2228 for(;w > 0; w--) {
2229 d[0] = (s1[0] + s2[0]) >> 1;
2230 s1++;
2231 s2++;
2232 d++;
2233 }
2234 src += 2 * src_wrap;
2235 dst += dst_wrap;
2236 }
2237 }
2238
2239 static void grow21_line(uint8_t *dst, const uint8_t *src,
2240 int width)
2241 {
2242 int w;
2243 const uint8_t *s1;
2244 uint8_t *d;
2245
2246 s1 = src;
2247 d = dst;
2248 for(w = width;w >= 4; w-=4) {
2249 d[1] = d[0] = s1[0];
2250 d[3] = d[2] = s1[1];
2251 s1 += 2;
2252 d += 4;
2253 }
2254 for(;w >= 2; w -= 2) {
2255 d[1] = d[0] = s1[0];
2256 s1 ++;
2257 d += 2;
2258 }
2259 /* only needed if width is not a multiple of two */
2260 /* XXX: veryfy that */
2261 if (w) {
2262 d[0] = s1[0];
2263 }
2264 }
2265
2266 static void grow41_line(uint8_t *dst, const uint8_t *src,
2267 int width)
2268 {
2269 int w, v;
2270 const uint8_t *s1;
2271 uint8_t *d;
2272
2273 s1 = src;
2274 d = dst;
2275 for(w = width;w >= 4; w-=4) {
2276 v = s1[0];
2277 d[0] = v;
2278 d[1] = v;
2279 d[2] = v;
2280 d[3] = v;
2281 s1 ++;
2282 d += 4;
2283 }
2284 }
2285
2286 /* 1x1 -> 2x1 */
2287 static void grow21(uint8_t *dst, int dst_wrap,
2288 const uint8_t *src, int src_wrap,
2289 int width, int height)
2290 {
2291 for(;height > 0; height--) {
2292 grow21_line(dst, src, width);
2293 src += src_wrap;
2294 dst += dst_wrap;
2295 }
2296 }
2297
2298 /* 1x1 -> 1x2 */
2299 static void grow12(uint8_t *dst, int dst_wrap,
2300 const uint8_t *src, int src_wrap,
2301 int width, int height)
2302 {
2303 for(;height > 0; height-=2) {
2304 memcpy(dst, src, width);
2305 dst += dst_wrap;
2306 memcpy(dst, src, width);
2307 dst += dst_wrap;
2308 src += src_wrap;
2309 }
2310 }
2311
2312 /* 1x1 -> 2x2 */
2313 static void grow22(uint8_t *dst, int dst_wrap,
2314 const uint8_t *src, int src_wrap,
2315 int width, int height)
2316 {
2317 for(;height > 0; height--) {
2318 grow21_line(dst, src, width);
2319 if (height%2)
2320 src += src_wrap;
2321 dst += dst_wrap;
2322 }
2323 }
2324
2325 /* 1x1 -> 4x1 */
2326 static void grow41(uint8_t *dst, int dst_wrap,
2327 const uint8_t *src, int src_wrap,
2328 int width, int height)
2329 {
2330 for(;height > 0; height--) {
2331 grow41_line(dst, src, width);
2332 src += src_wrap;
2333 dst += dst_wrap;
2334 }
2335 }
2336
2337 /* 1x1 -> 4x4 */
2338 static void grow44(uint8_t *dst, int dst_wrap,
2339 const uint8_t *src, int src_wrap,
2340 int width, int height)
2341 {
2342 for(;height > 0; height--) {
2343 grow41_line(dst, src, width);
2344 if ((height & 3) == 1)
2345 src += src_wrap;
2346 dst += dst_wrap;
2347 }
2348 }
2349
2350 /* 1x2 -> 2x1 */
2351 static void conv411(uint8_t *dst, int dst_wrap,
2352 const uint8_t *src, int src_wrap,
2353 int width, int height)
2354 {
2355 int w, c;
2356 const uint8_t *s1, *s2;
2357 uint8_t *d;
2358
2359 width>>=1;
2360
2361 for(;height > 0; height--) {
2362 s1 = src;
2363 s2 = src + src_wrap;
2364 d = dst;
2365 for(w = width;w > 0; w--) {
2366 c = (s1[0] + s2[0]) >> 1;
2367 d[0] = c;
2368 d[1] = c;
2369 s1++;
2370 s2++;
2371 d += 2;
2372 }
2373 src += src_wrap * 2;
2374 dst += dst_wrap;
2375 }
2376 }
2377
2378 /* XXX: always use linesize. Return -1 if not supported */
2379 int img_convert(AVPicture *dst, int dst_pix_fmt,
2380 const AVPicture *src, int src_pix_fmt,
2381 int src_width, int src_height)
2382 {
2383 static int initialized;
2384 int i, ret, dst_width, dst_height, int_pix_fmt;
2385 const PixFmtInfo *src_pix, *dst_pix;
2386 const ConvertEntry *ce;
2387 AVPicture tmp1, *tmp = &tmp1;
2388
2389 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2390 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2391 return -1;
2392 if (src_width <= 0 || src_height <= 0)
2393 return 0;
2394
2395 if (!initialized) {
2396 initialized = 1;
2397 img_convert_init();
2398 }
2399
2400 dst_width = src_width;
2401 dst_height = src_height;
2402
2403 dst_pix = &pix_fmt_info[dst_pix_fmt];
2404 src_pix = &pix_fmt_info[src_pix_fmt];
2405 if (src_pix_fmt == dst_pix_fmt) {
2406 /* no conversion needed: just copy */
2407 av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2408 return 0;
2409 }
2410
2411 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2412 if (ce->convert) {
2413 /* specific conversion routine */
2414 ce->convert(dst, src, dst_width, dst_height);
2415 return 0;
2416 }
2417
2418 /* gray to YUV */
2419 if (is_yuv_planar(dst_pix) &&
2420 src_pix_fmt == PIX_FMT_GRAY8) {
2421 int w, h, y;
2422 uint8_t *d;
2423
2424 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2425 ff_img_copy_plane(dst->data[0], dst->linesize[0],
2426 src->data[0], src->linesize[0],
2427 dst_width, dst_height);
2428 } else {
2429 img_apply_table(dst->data[0], dst->linesize[0],
2430 src->data[0], src->linesize[0],
2431 dst_width, dst_height,
2432 y_jpeg_to_ccir);
2433 }
2434 /* fill U and V with 128 */
2435 w = dst_width;
2436 h = dst_height;
2437 w >>= dst_pix->x_chroma_shift;
2438 h >>= dst_pix->y_chroma_shift;
2439 for(i = 1; i <= 2; i++) {
2440 d = dst->data[i];
2441 for(y = 0; y< h; y++) {
2442 memset(d, 128, w);
2443 d += dst->linesize[i];
2444 }
2445 }
2446 return 0;
2447 }
2448
2449 /* YUV to gray */
2450 if (is_yuv_planar(src_pix) &&
2451 dst_pix_fmt == PIX_FMT_GRAY8) {
2452 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2453 ff_img_copy_plane(dst->data[0], dst->linesize[0],
2454 src->data[0], src->linesize[0],
2455 dst_width, dst_height);
2456 } else {
2457 img_apply_table(dst->data[0], dst->linesize[0],
2458 src->data[0], src->linesize[0],
2459 dst_width, dst_height,
2460 y_ccir_to_jpeg);
2461 }
2462 return 0;
2463 }
2464
2465 /* YUV to YUV planar */
2466 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2467 int x_shift, y_shift, w, h, xy_shift;
2468 void (*resize_func)(uint8_t *dst, int dst_wrap,
2469 const uint8_t *src, int src_wrap,
2470 int width, int height);
2471
2472 /* compute chroma size of the smallest dimensions */
2473 w = dst_width;
2474 h = dst_height;
2475 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2476 w >>= dst_pix->x_chroma_shift;
2477 else
2478 w >>= src_pix->x_chroma_shift;
2479 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2480 h >>= dst_pix->y_chroma_shift;
2481 else
2482 h >>= src_pix->y_chroma_shift;
2483
2484 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2485 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2486 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2487 /* there must be filters for conversion at least from and to
2488 YUV444 format */
2489 switch(xy_shift) {
2490 case 0x00:
2491 resize_func = ff_img_copy_plane;
2492 break;
2493 case 0x10:
2494 resize_func = shrink21;
2495 break;
2496 case 0x20:
2497 resize_func = shrink41;
2498 break;
2499 case 0x01:
2500 resize_func = shrink12;
2501 break;
2502 case 0x11:
2503 resize_func = ff_shrink22;
2504 break;
2505 case 0x22:
2506 resize_func = ff_shrink44;
2507 break;
2508 case 0xf0:
2509 resize_func = grow21;
2510 break;
2511 case 0x0f:
2512 resize_func = grow12;
2513 break;
2514 case 0xe0:
2515 resize_func = grow41;
2516 break;
2517 case 0xff:
2518 resize_func = grow22;
2519 break;
2520 case 0xee:
2521 resize_func = grow44;
2522 break;
2523 case 0xf1:
2524 resize_func = conv411;
2525 break;
2526 default:
2527 /* currently not handled */
2528 goto no_chroma_filter;
2529 }
2530
2531 ff_img_copy_plane(dst->data[0], dst->linesize[0],
2532 src->data[0], src->linesize[0],
2533 dst_width, dst_height);
2534
2535 for(i = 1;i <= 2; i++)
2536 resize_func(dst->data[i], dst->linesize[i],
2537 src->data[i], src->linesize[i],
2538 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2539 /* if yuv color space conversion is needed, we do it here on
2540 the destination image */
2541 if (dst_pix->color_type != src_pix->color_type) {
2542 const uint8_t *y_table, *c_table;
2543 if (dst_pix->color_type == FF_COLOR_YUV) {
2544 y_table = y_jpeg_to_ccir;
2545 c_table = c_jpeg_to_ccir;
2546 } else {
2547 y_table = y_ccir_to_jpeg;
2548 c_table = c_ccir_to_jpeg;
2549 }
2550 img_apply_table(dst->data[0], dst->linesize[0],
2551 dst->data[0], dst->linesize[0],
2552 dst_width, dst_height,
2553 y_table);
2554
2555 for(i = 1;i <= 2; i++)
2556 img_apply_table(dst->data[i], dst->linesize[i],
2557 dst->data[i], dst->linesize[i],
2558 dst_width>>dst_pix->x_chroma_shift,
2559 dst_height>>dst_pix->y_chroma_shift,
2560 c_table);
2561 }
2562 return 0;
2563 }
2564 no_chroma_filter:
2565
2566 /* try to use an intermediate format */
2567 if (src_pix_fmt == PIX_FMT_YUYV422 ||
2568 dst_pix_fmt == PIX_FMT_YUYV422) {
2569 /* specific case: convert to YUV422P first */
2570 int_pix_fmt = PIX_FMT_YUV422P;
2571 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2572 dst_pix_fmt == PIX_FMT_UYVY422) {
2573 /* specific case: convert to YUV422P first */
2574 int_pix_fmt = PIX_FMT_YUV422P;
2575 } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2576 dst_pix_fmt == PIX_FMT_UYYVYY411) {
2577 /* specific case: convert to YUV411P first */
2578 int_pix_fmt = PIX_FMT_YUV411P;
2579 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2580 src_pix_fmt != PIX_FMT_GRAY8) ||
2581 (dst_pix->color_type == FF_COLOR_GRAY &&
2582 dst_pix_fmt != PIX_FMT_GRAY8)) {
2583 /* gray8 is the normalized format */
2584 int_pix_fmt = PIX_FMT_GRAY8;
2585 } else if ((is_yuv_planar(src_pix) &&
2586 src_pix_fmt != PIX_FMT_YUV444P &&
2587 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2588 /* yuv444 is the normalized format */
2589 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2590 int_pix_fmt = PIX_FMT_YUVJ444P;
2591 else
2592 int_pix_fmt = PIX_FMT_YUV444P;
2593 } else if ((is_yuv_planar(dst_pix) &&
2594 dst_pix_fmt != PIX_FMT_YUV444P &&
2595 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2596 /* yuv444 is the normalized format */
2597 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2598 int_pix_fmt = PIX_FMT_YUVJ444P;
2599 else
2600 int_pix_fmt = PIX_FMT_YUV444P;
2601 } else {
2602 /* the two formats are rgb or gray8 or yuv[j]444p */
2603 if (src_pix->is_alpha && dst_pix->is_alpha)
2604 int_pix_fmt = PIX_FMT_RGB32;
2605 else
2606 int_pix_fmt = PIX_FMT_RGB24;
2607 }
2608 if (src_pix_fmt == int_pix_fmt)
2609 return -1;
2610 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2611 return -1;
2612 ret = -1;
2613 if (img_convert(tmp, int_pix_fmt,
2614 src, src_pix_fmt, src_width, src_height) < 0)
2615 goto fail1;
2616 if (img_convert(dst, dst_pix_fmt,
2617 tmp, int_pix_fmt, dst_width, dst_height) < 0)
2618 goto fail1;
2619 ret = 0;
2620 fail1:
2621 avpicture_free(tmp);
2622 return ret;
2623 }
2624 #endif
2625
2626 /* NOTE: we scan all the pixels to have an exact information */
2627 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2628 {
2629 const unsigned char *p;
2630 int src_wrap, ret, x, y;
2631 unsigned int a;
2632 uint32_t *palette = (uint32_t *)src->data[1];
2633
2634 p = src->data[0];
2635 src_wrap = src->linesize[0] - width;
2636 ret = 0;
2637 for(y=0;y<height;y++) {
2638 for(x=0;x<width;x++) {
2639 a = palette[p[0]] >> 24;
2640 if (a == 0x00) {
2641 ret |= FF_ALPHA_TRANSP;
2642 } else if (a != 0xff) {
2643 ret |= FF_ALPHA_SEMI_TRANSP;
2644 }
2645 p++;
2646 }
2647 p += src_wrap;
2648 }
2649 return ret;
2650 }
2651
2652 int img_get_alpha_info(const AVPicture *src,
2653 int pix_fmt, int width, int height)
2654 {
2655 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2656 int ret;
2657
2658 pf = &pix_fmt_info[pix_fmt];
2659 /* no alpha can be represented in format */
2660 if (!pf->is_alpha)
2661 return 0;
2662 switch(pix_fmt) {
2663 case PIX_FMT_RGB32:
2664 ret = get_alpha_info_rgb32(src, width, height);
2665 break;
2666 case PIX_FMT_PAL8:
2667 ret = get_alpha_info_pal8(src, width, height);
2668 break;
2669 default:
2670 /* we do not know, so everything is indicated */
2671 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2672 break;
2673 }
2674 return ret;
2675 }
2676
2677 #if HAVE_MMX
2678 #define DEINT_INPLACE_LINE_LUM \
2679 movd_m2r(lum_m4[0],mm0);\
2680 movd_m2r(lum_m3[0],mm1);\
2681 movd_m2r(lum_m2[0],mm2);\
2682 movd_m2r(lum_m1[0],mm3);\
2683 movd_m2r(lum[0],mm4);\
2684 punpcklbw_r2r(mm7,mm0);\
2685 movd_r2m(mm2,lum_m4[0]);\
2686 punpcklbw_r2r(mm7,mm1);\
2687 punpcklbw_r2r(mm7,mm2);\
2688 punpcklbw_r2r(mm7,mm3);\
2689 punpcklbw_r2r(mm7,mm4);\
2690 paddw_r2r(mm3,mm1);\
2691 psllw_i2r(1,mm2);\
2692 paddw_r2r(mm4,mm0);\
2693 psllw_i2r(2,mm1);\
2694 paddw_r2r(mm6,mm2);\
2695 paddw_r2r(mm2,mm1);\
2696 psubusw_r2r(mm0,mm1);\
2697 psrlw_i2r(3,mm1);\
2698 packuswb_r2r(mm7,mm1);\
2699 movd_r2m(mm1,lum_m2[0]);
2700
2701 #define DEINT_LINE_LUM \
2702 movd_m2r(lum_m4[0],mm0);\
2703 movd_m2r(lum_m3[0],mm1);\
2704 movd_m2r(lum_m2[0],mm2);\
2705 movd_m2r(lum_m1[0],mm3);\
2706 movd_m2r(lum[0],mm4);\
2707 punpcklbw_r2r(mm7,mm0);\
2708 punpcklbw_r2r(mm7,mm1);\
2709 punpcklbw_r2r(mm7,mm2);\
2710 punpcklbw_r2r(mm7,mm3);\
2711 punpcklbw_r2r(mm7,mm4);\
2712 paddw_r2r(mm3,mm1);\
2713 psllw_i2r(1,mm2);\
2714 paddw_r2r(mm4,mm0);\
2715 psllw_i2r(2,mm1);\
2716 paddw_r2r(mm6,mm2);\
2717 paddw_r2r(mm2,mm1);\
2718 psubusw_r2r(mm0,mm1);\
2719 psrlw_i2r(3,mm1);\
2720 packuswb_r2r(mm7,mm1);\
2721 movd_r2m(mm1,dst[0]);
2722 #endif
2723
2724 /* filter parameters: [-1 4 2 4 -1] // 8 */
2725 static void deinterlace_line(uint8_t *dst,
2726 const uint8_t *lum_m4, const uint8_t *lum_m3,
2727 const uint8_t *lum_m2, const uint8_t *lum_m1,
2728 const uint8_t *lum,
2729 int size)
2730 {
2731 #if !HAVE_MMX
2732 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2733 int sum;
2734
2735 for(;size > 0;size--) {
2736 sum = -lum_m4[0];
2737 sum += lum_m3[0] << 2;
2738 sum += lum_m2[0] << 1;
2739 sum += lum_m1[0] << 2;
2740 sum += -lum[0];
2741 dst[0] = cm[(sum + 4) >> 3];
2742 lum_m4++;
2743 lum_m3++;
2744 lum_m2++;
2745 lum_m1++;
2746 lum++;
2747 dst++;
2748 }
2749 #else
2750
2751 {
2752 pxor_r2r(mm7,mm7);
2753 movq_m2r(ff_pw_4,mm6);
2754 }
2755 for (;size > 3; size-=4) {
2756 DEINT_LINE_LUM
2757 lum_m4+=4;
2758 lum_m3+=4;
2759 lum_m2+=4;
2760 lum_m1+=4;
2761 lum+=4;
2762 dst+=4;
2763 }
2764 #endif
2765 }
2766 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2767 int size)
2768 {
2769 #if !HAVE_MMX
2770 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2771 int sum;
2772
2773 for(;size > 0;size--) {
2774 sum = -lum_m4[0];
2775 sum += lum_m3[0] << 2;
2776 sum += lum_m2[0] << 1;
2777 lum_m4[0]=lum_m2[0];
2778 sum += lum_m1[0] << 2;
2779 sum += -lum[0];
2780 lum_m2[0] = cm[(sum + 4) >> 3];
2781 lum_m4++;
2782 lum_m3++;
2783 lum_m2++;
2784 lum_m1++;
2785 lum++;
2786 }
2787 #else
2788
2789 {
2790 pxor_r2r(mm7,mm7);
2791 movq_m2r(ff_pw_4,mm6);
2792 }
2793 for (;size > 3; size-=4) {
2794 DEINT_INPLACE_LINE_LUM
2795 lum_m4+=4;
2796 lum_m3+=4;
2797 lum_m2+=4;
2798 lum_m1+=4;
2799 lum+=4;
2800 }
2801 #endif
2802 }
2803
2804 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2805 top field is copied as is, but the bottom field is deinterlaced
2806 against the top field. */
2807 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2808 const uint8_t *src1, int src_wrap,
2809 int width, int height)
2810 {
2811 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2812 int y;
2813
2814 src_m2 = src1;
2815 src_m1 = src1;
2816 src_0=&src_m1[src_wrap];
2817 src_p1=&src_0[src_wrap];
2818 src_p2=&src_p1[src_wrap];
2819 for(y=0;y<(height-2);y+=2) {
2820 memcpy(dst,src_m1,width);
2821 dst += dst_wrap;
2822 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2823 src_m2 = src_0;
2824 src_m1 = src_p1;
2825 src_0 = src_p2;
2826 src_p1 += 2*src_wrap;
2827 src_p2 += 2*src_wrap;
2828 dst += dst_wrap;
2829 }
2830 memcpy(dst,src_m1,width);
2831 dst += dst_wrap;
2832 /* do last line */
2833 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2834 }
2835
2836 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2837 int width, int height)
2838 {
2839 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2840 int y;
2841 uint8_t *buf;
2842 buf = (uint8_t*)av_malloc(width);
2843
2844 src_m1 = src1;
2845 memcpy(buf,src_m1,width);
2846 src_0=&src_m1[src_wrap];
2847 src_p1=&src_0[src_wrap];
2848 src_p2=&src_p1[src_wrap];
2849 for(y=0;y<(height-2);y+=2) {
2850 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2851 src_m1 = src_p1;
2852 src_0 = src_p2;
2853 src_p1 += 2*src_wrap;
2854 src_p2 += 2*src_wrap;
2855 }
2856 /* do last line */
2857 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2858 av_free(buf);
2859 }
2860
2861 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2862 int pix_fmt, int width, int height)
2863 {
2864 int i;
2865
2866 if (pix_fmt != PIX_FMT_YUV420P &&
2867 pix_fmt != PIX_FMT_YUV422P &&
2868 pix_fmt != PIX_FMT_YUV444P &&
2869 pix_fmt != PIX_FMT_YUV411P &&
2870 pix_fmt != PIX_FMT_GRAY8)
2871 return -1;
2872 if ((width & 3) != 0 || (height & 3) != 0)
2873 return -1;
2874
2875 for(i=0;i<3;i++) {
2876 if (i == 1) {
2877 switch(pix_fmt) {
2878 case PIX_FMT_YUV420P:
2879 width >>= 1;
2880 height >>= 1;
2881 break;
2882 case PIX_FMT_YUV422P:
2883 width >>= 1;
2884 break;
2885 case PIX_FMT_YUV411P:
2886 width >>= 2;
2887 break;
2888 default:
2889 break;
2890 }
2891 if (pix_fmt == PIX_FMT_GRAY8) {
2892 break;
2893 }
2894 }
2895 if (src == dst) {
2896 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2897 width, height);
2898 } else {
2899 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2900 src->data[i], src->linesize[i],
2901 width, height);
2902 }
2903 }
2904 emms_c();
2905 return 0;
2906 }
2907