2 * Misc image conversion routines
3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavcodec/imgconvert.c
24 * misc image conversion routines
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
35 #include "colorspace.h"
39 #include "x86/dsputil_mmx.h"
42 #define xglue(x, y) x ## y
43 #define glue(x, y) xglue(x, y)
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 */
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 */
54 typedef struct PixFmtInfo {
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 is_hwaccel : 1; /**< true if this is an HW accelerated format */
61 uint8_t x_chroma_shift; /**< X chroma subsampling factor is 2 ^ shift */
62 uint8_t y_chroma_shift; /**< Y chroma subsampling factor is 2 ^ shift */
63 uint8_t depth; /**< bit depth of the color components */
66 /* this table gives more information about formats */
67 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
72 .color_type = FF_COLOR_YUV,
73 .pixel_type = FF_PIXEL_PLANAR,
75 .x_chroma_shift = 1, .y_chroma_shift = 1,
80 .color_type = FF_COLOR_YUV,
81 .pixel_type = FF_PIXEL_PLANAR,
83 .x_chroma_shift = 1, .y_chroma_shift = 0,
88 .color_type = FF_COLOR_YUV,
89 .pixel_type = FF_PIXEL_PLANAR,
91 .x_chroma_shift = 0, .y_chroma_shift = 0,
96 .color_type = FF_COLOR_YUV,
97 .pixel_type = FF_PIXEL_PACKED,
99 .x_chroma_shift = 1, .y_chroma_shift = 0,
101 [PIX_FMT_UYVY422] = {
104 .color_type = FF_COLOR_YUV,
105 .pixel_type = FF_PIXEL_PACKED,
107 .x_chroma_shift = 1, .y_chroma_shift = 0,
109 [PIX_FMT_YUV410P] = {
112 .color_type = FF_COLOR_YUV,
113 .pixel_type = FF_PIXEL_PLANAR,
115 .x_chroma_shift = 2, .y_chroma_shift = 2,
117 [PIX_FMT_YUV411P] = {
120 .color_type = FF_COLOR_YUV,
121 .pixel_type = FF_PIXEL_PLANAR,
123 .x_chroma_shift = 2, .y_chroma_shift = 0,
125 [PIX_FMT_YUV440P] = {
128 .color_type = FF_COLOR_YUV,
129 .pixel_type = FF_PIXEL_PLANAR,
131 .x_chroma_shift = 0, .y_chroma_shift = 1,
134 /* YUV formats with alpha plane */
135 [PIX_FMT_YUVA420P] = {
138 .color_type = FF_COLOR_YUV,
139 .pixel_type = FF_PIXEL_PLANAR,
141 .x_chroma_shift = 1, .y_chroma_shift = 1,
145 [PIX_FMT_YUVJ420P] = {
148 .color_type = FF_COLOR_YUV_JPEG,
149 .pixel_type = FF_PIXEL_PLANAR,
151 .x_chroma_shift = 1, .y_chroma_shift = 1,
153 [PIX_FMT_YUVJ422P] = {
156 .color_type = FF_COLOR_YUV_JPEG,
157 .pixel_type = FF_PIXEL_PLANAR,
159 .x_chroma_shift = 1, .y_chroma_shift = 0,
161 [PIX_FMT_YUVJ444P] = {
164 .color_type = FF_COLOR_YUV_JPEG,
165 .pixel_type = FF_PIXEL_PLANAR,
167 .x_chroma_shift = 0, .y_chroma_shift = 0,
169 [PIX_FMT_YUVJ440P] = {
172 .color_type = FF_COLOR_YUV_JPEG,
173 .pixel_type = FF_PIXEL_PLANAR,
175 .x_chroma_shift = 0, .y_chroma_shift = 1,
182 .color_type = FF_COLOR_RGB,
183 .pixel_type = FF_PIXEL_PACKED,
185 .x_chroma_shift = 0, .y_chroma_shift = 0,
190 .color_type = FF_COLOR_RGB,
191 .pixel_type = FF_PIXEL_PACKED,
193 .x_chroma_shift = 0, .y_chroma_shift = 0,
197 .nb_channels = 4, .is_alpha = 1,
198 .color_type = FF_COLOR_RGB,
199 .pixel_type = FF_PIXEL_PACKED,
201 .x_chroma_shift = 0, .y_chroma_shift = 0,
203 [PIX_FMT_RGB48BE] = {
206 .color_type = FF_COLOR_RGB,
207 .pixel_type = FF_PIXEL_PACKED,
209 .x_chroma_shift = 0, .y_chroma_shift = 0,
211 [PIX_FMT_RGB48LE] = {
214 .color_type = FF_COLOR_RGB,
215 .pixel_type = FF_PIXEL_PACKED,
217 .x_chroma_shift = 0, .y_chroma_shift = 0,
222 .color_type = FF_COLOR_RGB,
223 .pixel_type = FF_PIXEL_PACKED,
225 .x_chroma_shift = 0, .y_chroma_shift = 0,
230 .color_type = FF_COLOR_RGB,
231 .pixel_type = FF_PIXEL_PACKED,
233 .x_chroma_shift = 0, .y_chroma_shift = 0,
236 /* gray / mono formats */
237 [PIX_FMT_GRAY16BE] = {
240 .color_type = FF_COLOR_GRAY,
241 .pixel_type = FF_PIXEL_PLANAR,
244 [PIX_FMT_GRAY16LE] = {
247 .color_type = FF_COLOR_GRAY,
248 .pixel_type = FF_PIXEL_PLANAR,
254 .color_type = FF_COLOR_GRAY,
255 .pixel_type = FF_PIXEL_PLANAR,
258 [PIX_FMT_MONOWHITE] = {
261 .color_type = FF_COLOR_GRAY,
262 .pixel_type = FF_PIXEL_PLANAR,
265 [PIX_FMT_MONOBLACK] = {
268 .color_type = FF_COLOR_GRAY,
269 .pixel_type = FF_PIXEL_PLANAR,
273 /* paletted formats */
276 .nb_channels = 4, .is_alpha = 1,
277 .color_type = FF_COLOR_RGB,
278 .pixel_type = FF_PIXEL_PALETTE,
281 [PIX_FMT_XVMC_MPEG2_MC] = {
285 [PIX_FMT_XVMC_MPEG2_IDCT] = {
289 [PIX_FMT_VDPAU_MPEG1] = {
290 .name = "vdpau_mpeg1",
293 [PIX_FMT_VDPAU_MPEG2] = {
294 .name = "vdpau_mpeg2",
297 [PIX_FMT_VDPAU_H264] = {
298 .name = "vdpau_h264",
301 [PIX_FMT_VDPAU_WMV3] = {
302 .name = "vdpau_wmv3",
305 [PIX_FMT_VDPAU_VC1] = {
309 [PIX_FMT_UYYVYY411] = {
312 .color_type = FF_COLOR_YUV,
313 .pixel_type = FF_PIXEL_PACKED,
315 .x_chroma_shift = 2, .y_chroma_shift = 0,
319 .nb_channels = 4, .is_alpha = 1,
320 .color_type = FF_COLOR_RGB,
321 .pixel_type = FF_PIXEL_PACKED,
323 .x_chroma_shift = 0, .y_chroma_shift = 0,
328 .color_type = FF_COLOR_RGB,
329 .pixel_type = FF_PIXEL_PACKED,
331 .x_chroma_shift = 0, .y_chroma_shift = 0,
336 .color_type = FF_COLOR_RGB,
337 .pixel_type = FF_PIXEL_PACKED,
339 .x_chroma_shift = 0, .y_chroma_shift = 0,
344 .color_type = FF_COLOR_RGB,
345 .pixel_type = FF_PIXEL_PACKED,
347 .x_chroma_shift = 0, .y_chroma_shift = 0,
352 .color_type = FF_COLOR_RGB,
353 .pixel_type = FF_PIXEL_PACKED,
355 .x_chroma_shift = 0, .y_chroma_shift = 0,
357 [PIX_FMT_RGB4_BYTE] = {
360 .color_type = FF_COLOR_RGB,
361 .pixel_type = FF_PIXEL_PACKED,
363 .x_chroma_shift = 0, .y_chroma_shift = 0,
368 .color_type = FF_COLOR_RGB,
369 .pixel_type = FF_PIXEL_PACKED,
371 .x_chroma_shift = 0, .y_chroma_shift = 0,
376 .color_type = FF_COLOR_RGB,
377 .pixel_type = FF_PIXEL_PACKED,
379 .x_chroma_shift = 0, .y_chroma_shift = 0,
381 [PIX_FMT_BGR4_BYTE] = {
384 .color_type = FF_COLOR_RGB,
385 .pixel_type = FF_PIXEL_PACKED,
387 .x_chroma_shift = 0, .y_chroma_shift = 0,
392 .color_type = FF_COLOR_YUV,
393 .pixel_type = FF_PIXEL_PLANAR,
395 .x_chroma_shift = 1, .y_chroma_shift = 1,
400 .color_type = FF_COLOR_YUV,
401 .pixel_type = FF_PIXEL_PLANAR,
403 .x_chroma_shift = 1, .y_chroma_shift = 1,
406 [PIX_FMT_BGR32_1] = {
408 .nb_channels = 4, .is_alpha = 1,
409 .color_type = FF_COLOR_RGB,
410 .pixel_type = FF_PIXEL_PACKED,
412 .x_chroma_shift = 0, .y_chroma_shift = 0,
414 [PIX_FMT_RGB32_1] = {
416 .nb_channels = 4, .is_alpha = 1,
417 .color_type = FF_COLOR_RGB,
418 .pixel_type = FF_PIXEL_PACKED,
420 .x_chroma_shift = 0, .y_chroma_shift = 0,
424 [PIX_FMT_VAAPI_MOCO] = {
425 .name = "vaapi_moco",
428 [PIX_FMT_VAAPI_IDCT] = {
429 .name = "vaapi_idct",
432 [PIX_FMT_VAAPI_VLD] = {
438 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
440 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
441 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
444 const char *avcodec_get_pix_fmt_name(int pix_fmt)
446 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
449 return pix_fmt_info[pix_fmt].name;
452 enum PixelFormat avcodec_get_pix_fmt(const char* name)
456 for (i=0; i < PIX_FMT_NB; i++)
457 if (!strcmp(pix_fmt_info[i].name, name))
462 void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
466 snprintf (buf, buf_size,
467 "name " " nb_channels" " depth" " is_alpha"
470 PixFmtInfo info= pix_fmt_info[pix_fmt];
472 char is_alpha_char= info.is_alpha ? 'y' : 'n';
474 snprintf (buf, buf_size,
475 "%-10s" " %1d " " %2d " " %c ",
484 int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
486 return pix_fmt_info[pix_fmt].is_hwaccel;
489 int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
492 for(i=0; i<256; i++){
506 case PIX_FMT_RGB4_BYTE:
511 case PIX_FMT_BGR4_BYTE:
522 pal[i] = b + (g<<8) + (r<<16);
528 int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
531 const PixFmtInfo *pinfo;
533 memset(picture->linesize, 0, sizeof(picture->linesize));
535 pinfo = &pix_fmt_info[pix_fmt];
537 case PIX_FMT_YUV420P:
538 case PIX_FMT_YUV422P:
539 case PIX_FMT_YUV444P:
540 case PIX_FMT_YUV410P:
541 case PIX_FMT_YUV411P:
542 case PIX_FMT_YUV440P:
543 case PIX_FMT_YUVJ420P:
544 case PIX_FMT_YUVJ422P:
545 case PIX_FMT_YUVJ444P:
546 case PIX_FMT_YUVJ440P:
547 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
548 picture->linesize[0] = width;
549 picture->linesize[1] = w2;
550 picture->linesize[2] = w2;
552 case PIX_FMT_YUVA420P:
553 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
554 picture->linesize[0] = width;
555 picture->linesize[1] = w2;
556 picture->linesize[2] = w2;
557 picture->linesize[3] = width;
561 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
562 picture->linesize[0] = width;
563 picture->linesize[1] = w2;
567 picture->linesize[0] = width * 3;
571 case PIX_FMT_RGB32_1:
572 case PIX_FMT_BGR32_1:
573 picture->linesize[0] = width * 4;
575 case PIX_FMT_RGB48BE:
576 case PIX_FMT_RGB48LE:
577 picture->linesize[0] = width * 6;
579 case PIX_FMT_GRAY16BE:
580 case PIX_FMT_GRAY16LE:
585 case PIX_FMT_YUYV422:
586 picture->linesize[0] = width * 2;
588 case PIX_FMT_UYVY422:
589 picture->linesize[0] = width * 2;
591 case PIX_FMT_UYYVYY411:
592 picture->linesize[0] = width + width/2;
596 picture->linesize[0] = width / 2;
598 case PIX_FMT_MONOWHITE:
599 case PIX_FMT_MONOBLACK:
600 picture->linesize[0] = (width + 7) >> 3;
605 case PIX_FMT_RGB4_BYTE:
606 case PIX_FMT_BGR4_BYTE:
608 picture->linesize[0] = width;
609 picture->linesize[1] = 4;
617 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
621 const PixFmtInfo *pinfo;
623 pinfo = &pix_fmt_info[pix_fmt];
624 size = picture->linesize[0] * height;
626 case PIX_FMT_YUV420P:
627 case PIX_FMT_YUV422P:
628 case PIX_FMT_YUV444P:
629 case PIX_FMT_YUV410P:
630 case PIX_FMT_YUV411P:
631 case PIX_FMT_YUV440P:
632 case PIX_FMT_YUVJ420P:
633 case PIX_FMT_YUVJ422P:
634 case PIX_FMT_YUVJ444P:
635 case PIX_FMT_YUVJ440P:
636 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
637 size2 = picture->linesize[1] * h2;
638 picture->data[0] = ptr;
639 picture->data[1] = picture->data[0] + size;
640 picture->data[2] = picture->data[1] + size2;
641 picture->data[3] = NULL;
642 return size + 2 * size2;
643 case PIX_FMT_YUVA420P:
644 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
645 size2 = picture->linesize[1] * h2;
646 picture->data[0] = ptr;
647 picture->data[1] = picture->data[0] + size;
648 picture->data[2] = picture->data[1] + size2;
649 picture->data[3] = picture->data[1] + size2 + size2;
650 return 2 * size + 2 * size2;
653 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
654 size2 = picture->linesize[1] * h2 * 2;
655 picture->data[0] = ptr;
656 picture->data[1] = picture->data[0] + size;
657 picture->data[2] = NULL;
658 picture->data[3] = NULL;
659 return size + 2 * size2;
664 case PIX_FMT_RGB32_1:
665 case PIX_FMT_BGR32_1:
666 case PIX_FMT_RGB48BE:
667 case PIX_FMT_RGB48LE:
668 case PIX_FMT_GRAY16BE:
669 case PIX_FMT_GRAY16LE:
674 case PIX_FMT_YUYV422:
675 case PIX_FMT_UYVY422:
676 case PIX_FMT_UYYVYY411:
679 case PIX_FMT_MONOWHITE:
680 case PIX_FMT_MONOBLACK:
681 picture->data[0] = ptr;
682 picture->data[1] = NULL;
683 picture->data[2] = NULL;
684 picture->data[3] = NULL;
689 case PIX_FMT_RGB4_BYTE:
690 case PIX_FMT_BGR4_BYTE:
692 size2 = (size + 3) & ~3;
693 picture->data[0] = ptr;
694 picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
695 picture->data[2] = NULL;
696 picture->data[3] = NULL;
697 return size2 + 256 * 4;
699 picture->data[0] = NULL;
700 picture->data[1] = NULL;
701 picture->data[2] = NULL;
702 picture->data[3] = NULL;
707 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
708 int pix_fmt, int width, int height)
711 if(avcodec_check_dimensions(NULL, width, height))
714 if (ff_fill_linesize(picture, pix_fmt, width))
717 return ff_fill_pointer(picture, ptr, pix_fmt, height);
720 int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
721 unsigned char *dest, int dest_size)
723 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
724 int i, j, w, ow, h, oh, data_planes;
725 const unsigned char* s;
726 int size = avpicture_get_size(pix_fmt, width, height);
728 if (size > dest_size || size < 0)
731 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
732 if (pix_fmt == PIX_FMT_YUYV422 ||
733 pix_fmt == PIX_FMT_UYVY422 ||
734 pix_fmt == PIX_FMT_BGR565 ||
735 pix_fmt == PIX_FMT_BGR555 ||
736 pix_fmt == PIX_FMT_RGB565 ||
737 pix_fmt == PIX_FMT_RGB555)
739 else if (pix_fmt == PIX_FMT_UYYVYY411)
741 else if (pix_fmt == PIX_FMT_PAL8)
744 w = width * (pf->depth * pf->nb_channels / 8);
749 data_planes = pf->nb_channels;
750 w = (width*pf->depth + 7)/8;
757 for (i=0; i<data_planes; i++) {
759 w = width >> pf->x_chroma_shift;
760 h = height >> pf->y_chroma_shift;
769 s += src->linesize[i];
773 if (pf->pixel_type == FF_PIXEL_PALETTE)
774 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
779 int avpicture_get_size(int pix_fmt, int width, int height)
781 AVPicture dummy_pict;
782 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
785 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
788 const PixFmtInfo *pf, *ps;
791 ps = &pix_fmt_info[src_pix_fmt];
792 pf = &pix_fmt_info[dst_pix_fmt];
796 pf = &pix_fmt_info[dst_pix_fmt];
797 if (pf->depth < ps->depth ||
798 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
799 loss |= FF_LOSS_DEPTH;
800 if (pf->x_chroma_shift > ps->x_chroma_shift ||
801 pf->y_chroma_shift > ps->y_chroma_shift)
802 loss |= FF_LOSS_RESOLUTION;
803 switch(pf->color_type) {
805 if (ps->color_type != FF_COLOR_RGB &&
806 ps->color_type != FF_COLOR_GRAY)
807 loss |= FF_LOSS_COLORSPACE;
810 if (ps->color_type != FF_COLOR_GRAY)
811 loss |= FF_LOSS_COLORSPACE;
814 if (ps->color_type != FF_COLOR_YUV)
815 loss |= FF_LOSS_COLORSPACE;
817 case FF_COLOR_YUV_JPEG:
818 if (ps->color_type != FF_COLOR_YUV_JPEG &&
819 ps->color_type != FF_COLOR_YUV &&
820 ps->color_type != FF_COLOR_GRAY)
821 loss |= FF_LOSS_COLORSPACE;
825 if (ps->color_type != pf->color_type)
826 loss |= FF_LOSS_COLORSPACE;
829 if (pf->color_type == FF_COLOR_GRAY &&
830 ps->color_type != FF_COLOR_GRAY)
831 loss |= FF_LOSS_CHROMA;
832 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
833 loss |= FF_LOSS_ALPHA;
834 if (pf->pixel_type == FF_PIXEL_PALETTE &&
835 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
836 loss |= FF_LOSS_COLORQUANT;
840 static int avg_bits_per_pixel(int pix_fmt)
843 const PixFmtInfo *pf;
845 pf = &pix_fmt_info[pix_fmt];
846 switch(pf->pixel_type) {
847 case FF_PIXEL_PACKED:
849 case PIX_FMT_YUYV422:
850 case PIX_FMT_UYVY422:
857 case PIX_FMT_UYYVYY411:
861 bits = pf->depth * pf->nb_channels;
865 case FF_PIXEL_PLANAR:
866 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
867 bits = pf->depth * pf->nb_channels;
869 bits = pf->depth + ((2 * pf->depth) >>
870 (pf->x_chroma_shift + pf->y_chroma_shift));
873 case FF_PIXEL_PALETTE:
883 static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
888 int dist, i, loss, min_dist, dst_pix_fmt;
890 /* find exact color match with smallest size */
892 min_dist = 0x7fffffff;
893 for(i = 0;i < PIX_FMT_NB; i++) {
894 if (pix_fmt_mask & (1ULL << i)) {
895 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
897 dist = avg_bits_per_pixel(i);
898 if (dist < min_dist) {
908 int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
909 int has_alpha, int *loss_ptr)
911 int dst_pix_fmt, loss_mask, i;
912 static const int loss_mask_order[] = {
913 ~0, /* no loss first */
916 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
922 /* try with successive loss */
925 loss_mask = loss_mask_order[i++];
926 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
927 has_alpha, loss_mask);
928 if (dst_pix_fmt >= 0)
936 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
940 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
941 const uint8_t *src, int src_wrap,
942 int width, int height)
946 for(;height > 0; height--) {
947 memcpy(dst, src, width);
953 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
956 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
958 pf = &pix_fmt_info[pix_fmt];
959 switch(pf->pixel_type) {
960 case FF_PIXEL_PACKED:
962 case PIX_FMT_YUYV422:
963 case PIX_FMT_UYVY422:
970 case PIX_FMT_UYYVYY411:
974 bits = pf->depth * pf->nb_channels;
977 return (width * bits + 7) >> 3;
979 case FF_PIXEL_PLANAR:
980 if (plane == 1 || plane == 2)
981 width= -((-width)>>pf->x_chroma_shift);
983 return (width * pf->depth + 7) >> 3;
985 case FF_PIXEL_PALETTE:
994 void av_picture_copy(AVPicture *dst, const AVPicture *src,
995 int pix_fmt, int width, int height)
998 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
1000 pf = &pix_fmt_info[pix_fmt];
1001 switch(pf->pixel_type) {
1002 case FF_PIXEL_PACKED:
1003 case FF_PIXEL_PLANAR:
1004 for(i = 0; i < pf->nb_channels; i++) {
1006 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
1008 if (i == 1 || i == 2) {
1009 h= -((-height)>>pf->y_chroma_shift);
1011 ff_img_copy_plane(dst->data[i], dst->linesize[i],
1012 src->data[i], src->linesize[i],
1016 case FF_PIXEL_PALETTE:
1017 ff_img_copy_plane(dst->data[0], dst->linesize[0],
1018 src->data[0], src->linesize[0],
1020 /* copy the palette */
1021 ff_img_copy_plane(dst->data[1], dst->linesize[1],
1022 src->data[1], src->linesize[1],
1028 /* XXX: totally non optimized */
1030 static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
1031 int width, int height)
1033 const uint8_t *p, *p1;
1034 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1038 lum1 = dst->data[0];
1042 for(;height >= 1; height -= 2) {
1047 for(w = width; w >= 2; w -= 2) {
1064 p1 += src->linesize[0];
1065 lum1 += dst->linesize[0];
1069 for(w = width; w >= 2; w -= 2) {
1078 p1 += src->linesize[0];
1079 lum1 += dst->linesize[0];
1081 cb1 += dst->linesize[1];
1082 cr1 += dst->linesize[2];
1086 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
1087 int width, int height)
1089 const uint8_t *p, *p1;
1090 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1095 lum1 = dst->data[0];
1099 for(;height >= 1; height -= 2) {
1104 for(w = width; w >= 2; w -= 2) {
1121 p1 += src->linesize[0];
1122 lum1 += dst->linesize[0];
1126 for(w = width; w >= 2; w -= 2) {
1135 p1 += src->linesize[0];
1136 lum1 += dst->linesize[0];
1138 cb1 += dst->linesize[1];
1139 cr1 += dst->linesize[2];
1144 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1145 int width, int height)
1147 const uint8_t *p, *p1;
1148 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1152 lum1 = dst->data[0];
1155 for(;height > 0; height--) {
1160 for(w = width; w >= 2; w -= 2) {
1170 p1 += src->linesize[0];
1171 lum1 += dst->linesize[0];
1172 cb1 += dst->linesize[1];
1173 cr1 += dst->linesize[2];
1178 static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
1179 int width, int height)
1181 const uint8_t *p, *p1;
1182 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1186 lum1 = dst->data[0];
1189 for(;height > 0; height--) {
1194 for(w = width; w >= 2; w -= 2) {
1204 p1 += src->linesize[0];
1205 lum1 += dst->linesize[0];
1206 cb1 += dst->linesize[1];
1207 cr1 += dst->linesize[2];
1211 static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1212 int width, int height)
1215 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1219 lum1 = src->data[0];
1222 for(;height > 0; height--) {
1227 for(w = width; w >= 2; w -= 2) {
1237 p1 += dst->linesize[0];
1238 lum1 += src->linesize[0];
1239 cb1 += src->linesize[1];
1240 cr1 += src->linesize[2];
1244 static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1245 int width, int height)
1248 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1252 lum1 = src->data[0];
1255 for(;height > 0; height--) {
1260 for(w = width; w >= 2; w -= 2) {
1270 p1 += dst->linesize[0];
1271 lum1 += src->linesize[0];
1272 cb1 += src->linesize[1];
1273 cr1 += src->linesize[2];
1277 static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
1278 int width, int height)
1280 const uint8_t *p, *p1;
1281 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
1285 lum1 = dst->data[0];
1288 for(;height > 0; height--) {
1293 for(w = width; w >= 4; w -= 4) {
1305 p1 += src->linesize[0];
1306 lum1 += dst->linesize[0];
1307 cb1 += dst->linesize[1];
1308 cr1 += dst->linesize[2];
1313 static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
1314 int width, int height)
1317 uint8_t *line1, *line2, *linesrc = dst->data[0];
1318 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1319 uint8_t *cb1, *cb2 = src->data[1];
1320 uint8_t *cr1, *cr2 = src->data[2];
1322 for(h = height / 2; h--;) {
1324 line2 = linesrc + dst->linesize[0];
1327 lum2 = lumsrc + src->linesize[0];
1332 for(w = width / 2; w--;) {
1333 *line1++ = *lum1++; *line2++ = *lum2++;
1334 *line1++ = *line2++ = *cb1++;
1335 *line1++ = *lum1++; *line2++ = *lum2++;
1336 *line1++ = *line2++ = *cr1++;
1339 linesrc += dst->linesize[0] * 2;
1340 lumsrc += src->linesize[0] * 2;
1341 cb2 += src->linesize[1];
1342 cr2 += src->linesize[2];
1346 static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
1347 int width, int height)
1350 uint8_t *line1, *line2, *linesrc = dst->data[0];
1351 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
1352 uint8_t *cb1, *cb2 = src->data[1];
1353 uint8_t *cr1, *cr2 = src->data[2];
1355 for(h = height / 2; h--;) {
1357 line2 = linesrc + dst->linesize[0];
1360 lum2 = lumsrc + src->linesize[0];
1365 for(w = width / 2; w--;) {
1366 *line1++ = *line2++ = *cb1++;
1367 *line1++ = *lum1++; *line2++ = *lum2++;
1368 *line1++ = *line2++ = *cr1++;
1369 *line1++ = *lum1++; *line2++ = *lum2++;
1372 linesrc += dst->linesize[0] * 2;
1373 lumsrc += src->linesize[0] * 2;
1374 cb2 += src->linesize[1];
1375 cr2 += src->linesize[2];
1380 void ff_shrink22(uint8_t *dst, int dst_wrap,
1381 const uint8_t *src, int src_wrap,
1382 int width, int height)
1385 const uint8_t *s1, *s2;
1388 for(;height > 0; height--) {
1392 for(w = width;w >= 4; w-=4) {
1393 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1394 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
1395 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
1396 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
1402 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
1407 src += 2 * src_wrap;
1413 void ff_shrink44(uint8_t *dst, int dst_wrap,
1414 const uint8_t *src, int src_wrap,
1415 int width, int height)
1418 const uint8_t *s1, *s2, *s3, *s4;
1421 for(;height > 0; height--) {
1427 for(w = width;w > 0; w--) {
1428 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
1429 s2[0] + s2[1] + s2[2] + s2[3] +
1430 s3[0] + s3[1] + s3[2] + s3[3] +
1431 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
1438 src += 4 * src_wrap;
1444 void ff_shrink88(uint8_t *dst, int dst_wrap,
1445 const uint8_t *src, int src_wrap,
1446 int width, int height)
1450 for(;height > 0; height--) {
1451 for(w = width;w > 0; w--) {
1454 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
1457 *(dst++) = (tmp + 32)>>6;
1458 src += 8 - 8*src_wrap;
1460 src += 8*src_wrap - 8*width;
1461 dst += dst_wrap - width;
1465 /* XXX: add jpeg quantize code */
1467 #define TRANSP_INDEX (6*6*6)
1469 /* this is maybe slow, but allows for extensions */
1470 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
1472 return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
1475 static void build_rgb_palette(uint8_t *palette, int has_alpha)
1478 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
1481 pal = (uint32_t *)palette;
1483 for(r = 0; r < 6; r++) {
1484 for(g = 0; g < 6; g++) {
1485 for(b = 0; b < 6; b++) {
1486 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
1487 (pal_value[g] << 8) | pal_value[b];
1494 pal[i++] = 0xff000000;
1497 /* copy bit n to bits 0 ... n - 1 */
1498 static inline unsigned int bitcopy_n(unsigned int a, int n)
1501 mask = (1 << n) - 1;
1502 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
1505 /* rgb555 handling */
1507 #define RGB_NAME rgb555
1509 #define RGB_IN(r, g, b, s)\
1511 unsigned int v = ((const uint16_t *)(s))[0];\
1512 r = bitcopy_n(v >> (10 - 3), 3);\
1513 g = bitcopy_n(v >> (5 - 3), 3);\
1514 b = bitcopy_n(v << 3, 3);\
1518 #define RGB_OUT(d, r, g, b)\
1520 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
1525 #include "imgconvert_template.c"
1527 /* rgb565 handling */
1529 #define RGB_NAME rgb565
1531 #define RGB_IN(r, g, b, s)\
1533 unsigned int v = ((const uint16_t *)(s))[0];\
1534 r = bitcopy_n(v >> (11 - 3), 3);\
1535 g = bitcopy_n(v >> (5 - 2), 2);\
1536 b = bitcopy_n(v << 3, 3);\
1539 #define RGB_OUT(d, r, g, b)\
1541 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
1546 #include "imgconvert_template.c"
1548 /* bgr24 handling */
1550 #define RGB_NAME bgr24
1552 #define RGB_IN(r, g, b, s)\
1559 #define RGB_OUT(d, r, g, b)\
1568 #include "imgconvert_template.c"
1574 /* rgb24 handling */
1576 #define RGB_NAME rgb24
1579 #define RGB_IN(r, g, b, s)\
1586 #define RGB_OUT(d, r, g, b)\
1595 #include "imgconvert_template.c"
1597 /* rgb32 handling */
1599 #define RGB_NAME rgb32
1602 #define RGB_IN(r, g, b, s)\
1604 unsigned int v = ((const uint32_t *)(s))[0];\
1605 r = (v >> 16) & 0xff;\
1606 g = (v >> 8) & 0xff;\
1610 #define RGBA_IN(r, g, b, a, s)\
1612 unsigned int v = ((const uint32_t *)(s))[0];\
1613 a = (v >> 24) & 0xff;\
1614 r = (v >> 16) & 0xff;\
1615 g = (v >> 8) & 0xff;\
1619 #define RGBA_OUT(d, r, g, b, a)\
1621 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
1626 #include "imgconvert_template.c"
1628 static void mono_to_gray(AVPicture *dst, const AVPicture *src,
1629 int width, int height, int xor_mask)
1631 const unsigned char *p;
1633 int v, dst_wrap, src_wrap;
1637 src_wrap = src->linesize[0] - ((width + 7) >> 3);
1640 dst_wrap = dst->linesize[0] - width;
1641 for(y=0;y<height;y++) {
1644 v = *p++ ^ xor_mask;
1646 q[1] = -((v >> 6) & 1);
1647 q[2] = -((v >> 5) & 1);
1648 q[3] = -((v >> 4) & 1);
1649 q[4] = -((v >> 3) & 1);
1650 q[5] = -((v >> 2) & 1);
1651 q[6] = -((v >> 1) & 1);
1652 q[7] = -((v >> 0) & 1);
1657 v = *p++ ^ xor_mask;
1659 q[0] = -((v >> 7) & 1);
1669 static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
1670 int width, int height)
1672 mono_to_gray(dst, src, width, height, 0xff);
1675 static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
1676 int width, int height)
1678 mono_to_gray(dst, src, width, height, 0x00);
1681 static void gray_to_mono(AVPicture *dst, const AVPicture *src,
1682 int width, int height, int xor_mask)
1687 int j, b, v, n1, src_wrap, dst_wrap, y;
1690 src_wrap = src->linesize[0] - width;
1693 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
1695 for(y=0;y<height;y++) {
1702 v = (v << 1) | (b >> 7);
1704 d[0] = v ^ xor_mask;
1714 v = (v << 1) | (b >> 7);
1717 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
1725 static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
1726 int width, int height)
1728 gray_to_mono(dst, src, width, height, 0xff);
1731 static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
1732 int width, int height)
1734 gray_to_mono(dst, src, width, height, 0x00);
1737 static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
1738 int width, int height)
1740 int x, y, src_wrap, dst_wrap;
1743 src_wrap = src->linesize[0] - width;
1745 dst_wrap = dst->linesize[0] - width * 2;
1746 for(y=0; y<height; y++){
1747 for(x=0; x<width; x++){
1756 static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
1757 int width, int height)
1759 int x, y, src_wrap, dst_wrap;
1762 src_wrap = src->linesize[0] - width * 2;
1764 dst_wrap = dst->linesize[0] - width;
1765 for(y=0; y<height; y++){
1766 for(x=0; x<width; x++){
1775 static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
1776 int width, int height)
1778 gray16_to_gray(dst, src, width, height);
1781 static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
1782 int width, int height)
1784 AVPicture tmpsrc = *src;
1786 gray16_to_gray(dst, &tmpsrc, width, height);
1789 static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
1790 int width, int height)
1792 int x, y, src_wrap, dst_wrap;
1794 s = (uint16_t*)src->data[0];
1795 src_wrap = (src->linesize[0] - width * 2)/2;
1796 d = (uint16_t*)dst->data[0];
1797 dst_wrap = (dst->linesize[0] - width * 2)/2;
1798 for(y=0; y<height; y++){
1799 for(x=0; x<width; x++){
1800 *d++ = bswap_16(*s++);
1808 typedef struct ConvertEntry {
1809 void (*convert)(AVPicture *dst,
1810 const AVPicture *src, int width, int height);
1813 /* Add each new conversion function in this table. In order to be able
1814 to convert from any format to any format, the following constraints
1817 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
1819 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
1821 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
1823 - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
1826 - PIX_FMT_422 must convert to and from PIX_FMT_422P.
1828 The other conversion functions are just optimizations for common cases.
1830 static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
1831 [PIX_FMT_YUV420P] = {
1832 [PIX_FMT_YUYV422] = {
1833 .convert = yuv420p_to_yuyv422,
1835 [PIX_FMT_RGB555] = {
1836 .convert = yuv420p_to_rgb555
1838 [PIX_FMT_RGB565] = {
1839 .convert = yuv420p_to_rgb565
1842 .convert = yuv420p_to_bgr24
1845 .convert = yuv420p_to_rgb24
1848 .convert = yuv420p_to_rgb32
1850 [PIX_FMT_UYVY422] = {
1851 .convert = yuv420p_to_uyvy422,
1854 [PIX_FMT_YUV422P] = {
1855 [PIX_FMT_YUYV422] = {
1856 .convert = yuv422p_to_yuyv422,
1858 [PIX_FMT_UYVY422] = {
1859 .convert = yuv422p_to_uyvy422,
1862 [PIX_FMT_YUV444P] = {
1864 .convert = yuv444p_to_rgb24
1867 [PIX_FMT_YUVJ420P] = {
1868 [PIX_FMT_RGB555] = {
1869 .convert = yuvj420p_to_rgb555
1871 [PIX_FMT_RGB565] = {
1872 .convert = yuvj420p_to_rgb565
1875 .convert = yuvj420p_to_bgr24
1878 .convert = yuvj420p_to_rgb24
1881 .convert = yuvj420p_to_rgb32
1884 [PIX_FMT_YUVJ444P] = {
1886 .convert = yuvj444p_to_rgb24
1889 [PIX_FMT_YUYV422] = {
1890 [PIX_FMT_YUV420P] = {
1891 .convert = yuyv422_to_yuv420p,
1893 [PIX_FMT_YUV422P] = {
1894 .convert = yuyv422_to_yuv422p,
1897 [PIX_FMT_UYVY422] = {
1898 [PIX_FMT_YUV420P] = {
1899 .convert = uyvy422_to_yuv420p,
1901 [PIX_FMT_YUV422P] = {
1902 .convert = uyvy422_to_yuv422p,
1906 [PIX_FMT_YUV420P] = {
1907 .convert = rgb24_to_yuv420p
1909 [PIX_FMT_RGB565] = {
1910 .convert = rgb24_to_rgb565
1912 [PIX_FMT_RGB555] = {
1913 .convert = rgb24_to_rgb555
1916 .convert = rgb24_to_rgb32
1919 .convert = rgb24_to_bgr24
1922 .convert = rgb24_to_gray
1925 .convert = rgb24_to_pal8
1927 [PIX_FMT_YUV444P] = {
1928 .convert = rgb24_to_yuv444p
1930 [PIX_FMT_YUVJ420P] = {
1931 .convert = rgb24_to_yuvj420p
1933 [PIX_FMT_YUVJ444P] = {
1934 .convert = rgb24_to_yuvj444p
1939 .convert = rgb32_to_rgb24
1942 .convert = rgb32_to_bgr24
1944 [PIX_FMT_RGB565] = {
1945 .convert = rgb32_to_rgb565
1947 [PIX_FMT_RGB555] = {
1948 .convert = rgb32_to_rgb555
1951 .convert = rgb32_to_pal8
1953 [PIX_FMT_YUV420P] = {
1954 .convert = rgb32_to_yuv420p
1957 .convert = rgb32_to_gray
1962 .convert = bgr24_to_rgb32
1965 .convert = bgr24_to_rgb24
1967 [PIX_FMT_YUV420P] = {
1968 .convert = bgr24_to_yuv420p
1971 .convert = bgr24_to_gray
1974 [PIX_FMT_RGB555] = {
1976 .convert = rgb555_to_rgb24
1979 .convert = rgb555_to_rgb32
1981 [PIX_FMT_YUV420P] = {
1982 .convert = rgb555_to_yuv420p
1985 .convert = rgb555_to_gray
1988 [PIX_FMT_RGB565] = {
1990 .convert = rgb565_to_rgb32
1993 .convert = rgb565_to_rgb24
1995 [PIX_FMT_YUV420P] = {
1996 .convert = rgb565_to_yuv420p
1999 .convert = rgb565_to_gray
2002 [PIX_FMT_GRAY16BE] = {
2004 .convert = gray16be_to_gray
2006 [PIX_FMT_GRAY16LE] = {
2007 .convert = gray16_to_gray16
2010 [PIX_FMT_GRAY16LE] = {
2012 .convert = gray16le_to_gray
2014 [PIX_FMT_GRAY16BE] = {
2015 .convert = gray16_to_gray16
2019 [PIX_FMT_RGB555] = {
2020 .convert = gray_to_rgb555
2022 [PIX_FMT_RGB565] = {
2023 .convert = gray_to_rgb565
2026 .convert = gray_to_rgb24
2029 .convert = gray_to_bgr24
2032 .convert = gray_to_rgb32
2034 [PIX_FMT_MONOWHITE] = {
2035 .convert = gray_to_monowhite
2037 [PIX_FMT_MONOBLACK] = {
2038 .convert = gray_to_monoblack
2040 [PIX_FMT_GRAY16LE] = {
2041 .convert = gray_to_gray16
2043 [PIX_FMT_GRAY16BE] = {
2044 .convert = gray_to_gray16
2047 [PIX_FMT_MONOWHITE] = {
2049 .convert = monowhite_to_gray
2052 [PIX_FMT_MONOBLACK] = {
2054 .convert = monoblack_to_gray
2058 [PIX_FMT_RGB555] = {
2059 .convert = pal8_to_rgb555
2061 [PIX_FMT_RGB565] = {
2062 .convert = pal8_to_rgb565
2065 .convert = pal8_to_bgr24
2068 .convert = pal8_to_rgb24
2071 .convert = pal8_to_rgb32
2074 [PIX_FMT_UYYVYY411] = {
2075 [PIX_FMT_YUV411P] = {
2076 .convert = uyyvyy411_to_yuv411p,
2082 int avpicture_alloc(AVPicture *picture,
2083 int pix_fmt, int width, int height)
2088 size = avpicture_get_size(pix_fmt, width, height);
2091 ptr = av_malloc(size);
2094 avpicture_fill(picture, ptr, pix_fmt, width, height);
2095 if(picture->data[1] && !picture->data[2])
2096 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
2100 memset(picture, 0, sizeof(AVPicture));
2104 void avpicture_free(AVPicture *picture)
2106 av_free(picture->data[0]);
2109 /* return true if yuv planar */
2110 static inline int is_yuv_planar(const PixFmtInfo *ps)
2112 return (ps->color_type == FF_COLOR_YUV ||
2113 ps->color_type == FF_COLOR_YUV_JPEG) &&
2114 ps->pixel_type == FF_PIXEL_PLANAR;
2117 int av_picture_crop(AVPicture *dst, const AVPicture *src,
2118 int pix_fmt, int top_band, int left_band)
2123 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
2126 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
2127 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
2129 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
2130 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
2131 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
2133 dst->linesize[0] = src->linesize[0];
2134 dst->linesize[1] = src->linesize[1];
2135 dst->linesize[2] = src->linesize[2];
2139 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
2140 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
2149 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
2150 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
2152 for (i = 0; i < 3; i++) {
2153 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
2154 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
2156 if (padtop || padleft) {
2157 memset(dst->data[i], color[i],
2158 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
2161 if (padleft || padright) {
2162 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2163 (dst->linesize[i] - (padright >> x_shift));
2164 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2165 for (y = 0; y < yheight; y++) {
2166 memset(optr, color[i], (padleft + padright) >> x_shift);
2167 optr += dst->linesize[i];
2171 if (src) { /* first line */
2172 uint8_t *iptr = src->data[i];
2173 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2174 (padleft >> x_shift);
2175 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
2176 iptr += src->linesize[i];
2177 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
2178 (dst->linesize[i] - (padright >> x_shift));
2179 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
2180 for (y = 0; y < yheight; y++) {
2181 memset(optr, color[i], (padleft + padright) >> x_shift);
2182 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
2183 (width - padleft - padright) >> x_shift);
2184 iptr += src->linesize[i];
2185 optr += dst->linesize[i];
2189 if (padbottom || padright) {
2190 optr = dst->data[i] + dst->linesize[i] *
2191 ((height - padbottom) >> y_shift) - (padright >> x_shift);
2192 memset(optr, color[i],dst->linesize[i] *
2193 (padbottom >> y_shift) + (padright >> x_shift));
2200 static uint8_t y_ccir_to_jpeg[256];
2201 static uint8_t y_jpeg_to_ccir[256];
2202 static uint8_t c_ccir_to_jpeg[256];
2203 static uint8_t c_jpeg_to_ccir[256];
2205 /* init various conversion tables */
2206 static av_cold void img_convert_init(void)
2209 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2211 for(i = 0;i < 256; i++) {
2212 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
2213 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
2214 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
2215 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
2219 /* apply to each pixel the given table */
2220 static void img_apply_table(uint8_t *dst, int dst_wrap,
2221 const uint8_t *src, int src_wrap,
2222 int width, int height, const uint8_t *table1)
2227 const uint8_t *table;
2230 for(;height > 0; height--) {
2254 /* XXX: use generic filter ? */
2255 /* XXX: in most cases, the sampling position is incorrect */
2258 static void shrink41(uint8_t *dst, int dst_wrap,
2259 const uint8_t *src, int src_wrap,
2260 int width, int height)
2266 for(;height > 0; height--) {
2269 for(w = width;w > 0; w--) {
2270 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
2280 static void shrink21(uint8_t *dst, int dst_wrap,
2281 const uint8_t *src, int src_wrap,
2282 int width, int height)
2288 for(;height > 0; height--) {
2291 for(w = width;w > 0; w--) {
2292 d[0] = (s[0] + s[1]) >> 1;
2302 static void shrink12(uint8_t *dst, int dst_wrap,
2303 const uint8_t *src, int src_wrap,
2304 int width, int height)
2308 const uint8_t *s1, *s2;
2310 for(;height > 0; height--) {
2314 for(w = width;w >= 4; w-=4) {
2315 d[0] = (s1[0] + s2[0]) >> 1;
2316 d[1] = (s1[1] + s2[1]) >> 1;
2317 d[2] = (s1[2] + s2[2]) >> 1;
2318 d[3] = (s1[3] + s2[3]) >> 1;
2324 d[0] = (s1[0] + s2[0]) >> 1;
2329 src += 2 * src_wrap;
2334 static void grow21_line(uint8_t *dst, const uint8_t *src,
2343 for(w = width;w >= 4; w-=4) {
2344 d[1] = d[0] = s1[0];
2345 d[3] = d[2] = s1[1];
2349 for(;w >= 2; w -= 2) {
2350 d[1] = d[0] = s1[0];
2354 /* only needed if width is not a multiple of two */
2355 /* XXX: veryfy that */
2361 static void grow41_line(uint8_t *dst, const uint8_t *src,
2370 for(w = width;w >= 4; w-=4) {
2382 static void grow21(uint8_t *dst, int dst_wrap,
2383 const uint8_t *src, int src_wrap,
2384 int width, int height)
2386 for(;height > 0; height--) {
2387 grow21_line(dst, src, width);
2394 static void grow12(uint8_t *dst, int dst_wrap,
2395 const uint8_t *src, int src_wrap,
2396 int width, int height)
2398 for(;height > 0; height-=2) {
2399 memcpy(dst, src, width);
2401 memcpy(dst, src, width);
2408 static void grow22(uint8_t *dst, int dst_wrap,
2409 const uint8_t *src, int src_wrap,
2410 int width, int height)
2412 for(;height > 0; height--) {
2413 grow21_line(dst, src, width);
2421 static void grow41(uint8_t *dst, int dst_wrap,
2422 const uint8_t *src, int src_wrap,
2423 int width, int height)
2425 for(;height > 0; height--) {
2426 grow41_line(dst, src, width);
2433 static void grow44(uint8_t *dst, int dst_wrap,
2434 const uint8_t *src, int src_wrap,
2435 int width, int height)
2437 for(;height > 0; height--) {
2438 grow41_line(dst, src, width);
2439 if ((height & 3) == 1)
2446 static void conv411(uint8_t *dst, int dst_wrap,
2447 const uint8_t *src, int src_wrap,
2448 int width, int height)
2451 const uint8_t *s1, *s2;
2456 for(;height > 0; height--) {
2458 s2 = src + src_wrap;
2460 for(w = width;w > 0; w--) {
2461 c = (s1[0] + s2[0]) >> 1;
2468 src += src_wrap * 2;
2473 /* XXX: always use linesize. Return -1 if not supported */
2474 int img_convert(AVPicture *dst, int dst_pix_fmt,
2475 const AVPicture *src, int src_pix_fmt,
2476 int src_width, int src_height)
2478 static int initialized;
2479 int i, ret, dst_width, dst_height, int_pix_fmt;
2480 const PixFmtInfo *src_pix, *dst_pix;
2481 const ConvertEntry *ce;
2482 AVPicture tmp1, *tmp = &tmp1;
2484 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
2485 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
2487 if (src_width <= 0 || src_height <= 0)
2495 dst_width = src_width;
2496 dst_height = src_height;
2498 dst_pix = &pix_fmt_info[dst_pix_fmt];
2499 src_pix = &pix_fmt_info[src_pix_fmt];
2500 if (src_pix_fmt == dst_pix_fmt) {
2501 /* no conversion needed: just copy */
2502 av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
2506 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
2508 /* specific conversion routine */
2509 ce->convert(dst, src, dst_width, dst_height);
2514 if (is_yuv_planar(dst_pix) &&
2515 src_pix_fmt == PIX_FMT_GRAY8) {
2519 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
2520 ff_img_copy_plane(dst->data[0], dst->linesize[0],
2521 src->data[0], src->linesize[0],
2522 dst_width, dst_height);
2524 img_apply_table(dst->data[0], dst->linesize[0],
2525 src->data[0], src->linesize[0],
2526 dst_width, dst_height,
2529 /* fill U and V with 128 */
2532 w >>= dst_pix->x_chroma_shift;
2533 h >>= dst_pix->y_chroma_shift;
2534 for(i = 1; i <= 2; i++) {
2536 for(y = 0; y< h; y++) {
2538 d += dst->linesize[i];
2545 if (is_yuv_planar(src_pix) &&
2546 dst_pix_fmt == PIX_FMT_GRAY8) {
2547 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
2548 ff_img_copy_plane(dst->data[0], dst->linesize[0],
2549 src->data[0], src->linesize[0],
2550 dst_width, dst_height);
2552 img_apply_table(dst->data[0], dst->linesize[0],
2553 src->data[0], src->linesize[0],
2554 dst_width, dst_height,
2560 /* YUV to YUV planar */
2561 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
2562 int x_shift, y_shift, w, h, xy_shift;
2563 void (*resize_func)(uint8_t *dst, int dst_wrap,
2564 const uint8_t *src, int src_wrap,
2565 int width, int height);
2567 /* compute chroma size of the smallest dimensions */
2570 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
2571 w >>= dst_pix->x_chroma_shift;
2573 w >>= src_pix->x_chroma_shift;
2574 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
2575 h >>= dst_pix->y_chroma_shift;
2577 h >>= src_pix->y_chroma_shift;
2579 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
2580 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
2581 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
2582 /* there must be filters for conversion at least from and to
2586 resize_func = ff_img_copy_plane;
2589 resize_func = shrink21;
2592 resize_func = shrink41;
2595 resize_func = shrink12;
2598 resize_func = ff_shrink22;
2601 resize_func = ff_shrink44;
2604 resize_func = grow21;
2607 resize_func = grow12;
2610 resize_func = grow41;
2613 resize_func = grow22;
2616 resize_func = grow44;
2619 resize_func = conv411;
2622 /* currently not handled */
2623 goto no_chroma_filter;
2626 ff_img_copy_plane(dst->data[0], dst->linesize[0],
2627 src->data[0], src->linesize[0],
2628 dst_width, dst_height);
2630 for(i = 1;i <= 2; i++)
2631 resize_func(dst->data[i], dst->linesize[i],
2632 src->data[i], src->linesize[i],
2633 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
2634 /* if yuv color space conversion is needed, we do it here on
2635 the destination image */
2636 if (dst_pix->color_type != src_pix->color_type) {
2637 const uint8_t *y_table, *c_table;
2638 if (dst_pix->color_type == FF_COLOR_YUV) {
2639 y_table = y_jpeg_to_ccir;
2640 c_table = c_jpeg_to_ccir;
2642 y_table = y_ccir_to_jpeg;
2643 c_table = c_ccir_to_jpeg;
2645 img_apply_table(dst->data[0], dst->linesize[0],
2646 dst->data[0], dst->linesize[0],
2647 dst_width, dst_height,
2650 for(i = 1;i <= 2; i++)
2651 img_apply_table(dst->data[i], dst->linesize[i],
2652 dst->data[i], dst->linesize[i],
2653 dst_width>>dst_pix->x_chroma_shift,
2654 dst_height>>dst_pix->y_chroma_shift,
2661 /* try to use an intermediate format */
2662 if (src_pix_fmt == PIX_FMT_YUYV422 ||
2663 dst_pix_fmt == PIX_FMT_YUYV422) {
2664 /* specific case: convert to YUV422P first */
2665 int_pix_fmt = PIX_FMT_YUV422P;
2666 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
2667 dst_pix_fmt == PIX_FMT_UYVY422) {
2668 /* specific case: convert to YUV422P first */
2669 int_pix_fmt = PIX_FMT_YUV422P;
2670 } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
2671 dst_pix_fmt == PIX_FMT_UYYVYY411) {
2672 /* specific case: convert to YUV411P first */
2673 int_pix_fmt = PIX_FMT_YUV411P;
2674 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
2675 src_pix_fmt != PIX_FMT_GRAY8) ||
2676 (dst_pix->color_type == FF_COLOR_GRAY &&
2677 dst_pix_fmt != PIX_FMT_GRAY8)) {
2678 /* gray8 is the normalized format */
2679 int_pix_fmt = PIX_FMT_GRAY8;
2680 } else if ((is_yuv_planar(src_pix) &&
2681 src_pix_fmt != PIX_FMT_YUV444P &&
2682 src_pix_fmt != PIX_FMT_YUVJ444P)) {
2683 /* yuv444 is the normalized format */
2684 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
2685 int_pix_fmt = PIX_FMT_YUVJ444P;
2687 int_pix_fmt = PIX_FMT_YUV444P;
2688 } else if ((is_yuv_planar(dst_pix) &&
2689 dst_pix_fmt != PIX_FMT_YUV444P &&
2690 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
2691 /* yuv444 is the normalized format */
2692 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
2693 int_pix_fmt = PIX_FMT_YUVJ444P;
2695 int_pix_fmt = PIX_FMT_YUV444P;
2697 /* the two formats are rgb or gray8 or yuv[j]444p */
2698 if (src_pix->is_alpha && dst_pix->is_alpha)
2699 int_pix_fmt = PIX_FMT_RGB32;
2701 int_pix_fmt = PIX_FMT_RGB24;
2703 if (src_pix_fmt == int_pix_fmt)
2705 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
2708 if (img_convert(tmp, int_pix_fmt,
2709 src, src_pix_fmt, src_width, src_height) < 0)
2711 if (img_convert(dst, dst_pix_fmt,
2712 tmp, int_pix_fmt, dst_width, dst_height) < 0)
2716 avpicture_free(tmp);
2721 /* NOTE: we scan all the pixels to have an exact information */
2722 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
2724 const unsigned char *p;
2725 int src_wrap, ret, x, y;
2727 uint32_t *palette = (uint32_t *)src->data[1];
2730 src_wrap = src->linesize[0] - width;
2732 for(y=0;y<height;y++) {
2733 for(x=0;x<width;x++) {
2734 a = palette[p[0]] >> 24;
2736 ret |= FF_ALPHA_TRANSP;
2737 } else if (a != 0xff) {
2738 ret |= FF_ALPHA_SEMI_TRANSP;
2747 int img_get_alpha_info(const AVPicture *src,
2748 int pix_fmt, int width, int height)
2750 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
2753 pf = &pix_fmt_info[pix_fmt];
2754 /* no alpha can be represented in format */
2759 ret = get_alpha_info_rgb32(src, width, height);
2762 ret = get_alpha_info_pal8(src, width, height);
2765 /* we do not know, so everything is indicated */
2766 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
2773 #define DEINT_INPLACE_LINE_LUM \
2774 movd_m2r(lum_m4[0],mm0);\
2775 movd_m2r(lum_m3[0],mm1);\
2776 movd_m2r(lum_m2[0],mm2);\
2777 movd_m2r(lum_m1[0],mm3);\
2778 movd_m2r(lum[0],mm4);\
2779 punpcklbw_r2r(mm7,mm0);\
2780 movd_r2m(mm2,lum_m4[0]);\
2781 punpcklbw_r2r(mm7,mm1);\
2782 punpcklbw_r2r(mm7,mm2);\
2783 punpcklbw_r2r(mm7,mm3);\
2784 punpcklbw_r2r(mm7,mm4);\
2785 paddw_r2r(mm3,mm1);\
2787 paddw_r2r(mm4,mm0);\
2789 paddw_r2r(mm6,mm2);\
2790 paddw_r2r(mm2,mm1);\
2791 psubusw_r2r(mm0,mm1);\
2793 packuswb_r2r(mm7,mm1);\
2794 movd_r2m(mm1,lum_m2[0]);
2796 #define DEINT_LINE_LUM \
2797 movd_m2r(lum_m4[0],mm0);\
2798 movd_m2r(lum_m3[0],mm1);\
2799 movd_m2r(lum_m2[0],mm2);\
2800 movd_m2r(lum_m1[0],mm3);\
2801 movd_m2r(lum[0],mm4);\
2802 punpcklbw_r2r(mm7,mm0);\
2803 punpcklbw_r2r(mm7,mm1);\
2804 punpcklbw_r2r(mm7,mm2);\
2805 punpcklbw_r2r(mm7,mm3);\
2806 punpcklbw_r2r(mm7,mm4);\
2807 paddw_r2r(mm3,mm1);\
2809 paddw_r2r(mm4,mm0);\
2811 paddw_r2r(mm6,mm2);\
2812 paddw_r2r(mm2,mm1);\
2813 psubusw_r2r(mm0,mm1);\
2815 packuswb_r2r(mm7,mm1);\
2816 movd_r2m(mm1,dst[0]);
2819 /* filter parameters: [-1 4 2 4 -1] // 8 */
2820 static void deinterlace_line(uint8_t *dst,
2821 const uint8_t *lum_m4, const uint8_t *lum_m3,
2822 const uint8_t *lum_m2, const uint8_t *lum_m1,
2827 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2830 for(;size > 0;size--) {
2832 sum += lum_m3[0] << 2;
2833 sum += lum_m2[0] << 1;
2834 sum += lum_m1[0] << 2;
2836 dst[0] = cm[(sum + 4) >> 3];
2848 movq_m2r(ff_pw_4,mm6);
2850 for (;size > 3; size-=4) {
2861 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
2865 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
2868 for(;size > 0;size--) {
2870 sum += lum_m3[0] << 2;
2871 sum += lum_m2[0] << 1;
2872 lum_m4[0]=lum_m2[0];
2873 sum += lum_m1[0] << 2;
2875 lum_m2[0] = cm[(sum + 4) >> 3];
2886 movq_m2r(ff_pw_4,mm6);
2888 for (;size > 3; size-=4) {
2889 DEINT_INPLACE_LINE_LUM
2899 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
2900 top field is copied as is, but the bottom field is deinterlaced
2901 against the top field. */
2902 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
2903 const uint8_t *src1, int src_wrap,
2904 int width, int height)
2906 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
2911 src_0=&src_m1[src_wrap];
2912 src_p1=&src_0[src_wrap];
2913 src_p2=&src_p1[src_wrap];
2914 for(y=0;y<(height-2);y+=2) {
2915 memcpy(dst,src_m1,width);
2917 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
2921 src_p1 += 2*src_wrap;
2922 src_p2 += 2*src_wrap;
2925 memcpy(dst,src_m1,width);
2928 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
2931 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
2932 int width, int height)
2934 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
2937 buf = (uint8_t*)av_malloc(width);
2940 memcpy(buf,src_m1,width);
2941 src_0=&src_m1[src_wrap];
2942 src_p1=&src_0[src_wrap];
2943 src_p2=&src_p1[src_wrap];
2944 for(y=0;y<(height-2);y+=2) {
2945 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
2948 src_p1 += 2*src_wrap;
2949 src_p2 += 2*src_wrap;
2952 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
2956 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
2957 int pix_fmt, int width, int height)
2961 if (pix_fmt != PIX_FMT_YUV420P &&
2962 pix_fmt != PIX_FMT_YUV422P &&
2963 pix_fmt != PIX_FMT_YUV444P &&
2964 pix_fmt != PIX_FMT_YUV411P &&
2965 pix_fmt != PIX_FMT_GRAY8)
2967 if ((width & 3) != 0 || (height & 3) != 0)
2973 case PIX_FMT_YUV420P:
2977 case PIX_FMT_YUV422P:
2980 case PIX_FMT_YUV411P:
2986 if (pix_fmt == PIX_FMT_GRAY8) {
2991 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
2994 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
2995 src->data[i], src->linesize[i],