mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
1469453cb9
Fix conversions to IYU1, they allocated infinite amounts of memory before because no conversion to IYU1 was actually implemented and it was running into an infinite loop trying to find suitable intermediate formats. Also fix the stride and sizes used for IYU1.
4126 lines
108 KiB
C
4126 lines
108 KiB
C
/*
|
|
* Misc image convertion routines
|
|
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
/**
|
|
* @file imgconvert.c
|
|
* Misc image convertion routines.
|
|
*/
|
|
|
|
/* TODO:
|
|
* - write 'ffimg' program to test all the image related stuff
|
|
* - move all api to slice based system
|
|
* - integrate deinterlacing, postprocessing and scaling in the conversion process
|
|
*/
|
|
|
|
#include "avcodec.h"
|
|
#include "dsputil.h"
|
|
#include "gstffmpegcodecmap.h"
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
GST_DEBUG_CATEGORY_EXTERN (ffmpegcolorspace_performance);
|
|
|
|
#define xglue(x, y) x ## y
|
|
#define glue(x, y) xglue(x, y)
|
|
|
|
/* this table gives more information about formats */
|
|
/* FIXME, this table is also in ffmpegcodecmap */
|
|
static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
|
|
/* YUV formats */
|
|
/* [PIX_FMT_YUV420P] = */ {
|
|
/* .format = */ PIX_FMT_YUV420P,
|
|
/* .name = */ "yuv420p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 1,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YVU420P] = */ {
|
|
/* .format = */ PIX_FMT_YVU420P,
|
|
/* .name = */ "yvu420p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 1,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_NV12] = */ {
|
|
/* .format = */ PIX_FMT_NV12,
|
|
/* .name = */ "nv12",
|
|
/* .nb_channels = */ 2,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 1,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_NV21] = */ {
|
|
/* .format = */ PIX_FMT_NV21,
|
|
/* .name = */ "nv21",
|
|
/* .nb_channels = */ 2,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 1,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUV422P] = */ {
|
|
/* .format = */ PIX_FMT_YUV422P,
|
|
/* .name = */ "yuv422p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUV444P] = */ {
|
|
/* .format = */ PIX_FMT_YUV444P,
|
|
/* .name = */ "yuv444p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUV422] = */ {
|
|
/* .format = */ PIX_FMT_YUV422,
|
|
/* .name = */ "yuv422",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_UYVY422] = */ {
|
|
/* .format = */ PIX_FMT_UYVY422,
|
|
/* .name = */ "uyvy422",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YVYU422] = */ {
|
|
/* .format = */ PIX_FMT_YVYU422,
|
|
/* .name = */ "yvyu422",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_V308] = */ {
|
|
/* .format = */ PIX_FMT_V308,
|
|
/* .name = */ "v308",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUV410P] = */ {
|
|
/* .format = */ PIX_FMT_YUV410P,
|
|
/* .name = */ "yuv410p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 2,
|
|
/* .y_chroma_shift = */ 2,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YVU410P] = */ {
|
|
/* .format = */ PIX_FMT_YVU410P,
|
|
/* .name = */ "yvu410p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 2,
|
|
/* .y_chroma_shift = */ 2,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUV411P] = */ {
|
|
/* .format = */ PIX_FMT_YUV411P,
|
|
/* .name = */ "yuv411p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 2,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_Y800] = */ {
|
|
/* .format = */ PIX_FMT_Y800,
|
|
/* .name = */ "y800",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_Y16] = */ {
|
|
/* .format = */ PIX_FMT_Y16,
|
|
/* .name = */ "y16",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 16,
|
|
},
|
|
|
|
/* JPEG YUV */
|
|
/* [PIX_FMT_YUVJ420P] = */ {
|
|
/* .format = */ PIX_FMT_YUVJ420P,
|
|
/* .name = */ "yuvj420p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV_JPEG,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 1,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUVJ422P] = */ {
|
|
/* .format = */ PIX_FMT_YUVJ422P,
|
|
/* .name = */ "yuvj422p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV_JPEG,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_YUVJ444P] = */ {
|
|
/* .format = */ PIX_FMT_YUVJ444P,
|
|
/* .name = */ "yuvj444p",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_YUV_JPEG,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
|
|
/* RGB formats */
|
|
/* [PIX_FMT_RGB24] = */ {
|
|
/* .format = */ PIX_FMT_RGB24,
|
|
/* .name = */ "rgb24",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_BGR24] = */ {
|
|
/* .format = */ PIX_FMT_BGR24,
|
|
/* .name = */ "bgr24",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_RGB32] = */ {
|
|
/* .format = */ PIX_FMT_RGB32,
|
|
/* .name = */ "rgb32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_BGR32] = */ {
|
|
/* .format = */ PIX_FMT_BGR32,
|
|
/* .name = */ "bgr32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_RGB32] = */ {
|
|
/* .format = */ PIX_FMT_xRGB32,
|
|
/* .name = */ "xrgb32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_BGR32] = */ {
|
|
/* .format = */ PIX_FMT_BGRx32,
|
|
/* .name = */ "bgrx32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_RGBA32] = */ {
|
|
/* .format = */ PIX_FMT_RGBA32,
|
|
/* .name = */ "rgba32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_BGRA32] = */ {
|
|
/* .format = */ PIX_FMT_BGRA32,
|
|
/* .name = */ "bgra32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_ARGB32] = */ {
|
|
/* .format = */ PIX_FMT_ARGB32,
|
|
/* .name = */ "argb32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_ABGR32] = */ {
|
|
/* .format = */ PIX_FMT_ABGR32,
|
|
/* .name = */ "abgr32",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_RGB565] = */ {
|
|
/* .format = */ PIX_FMT_RGB565,
|
|
/* .name = */ "rgb565",
|
|
/* .nb_channels = */ 3,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 5,
|
|
},
|
|
/* [PIX_FMT_RGB555] = */ {
|
|
/* .format = */ PIX_FMT_RGB555,
|
|
/* .name = */ "rgb555",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 5,
|
|
},
|
|
|
|
/* gray / mono formats */
|
|
/* [PIX_FMT_GRAY8] = */ {
|
|
/* .format = */ PIX_FMT_GRAY8,
|
|
/* .name = */ "gray",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_GRAY,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_GRAY16_L] = */ {
|
|
/* .format = */ PIX_FMT_GRAY16_L,
|
|
/* .name = */ "gray",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_GRAY,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 16,
|
|
},
|
|
/* [PIX_FMT_GRAY16_B] = */ {
|
|
/* .format = */ PIX_FMT_GRAY16_B,
|
|
/* .name = */ "gray",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_GRAY,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 16,
|
|
},
|
|
/* [PIX_FMT_MONOWHITE] = */ {
|
|
/* .format = */ PIX_FMT_MONOWHITE,
|
|
/* .name = */ "monow",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_GRAY,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 1,
|
|
},
|
|
/* [PIX_FMT_MONOBLACK] = */ {
|
|
/* .format = */ PIX_FMT_MONOBLACK,
|
|
/* .name = */ "monob",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_GRAY,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 1,
|
|
},
|
|
|
|
/* paletted formats */
|
|
/* [PIX_FMT_PAL8] = */ {
|
|
/* .format = */ PIX_FMT_PAL8,
|
|
/* .name = */ "pal8",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_RGB,
|
|
/* .pixel_type = */ FF_PIXEL_PALETTE,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_XVMC_MPEG2_MC] = */ {
|
|
/* .format = */ PIX_FMT_XVMC_MPEG2_MC,
|
|
/* .name = */ "xvmcmc",
|
|
},
|
|
/* [PIX_FMT_XVMC_MPEG2_IDCT] = */ {
|
|
/* .format = */ PIX_FMT_XVMC_MPEG2_IDCT,
|
|
/* .name = */ "xvmcidct",
|
|
},
|
|
/* [PIX_FMT_UYVY411] = */ {
|
|
/* .format = */ PIX_FMT_UYVY411,
|
|
/* .name = */ "uyvy411",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 0,
|
|
/* .x_chroma_shift = */ 2,
|
|
/* .y_chroma_shift = */ 0,
|
|
/* .depth = */ 8,
|
|
},
|
|
/* [PIX_FMT_AYUV4444] = */ {
|
|
/* .format = */ PIX_FMT_AYUV4444,
|
|
/* .name = */ "ayuv4444",
|
|
/* .nb_channels = */ 1,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PACKED,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 0,
|
|
/* .y_chroma_shift = */ 0,
|
|
/*.depth = */ 8
|
|
},
|
|
/* [PIX_FMT_YUVA420P] = */ {
|
|
/* .format = */ PIX_FMT_YUVA420P,
|
|
/* .name = */ "yuva420p",
|
|
/* .nb_channels = */ 4,
|
|
/* .color_type = */ FF_COLOR_YUV,
|
|
/* .pixel_type = */ FF_PIXEL_PLANAR,
|
|
/* .is_alpha = */ 1,
|
|
/* .x_chroma_shift = */ 1,
|
|
/* .y_chroma_shift = */ 1,
|
|
/* .depth = */ 8,
|
|
}
|
|
};
|
|
|
|
/* returns NULL if not found */
|
|
/* undid static since this is also used in gstffmpegcodecmap.c */
|
|
PixFmtInfo *
|
|
get_pix_fmt_info (enum PixelFormat format)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < sizeof (pix_fmt_info) / sizeof (pix_fmt_info[0]); i++) {
|
|
if (pix_fmt_info[i].format == format) {
|
|
return pix_fmt_info + i;
|
|
}
|
|
}
|
|
|
|
/* since this doesn't get checked *anywhere*, we might as well warn
|
|
here if we return NULL so you have *some* idea what's going on */
|
|
g_warning
|
|
("Could not find info for pixel format %d out of %d known pixel formats. One segfault coming up",
|
|
format, PIX_FMT_NB);
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
avcodec_get_chroma_sub_sample (int pix_fmt, int *h_shift, int *v_shift)
|
|
{
|
|
*h_shift = get_pix_fmt_info (pix_fmt)->x_chroma_shift;
|
|
*v_shift = get_pix_fmt_info (pix_fmt)->y_chroma_shift;
|
|
}
|
|
|
|
const char *
|
|
avcodec_get_pix_fmt_name (int pix_fmt)
|
|
{
|
|
if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
|
|
return "???";
|
|
else
|
|
return get_pix_fmt_info (pix_fmt)->name;
|
|
}
|
|
|
|
enum PixelFormat
|
|
avcodec_get_pix_fmt (const char *name)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < PIX_FMT_NB; i++)
|
|
if (!strcmp (pix_fmt_info[i].name, name))
|
|
break;
|
|
return pix_fmt_info[i].format;
|
|
}
|
|
|
|
#if 0
|
|
static int
|
|
avpicture_layout (const AVPicture * src, int pix_fmt, int width, int height,
|
|
unsigned char *dest, int dest_size)
|
|
{
|
|
PixFmtInfo *pf = get_pix_fmt_info (pix_fmt);
|
|
int i, j, w, h, data_planes;
|
|
const unsigned char *s;
|
|
int size = avpicture_get_size (pix_fmt, width, height);
|
|
|
|
if (size > dest_size)
|
|
return -1;
|
|
|
|
if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
|
|
if (pix_fmt == PIX_FMT_YUV422 ||
|
|
pix_fmt == PIX_FMT_UYVY422 ||
|
|
pix_fmt == PIX_FMT_RGB565 || pix_fmt == PIX_FMT_RGB555)
|
|
w = width * 2;
|
|
else if (pix_fmt == PIX_FMT_UYVY411)
|
|
w = width + width / 2;
|
|
else if (pix_fmt == PIX_FMT_PAL8)
|
|
w = width;
|
|
else
|
|
w = width * (pf->depth * pf->nb_channels / 8);
|
|
|
|
data_planes = 1;
|
|
h = height;
|
|
} else {
|
|
data_planes = pf->nb_channels;
|
|
w = (width * pf->depth + 7) / 8;
|
|
h = height;
|
|
}
|
|
|
|
for (i = 0; i < data_planes; i++) {
|
|
if (i == 1) {
|
|
w = width >> pf->x_chroma_shift;
|
|
h = height >> pf->y_chroma_shift;
|
|
}
|
|
s = src->data[i];
|
|
for (j = 0; j < h; j++) {
|
|
memcpy (dest, s, w);
|
|
dest += w;
|
|
s += src->linesize[i];
|
|
}
|
|
}
|
|
|
|
if (pf->pixel_type == FF_PIXEL_PALETTE)
|
|
memcpy ((unsigned char *) (((size_t) dest + 3) & ~3), src->data[1],
|
|
256 * 4);
|
|
|
|
return size;
|
|
}
|
|
#endif
|
|
|
|
int
|
|
avpicture_get_size (int pix_fmt, int width, int height)
|
|
{
|
|
AVPicture dummy_pict;
|
|
|
|
return gst_ffmpegcsp_avpicture_fill (&dummy_pict, NULL, pix_fmt, width,
|
|
height, FALSE);
|
|
}
|
|
|
|
/**
|
|
* compute the loss when converting from a pixel format to another
|
|
*/
|
|
int
|
|
avcodec_get_pix_fmt_loss (int dst_pix_fmt, int src_pix_fmt, int has_alpha)
|
|
{
|
|
const PixFmtInfo *pf, *ps;
|
|
int loss;
|
|
|
|
ps = get_pix_fmt_info (src_pix_fmt);
|
|
pf = get_pix_fmt_info (dst_pix_fmt);
|
|
|
|
/* compute loss */
|
|
loss = 0;
|
|
if (pf->depth < ps->depth ||
|
|
(dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
|
|
loss |= FF_LOSS_DEPTH;
|
|
if (pf->x_chroma_shift > ps->x_chroma_shift ||
|
|
pf->y_chroma_shift > ps->y_chroma_shift)
|
|
loss |= FF_LOSS_RESOLUTION;
|
|
switch (pf->color_type) {
|
|
case FF_COLOR_RGB:
|
|
if (ps->color_type != FF_COLOR_RGB && ps->color_type != FF_COLOR_GRAY)
|
|
loss |= FF_LOSS_COLORSPACE;
|
|
break;
|
|
case FF_COLOR_GRAY:
|
|
if (ps->color_type != FF_COLOR_GRAY)
|
|
loss |= FF_LOSS_COLORSPACE;
|
|
break;
|
|
case FF_COLOR_YUV:
|
|
if (ps->color_type != FF_COLOR_YUV)
|
|
loss |= FF_LOSS_COLORSPACE;
|
|
break;
|
|
case FF_COLOR_YUV_JPEG:
|
|
if (ps->color_type != FF_COLOR_YUV_JPEG &&
|
|
ps->color_type != FF_COLOR_YUV && ps->color_type != FF_COLOR_GRAY)
|
|
loss |= FF_LOSS_COLORSPACE;
|
|
break;
|
|
default:
|
|
/* fail safe test */
|
|
if (ps->color_type != pf->color_type)
|
|
loss |= FF_LOSS_COLORSPACE;
|
|
break;
|
|
}
|
|
if (pf->color_type == FF_COLOR_GRAY && ps->color_type != FF_COLOR_GRAY)
|
|
loss |= FF_LOSS_CHROMA;
|
|
if (!pf->is_alpha && (ps->is_alpha && has_alpha))
|
|
loss |= FF_LOSS_ALPHA;
|
|
if (pf->pixel_type == FF_PIXEL_PALETTE &&
|
|
(ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
|
|
loss |= FF_LOSS_COLORQUANT;
|
|
return loss;
|
|
}
|
|
|
|
static int
|
|
avg_bits_per_pixel (int pix_fmt)
|
|
{
|
|
int bits;
|
|
const PixFmtInfo *pf;
|
|
|
|
pf = get_pix_fmt_info (pix_fmt);
|
|
switch (pf->pixel_type) {
|
|
case FF_PIXEL_PACKED:
|
|
switch (pix_fmt) {
|
|
case PIX_FMT_YUV422:
|
|
case PIX_FMT_UYVY422:
|
|
case PIX_FMT_YVYU422:
|
|
case PIX_FMT_RGB565:
|
|
case PIX_FMT_RGB555:
|
|
bits = 16;
|
|
break;
|
|
case PIX_FMT_UYVY411:
|
|
bits = 12;
|
|
break;
|
|
default:
|
|
bits = pf->depth * pf->nb_channels;
|
|
break;
|
|
}
|
|
break;
|
|
case FF_PIXEL_PLANAR:
|
|
if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
|
|
bits = pf->depth * pf->nb_channels;
|
|
} else {
|
|
bits = pf->depth + ((2 * pf->depth) >>
|
|
(pf->x_chroma_shift + pf->y_chroma_shift));
|
|
}
|
|
break;
|
|
case FF_PIXEL_PALETTE:
|
|
bits = 8;
|
|
break;
|
|
default:
|
|
bits = -1;
|
|
break;
|
|
}
|
|
return bits;
|
|
}
|
|
|
|
static int
|
|
avcodec_find_best_pix_fmt1 (int pix_fmt_mask,
|
|
int src_pix_fmt, int has_alpha, int loss_mask)
|
|
{
|
|
int dist, i, loss, min_dist, dst_pix_fmt;
|
|
|
|
/* find exact color match with smallest size */
|
|
dst_pix_fmt = -1;
|
|
min_dist = 0x7fffffff;
|
|
for (i = 0; i < PIX_FMT_NB; i++) {
|
|
if (pix_fmt_mask & (1 << i)) {
|
|
loss = avcodec_get_pix_fmt_loss (i, src_pix_fmt, has_alpha) & loss_mask;
|
|
if (loss == 0) {
|
|
dist = avg_bits_per_pixel (i);
|
|
if (dist < min_dist) {
|
|
min_dist = dist;
|
|
dst_pix_fmt = i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return dst_pix_fmt;
|
|
}
|
|
|
|
/**
|
|
* find best pixel format to convert to. Return -1 if none found
|
|
*/
|
|
int
|
|
avcodec_find_best_pix_fmt (int pix_fmt_mask, int src_pix_fmt,
|
|
int has_alpha, int *loss_ptr)
|
|
{
|
|
int dst_pix_fmt, loss_mask, i;
|
|
static const int loss_mask_order[] = {
|
|
~0, /* no loss first */
|
|
~FF_LOSS_ALPHA,
|
|
~FF_LOSS_RESOLUTION,
|
|
~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
|
|
~FF_LOSS_COLORQUANT,
|
|
~FF_LOSS_DEPTH,
|
|
0,
|
|
};
|
|
|
|
/* try with successive loss */
|
|
i = 0;
|
|
for (;;) {
|
|
loss_mask = loss_mask_order[i++];
|
|
dst_pix_fmt = avcodec_find_best_pix_fmt1 (pix_fmt_mask, src_pix_fmt,
|
|
has_alpha, loss_mask);
|
|
if (dst_pix_fmt >= 0)
|
|
goto found;
|
|
if (loss_mask == 0)
|
|
break;
|
|
}
|
|
return -1;
|
|
found:
|
|
if (loss_ptr)
|
|
*loss_ptr = avcodec_get_pix_fmt_loss (dst_pix_fmt, src_pix_fmt, has_alpha);
|
|
return dst_pix_fmt;
|
|
}
|
|
|
|
static void
|
|
img_copy_plane (uint8_t * dst, int dst_wrap,
|
|
const uint8_t * src, int src_wrap, int width, int height)
|
|
{
|
|
for (; height > 0; height--) {
|
|
memcpy (dst, src, width);
|
|
dst += dst_wrap;
|
|
src += src_wrap;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copy image 'src' to 'dst'.
|
|
*/
|
|
static void
|
|
img_copy (AVPicture * dst, const AVPicture * src,
|
|
int pix_fmt, int width, int height)
|
|
{
|
|
int bwidth, bits, i;
|
|
const PixFmtInfo *pf;
|
|
|
|
pf = get_pix_fmt_info (pix_fmt);
|
|
switch (pf->pixel_type) {
|
|
case FF_PIXEL_PACKED:
|
|
switch (pix_fmt) {
|
|
case PIX_FMT_YUV422:
|
|
case PIX_FMT_UYVY422:
|
|
case PIX_FMT_YVYU422:
|
|
case PIX_FMT_RGB565:
|
|
case PIX_FMT_RGB555:
|
|
bits = 16;
|
|
break;
|
|
case PIX_FMT_UYVY411:
|
|
bits = 12;
|
|
break;
|
|
default:
|
|
bits = pf->depth * pf->nb_channels;
|
|
break;
|
|
}
|
|
bwidth = (width * bits + 7) >> 3;
|
|
img_copy_plane (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0], bwidth, height);
|
|
break;
|
|
case FF_PIXEL_PLANAR:
|
|
for (i = 0; i < pf->nb_channels; i++) {
|
|
int w, h;
|
|
|
|
w = width;
|
|
h = height;
|
|
if (i == 1 || i == 2) {
|
|
w >>= pf->x_chroma_shift;
|
|
h >>= pf->y_chroma_shift;
|
|
}
|
|
bwidth = (w * pf->depth + 7) >> 3;
|
|
img_copy_plane (dst->data[i], dst->linesize[i],
|
|
src->data[i], src->linesize[i], bwidth, h);
|
|
}
|
|
break;
|
|
case FF_PIXEL_PALETTE:
|
|
img_copy_plane (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0], width, height);
|
|
/* copy the palette */
|
|
img_copy_plane (dst->data[1], dst->linesize[1],
|
|
src->data[1], src->linesize[1], 4, 256);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* XXX: totally non optimized */
|
|
|
|
static void
|
|
yuv422_to_yuv420p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
|
|
for (; height >= 1; height -= 2) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[1];
|
|
lum[1] = p[2];
|
|
cr[0] = p[3];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[1];
|
|
cr[0] = p[3];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
if (height > 1) {
|
|
p = p1;
|
|
lum = lum1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
lum[1] = p[2];
|
|
p += 4;
|
|
lum += 2;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[0];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
}
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
uyvy422_to_gray (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *lum1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[1];
|
|
lum[1] = p[3];
|
|
p += 4;
|
|
lum += 2;
|
|
}
|
|
|
|
if (w)
|
|
lum[0] = p[1];
|
|
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
uyvy422_to_yuv420p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
|
|
for (; height >= 1; height -= 2) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[1];
|
|
cb[0] = p[0];
|
|
lum[1] = p[3];
|
|
cr[0] = p[2];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[1];
|
|
cb[0] = p[0];
|
|
cr[0] = p[2];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
if (height > 1) {
|
|
p = p1;
|
|
lum = lum1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[1];
|
|
lum[1] = p[3];
|
|
p += 4;
|
|
lum += 2;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[1];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
}
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
uyvy422_to_yuv422p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[1];
|
|
cb[0] = p[0];
|
|
lum[1] = p[3];
|
|
cr[0] = p[2];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[1];
|
|
cb[0] = p[0];
|
|
cr[0] = p[2];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yvyu422_to_gray (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *lum1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
lum[1] = p[2];
|
|
p += 4;
|
|
lum += 2;
|
|
}
|
|
|
|
if (w)
|
|
lum[0] = p[0];
|
|
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yvyu422_to_yuv420p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
|
|
for (; height >= 1; height -= 2) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[3];
|
|
lum[1] = p[2];
|
|
cr[0] = p[1];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[3];
|
|
cr[0] = p[1];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
if (height > 1) {
|
|
p = p1;
|
|
lum = lum1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
lum[1] = p[2];
|
|
p += 4;
|
|
lum += 2;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[0];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
}
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yvyu422_to_yuv422p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[3];
|
|
lum[1] = p[2];
|
|
cr[0] = p[1];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[3];
|
|
cr[0] = p[1];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuv422_to_yuv422p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[1];
|
|
lum[1] = p[2];
|
|
cr[0] = p[3];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
lum[0] = p[0];
|
|
cb[0] = p[1];
|
|
cr[0] = p[3];
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuv422p_to_yuv422 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
uint8_t *p, *p1;
|
|
const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = dst->data[0];
|
|
lum1 = src->data[0];
|
|
cb1 = src->data[1];
|
|
cr1 = src->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
p[0] = lum[0];
|
|
p[1] = cb[0];
|
|
p[2] = lum[1];
|
|
p[3] = cr[0];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
p[0] = lum[0];
|
|
p[1] = cb[0];
|
|
p[3] = cr[0];
|
|
}
|
|
p1 += dst->linesize[0];
|
|
lum1 += src->linesize[0];
|
|
cb1 += src->linesize[1];
|
|
cr1 += src->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuv422p_to_uyvy422 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
uint8_t *p, *p1;
|
|
const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = dst->data[0];
|
|
lum1 = src->data[0];
|
|
cb1 = src->data[1];
|
|
cr1 = src->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
p[1] = lum[0];
|
|
p[0] = cb[0];
|
|
p[3] = lum[1];
|
|
p[2] = cr[0];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
p[1] = lum[0];
|
|
p[0] = cb[0];
|
|
p[2] = cr[0];
|
|
}
|
|
p1 += dst->linesize[0];
|
|
lum1 += src->linesize[0];
|
|
cb1 += src->linesize[1];
|
|
cr1 += src->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuv422p_to_yvyu422 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
uint8_t *p, *p1;
|
|
const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = dst->data[0];
|
|
lum1 = src->data[0];
|
|
cb1 = src->data[1];
|
|
cr1 = src->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
p[0] = lum[0];
|
|
p[3] = cb[0];
|
|
p[2] = lum[1];
|
|
p[1] = cr[0];
|
|
p += 4;
|
|
lum += 2;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
if (w) {
|
|
p[0] = lum[0];
|
|
p[3] = cb[0];
|
|
p[1] = cr[0];
|
|
}
|
|
p1 += dst->linesize[0];
|
|
lum1 += src->linesize[0];
|
|
cb1 += src->linesize[1];
|
|
cr1 += src->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
uyvy411_to_yuv411p (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *p, *p1;
|
|
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = src->data[0];
|
|
lum1 = dst->data[0];
|
|
cb1 = dst->data[1];
|
|
cr1 = dst->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 4; w -= 4) {
|
|
cb[0] = p[0];
|
|
lum[0] = p[1];
|
|
lum[1] = p[2];
|
|
cr[0] = p[3];
|
|
lum[2] = p[4];
|
|
lum[3] = p[5];
|
|
p += 6;
|
|
lum += 4;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
p1 += src->linesize[0];
|
|
lum1 += dst->linesize[0];
|
|
cb1 += dst->linesize[1];
|
|
cr1 += dst->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuv411p_to_uyvy411 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
uint8_t *p, *p1;
|
|
const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
|
|
int w;
|
|
|
|
p1 = dst->data[0];
|
|
lum1 = src->data[0];
|
|
cb1 = src->data[1];
|
|
cr1 = src->data[2];
|
|
for (; height > 0; height--) {
|
|
p = p1;
|
|
lum = lum1;
|
|
cb = cb1;
|
|
cr = cr1;
|
|
for (w = width; w >= 4; w -= 4) {
|
|
p[0] = cb[0];
|
|
p[1] = lum[0];
|
|
p[2] = lum[1];
|
|
p[3] = cr[0];
|
|
p[4] = lum[2];
|
|
p[5] = lum[3];
|
|
p += 6;
|
|
lum += 4;
|
|
cb++;
|
|
cr++;
|
|
}
|
|
p1 += dst->linesize[0];
|
|
lum1 += src->linesize[0];
|
|
cb1 += src->linesize[1];
|
|
cr1 += src->linesize[2];
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuv420p_to_yuv422 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
int w, h;
|
|
uint8_t *line1, *line2, *linesrc = dst->data[0];
|
|
uint8_t *lum1, *lum2, *lumsrc = src->data[0];
|
|
uint8_t *cb1, *cb2 = src->data[1];
|
|
uint8_t *cr1, *cr2 = src->data[2];
|
|
|
|
for (h = height / 2; h--;) {
|
|
line1 = linesrc;
|
|
line2 = linesrc + dst->linesize[0];
|
|
|
|
lum1 = lumsrc;
|
|
lum2 = lumsrc + src->linesize[0];
|
|
|
|
cb1 = cb2;
|
|
cr1 = cr2;
|
|
|
|
for (w = width / 2; w--;) {
|
|
*line1++ = *lum1++;
|
|
*line2++ = *lum2++;
|
|
*line1++ = *line2++ = *cb1++;
|
|
*line1++ = *lum1++;
|
|
*line2++ = *lum2++;
|
|
*line1++ = *line2++ = *cr1++;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
*line1++ = *lum1++;
|
|
*line2++ = *lum2++;
|
|
*line1++ = *line2++ = *cb1++;
|
|
}
|
|
|
|
linesrc += dst->linesize[0] * 2;
|
|
lumsrc += src->linesize[0] * 2;
|
|
cb2 += src->linesize[1];
|
|
cr2 += src->linesize[2];
|
|
}
|
|
/* odd height */
|
|
if (height % 2 != 0) {
|
|
line1 = linesrc;
|
|
lum1 = lumsrc;
|
|
cb1 = cb2;
|
|
cr1 = cr2;
|
|
|
|
for (w = width / 2; w--;) {
|
|
*line1++ = *lum1++;
|
|
*line1++ = *cb1++;
|
|
*line1++ = *lum1++;
|
|
*line1++ = *cr1++;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
*line1++ = *lum1++;
|
|
*line1++ = *cb1++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
nv12_to_nv21 (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const uint8_t *s_c_ptr;
|
|
uint8_t *d_c_ptr;
|
|
int w, c_wrap;
|
|
|
|
memcpy (dst->data[0], src->data[0], src->linesize[0] * height);
|
|
|
|
s_c_ptr = src->data[1];
|
|
d_c_ptr = dst->data[1];
|
|
c_wrap = src->linesize[1] - ((width + 1) & ~0x01);
|
|
|
|
for (; height >= 2; height -= 2) {
|
|
for (w = width; w >= 2; w -= 2) {
|
|
d_c_ptr[0] = s_c_ptr[1];
|
|
d_c_ptr[1] = s_c_ptr[0];
|
|
s_c_ptr += 2;
|
|
d_c_ptr += 2;
|
|
}
|
|
|
|
/* handle odd width */
|
|
if (w) {
|
|
d_c_ptr[0] = s_c_ptr[1];
|
|
d_c_ptr[1] = s_c_ptr[0];
|
|
s_c_ptr += 2;
|
|
d_c_ptr += 2;
|
|
}
|
|
s_c_ptr += c_wrap;
|
|
d_c_ptr += c_wrap;
|
|
}
|
|
|
|
/* handle odd height */
|
|
if (height) {
|
|
for (w = width; w >= 2; w -= 2) {
|
|
d_c_ptr[0] = s_c_ptr[1];
|
|
d_c_ptr[1] = s_c_ptr[0];
|
|
s_c_ptr += 2;
|
|
d_c_ptr += 2;
|
|
}
|
|
|
|
/* handle odd width */
|
|
if (w) {
|
|
d_c_ptr[0] = s_c_ptr[1];
|
|
d_c_ptr[1] = s_c_ptr[0];
|
|
s_c_ptr += 2;
|
|
d_c_ptr += 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
nv12_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
int w, h;
|
|
uint8_t *dst_lum1, *dst_lum2, *dst_line = dst->data[0];
|
|
uint8_t *dst_cb1, *dst_cb2, *dst_cb_line = dst->data[1];
|
|
uint8_t *dst_cr1, *dst_cr2, *dst_cr_line = dst->data[2];
|
|
uint8_t *lum1, *lum2, *src_lum_line = src->data[0];
|
|
uint8_t *src_c1, *src_c_line = src->data[1];
|
|
uint8_t cb, cr;
|
|
|
|
for (h = height / 2; h--;) {
|
|
dst_lum1 = dst_line;
|
|
dst_lum2 = dst_line + dst->linesize[0];
|
|
|
|
dst_cb1 = dst_cb_line;
|
|
dst_cb2 = dst_cb_line + dst->linesize[1];
|
|
dst_cr1 = dst_cr_line;
|
|
dst_cr2 = dst_cr_line + dst->linesize[2];
|
|
|
|
lum1 = src_lum_line;
|
|
lum2 = src_lum_line + src->linesize[0];
|
|
|
|
src_c1 = src_c_line;
|
|
|
|
for (w = width / 2; w--;) {
|
|
cb = *src_c1++;
|
|
cr = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_lum2++ = *lum2++;
|
|
*dst_cb1++ = *dst_cb2++ = cb;
|
|
*dst_cr1++ = *dst_cr2++ = cr;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_lum2++ = *lum2++;
|
|
*dst_cb1++ = *dst_cb2++ = cb;
|
|
*dst_cr1++ = *dst_cr2++ = cr;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
cb = *src_c1++;
|
|
cr = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_lum2++ = *lum2++;
|
|
*dst_cb1++ = *dst_cb2++ = *src_c1++;
|
|
*dst_cr1++ = *dst_cr2++ = *src_c1++;
|
|
}
|
|
|
|
dst_line += dst->linesize[0] * 2;
|
|
dst_cb_line += dst->linesize[1] * 2;
|
|
dst_cr_line += dst->linesize[2] * 2;
|
|
src_lum_line += src->linesize[0] * 2;
|
|
src_c_line += src->linesize[1];
|
|
}
|
|
|
|
/* odd height */
|
|
if (height % 2 != 0) {
|
|
dst_lum1 = dst_line;
|
|
lum1 = src_lum_line;
|
|
src_c1 = src_c_line;
|
|
dst_cb1 = dst_cb_line;
|
|
dst_cr1 = dst_cr_line;
|
|
|
|
for (w = width / 2; w--;) {
|
|
cb = *src_c1++;
|
|
cr = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_cb1++ = cb;
|
|
*dst_cr1++ = cr;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_cb1++ = cb;
|
|
*dst_cr1++ = cr;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
cb = *src_c1++;
|
|
cr = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_cb1++ = cb;
|
|
*dst_cr1++ = cr;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define nv21_to_nv12 nv12_to_nv21
|
|
|
|
static void
|
|
nv21_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
int w, h;
|
|
uint8_t *dst_lum1, *dst_lum2, *dst_line = dst->data[0];
|
|
uint8_t *dst_cb1, *dst_cb2, *dst_cb_line = dst->data[1];
|
|
uint8_t *dst_cr1, *dst_cr2, *dst_cr_line = dst->data[2];
|
|
uint8_t *lum1, *lum2, *src_lum_line = src->data[0];
|
|
uint8_t *src_c1, *src_c_line = src->data[1];
|
|
uint8_t cb, cr;
|
|
|
|
for (h = height / 2; h--;) {
|
|
dst_lum1 = dst_line;
|
|
dst_lum2 = dst_line + dst->linesize[0];
|
|
|
|
dst_cb1 = dst_cb_line;
|
|
dst_cb2 = dst_cb_line + dst->linesize[1];
|
|
dst_cr1 = dst_cr_line;
|
|
dst_cr2 = dst_cr_line + dst->linesize[2];
|
|
|
|
lum1 = src_lum_line;
|
|
lum2 = src_lum_line + src->linesize[0];
|
|
|
|
src_c1 = src_c_line;
|
|
|
|
for (w = width / 2; w--;) {
|
|
cr = *src_c1++;
|
|
cb = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_lum2++ = *lum2++;
|
|
*dst_cb1++ = *dst_cb2++ = cb;
|
|
*dst_cr1++ = *dst_cr2++ = cr;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_lum2++ = *lum2++;
|
|
*dst_cb1++ = *dst_cb2++ = cb;
|
|
*dst_cr1++ = *dst_cr2++ = cr;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
cr = *src_c1++;
|
|
cb = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_lum2++ = *lum2++;
|
|
*dst_cb1++ = *dst_cb2++ = *src_c1++;
|
|
*dst_cr1++ = *dst_cr2++ = *src_c1++;
|
|
}
|
|
|
|
dst_line += dst->linesize[0] * 2;
|
|
dst_cb_line += dst->linesize[1] * 2;
|
|
dst_cr_line += dst->linesize[2] * 2;
|
|
src_lum_line += src->linesize[0] * 2;
|
|
src_c_line += src->linesize[1];
|
|
}
|
|
|
|
/* odd height */
|
|
if (height % 2 != 0) {
|
|
dst_lum1 = dst_line;
|
|
lum1 = src_lum_line;
|
|
src_c1 = src_c_line;
|
|
|
|
dst_cb1 = dst_cb_line;
|
|
dst_cr1 = dst_cr_line;
|
|
|
|
for (w = width / 2; w--;) {
|
|
cr = *src_c1++;
|
|
cb = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_cb1++ = cb;
|
|
*dst_cr1++ = cr;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_cb1++ = cb;
|
|
*dst_cr1++ = cr;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
cr = *src_c1++;
|
|
cb = *src_c1++;
|
|
*dst_lum1++ = *lum1++;
|
|
*dst_cb1++ = cb;
|
|
*dst_cr1++ = cr;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuva420p_to_yuv420p (AVPicture * dst, const AVPicture * src, int width,
|
|
int height)
|
|
{
|
|
memcpy (dst->data[0], src->data[0], dst->linesize[0] * height);
|
|
memcpy (dst->data[1], src->data[1], dst->linesize[1] * ((height + 1) / 2));
|
|
memcpy (dst->data[2], src->data[2], dst->linesize[2] * ((height + 1) / 2));
|
|
}
|
|
|
|
static void
|
|
yuva420p_to_yuv422 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
int w, h;
|
|
uint8_t *line1, *line2, *linesrc = dst->data[0];
|
|
uint8_t *lum1, *lum2, *lumsrc = src->data[0];
|
|
uint8_t *cb1, *cb2 = src->data[1];
|
|
uint8_t *cr1, *cr2 = src->data[2];
|
|
|
|
for (h = height / 2; h--;) {
|
|
line1 = linesrc;
|
|
line2 = linesrc + dst->linesize[0];
|
|
|
|
lum1 = lumsrc;
|
|
lum2 = lumsrc + src->linesize[0];
|
|
|
|
cb1 = cb2;
|
|
cr1 = cr2;
|
|
|
|
for (w = width / 2; w--;) {
|
|
*line1++ = *lum1++;
|
|
*line2++ = *lum2++;
|
|
*line1++ = *line2++ = *cb1++;
|
|
*line1++ = *lum1++;
|
|
*line2++ = *lum2++;
|
|
*line1++ = *line2++ = *cr1++;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
*line1++ = *lum1++;
|
|
*line2++ = *lum2++;
|
|
*line1++ = *line2++ = *cb1++;
|
|
}
|
|
|
|
linesrc += dst->linesize[0] * 2;
|
|
lumsrc += src->linesize[0] * 2;
|
|
cb2 += src->linesize[1];
|
|
cr2 += src->linesize[2];
|
|
}
|
|
/* odd height */
|
|
if (height % 2 != 0) {
|
|
line1 = linesrc;
|
|
lum1 = lumsrc;
|
|
cb1 = cb2;
|
|
cr1 = cr2;
|
|
|
|
for (w = width / 2; w--;) {
|
|
*line1++ = *lum1++;
|
|
*line1++ = *cb1++;
|
|
*line1++ = *lum1++;
|
|
*line1++ = *cr1++;
|
|
}
|
|
/* odd width */
|
|
if (width % 2 != 0) {
|
|
*line1++ = *lum1++;
|
|
*line1++ = *cb1++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define SCALEBITS 10
|
|
#define ONE_HALF (1 << (SCALEBITS - 1))
|
|
#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
|
|
|
|
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
|
|
{\
|
|
cb = (cb1) - 128;\
|
|
cr = (cr1) - 128;\
|
|
r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
|
|
g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
|
|
ONE_HALF;\
|
|
b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
|
|
}
|
|
|
|
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
|
|
{\
|
|
y = ((y1) - 16) * FIX(255.0/219.0);\
|
|
r = cm[(y + r_add) >> SCALEBITS];\
|
|
g = cm[(y + g_add) >> SCALEBITS];\
|
|
b = cm[(y + b_add) >> SCALEBITS];\
|
|
}
|
|
|
|
#define YUV_TO_RGB1(cb1, cr1)\
|
|
{\
|
|
cb = (cb1) - 128;\
|
|
cr = (cr1) - 128;\
|
|
r_add = FIX(1.40200) * cr + ONE_HALF;\
|
|
g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
|
|
b_add = FIX(1.77200) * cb + ONE_HALF;\
|
|
}
|
|
|
|
#define YUV_TO_RGB2(r, g, b, y1)\
|
|
{\
|
|
y = (y1) << SCALEBITS;\
|
|
r = cm[(y + r_add) >> SCALEBITS];\
|
|
g = cm[(y + g_add) >> SCALEBITS];\
|
|
b = cm[(y + b_add) >> SCALEBITS];\
|
|
}
|
|
|
|
#define Y_CCIR_TO_JPEG(y)\
|
|
cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
|
|
|
|
#define Y_JPEG_TO_CCIR(y)\
|
|
(((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
|
|
|
|
#define C_CCIR_TO_JPEG(y)\
|
|
cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
|
|
|
|
/* NOTE: the clamp is really necessary! */
|
|
static inline int
|
|
C_JPEG_TO_CCIR (int y)
|
|
{
|
|
y = (((y - 128) * FIX (112.0 / 127.0) + (ONE_HALF +
|
|
(128 << SCALEBITS))) >> SCALEBITS);
|
|
if (y < 16)
|
|
y = 16;
|
|
return y;
|
|
}
|
|
|
|
|
|
#define RGB_TO_Y(r, g, b) \
|
|
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
|
|
FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
|
|
|
|
#define RGB_TO_U(r1, g1, b1, shift)\
|
|
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
|
|
FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
|
|
|
|
#define RGB_TO_V(r1, g1, b1, shift)\
|
|
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
|
|
FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
|
|
|
|
#define RGB_TO_Y_CCIR(r, g, b) \
|
|
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
|
|
FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
|
|
|
|
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
|
|
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
|
|
FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
|
|
|
|
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
|
|
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
|
|
FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
|
|
|
|
static uint8_t y_ccir_to_jpeg[256];
|
|
static uint8_t y_jpeg_to_ccir[256];
|
|
static uint8_t c_ccir_to_jpeg[256];
|
|
static uint8_t c_jpeg_to_ccir[256];
|
|
|
|
/* init various conversion tables */
|
|
static void
|
|
img_convert_init (void)
|
|
{
|
|
int i;
|
|
uint8_t *cm = cropTbl + MAX_NEG_CROP;
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG (i);
|
|
y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR (i);
|
|
c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG (i);
|
|
c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR (i);
|
|
}
|
|
}
|
|
|
|
/* apply to each pixel the given table */
|
|
static void
|
|
img_apply_table (uint8_t * dst, int dst_wrap,
|
|
const uint8_t * src, int src_wrap,
|
|
int width, int height, const uint8_t * table1)
|
|
{
|
|
int n;
|
|
const uint8_t *s;
|
|
uint8_t *d;
|
|
const uint8_t *table;
|
|
|
|
table = table1;
|
|
for (; height > 0; height--) {
|
|
s = src;
|
|
d = dst;
|
|
n = width;
|
|
while (n >= 4) {
|
|
d[0] = table[s[0]];
|
|
d[1] = table[s[1]];
|
|
d[2] = table[s[2]];
|
|
d[3] = table[s[3]];
|
|
d += 4;
|
|
s += 4;
|
|
n -= 4;
|
|
}
|
|
while (n > 0) {
|
|
d[0] = table[s[0]];
|
|
d++;
|
|
s++;
|
|
n--;
|
|
}
|
|
dst += dst_wrap;
|
|
src += src_wrap;
|
|
}
|
|
}
|
|
|
|
/* XXX: use generic filter ? */
|
|
/* XXX: in most cases, the sampling position is incorrect */
|
|
|
|
static void
|
|
img_copy_plane_resize (uint8_t * dst, int dst_wrap, int dst_width,
|
|
int dst_height, const uint8_t * src, int src_wrap, int src_width,
|
|
int src_height)
|
|
{
|
|
img_copy_plane (dst, dst_wrap, src, src_wrap, dst_width, dst_height);
|
|
}
|
|
|
|
/* 4x1 -> 1x1 */
|
|
static void
|
|
shrink41 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
int w, s_w;
|
|
const uint8_t *s;
|
|
uint8_t *d;
|
|
|
|
for (; dst_height > 0; dst_height--) {
|
|
s = src;
|
|
d = dst;
|
|
for (s_w = src_width, w = dst_width; w > 0 && s_w > 3; w--, s_w -= 4) {
|
|
d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
|
|
s += 4;
|
|
d++;
|
|
}
|
|
|
|
if (w) {
|
|
if (s_w == 3)
|
|
d[0] = (s[0] + s[1] + s[2]) / 3;
|
|
else if (s_w == 2)
|
|
d[0] = (s[0] + s[1]) / 2;
|
|
else /* s_w == 1 */
|
|
d[0] = s[0];
|
|
}
|
|
|
|
src += src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 2x1 -> 1x1 */
|
|
static void
|
|
shrink21 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
int w, s_w;
|
|
const uint8_t *s;
|
|
uint8_t *d;
|
|
|
|
for (; dst_height > 0; dst_height--) {
|
|
s = src;
|
|
d = dst;
|
|
for (s_w = src_width, w = dst_width; w > 0 && s_w > 1; w--, s_w -= 2) {
|
|
d[0] = (s[0] + s[1]) >> 1;
|
|
s += 2;
|
|
d++;
|
|
}
|
|
|
|
if (w) /* s_w == 1 */
|
|
d[0] = s[0];
|
|
|
|
src += src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 1x2 -> 1x1 */
|
|
static void
|
|
shrink12 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
int w;
|
|
uint8_t *d;
|
|
const uint8_t *s1, *s2;
|
|
|
|
for (; dst_height > 0; dst_height--, src_height -= 2) {
|
|
s1 = src;
|
|
s2 = s1 + (src_height > 1 ? src_wrap : 0);
|
|
d = dst;
|
|
for (w = dst_width; w >= 4; w -= 4) {
|
|
d[0] = (s1[0] + s2[0]) >> 1;
|
|
d[1] = (s1[1] + s2[1]) >> 1;
|
|
d[2] = (s1[2] + s2[2]) >> 1;
|
|
d[3] = (s1[3] + s2[3]) >> 1;
|
|
s1 += 4;
|
|
s2 += 4;
|
|
d += 4;
|
|
}
|
|
for (; w > 0; w--) {
|
|
d[0] = (s1[0] + s2[0]) >> 1;
|
|
s1++;
|
|
s2++;
|
|
d++;
|
|
}
|
|
src += 2 * src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 2x2 -> 1x1 */
|
|
static void
|
|
shrink22 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
int w, s_w;
|
|
const uint8_t *s1, *s2;
|
|
uint8_t *d;
|
|
|
|
for (; dst_height > 0; dst_height--, src_height -= 2) {
|
|
s1 = src;
|
|
s2 = s1 + (src_height > 1 ? src_wrap : 0);
|
|
d = dst;
|
|
for (s_w = src_width, w = dst_width; w >= 4; w -= 4, s_w -= 8) {
|
|
d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
|
|
d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
|
|
d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
|
|
d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
|
|
s1 += 8;
|
|
s2 += 8;
|
|
d += 4;
|
|
}
|
|
for (; w > 0 && s_w > 1; w--, s_w -= 2) {
|
|
d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
|
|
s1 += 2;
|
|
s2 += 2;
|
|
d++;
|
|
}
|
|
|
|
if (w)
|
|
d[0] = (s1[0] + s2[0] + 1) >> 1;
|
|
|
|
src += 2 * src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 4x4 -> 1x1 */
|
|
static void
|
|
shrink44 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
int s_w, w;
|
|
const uint8_t *s1, *s2, *s3, *s4;
|
|
uint8_t *d;
|
|
|
|
for (; dst_height > 0; dst_height--, src_height -= 4) {
|
|
s1 = src;
|
|
s2 = s1 + (src_height > 1 ? src_wrap : 0);
|
|
s3 = s2 + (src_height > 2 ? src_wrap : 0);
|
|
s4 = s3 + (src_height > 3 ? src_wrap : 0);
|
|
d = dst;
|
|
for (s_w = src_width, w = dst_width; s_w > 3 && w > 0; w--, s_w -= 4) {
|
|
d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
|
|
s2[0] + s2[1] + s2[2] + s2[3] +
|
|
s3[0] + s3[1] + s3[2] + s3[3] +
|
|
s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
|
|
s1 += 4;
|
|
s2 += 4;
|
|
s3 += 4;
|
|
s4 += 4;
|
|
d++;
|
|
}
|
|
|
|
if (w) {
|
|
if (s_w == 3)
|
|
d[0] = (s1[0] + s1[1] + s1[2] +
|
|
s2[0] + s2[1] + s2[2] +
|
|
s3[0] + s3[1] + s3[2] + s4[0] + s4[1] + s4[2]) / 12;
|
|
else if (s_w == 2)
|
|
d[0] = (s1[0] + s1[1] +
|
|
s2[0] + s2[1] + s3[0] + s3[1] + s4[0] + s4[1]) / 8;
|
|
else /* s_w == 1 */
|
|
d[0] = (s1[0] + s2[0] + s3[0] + s4[0]) / 4;
|
|
}
|
|
|
|
src += 4 * src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
grow21_line (uint8_t * dst, const uint8_t * src, int width)
|
|
{
|
|
int w;
|
|
const uint8_t *s1;
|
|
uint8_t *d;
|
|
|
|
s1 = src;
|
|
d = dst;
|
|
for (w = width; w >= 4; w -= 4) {
|
|
d[1] = d[0] = s1[0];
|
|
d[3] = d[2] = s1[1];
|
|
s1 += 2;
|
|
d += 4;
|
|
}
|
|
for (; w >= 2; w -= 2) {
|
|
d[1] = d[0] = s1[0];
|
|
s1++;
|
|
d += 2;
|
|
}
|
|
/* only needed if width is not a multiple of two */
|
|
if (w) {
|
|
d[0] = s1[0];
|
|
}
|
|
}
|
|
|
|
static void
|
|
grow41_line (uint8_t * dst, const uint8_t * src, int width)
|
|
{
|
|
int w, v;
|
|
const uint8_t *s1;
|
|
uint8_t *d;
|
|
|
|
s1 = src;
|
|
d = dst;
|
|
for (w = width; w >= 4; w -= 4) {
|
|
v = s1[0];
|
|
d[0] = v;
|
|
d[1] = v;
|
|
d[2] = v;
|
|
d[3] = v;
|
|
s1++;
|
|
d += 4;
|
|
}
|
|
for (; w > 0; w--) {
|
|
d[0] = s1[0];
|
|
d++;
|
|
}
|
|
}
|
|
|
|
/* 1x1 -> 2x1 */
|
|
static void
|
|
grow21 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
for (; dst_height > 0; dst_height--) {
|
|
grow21_line (dst, src, dst_width);
|
|
src += src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 1x1 -> 2x2 */
|
|
static void
|
|
grow22 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
for (; dst_height > 0; dst_height--) {
|
|
grow21_line (dst, src, dst_width);
|
|
if (dst_height % 2)
|
|
src += src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 1x1 -> 4x1 */
|
|
static void
|
|
grow41 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
for (; dst_height > 0; dst_height--) {
|
|
grow41_line (dst, src, dst_width);
|
|
src += src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 1x1 -> 4x4 */
|
|
static void
|
|
grow44 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
for (; dst_height > 0; dst_height--) {
|
|
grow41_line (dst, src, dst_width);
|
|
if ((dst_height & 3) == 1)
|
|
src += src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* 1x2 -> 2x1 */
|
|
static void
|
|
conv411 (uint8_t * dst, int dst_wrap, int dst_width, int dst_height,
|
|
const uint8_t * src, int src_wrap, int src_width, int src_height)
|
|
{
|
|
int w, c;
|
|
const uint8_t *s1, *s2;
|
|
uint8_t *d;
|
|
|
|
for (; dst_height > 0; dst_height--, src_height -= 2) {
|
|
s1 = src;
|
|
s2 = src + (src_height > 1 ? src_wrap : 0);
|
|
d = dst;
|
|
for (w = dst_width; w > 1; w -= 2) {
|
|
c = (s1[0] + s2[0]) >> 1;
|
|
d[0] = c;
|
|
d[1] = c;
|
|
s1++;
|
|
s2++;
|
|
d += 2;
|
|
}
|
|
|
|
if (w) {
|
|
d[0] = (s1[0] + s2[0]) >> 1;
|
|
}
|
|
|
|
src += src_wrap * 2;
|
|
dst += dst_wrap;
|
|
}
|
|
}
|
|
|
|
/* XXX: add jpeg quantize code */
|
|
|
|
#define TRANSP_INDEX (6*6*6)
|
|
|
|
/* this is maybe slow, but allows for extensions */
|
|
static inline unsigned char
|
|
gif_clut_index (uint8_t r, uint8_t g, uint8_t b)
|
|
{
|
|
return ((((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6));
|
|
}
|
|
|
|
static void
|
|
build_rgb_palette (uint8_t * palette, int has_alpha)
|
|
{
|
|
uint32_t *pal;
|
|
static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
|
|
int i, r, g, b;
|
|
|
|
pal = (uint32_t *) palette;
|
|
i = 0;
|
|
for (r = 0; r < 6; r++) {
|
|
for (g = 0; g < 6; g++) {
|
|
for (b = 0; b < 6; b++) {
|
|
pal[i++] = (0xffU << 24) | (pal_value[r] << 16) |
|
|
(pal_value[g] << 8) | pal_value[b];
|
|
}
|
|
}
|
|
}
|
|
if (has_alpha)
|
|
pal[i++] = 0;
|
|
while (i < 256)
|
|
pal[i++] = 0xff000000;
|
|
}
|
|
|
|
/* copy bit n to bits 0 ... n - 1 */
|
|
static inline unsigned int
|
|
bitcopy_n (unsigned int a, int n)
|
|
{
|
|
int mask;
|
|
|
|
mask = (1 << n) - 1;
|
|
return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
|
|
}
|
|
|
|
/* rgb555 handling */
|
|
|
|
#define RGB_NAME rgb555
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint16_t *)(s))[0];\
|
|
r = bitcopy_n(v >> (10 - 3), 3);\
|
|
g = bitcopy_n(v >> (5 - 3), 3);\
|
|
b = bitcopy_n(v << 3, 3);\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint16_t *)(s))[0];\
|
|
r = bitcopy_n(v >> (10 - 3), 3);\
|
|
g = bitcopy_n(v >> (5 - 3), 3);\
|
|
b = bitcopy_n(v << 3, 3);\
|
|
a = (-(v >> 15)) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \
|
|
((a << 8) & 0x8000);\
|
|
}
|
|
|
|
#define BPP 2
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* rgb565 handling */
|
|
|
|
#define RGB_NAME rgb565
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint16_t *)(s))[0];\
|
|
r = bitcopy_n(v >> (11 - 3), 3);\
|
|
g = bitcopy_n(v >> (5 - 2), 2);\
|
|
b = bitcopy_n(v << 3, 3);\
|
|
}
|
|
|
|
#define RGB_OUT(d, r, g, b)\
|
|
{\
|
|
((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
|
|
}
|
|
|
|
#define BPP 2
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* bgr24 handling */
|
|
|
|
#define RGB_NAME bgr24
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
b = (s)[0];\
|
|
g = (s)[1];\
|
|
r = (s)[2];\
|
|
}
|
|
|
|
#define RGB_OUT(d, r, g, b)\
|
|
{\
|
|
(d)[0] = b;\
|
|
(d)[1] = g;\
|
|
(d)[2] = r;\
|
|
}
|
|
|
|
#define BPP 3
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
#undef RGB_IN
|
|
#undef RGB_OUT
|
|
#undef BPP
|
|
|
|
/* rgb24 handling */
|
|
|
|
#define RGB_NAME rgb24
|
|
#define FMT_RGB24
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
r = (s)[0];\
|
|
g = (s)[1];\
|
|
b = (s)[2];\
|
|
}
|
|
|
|
#define RGB_OUT(d, r, g, b)\
|
|
{\
|
|
(d)[0] = r;\
|
|
(d)[1] = g;\
|
|
(d)[2] = b;\
|
|
}
|
|
|
|
#define BPP 3
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* rgb32 handling */
|
|
|
|
#define RGB_NAME rgb32
|
|
#define FMT_RGBA32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 16) & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = v & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
a = 0xff;\
|
|
r = (v >> 16) & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = v & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* bgr32 handling */
|
|
|
|
#define RGB_NAME bgr32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 8) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 24) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
a = 0xff;\
|
|
r = (v >> 8) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 24) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = a | (r << 8) | (g << 16) | (b << 24);\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* xrgb32 handling */
|
|
|
|
#define RGB_NAME xrgb32
|
|
#define FMT_RGBA32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 24) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 8) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
a = 0xff;\
|
|
r = (v >> 24) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 8) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = (r << 24) | (g << 16) | (b << 8) | a;\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* bgrx32 handling */
|
|
|
|
#define RGB_NAME bgrx32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v) & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = (v >> 16) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
a = 0xff;\
|
|
r = (v) & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = (v >> 16) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = r | (g << 8) | (b << 16) | (a << 24);\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* rgba32 handling */
|
|
|
|
#define RGB_NAME rgba32
|
|
#define FMT_RGBA32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 16) & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = v & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
a = (v >> 24) & 0xff;\
|
|
r = (v >> 16) & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = v & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* bgra32 handling */
|
|
|
|
#define RGB_NAME bgra32
|
|
#define FMT_BGRA32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 8) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 24) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
a = v & 0xff;\
|
|
r = (v >> 8) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 24) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = a | (r << 8) | (g << 16) | (b << 24 );\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* argb32 handling */
|
|
|
|
#define RGB_NAME argb32
|
|
#define FMT_ARGB32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 24) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 8) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = (v >> 24) & 0xff;\
|
|
g = (v >> 16) & 0xff;\
|
|
b = (v >> 8) & 0xff;\
|
|
a = v & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = (r << 24) | (g << 16) | (b << 8) | a;\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
/* abgr32 handling */
|
|
|
|
#define RGB_NAME abgr32
|
|
#define FMT_ABGR32
|
|
|
|
#define RGB_IN(r, g, b, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = v & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = (v >> 16) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_IN(r, g, b, a, s)\
|
|
{\
|
|
unsigned int v = ((const uint32_t *)(s))[0];\
|
|
r = v & 0xff;\
|
|
g = (v >> 8) & 0xff;\
|
|
b = (v >> 16) & 0xff;\
|
|
a = (v >> 24) & 0xff;\
|
|
}
|
|
|
|
#define RGBA_OUT(d, r, g, b, a)\
|
|
{\
|
|
((uint32_t *)(d))[0] = r | (g << 8) | (b << 16) | (a << 24 );\
|
|
}
|
|
|
|
#define BPP 4
|
|
|
|
#include "imgconvert_template.h"
|
|
|
|
static void
|
|
gray_to_gray16_l (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - 2 * width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
GST_WRITE_UINT16_LE (q, (*p << 8));
|
|
q += 2;
|
|
p++;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gray_to_gray16_b (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - 2 * width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
GST_WRITE_UINT16_BE (q, (*p << 8));
|
|
q += 2;
|
|
p++;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gray16_l_to_gray (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - 2 * width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
q[0] = GST_READ_UINT16_LE (p) >> 8;
|
|
q++;
|
|
p += 2;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gray16_b_to_gray (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - 2 * width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
q[0] = GST_READ_UINT16_BE (p) >> 8;
|
|
q++;
|
|
p += 2;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gray16_b_to_gray16_l (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - 2 * width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - 2 * width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
q[0] = p[1];
|
|
q[1] = p[0];
|
|
q += 2;
|
|
p += 2;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
mono_to_gray (AVPicture * dst, const AVPicture * src,
|
|
int width, int height, int xor_mask)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int v, dst_wrap, src_wrap;
|
|
int y, w;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - ((width + 7) >> 3);
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - width;
|
|
for (y = 0; y < height; y++) {
|
|
w = width;
|
|
while (w >= 8) {
|
|
v = *p++ ^ xor_mask;
|
|
q[0] = -(v >> 7);
|
|
q[1] = -((v >> 6) & 1);
|
|
q[2] = -((v >> 5) & 1);
|
|
q[3] = -((v >> 4) & 1);
|
|
q[4] = -((v >> 3) & 1);
|
|
q[5] = -((v >> 2) & 1);
|
|
q[6] = -((v >> 1) & 1);
|
|
q[7] = -((v >> 0) & 1);
|
|
w -= 8;
|
|
q += 8;
|
|
}
|
|
if (w > 0) {
|
|
v = *p++ ^ xor_mask;
|
|
do {
|
|
q[0] = -((v >> 7) & 1);
|
|
q++;
|
|
v <<= 1;
|
|
} while (--w);
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
monowhite_to_gray (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
mono_to_gray (dst, src, width, height, 0xff);
|
|
}
|
|
|
|
static void
|
|
monoblack_to_gray (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
mono_to_gray (dst, src, width, height, 0x00);
|
|
}
|
|
|
|
static void
|
|
gray_to_mono (AVPicture * dst, const AVPicture * src,
|
|
int width, int height, int xor_mask)
|
|
{
|
|
int n;
|
|
const uint8_t *s;
|
|
uint8_t *d;
|
|
int j, b, v, n1, src_wrap, dst_wrap, y;
|
|
|
|
s = src->data[0];
|
|
src_wrap = src->linesize[0] - width;
|
|
|
|
d = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
|
|
|
|
for (y = 0; y < height; y++) {
|
|
n = width;
|
|
while (n >= 8) {
|
|
v = 0;
|
|
for (j = 0; j < 8; j++) {
|
|
b = s[0];
|
|
s++;
|
|
v = (v << 1) | (b >> 7);
|
|
}
|
|
d[0] = v ^ xor_mask;
|
|
d++;
|
|
n -= 8;
|
|
}
|
|
if (n > 0) {
|
|
n1 = n;
|
|
v = 0;
|
|
while (n > 0) {
|
|
b = s[0];
|
|
s++;
|
|
v = (v << 1) | (b >> 7);
|
|
n--;
|
|
}
|
|
d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
|
|
d++;
|
|
}
|
|
s += src_wrap;
|
|
d += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gray_to_monowhite (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
gray_to_mono (dst, src, width, height, 0xff);
|
|
}
|
|
|
|
static void
|
|
gray_to_monoblack (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
gray_to_mono (dst, src, width, height, 0x00);
|
|
}
|
|
|
|
static void
|
|
y800_to_y16 (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - 2 * width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
GST_WRITE_UINT16_LE (q, (*p << 8));
|
|
q += 2;
|
|
p++;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
y16_to_y800 (AVPicture * dst, const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
unsigned char *q;
|
|
int dst_wrap, src_wrap;
|
|
int x, y;
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - 2 * width;
|
|
|
|
q = dst->data[0];
|
|
dst_wrap = dst->linesize[0] - width;
|
|
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
q[0] = GST_READ_UINT16_LE (p) >> 8;
|
|
q++;
|
|
p += 2;
|
|
}
|
|
p += src_wrap;
|
|
q += dst_wrap;
|
|
}
|
|
}
|
|
|
|
static void
|
|
yuva420p_to_ayuv4444 (AVPicture * dst, const AVPicture * src,
|
|
int width, int height)
|
|
{
|
|
const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *a1_ptr, *a2_ptr;
|
|
uint8_t *d, *d1, *d2;
|
|
int w, width2;
|
|
|
|
d = dst->data[0];
|
|
y1_ptr = src->data[0];
|
|
cb_ptr = src->data[1];
|
|
cr_ptr = src->data[2];
|
|
a1_ptr = src->data[3];
|
|
width2 = (width + 1) >> 1;
|
|
for (; height >= 2; height -= 2) {
|
|
d1 = d;
|
|
d2 = d + dst->linesize[0];
|
|
y2_ptr = y1_ptr + src->linesize[0];
|
|
a2_ptr = a1_ptr + src->linesize[3];
|
|
for (w = width; w >= 2; w -= 2) {
|
|
d1[0] = a1_ptr[0];
|
|
d1[1] = y1_ptr[0];
|
|
d1[2] = cb_ptr[0];
|
|
d1[3] = cr_ptr[0];
|
|
|
|
d1[4 + 0] = a1_ptr[1];
|
|
d1[4 + 1] = y1_ptr[1];
|
|
d1[4 + 2] = cb_ptr[0];
|
|
d1[4 + 3] = cr_ptr[0];
|
|
|
|
d2[0] = a2_ptr[0];
|
|
d2[1] = y2_ptr[0];
|
|
d2[2] = cb_ptr[0];
|
|
d2[3] = cr_ptr[0];
|
|
|
|
d2[4 + 0] = a2_ptr[1];
|
|
d2[4 + 1] = y2_ptr[1];
|
|
d2[4 + 2] = cb_ptr[0];
|
|
d2[4 + 3] = cr_ptr[0];
|
|
|
|
d1 += 2 * 4;
|
|
d2 += 2 * 4;
|
|
|
|
y1_ptr += 2;
|
|
y2_ptr += 2;
|
|
cb_ptr++;
|
|
cr_ptr++;
|
|
a1_ptr += 2;
|
|
a2_ptr += 2;
|
|
}
|
|
/* handle odd width */
|
|
if (w) {
|
|
d1[0] = a1_ptr[0];
|
|
d1[1] = y1_ptr[0];
|
|
d1[2] = cb_ptr[0];
|
|
d1[3] = cr_ptr[0];
|
|
|
|
d2[0] = a2_ptr[0];
|
|
d2[1] = y2_ptr[0];
|
|
d2[2] = cb_ptr[0];
|
|
d2[3] = cr_ptr[0];
|
|
|
|
d1 += 4;
|
|
d2 += 4;
|
|
y1_ptr++;
|
|
y2_ptr++;
|
|
cb_ptr++;
|
|
cr_ptr++;
|
|
a1_ptr++;
|
|
a2_ptr++;
|
|
}
|
|
d += 2 * dst->linesize[0];
|
|
y1_ptr += 2 * src->linesize[0] - width;
|
|
cb_ptr += src->linesize[1] - width2;
|
|
cr_ptr += src->linesize[2] - width2;
|
|
a1_ptr += 2 * src->linesize[3] - width;
|
|
}
|
|
/* handle odd height */
|
|
if (height) {
|
|
d1 = d;
|
|
for (w = width; w >= 2; w -= 2) {
|
|
d1[0] = a1_ptr[0];
|
|
d1[1] = y1_ptr[0];
|
|
d1[2] = cb_ptr[0];
|
|
d1[3] = cr_ptr[0];
|
|
|
|
d1[4 + 0] = a1_ptr[1];
|
|
d1[4 + 1] = y1_ptr[1];
|
|
d1[4 + 2] = cb_ptr[0];
|
|
d1[4 + 3] = cr_ptr[0];
|
|
|
|
d1 += 2 * 4;
|
|
|
|
y1_ptr += 2;
|
|
cb_ptr++;
|
|
cr_ptr++;
|
|
a1_ptr += 2;
|
|
}
|
|
/* handle width */
|
|
if (w) {
|
|
d1[0] = a1_ptr[0];
|
|
d1[1] = y1_ptr[0];
|
|
d1[2] = cb_ptr[0];
|
|
d1[3] = cr_ptr[0];
|
|
d1 += 4;
|
|
|
|
y1_ptr++;
|
|
cb_ptr++;
|
|
cr_ptr++;
|
|
a1_ptr++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
ayuv4444_to_yuva420p (AVPicture * dst,
|
|
const AVPicture * src, int width, int height)
|
|
{
|
|
int wrap, wrap3, width2;
|
|
int u1, v1, w;
|
|
uint8_t *lum, *cb, *cr, *a;
|
|
const uint8_t *p;
|
|
|
|
lum = dst->data[0];
|
|
cb = dst->data[1];
|
|
cr = dst->data[2];
|
|
a = dst->data[3];
|
|
|
|
width2 = (width + 1) >> 1;
|
|
wrap = dst->linesize[0];
|
|
wrap3 = src->linesize[0];
|
|
p = src->data[0];
|
|
for (; height >= 2; height -= 2) {
|
|
for (w = width; w >= 2; w -= 2) {
|
|
a[0] = p[0];
|
|
lum[0] = p[1];
|
|
u1 = p[2];
|
|
v1 = p[3];
|
|
|
|
a[1] = p[4 + 0];
|
|
lum[1] = p[4 + 1];
|
|
u1 += p[4 + 2];
|
|
v1 += p[4 + 3];
|
|
p += wrap3;
|
|
lum += wrap;
|
|
a += wrap;
|
|
|
|
a[0] = p[0];
|
|
lum[0] = p[1];
|
|
u1 += p[2];
|
|
v1 += p[3];
|
|
|
|
a[1] = p[4 + 0];
|
|
lum[1] = p[4 + 1];
|
|
u1 += p[4 + 2];
|
|
v1 += p[4 + 3];
|
|
|
|
cb[0] = u1 >> 2;
|
|
cr[0] = v1 >> 2;
|
|
|
|
cb++;
|
|
cr++;
|
|
p += -wrap3 + 2 * 4;
|
|
lum += -wrap + 2;
|
|
a += -wrap + 2;
|
|
}
|
|
if (w) {
|
|
a[0] = p[0];
|
|
lum[0] = p[1];
|
|
u1 = p[2];
|
|
v1 = p[3];
|
|
p += wrap3;
|
|
lum += wrap;
|
|
a += wrap;
|
|
|
|
a[0] = p[0];
|
|
lum[0] = p[1];
|
|
u1 += p[2];
|
|
v1 += p[3];
|
|
|
|
cb[0] = u1 >> 1;
|
|
cr[0] = v1 >> 1;
|
|
cb++;
|
|
cr++;
|
|
p += -wrap3 + 4;
|
|
lum += -wrap + 1;
|
|
a += -wrap + 1;
|
|
}
|
|
p += wrap3 + (wrap3 - width * 4);
|
|
lum += wrap + (wrap - width);
|
|
a += wrap + (wrap - width);
|
|
cb += dst->linesize[1] - width2;
|
|
cr += dst->linesize[2] - width2;
|
|
}
|
|
/* handle odd height */
|
|
if (height) {
|
|
for (w = width; w >= 2; w -= 2) {
|
|
a[0] = p[0];
|
|
lum[0] = p[1];
|
|
u1 = p[2];
|
|
v1 = p[3];
|
|
|
|
a[1] = p[4 + 0];
|
|
lum[1] = p[4 + 1];
|
|
u1 += p[4 + 2];
|
|
v1 += p[4 + 3];
|
|
cb[0] = u1 >> 1;
|
|
cr[0] = v1 >> 1;
|
|
cb++;
|
|
cr++;
|
|
p += 2 * 4;
|
|
lum += 2;
|
|
a += 2;
|
|
}
|
|
if (w) {
|
|
a[0] = p[0];
|
|
lum[0] = p[1];
|
|
cb[0] = p[2];
|
|
cr[0] = p[3];
|
|
}
|
|
}
|
|
}
|
|
|
|
typedef struct ConvertEntry
|
|
{
|
|
enum PixelFormat src;
|
|
enum PixelFormat dest;
|
|
void (*convert) (AVPicture * dst,
|
|
const AVPicture * src, int width, int height);
|
|
} ConvertEntry;
|
|
|
|
/* Add each new convertion function in this table. In order to be able
|
|
to convert from any format to any format, the following constraints
|
|
must be satisfied:
|
|
|
|
- all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
|
|
|
|
- all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
|
|
|
|
- all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32
|
|
|
|
- PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
|
|
PIX_FMT_RGB24.
|
|
|
|
- PIX_FMT_422 must convert to and from PIX_FMT_422P.
|
|
|
|
The other conversion functions are just optimisations for common cases.
|
|
*/
|
|
static ConvertEntry convert_table[] = {
|
|
{PIX_FMT_YUV420P, PIX_FMT_YUV422, yuv420p_to_yuv422},
|
|
{PIX_FMT_YUV420P, PIX_FMT_RGB555, yuv420p_to_rgb555},
|
|
{PIX_FMT_YUV420P, PIX_FMT_RGB565, yuv420p_to_rgb565},
|
|
{PIX_FMT_YUV420P, PIX_FMT_BGR24, yuv420p_to_bgr24},
|
|
{PIX_FMT_YUV420P, PIX_FMT_RGB24, yuv420p_to_rgb24},
|
|
{PIX_FMT_YUV420P, PIX_FMT_RGB32, yuv420p_to_rgb32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_BGR32, yuv420p_to_bgr32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_xRGB32, yuv420p_to_xrgb32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_BGRx32, yuv420p_to_bgrx32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_RGBA32, yuv420p_to_rgba32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_BGRA32, yuv420p_to_bgra32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_ARGB32, yuv420p_to_argb32},
|
|
{PIX_FMT_YUV420P, PIX_FMT_ABGR32, yuv420p_to_abgr32},
|
|
|
|
{PIX_FMT_NV12, PIX_FMT_RGB555, nv12_to_rgb555},
|
|
{PIX_FMT_NV12, PIX_FMT_RGB565, nv12_to_rgb565},
|
|
{PIX_FMT_NV12, PIX_FMT_BGR24, nv12_to_bgr24},
|
|
{PIX_FMT_NV12, PIX_FMT_RGB24, nv12_to_rgb24},
|
|
{PIX_FMT_NV12, PIX_FMT_RGB32, nv12_to_rgb32},
|
|
{PIX_FMT_NV12, PIX_FMT_BGR32, nv12_to_bgr32},
|
|
{PIX_FMT_NV12, PIX_FMT_xRGB32, nv12_to_xrgb32},
|
|
{PIX_FMT_NV12, PIX_FMT_BGRx32, nv12_to_bgrx32},
|
|
{PIX_FMT_NV12, PIX_FMT_RGBA32, nv12_to_rgba32},
|
|
{PIX_FMT_NV12, PIX_FMT_BGRA32, nv12_to_bgra32},
|
|
{PIX_FMT_NV12, PIX_FMT_ARGB32, nv12_to_argb32},
|
|
{PIX_FMT_NV12, PIX_FMT_ABGR32, nv12_to_abgr32},
|
|
{PIX_FMT_NV12, PIX_FMT_NV21, nv12_to_nv21},
|
|
{PIX_FMT_NV12, PIX_FMT_YUV444P, nv12_to_yuv444p},
|
|
|
|
{PIX_FMT_NV21, PIX_FMT_RGB555, nv21_to_rgb555},
|
|
{PIX_FMT_NV21, PIX_FMT_RGB565, nv21_to_rgb565},
|
|
{PIX_FMT_NV21, PIX_FMT_BGR24, nv21_to_bgr24},
|
|
{PIX_FMT_NV21, PIX_FMT_RGB24, nv21_to_rgb24},
|
|
{PIX_FMT_NV21, PIX_FMT_RGB32, nv21_to_rgb32},
|
|
{PIX_FMT_NV21, PIX_FMT_BGR32, nv21_to_bgr32},
|
|
{PIX_FMT_NV21, PIX_FMT_xRGB32, nv21_to_xrgb32},
|
|
{PIX_FMT_NV21, PIX_FMT_BGRx32, nv21_to_bgrx32},
|
|
{PIX_FMT_NV21, PIX_FMT_RGBA32, nv21_to_rgba32},
|
|
{PIX_FMT_NV21, PIX_FMT_BGRA32, nv21_to_bgra32},
|
|
{PIX_FMT_NV21, PIX_FMT_ARGB32, nv21_to_argb32},
|
|
{PIX_FMT_NV21, PIX_FMT_ABGR32, nv21_to_abgr32},
|
|
{PIX_FMT_NV21, PIX_FMT_YUV444P, nv21_to_yuv444p},
|
|
{PIX_FMT_NV21, PIX_FMT_NV12, nv21_to_nv12},
|
|
|
|
{PIX_FMT_YUV422P, PIX_FMT_YUV422, yuv422p_to_yuv422},
|
|
{PIX_FMT_YUV422P, PIX_FMT_UYVY422, yuv422p_to_uyvy422},
|
|
{PIX_FMT_YUV422P, PIX_FMT_YVYU422, yuv422p_to_yvyu422},
|
|
|
|
{PIX_FMT_YUV444P, PIX_FMT_RGB24, yuv444p_to_rgb24},
|
|
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_RGB555, yuvj420p_to_rgb555},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_RGB565, yuvj420p_to_rgb565},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_BGR24, yuvj420p_to_bgr24},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_RGB24, yuvj420p_to_rgb24},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_RGB32, yuvj420p_to_rgb32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_BGR32, yuvj420p_to_bgr32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_RGB32, yuvj420p_to_xrgb32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_BGR32, yuvj420p_to_bgrx32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_RGBA32, yuvj420p_to_rgba32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_BGRA32, yuvj420p_to_bgra32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_ARGB32, yuvj420p_to_argb32},
|
|
{PIX_FMT_YUVJ420P, PIX_FMT_ABGR32, yuvj420p_to_abgr32},
|
|
|
|
{PIX_FMT_YUVJ444P, PIX_FMT_RGB24, yuvj444p_to_rgb24},
|
|
|
|
{PIX_FMT_YUV422, PIX_FMT_YUV420P, yuv422_to_yuv420p},
|
|
{PIX_FMT_YUV422, PIX_FMT_YUV422P, yuv422_to_yuv422p},
|
|
{PIX_FMT_YUV422, PIX_FMT_GRAY8, yvyu422_to_gray},
|
|
{PIX_FMT_YUV422, PIX_FMT_RGB555, yuv422_to_rgb555},
|
|
{PIX_FMT_YUV422, PIX_FMT_RGB565, yuv422_to_rgb565},
|
|
{PIX_FMT_YUV422, PIX_FMT_BGR24, yuv422_to_bgr24},
|
|
{PIX_FMT_YUV422, PIX_FMT_RGB24, yuv422_to_rgb24},
|
|
{PIX_FMT_YUV422, PIX_FMT_BGR32, yuv422_to_bgr32},
|
|
{PIX_FMT_YUV422, PIX_FMT_RGB32, yuv422_to_rgb32},
|
|
{PIX_FMT_YUV422, PIX_FMT_xRGB32, yuv422_to_xrgb32},
|
|
{PIX_FMT_YUV422, PIX_FMT_BGRx32, yuv422_to_bgrx32},
|
|
{PIX_FMT_YUV422, PIX_FMT_BGRA32, yuv422_to_bgra32},
|
|
{PIX_FMT_YUV422, PIX_FMT_RGBA32, yuv422_to_rgba32},
|
|
{PIX_FMT_YUV422, PIX_FMT_ABGR32, yuv422_to_abgr32},
|
|
{PIX_FMT_YUV422, PIX_FMT_ARGB32, yuv422_to_argb32},
|
|
|
|
{PIX_FMT_UYVY422, PIX_FMT_YUV420P, uyvy422_to_yuv420p},
|
|
{PIX_FMT_UYVY422, PIX_FMT_YUV422P, uyvy422_to_yuv422p},
|
|
{PIX_FMT_UYVY422, PIX_FMT_GRAY8, uyvy422_to_gray},
|
|
{PIX_FMT_UYVY422, PIX_FMT_RGB555, uyvy422_to_rgb555},
|
|
{PIX_FMT_UYVY422, PIX_FMT_RGB565, uyvy422_to_rgb565},
|
|
{PIX_FMT_UYVY422, PIX_FMT_BGR24, uyvy422_to_bgr24},
|
|
{PIX_FMT_UYVY422, PIX_FMT_RGB24, uyvy422_to_rgb24},
|
|
{PIX_FMT_UYVY422, PIX_FMT_RGB32, uyvy422_to_rgb32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_BGR32, uyvy422_to_bgr32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_xRGB32, uyvy422_to_xrgb32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_BGRx32, uyvy422_to_bgrx32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_RGBA32, uyvy422_to_rgba32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_BGRA32, uyvy422_to_bgra32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_ARGB32, uyvy422_to_argb32},
|
|
{PIX_FMT_UYVY422, PIX_FMT_ABGR32, uyvy422_to_abgr32},
|
|
|
|
{PIX_FMT_YVYU422, PIX_FMT_YUV420P, yvyu422_to_yuv420p},
|
|
{PIX_FMT_YVYU422, PIX_FMT_YUV422P, yvyu422_to_yuv422p},
|
|
{PIX_FMT_YVYU422, PIX_FMT_GRAY8, yvyu422_to_gray},
|
|
{PIX_FMT_YVYU422, PIX_FMT_RGB555, yvyu422_to_rgb555},
|
|
{PIX_FMT_YVYU422, PIX_FMT_RGB565, yvyu422_to_rgb565},
|
|
{PIX_FMT_YVYU422, PIX_FMT_BGR24, yvyu422_to_bgr24},
|
|
{PIX_FMT_YVYU422, PIX_FMT_RGB24, yvyu422_to_rgb24},
|
|
{PIX_FMT_YVYU422, PIX_FMT_BGR32, yvyu422_to_bgr32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_RGB32, yvyu422_to_rgb32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_xRGB32, yvyu422_to_xrgb32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_BGRx32, yvyu422_to_bgrx32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_BGRA32, yvyu422_to_bgra32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_RGBA32, yvyu422_to_rgba32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_ABGR32, yvyu422_to_abgr32},
|
|
{PIX_FMT_YVYU422, PIX_FMT_ARGB32, yvyu422_to_argb32},
|
|
|
|
{PIX_FMT_RGB24, PIX_FMT_YUV420P, rgb24_to_yuv420p},
|
|
{PIX_FMT_RGB24, PIX_FMT_YUVA420P, rgb24_to_yuva420p},
|
|
{PIX_FMT_RGB24, PIX_FMT_NV12, rgb24_to_nv12},
|
|
{PIX_FMT_RGB24, PIX_FMT_NV21, rgb24_to_nv21},
|
|
{PIX_FMT_RGB24, PIX_FMT_RGB565, rgb24_to_rgb565},
|
|
{PIX_FMT_RGB24, PIX_FMT_RGB555, rgb24_to_rgb555},
|
|
{PIX_FMT_RGB24, PIX_FMT_RGB32, rgb24_to_rgb32},
|
|
{PIX_FMT_RGB24, PIX_FMT_BGR32, rgb24_to_bgr32},
|
|
{PIX_FMT_RGB24, PIX_FMT_xRGB32, rgb24_to_xrgb32},
|
|
{PIX_FMT_RGB24, PIX_FMT_BGRx32, rgb24_to_bgrx32},
|
|
{PIX_FMT_RGB24, PIX_FMT_RGBA32, rgb24_to_rgba32},
|
|
{PIX_FMT_RGB24, PIX_FMT_BGR24, rgb24_to_bgr24},
|
|
{PIX_FMT_RGB24, PIX_FMT_BGRA32, rgb24_to_bgra32},
|
|
{PIX_FMT_RGB24, PIX_FMT_ARGB32, rgb24_to_argb32},
|
|
{PIX_FMT_RGB24, PIX_FMT_ABGR32, rgb24_to_abgr32},
|
|
{PIX_FMT_RGB24, PIX_FMT_Y800, rgb24_to_y800},
|
|
{PIX_FMT_RGB24, PIX_FMT_Y16, rgb24_to_y16},
|
|
{PIX_FMT_RGB24, PIX_FMT_GRAY8, rgb24_to_gray},
|
|
{PIX_FMT_RGB24, PIX_FMT_GRAY16_L, rgb24_to_gray16_l},
|
|
{PIX_FMT_RGB24, PIX_FMT_GRAY16_B, rgb24_to_gray16_b},
|
|
{PIX_FMT_RGB24, PIX_FMT_PAL8, rgb24_to_pal8},
|
|
{PIX_FMT_RGB24, PIX_FMT_YUV444P, rgb24_to_yuv444p},
|
|
{PIX_FMT_RGB24, PIX_FMT_YUVJ420P, rgb24_to_yuvj420p},
|
|
{PIX_FMT_RGB24, PIX_FMT_YUVJ444P, rgb24_to_yuvj444p},
|
|
{PIX_FMT_RGB24, PIX_FMT_AYUV4444, rgb24_to_ayuv4444},
|
|
{PIX_FMT_RGB24, PIX_FMT_V308, rgb24_to_v308},
|
|
|
|
{PIX_FMT_RGB32, PIX_FMT_RGB24, rgb32_to_rgb24},
|
|
{PIX_FMT_RGB32, PIX_FMT_RGB555, rgba32_to_rgb555},
|
|
{PIX_FMT_RGB32, PIX_FMT_PAL8, rgb32_to_pal8},
|
|
{PIX_FMT_RGB32, PIX_FMT_YUV420P, rgb32_to_yuv420p},
|
|
{PIX_FMT_RGB32, PIX_FMT_YUVA420P, rgb32_to_yuva420p},
|
|
{PIX_FMT_RGB32, PIX_FMT_NV12, rgb32_to_nv12},
|
|
{PIX_FMT_RGB32, PIX_FMT_NV21, rgb32_to_nv21},
|
|
{PIX_FMT_RGB32, PIX_FMT_Y800, rgb32_to_y800},
|
|
{PIX_FMT_RGB32, PIX_FMT_Y16, rgb32_to_y16},
|
|
{PIX_FMT_RGB32, PIX_FMT_GRAY8, rgb32_to_gray},
|
|
{PIX_FMT_RGB32, PIX_FMT_GRAY16_L, rgb32_to_gray16_l},
|
|
{PIX_FMT_RGB32, PIX_FMT_GRAY16_B, rgb32_to_gray16_b},
|
|
|
|
{PIX_FMT_xRGB32, PIX_FMT_RGB24, xrgb32_to_rgb24},
|
|
{PIX_FMT_xRGB32, PIX_FMT_PAL8, xrgb32_to_pal8},
|
|
{PIX_FMT_xRGB32, PIX_FMT_YUV420P, xrgb32_to_yuv420p},
|
|
{PIX_FMT_xRGB32, PIX_FMT_YUVA420P, xrgb32_to_yuva420p},
|
|
{PIX_FMT_xRGB32, PIX_FMT_NV12, xrgb32_to_nv12},
|
|
{PIX_FMT_xRGB32, PIX_FMT_NV21, xrgb32_to_nv21},
|
|
{PIX_FMT_xRGB32, PIX_FMT_Y800, xrgb32_to_y800},
|
|
{PIX_FMT_xRGB32, PIX_FMT_Y16, xrgb32_to_y16},
|
|
{PIX_FMT_xRGB32, PIX_FMT_GRAY8, xrgb32_to_gray},
|
|
{PIX_FMT_xRGB32, PIX_FMT_GRAY16_L, xrgb32_to_gray16_l},
|
|
{PIX_FMT_xRGB32, PIX_FMT_GRAY16_B, xrgb32_to_gray16_b},
|
|
|
|
{PIX_FMT_RGBA32, PIX_FMT_BGRA32, rgba32_to_bgra32},
|
|
{PIX_FMT_RGBA32, PIX_FMT_ABGR32, rgba32_to_abgr32},
|
|
{PIX_FMT_RGBA32, PIX_FMT_ARGB32, rgba32_to_argb32},
|
|
{PIX_FMT_RGBA32, PIX_FMT_BGR32, rgba32_to_bgr32},
|
|
{PIX_FMT_RGBA32, PIX_FMT_BGRx32, rgba32_to_bgrx32},
|
|
{PIX_FMT_RGBA32, PIX_FMT_ABGR32, rgba32_to_abgr32},
|
|
{PIX_FMT_RGBA32, PIX_FMT_RGB24, rgba32_to_rgb24},
|
|
{PIX_FMT_RGBA32, PIX_FMT_RGB555, rgba32_to_rgb555},
|
|
{PIX_FMT_RGBA32, PIX_FMT_PAL8, rgba32_to_pal8},
|
|
{PIX_FMT_RGBA32, PIX_FMT_YUV420P, rgba32_to_yuv420p},
|
|
{PIX_FMT_RGBA32, PIX_FMT_YUVA420P, rgba32_to_yuva420p},
|
|
{PIX_FMT_RGBA32, PIX_FMT_NV12, rgba32_to_nv12},
|
|
{PIX_FMT_RGBA32, PIX_FMT_NV21, rgba32_to_nv21},
|
|
{PIX_FMT_RGBA32, PIX_FMT_Y800, rgba32_to_y800},
|
|
{PIX_FMT_RGBA32, PIX_FMT_Y16, rgba32_to_y16},
|
|
{PIX_FMT_RGBA32, PIX_FMT_GRAY8, rgba32_to_gray},
|
|
{PIX_FMT_RGBA32, PIX_FMT_GRAY16_L, rgba32_to_gray16_l},
|
|
{PIX_FMT_RGBA32, PIX_FMT_GRAY16_B, rgba32_to_gray16_b},
|
|
{PIX_FMT_RGBA32, PIX_FMT_AYUV4444, rgba32_to_ayuv4444},
|
|
|
|
{PIX_FMT_BGR24, PIX_FMT_RGB24, bgr24_to_rgb24},
|
|
{PIX_FMT_BGR24, PIX_FMT_YUV420P, bgr24_to_yuv420p},
|
|
{PIX_FMT_BGR24, PIX_FMT_YUVA420P, bgr24_to_yuva420p},
|
|
{PIX_FMT_BGR24, PIX_FMT_NV12, bgr24_to_nv12},
|
|
{PIX_FMT_BGR24, PIX_FMT_NV21, bgr24_to_nv21},
|
|
{PIX_FMT_BGR24, PIX_FMT_Y800, bgr24_to_y800},
|
|
{PIX_FMT_BGR24, PIX_FMT_Y16, bgr24_to_y16},
|
|
{PIX_FMT_BGR24, PIX_FMT_GRAY8, bgr24_to_gray},
|
|
{PIX_FMT_BGR24, PIX_FMT_GRAY16_L, bgr24_to_gray16_l},
|
|
{PIX_FMT_BGR24, PIX_FMT_GRAY16_B, bgr24_to_gray16_b},
|
|
|
|
{PIX_FMT_BGR32, PIX_FMT_RGB24, bgr32_to_rgb24},
|
|
{PIX_FMT_BGR32, PIX_FMT_RGBA32, bgr32_to_rgba32},
|
|
{PIX_FMT_BGR32, PIX_FMT_YUV420P, bgr32_to_yuv420p},
|
|
{PIX_FMT_BGR32, PIX_FMT_YUVA420P, bgr32_to_yuva420p},
|
|
{PIX_FMT_BGR32, PIX_FMT_NV12, bgr32_to_nv12},
|
|
{PIX_FMT_BGR32, PIX_FMT_NV21, bgr32_to_nv21},
|
|
{PIX_FMT_BGR32, PIX_FMT_Y800, bgr32_to_y800},
|
|
{PIX_FMT_BGR32, PIX_FMT_Y16, bgr32_to_y16},
|
|
{PIX_FMT_BGR32, PIX_FMT_GRAY8, bgr32_to_gray},
|
|
{PIX_FMT_BGR32, PIX_FMT_GRAY16_L, bgr32_to_gray16_l},
|
|
{PIX_FMT_BGR32, PIX_FMT_GRAY16_B, bgr32_to_gray16_b},
|
|
|
|
{PIX_FMT_BGRx32, PIX_FMT_RGB24, bgrx32_to_rgb24},
|
|
{PIX_FMT_BGRx32, PIX_FMT_RGBA32, bgrx32_to_rgba32},
|
|
{PIX_FMT_BGRx32, PIX_FMT_YUV420P, bgrx32_to_yuv420p},
|
|
{PIX_FMT_BGRx32, PIX_FMT_YUVA420P, bgrx32_to_yuva420p},
|
|
{PIX_FMT_BGRx32, PIX_FMT_NV12, bgrx32_to_nv12},
|
|
{PIX_FMT_BGRx32, PIX_FMT_NV21, bgrx32_to_nv21},
|
|
{PIX_FMT_BGRx32, PIX_FMT_Y800, bgrx32_to_y800},
|
|
{PIX_FMT_BGRx32, PIX_FMT_Y16, bgrx32_to_y16},
|
|
{PIX_FMT_BGRx32, PIX_FMT_GRAY8, bgrx32_to_gray},
|
|
{PIX_FMT_BGRx32, PIX_FMT_GRAY16_L, bgrx32_to_gray16_l},
|
|
{PIX_FMT_BGRx32, PIX_FMT_GRAY16_B, bgrx32_to_gray16_b},
|
|
|
|
{PIX_FMT_BGRA32, PIX_FMT_RGB24, bgra32_to_rgb24},
|
|
{PIX_FMT_BGRA32, PIX_FMT_RGBA32, bgra32_to_rgba32},
|
|
{PIX_FMT_BGRA32, PIX_FMT_YUV420P, bgra32_to_yuv420p},
|
|
{PIX_FMT_BGRA32, PIX_FMT_YUVA420P, bgra32_to_yuva420p},
|
|
{PIX_FMT_BGRA32, PIX_FMT_NV12, bgra32_to_nv12},
|
|
{PIX_FMT_BGRA32, PIX_FMT_NV21, bgra32_to_nv21},
|
|
{PIX_FMT_BGRA32, PIX_FMT_Y800, bgra32_to_y800},
|
|
{PIX_FMT_BGRA32, PIX_FMT_Y16, bgra32_to_y16},
|
|
{PIX_FMT_BGRA32, PIX_FMT_GRAY8, bgra32_to_gray},
|
|
{PIX_FMT_BGRA32, PIX_FMT_GRAY16_L, bgra32_to_gray16_l},
|
|
{PIX_FMT_BGRA32, PIX_FMT_GRAY16_B, bgra32_to_gray16_b},
|
|
{PIX_FMT_BGRA32, PIX_FMT_AYUV4444, bgra32_to_ayuv4444},
|
|
|
|
{PIX_FMT_ABGR32, PIX_FMT_RGB24, abgr32_to_rgb24},
|
|
{PIX_FMT_ABGR32, PIX_FMT_RGBA32, abgr32_to_rgba32},
|
|
{PIX_FMT_ABGR32, PIX_FMT_YUV420P, abgr32_to_yuv420p},
|
|
{PIX_FMT_ABGR32, PIX_FMT_YUVA420P, abgr32_to_yuva420p},
|
|
{PIX_FMT_ABGR32, PIX_FMT_NV12, abgr32_to_nv12},
|
|
{PIX_FMT_ABGR32, PIX_FMT_NV21, abgr32_to_nv21},
|
|
{PIX_FMT_ABGR32, PIX_FMT_Y800, abgr32_to_y800},
|
|
{PIX_FMT_ABGR32, PIX_FMT_Y16, abgr32_to_y16},
|
|
{PIX_FMT_ABGR32, PIX_FMT_GRAY8, abgr32_to_gray},
|
|
{PIX_FMT_ABGR32, PIX_FMT_GRAY16_L, abgr32_to_gray16_l},
|
|
{PIX_FMT_ABGR32, PIX_FMT_GRAY16_B, abgr32_to_gray16_b},
|
|
{PIX_FMT_ABGR32, PIX_FMT_AYUV4444, abgr32_to_ayuv4444},
|
|
|
|
{PIX_FMT_ARGB32, PIX_FMT_RGB24, argb32_to_rgb24},
|
|
{PIX_FMT_ARGB32, PIX_FMT_RGBA32, argb32_to_rgba32},
|
|
{PIX_FMT_ARGB32, PIX_FMT_YUV420P, argb32_to_yuv420p},
|
|
{PIX_FMT_ARGB32, PIX_FMT_YUVA420P, argb32_to_yuva420p},
|
|
{PIX_FMT_ARGB32, PIX_FMT_NV12, argb32_to_nv12},
|
|
{PIX_FMT_ARGB32, PIX_FMT_NV21, argb32_to_nv21},
|
|
{PIX_FMT_ARGB32, PIX_FMT_Y800, argb32_to_y800},
|
|
{PIX_FMT_ARGB32, PIX_FMT_Y16, argb32_to_y16},
|
|
{PIX_FMT_ARGB32, PIX_FMT_GRAY8, argb32_to_gray},
|
|
{PIX_FMT_ARGB32, PIX_FMT_GRAY16_L, argb32_to_gray16_l},
|
|
{PIX_FMT_ARGB32, PIX_FMT_GRAY16_B, argb32_to_gray16_b},
|
|
{PIX_FMT_ARGB32, PIX_FMT_AYUV4444, argb32_to_ayuv4444},
|
|
|
|
{PIX_FMT_RGB555, PIX_FMT_RGB24, rgb555_to_rgb24},
|
|
{PIX_FMT_RGB555, PIX_FMT_RGB32, rgb555_to_rgba32},
|
|
{PIX_FMT_RGB555, PIX_FMT_RGBA32, rgb555_to_rgba32},
|
|
{PIX_FMT_RGB555, PIX_FMT_YUV420P, rgb555_to_yuv420p},
|
|
{PIX_FMT_RGB555, PIX_FMT_YUVA420P, rgb555_to_yuva420p},
|
|
{PIX_FMT_RGB555, PIX_FMT_NV12, rgb555_to_nv12},
|
|
{PIX_FMT_RGB555, PIX_FMT_NV21, rgb555_to_nv21},
|
|
{PIX_FMT_RGB555, PIX_FMT_Y800, rgb555_to_y800},
|
|
{PIX_FMT_RGB555, PIX_FMT_Y16, rgb555_to_y16},
|
|
{PIX_FMT_RGB555, PIX_FMT_GRAY8, rgb555_to_gray},
|
|
{PIX_FMT_RGB555, PIX_FMT_GRAY16_L, rgb555_to_gray16_l},
|
|
{PIX_FMT_RGB555, PIX_FMT_GRAY16_B, rgb555_to_gray16_b},
|
|
|
|
{PIX_FMT_RGB565, PIX_FMT_RGB24, rgb565_to_rgb24},
|
|
{PIX_FMT_RGB565, PIX_FMT_YUV420P, rgb565_to_yuv420p},
|
|
{PIX_FMT_RGB565, PIX_FMT_YUVA420P, rgb565_to_yuva420p},
|
|
{PIX_FMT_RGB565, PIX_FMT_NV12, rgb565_to_nv12},
|
|
{PIX_FMT_RGB565, PIX_FMT_NV21, rgb565_to_nv21},
|
|
{PIX_FMT_RGB565, PIX_FMT_Y800, rgb565_to_y800},
|
|
{PIX_FMT_RGB565, PIX_FMT_Y16, rgb565_to_y16},
|
|
{PIX_FMT_RGB565, PIX_FMT_GRAY8, rgb565_to_gray},
|
|
{PIX_FMT_RGB565, PIX_FMT_GRAY16_L, rgb565_to_gray16_l},
|
|
{PIX_FMT_RGB565, PIX_FMT_GRAY16_B, rgb565_to_gray16_b},
|
|
|
|
{PIX_FMT_Y800, PIX_FMT_RGB555, y800_to_rgb555},
|
|
{PIX_FMT_Y800, PIX_FMT_RGB565, y800_to_rgb565},
|
|
{PIX_FMT_Y800, PIX_FMT_BGR24, y800_to_bgr24},
|
|
{PIX_FMT_Y800, PIX_FMT_RGB24, y800_to_rgb24},
|
|
{PIX_FMT_Y800, PIX_FMT_RGB32, y800_to_rgb32},
|
|
{PIX_FMT_Y800, PIX_FMT_BGR32, y800_to_bgr32},
|
|
{PIX_FMT_Y800, PIX_FMT_RGB32, y800_to_xrgb32},
|
|
{PIX_FMT_Y800, PIX_FMT_BGR32, y800_to_bgrx32},
|
|
{PIX_FMT_Y800, PIX_FMT_RGBA32, y800_to_rgba32},
|
|
{PIX_FMT_Y800, PIX_FMT_BGRA32, y800_to_bgra32},
|
|
{PIX_FMT_Y800, PIX_FMT_ARGB32, y800_to_argb32},
|
|
{PIX_FMT_Y800, PIX_FMT_ABGR32, y800_to_abgr32},
|
|
{PIX_FMT_Y800, PIX_FMT_Y16, y800_to_y16},
|
|
|
|
{PIX_FMT_Y16, PIX_FMT_RGB555, y16_to_rgb555},
|
|
{PIX_FMT_Y16, PIX_FMT_RGB565, y16_to_rgb565},
|
|
{PIX_FMT_Y16, PIX_FMT_BGR24, y16_to_bgr24},
|
|
{PIX_FMT_Y16, PIX_FMT_RGB24, y16_to_rgb24},
|
|
{PIX_FMT_Y16, PIX_FMT_RGB32, y16_to_rgb32},
|
|
{PIX_FMT_Y16, PIX_FMT_BGR32, y16_to_bgr32},
|
|
{PIX_FMT_Y16, PIX_FMT_RGB32, y16_to_xrgb32},
|
|
{PIX_FMT_Y16, PIX_FMT_BGR32, y16_to_bgrx32},
|
|
{PIX_FMT_Y16, PIX_FMT_RGBA32, y16_to_rgba32},
|
|
{PIX_FMT_Y16, PIX_FMT_BGRA32, y16_to_bgra32},
|
|
{PIX_FMT_Y16, PIX_FMT_ARGB32, y16_to_argb32},
|
|
{PIX_FMT_Y16, PIX_FMT_ABGR32, y16_to_abgr32},
|
|
{PIX_FMT_Y16, PIX_FMT_Y800, y16_to_y800},
|
|
|
|
{PIX_FMT_GRAY8, PIX_FMT_RGB555, gray_to_rgb555},
|
|
{PIX_FMT_GRAY8, PIX_FMT_RGB565, gray_to_rgb565},
|
|
{PIX_FMT_GRAY8, PIX_FMT_RGB24, gray_to_rgb24},
|
|
{PIX_FMT_GRAY8, PIX_FMT_BGR24, gray_to_bgr24},
|
|
{PIX_FMT_GRAY8, PIX_FMT_RGB32, gray_to_rgb32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_BGR32, gray_to_bgr32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_xRGB32, gray_to_xrgb32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_BGRx32, gray_to_bgrx32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_RGBA32, gray_to_rgba32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_BGRA32, gray_to_bgra32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_ARGB32, gray_to_argb32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_ABGR32, gray_to_abgr32},
|
|
{PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, gray_to_monowhite},
|
|
{PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, gray_to_monoblack},
|
|
{PIX_FMT_GRAY8, PIX_FMT_GRAY16_L, gray_to_gray16_l},
|
|
{PIX_FMT_GRAY8, PIX_FMT_GRAY16_B, gray_to_gray16_b},
|
|
|
|
{PIX_FMT_MONOWHITE, PIX_FMT_GRAY8, monowhite_to_gray},
|
|
|
|
{PIX_FMT_MONOBLACK, PIX_FMT_GRAY8, monoblack_to_gray},
|
|
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_GRAY8, gray16_l_to_gray},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_RGB555, gray16_l_to_rgb555},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_RGB565, gray16_l_to_rgb565},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_BGR24, gray16_l_to_bgr24},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_RGB24, gray16_l_to_rgb24},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_BGR32, gray16_l_to_bgr32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_RGB32, gray16_l_to_rgb32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_xRGB32, gray16_l_to_xrgb32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_BGRx32, gray16_l_to_bgrx32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_ABGR32, gray16_l_to_abgr32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_ARGB32, gray16_l_to_argb32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_BGRA32, gray16_l_to_bgra32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_RGBA32, gray16_l_to_rgba32},
|
|
{PIX_FMT_GRAY16_L, PIX_FMT_GRAY16_B, gray16_b_to_gray16_l},
|
|
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_GRAY8, gray16_b_to_gray},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_RGB555, gray16_b_to_rgb555},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_RGB565, gray16_b_to_rgb565},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_BGR24, gray16_b_to_bgr24},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_RGB24, gray16_b_to_rgb24},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_BGR32, gray16_b_to_bgr32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_RGB32, gray16_b_to_rgb32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_xRGB32, gray16_b_to_xrgb32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_BGRx32, gray16_b_to_bgrx32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_ABGR32, gray16_b_to_abgr32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_ARGB32, gray16_b_to_argb32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_BGRA32, gray16_b_to_bgra32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_RGBA32, gray16_b_to_rgba32},
|
|
{PIX_FMT_GRAY16_B, PIX_FMT_GRAY16_L, gray16_b_to_gray16_l},
|
|
|
|
{PIX_FMT_PAL8, PIX_FMT_RGB555, pal8_to_rgb555},
|
|
{PIX_FMT_PAL8, PIX_FMT_RGB565, pal8_to_rgb565},
|
|
{PIX_FMT_PAL8, PIX_FMT_BGR24, pal8_to_bgr24},
|
|
{PIX_FMT_PAL8, PIX_FMT_RGB24, pal8_to_rgb24},
|
|
{PIX_FMT_PAL8, PIX_FMT_RGB32, pal8_to_rgb32},
|
|
{PIX_FMT_PAL8, PIX_FMT_BGR32, pal8_to_bgr32},
|
|
{PIX_FMT_PAL8, PIX_FMT_xRGB32, pal8_to_xrgb32},
|
|
{PIX_FMT_PAL8, PIX_FMT_BGRx32, pal8_to_bgrx32},
|
|
{PIX_FMT_PAL8, PIX_FMT_RGBA32, pal8_to_rgba32},
|
|
{PIX_FMT_PAL8, PIX_FMT_BGRA32, pal8_to_bgra32},
|
|
{PIX_FMT_PAL8, PIX_FMT_ARGB32, pal8_to_argb32},
|
|
{PIX_FMT_PAL8, PIX_FMT_ABGR32, pal8_to_abgr32},
|
|
|
|
{PIX_FMT_UYVY411, PIX_FMT_YUV411P, uyvy411_to_yuv411p},
|
|
{PIX_FMT_YUV411P, PIX_FMT_UYVY411, yuv411p_to_uyvy411},
|
|
|
|
{PIX_FMT_V308, PIX_FMT_RGB24, v308_to_rgb24},
|
|
|
|
{PIX_FMT_AYUV4444, PIX_FMT_RGBA32, ayuv4444_to_rgba32},
|
|
{PIX_FMT_AYUV4444, PIX_FMT_ARGB32, ayuv4444_to_argb32},
|
|
{PIX_FMT_AYUV4444, PIX_FMT_BGRA32, ayuv4444_to_bgra32},
|
|
{PIX_FMT_AYUV4444, PIX_FMT_ABGR32, ayuv4444_to_abgr32},
|
|
{PIX_FMT_AYUV4444, PIX_FMT_RGB24, ayuv4444_to_rgb24},
|
|
{PIX_FMT_AYUV4444, PIX_FMT_YUVA420P, ayuv4444_to_yuva420p},
|
|
|
|
{PIX_FMT_YUVA420P, PIX_FMT_YUV420P, yuva420p_to_yuv420p},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_YUV422, yuva420p_to_yuv422},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_AYUV4444, yuva420p_to_ayuv4444},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_RGB555, yuva420p_to_rgb555},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_RGB565, yuva420p_to_rgb565},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_BGR24, yuva420p_to_bgr24},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_RGB24, yuva420p_to_rgb24},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_RGB32, yuva420p_to_rgb32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_BGR32, yuva420p_to_bgr32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_xRGB32, yuva420p_to_xrgb32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_BGRx32, yuva420p_to_bgrx32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_RGBA32, yuva420p_to_rgba32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_BGRA32, yuva420p_to_bgra32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_ARGB32, yuva420p_to_argb32},
|
|
{PIX_FMT_YUVA420P, PIX_FMT_ABGR32, yuva420p_to_abgr32},
|
|
};
|
|
|
|
static ConvertEntry *
|
|
get_convert_table_entry (int src_pix_fmt, int dst_pix_fmt)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < sizeof (convert_table) / sizeof (convert_table[0]); i++) {
|
|
if (convert_table[i].src == src_pix_fmt &&
|
|
convert_table[i].dest == dst_pix_fmt) {
|
|
return convert_table + i;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int
|
|
avpicture_alloc (AVPicture * picture, int pix_fmt, int width, int height,
|
|
int interlaced)
|
|
{
|
|
unsigned int size;
|
|
void *ptr;
|
|
|
|
size = avpicture_get_size (pix_fmt, width, height);
|
|
ptr = av_malloc (size);
|
|
if (!ptr)
|
|
goto fail;
|
|
gst_ffmpegcsp_avpicture_fill (picture, ptr, pix_fmt, width, height,
|
|
interlaced);
|
|
return 0;
|
|
fail:
|
|
memset (picture, 0, sizeof (AVPicture));
|
|
return -1;
|
|
}
|
|
|
|
static void
|
|
avpicture_free (AVPicture * picture)
|
|
{
|
|
av_free (picture->data[0]);
|
|
}
|
|
|
|
/* return true if yuv planar */
|
|
static inline int
|
|
is_yuv_planar (PixFmtInfo * ps)
|
|
{
|
|
return (ps->color_type == FF_COLOR_YUV ||
|
|
ps->color_type == FF_COLOR_YUV_JPEG) && ps->pixel_type == FF_PIXEL_PLANAR;
|
|
}
|
|
|
|
/* XXX: always use linesize. Return -1 if not supported */
|
|
int
|
|
img_convert (AVPicture * dst, int dst_pix_fmt,
|
|
const AVPicture * src, int src_pix_fmt, int src_width, int src_height)
|
|
{
|
|
static int inited;
|
|
int i, ret, dst_width, dst_height, int_pix_fmt;
|
|
PixFmtInfo *src_pix, *dst_pix;
|
|
ConvertEntry *ce;
|
|
AVPicture tmp1, *tmp = &tmp1;
|
|
|
|
if (G_UNLIKELY (src_width <= 0 || src_height <= 0))
|
|
return 0;
|
|
|
|
if (G_UNLIKELY (!inited)) {
|
|
inited = 1;
|
|
img_convert_init ();
|
|
}
|
|
|
|
dst_width = src_width;
|
|
dst_height = src_height;
|
|
|
|
dst_pix = get_pix_fmt_info (dst_pix_fmt);
|
|
src_pix = get_pix_fmt_info (src_pix_fmt);
|
|
if (G_UNLIKELY (src_pix_fmt == dst_pix_fmt)) {
|
|
/* no conversion needed: just copy */
|
|
img_copy (dst, src, dst_pix_fmt, dst_width, dst_height);
|
|
return 0;
|
|
}
|
|
|
|
ce = get_convert_table_entry (src_pix_fmt, dst_pix_fmt);
|
|
if (ce && ce->convert) {
|
|
/* specific conversion routine */
|
|
ce->convert (dst, src, dst_width, dst_height);
|
|
return 0;
|
|
}
|
|
|
|
/* gray to YUV */
|
|
if (is_yuv_planar (dst_pix) && dst_pix_fmt != PIX_FMT_Y16
|
|
&& src_pix_fmt == PIX_FMT_GRAY8) {
|
|
int w, h, y;
|
|
uint8_t *d;
|
|
|
|
if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
|
|
img_copy_plane (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0], dst_width, dst_height);
|
|
} else {
|
|
img_apply_table (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0],
|
|
dst_width, dst_height, y_jpeg_to_ccir);
|
|
}
|
|
/* fill U and V with 128 */
|
|
w = dst_width;
|
|
h = dst_height;
|
|
w >>= dst_pix->x_chroma_shift;
|
|
h >>= dst_pix->y_chroma_shift;
|
|
for (i = 1; i <= 2; i++) {
|
|
d = dst->data[i];
|
|
if (!d)
|
|
continue;
|
|
for (y = 0; y < h; y++) {
|
|
memset (d, 128, w);
|
|
d += dst->linesize[i];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* YUV to gray */
|
|
if (is_yuv_planar (src_pix) && src_pix_fmt != PIX_FMT_Y16
|
|
&& dst_pix_fmt == PIX_FMT_GRAY8) {
|
|
if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
|
|
img_copy_plane (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0], dst_width, dst_height);
|
|
} else {
|
|
img_apply_table (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0],
|
|
dst_width, dst_height, y_ccir_to_jpeg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* YUV to YUV planar */
|
|
if (is_yuv_planar (dst_pix) && is_yuv_planar (src_pix) &&
|
|
dst_pix->depth == src_pix->depth) {
|
|
int x_shift, y_shift, xy_shift;
|
|
void (*resize_func) (uint8_t * dst, int dst_wrap, int dst_width,
|
|
int dst_height, const uint8_t * src, int src_wrap, int src_width,
|
|
int src_height);
|
|
|
|
x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
|
|
y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
|
|
xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
|
|
|
|
/* there must be filters for conversion at least from and to
|
|
YUV444 format */
|
|
switch (xy_shift) {
|
|
case 0x00:
|
|
resize_func = img_copy_plane_resize;
|
|
break;
|
|
case 0x10:
|
|
resize_func = shrink21;
|
|
break;
|
|
case 0x20:
|
|
resize_func = shrink41;
|
|
break;
|
|
case 0x01:
|
|
resize_func = shrink12;
|
|
break;
|
|
case 0x11:
|
|
resize_func = shrink22;
|
|
break;
|
|
case 0x22:
|
|
resize_func = shrink44;
|
|
break;
|
|
case 0xf0:
|
|
resize_func = grow21;
|
|
break;
|
|
case 0xe0:
|
|
resize_func = grow41;
|
|
break;
|
|
case 0xff:
|
|
resize_func = grow22;
|
|
break;
|
|
case 0xee:
|
|
resize_func = grow44;
|
|
break;
|
|
case 0xf1:
|
|
resize_func = conv411;
|
|
break;
|
|
default:
|
|
/* currently not handled */
|
|
goto no_chroma_filter;
|
|
}
|
|
|
|
img_copy_plane (dst->data[0], dst->linesize[0],
|
|
src->data[0], src->linesize[0], dst_width, dst_height);
|
|
|
|
#define GEN_MASK(x) ((1<<(x))-1)
|
|
#define DIV_ROUND_UP_X(v,x) (((v) + GEN_MASK(x)) >> (x))
|
|
|
|
for (i = 1; i <= 2; i++) {
|
|
gint w, h;
|
|
gint s_w, s_h;
|
|
|
|
w = DIV_ROUND_UP_X (dst_width, dst_pix->x_chroma_shift);
|
|
h = DIV_ROUND_UP_X (dst_height, dst_pix->y_chroma_shift);
|
|
|
|
s_w = DIV_ROUND_UP_X (src_width, src_pix->x_chroma_shift);
|
|
s_h = DIV_ROUND_UP_X (src_height, src_pix->y_chroma_shift);
|
|
|
|
if (src->data[i] != NULL && dst->data[i] != NULL) {
|
|
resize_func (dst->data[i], dst->linesize[i], w, h,
|
|
src->data[i], src->linesize[i], s_w, s_h);
|
|
} else if (dst->data[i] != NULL) {
|
|
memset (dst->data[i], 128, dst->linesize[i] * h);
|
|
}
|
|
}
|
|
/* if yuv color space conversion is needed, we do it here on
|
|
the destination image */
|
|
if (dst_pix->color_type != src_pix->color_type) {
|
|
const uint8_t *y_table, *c_table;
|
|
|
|
if (dst_pix->color_type == FF_COLOR_YUV) {
|
|
y_table = y_jpeg_to_ccir;
|
|
c_table = c_jpeg_to_ccir;
|
|
} else {
|
|
y_table = y_ccir_to_jpeg;
|
|
c_table = c_ccir_to_jpeg;
|
|
}
|
|
img_apply_table (dst->data[0], dst->linesize[0],
|
|
dst->data[0], dst->linesize[0], dst_width, dst_height, y_table);
|
|
|
|
for (i = 1; i <= 2; i++)
|
|
img_apply_table (dst->data[i], dst->linesize[i],
|
|
dst->data[i], dst->linesize[i],
|
|
dst_width >> dst_pix->x_chroma_shift,
|
|
dst_height >> dst_pix->y_chroma_shift, c_table);
|
|
}
|
|
return 0;
|
|
}
|
|
no_chroma_filter:
|
|
GST_CAT_INFO (ffmpegcolorspace_performance,
|
|
"no direct path to convert colorspace from %s -> %s", src_pix->name,
|
|
dst_pix->name);
|
|
|
|
/* try to use an intermediate format */
|
|
if (src_pix_fmt == PIX_FMT_YUV422 || dst_pix_fmt == PIX_FMT_YUV422) {
|
|
/* specific case: convert to YUV422P first */
|
|
int_pix_fmt = PIX_FMT_YUV422P;
|
|
} else if (src_pix_fmt == PIX_FMT_UYVY422 || dst_pix_fmt == PIX_FMT_UYVY422 ||
|
|
src_pix_fmt == PIX_FMT_YVYU422 || dst_pix_fmt == PIX_FMT_YVYU422) {
|
|
/* specific case: convert to YUV422P first */
|
|
int_pix_fmt = PIX_FMT_YUV422P;
|
|
} else if (src_pix_fmt == PIX_FMT_UYVY411 || dst_pix_fmt == PIX_FMT_UYVY411) {
|
|
/* specific case: convert to YUV411P first */
|
|
int_pix_fmt = PIX_FMT_YUV411P;
|
|
} else if ((src_pix->color_type == FF_COLOR_GRAY &&
|
|
src_pix_fmt != PIX_FMT_GRAY8) ||
|
|
(dst_pix->color_type == FF_COLOR_GRAY && dst_pix_fmt != PIX_FMT_GRAY8)) {
|
|
/* gray8 is the normalized format */
|
|
int_pix_fmt = PIX_FMT_GRAY8;
|
|
} else if (src_pix_fmt == PIX_FMT_Y16 || dst_pix_fmt == PIX_FMT_Y16) {
|
|
/* y800 is the normalized format */
|
|
int_pix_fmt = PIX_FMT_Y800;
|
|
} else if ((is_yuv_planar (src_pix) &&
|
|
src_pix_fmt != PIX_FMT_YUV444P && src_pix_fmt != PIX_FMT_YUVJ444P)) {
|
|
/* yuv444 is the normalized format */
|
|
if (src_pix->color_type == FF_COLOR_YUV_JPEG)
|
|
int_pix_fmt = PIX_FMT_YUVJ444P;
|
|
else
|
|
int_pix_fmt = PIX_FMT_YUV444P;
|
|
} else if ((is_yuv_planar (dst_pix) &&
|
|
dst_pix_fmt != PIX_FMT_YUV444P && dst_pix_fmt != PIX_FMT_YUVJ444P)) {
|
|
/* yuv444 is the normalized format */
|
|
if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
|
|
int_pix_fmt = PIX_FMT_YUVJ444P;
|
|
else
|
|
int_pix_fmt = PIX_FMT_YUV444P;
|
|
} else {
|
|
/* the two formats are rgb or gray8 or yuv[j]444p */
|
|
if (src_pix->is_alpha && dst_pix->is_alpha)
|
|
int_pix_fmt = PIX_FMT_RGBA32;
|
|
else
|
|
int_pix_fmt = PIX_FMT_RGB24;
|
|
}
|
|
if (avpicture_alloc (tmp, int_pix_fmt, dst_width, dst_height,
|
|
dst->interlaced) < 0)
|
|
return -1;
|
|
ret = -1;
|
|
if (img_convert (tmp, int_pix_fmt,
|
|
src, src_pix_fmt, src_width, src_height) < 0)
|
|
goto fail1;
|
|
|
|
if (img_convert (dst, dst_pix_fmt,
|
|
tmp, int_pix_fmt, dst_width, dst_height) < 0)
|
|
goto fail1;
|
|
ret = 0;
|
|
fail1:
|
|
avpicture_free (tmp);
|
|
return ret;
|
|
}
|
|
|
|
/* NOTE: we scan all the pixels to have an exact information */
|
|
static int
|
|
get_alpha_info_pal8 (const AVPicture * src, int width, int height)
|
|
{
|
|
const unsigned char *p;
|
|
int src_wrap, ret, x, y;
|
|
unsigned int a;
|
|
uint32_t *palette = (uint32_t *) src->data[1];
|
|
|
|
p = src->data[0];
|
|
src_wrap = src->linesize[0] - width;
|
|
ret = 0;
|
|
for (y = 0; y < height; y++) {
|
|
for (x = 0; x < width; x++) {
|
|
a = palette[p[0]] >> 24;
|
|
if (a == 0x00) {
|
|
ret |= FF_ALPHA_TRANSP;
|
|
} else if (a != 0xff) {
|
|
ret |= FF_ALPHA_SEMI_TRANSP;
|
|
}
|
|
p++;
|
|
}
|
|
p += src_wrap;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Tell if an image really has transparent alpha values.
|
|
* @return ored mask of FF_ALPHA_xxx constants
|
|
*/
|
|
int
|
|
img_get_alpha_info (const AVPicture * src, int pix_fmt, int width, int height)
|
|
{
|
|
const PixFmtInfo *pf;
|
|
int ret;
|
|
|
|
pf = get_pix_fmt_info (pix_fmt);
|
|
/* no alpha can be represented in format */
|
|
if (!pf->is_alpha)
|
|
return 0;
|
|
switch (pix_fmt) {
|
|
case PIX_FMT_RGB32:
|
|
ret = get_alpha_info_rgb32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_BGR32:
|
|
ret = get_alpha_info_bgr32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_xRGB32:
|
|
ret = get_alpha_info_xrgb32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_BGRx32:
|
|
ret = get_alpha_info_bgrx32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_RGBA32:
|
|
ret = get_alpha_info_rgba32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_BGRA32:
|
|
ret = get_alpha_info_bgra32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_ARGB32:
|
|
ret = get_alpha_info_argb32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_ABGR32:
|
|
ret = get_alpha_info_abgr32 (src, width, height);
|
|
break;
|
|
case PIX_FMT_RGB555:
|
|
ret = get_alpha_info_rgb555 (src, width, height);
|
|
break;
|
|
case PIX_FMT_PAL8:
|
|
ret = get_alpha_info_pal8 (src, width, height);
|
|
break;
|
|
default:
|
|
/* we do not know, so everything is indicated */
|
|
ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#ifdef HAVE_MMX
|
|
#define DEINT_INPLACE_LINE_LUM \
|
|
movd_m2r(lum_m4[0],mm0);\
|
|
movd_m2r(lum_m3[0],mm1);\
|
|
movd_m2r(lum_m2[0],mm2);\
|
|
movd_m2r(lum_m1[0],mm3);\
|
|
movd_m2r(lum[0],mm4);\
|
|
punpcklbw_r2r(mm7,mm0);\
|
|
movd_r2m(mm2,lum_m4[0]);\
|
|
punpcklbw_r2r(mm7,mm1);\
|
|
punpcklbw_r2r(mm7,mm2);\
|
|
punpcklbw_r2r(mm7,mm3);\
|
|
punpcklbw_r2r(mm7,mm4);\
|
|
paddw_r2r(mm3,mm1);\
|
|
psllw_i2r(1,mm2);\
|
|
paddw_r2r(mm4,mm0);\
|
|
psllw_i2r(2,mm1);\
|
|
paddw_r2r(mm6,mm2);\
|
|
paddw_r2r(mm2,mm1);\
|
|
psubusw_r2r(mm0,mm1);\
|
|
psrlw_i2r(3,mm1);\
|
|
packuswb_r2r(mm7,mm1);\
|
|
movd_r2m(mm1,lum_m2[0]);
|
|
|
|
#define DEINT_LINE_LUM \
|
|
movd_m2r(lum_m4[0],mm0);\
|
|
movd_m2r(lum_m3[0],mm1);\
|
|
movd_m2r(lum_m2[0],mm2);\
|
|
movd_m2r(lum_m1[0],mm3);\
|
|
movd_m2r(lum[0],mm4);\
|
|
punpcklbw_r2r(mm7,mm0);\
|
|
punpcklbw_r2r(mm7,mm1);\
|
|
punpcklbw_r2r(mm7,mm2);\
|
|
punpcklbw_r2r(mm7,mm3);\
|
|
punpcklbw_r2r(mm7,mm4);\
|
|
paddw_r2r(mm3,mm1);\
|
|
psllw_i2r(1,mm2);\
|
|
paddw_r2r(mm4,mm0);\
|
|
psllw_i2r(2,mm1);\
|
|
paddw_r2r(mm6,mm2);\
|
|
paddw_r2r(mm2,mm1);\
|
|
psubusw_r2r(mm0,mm1);\
|
|
psrlw_i2r(3,mm1);\
|
|
packuswb_r2r(mm7,mm1);\
|
|
movd_r2m(mm1,dst[0]);
|
|
#endif
|
|
|
|
/* filter parameters: [-1 4 2 4 -1] // 8 */
|
|
#if 0
|
|
static void
|
|
deinterlace_line (uint8_t * dst,
|
|
const uint8_t * lum_m4, const uint8_t * lum_m3,
|
|
const uint8_t * lum_m2, const uint8_t * lum_m1,
|
|
const uint8_t * lum, int size)
|
|
{
|
|
#ifndef HAVE_MMX
|
|
uint8_t *cm = cropTbl + MAX_NEG_CROP;
|
|
int sum;
|
|
|
|
for (; size > 0; size--) {
|
|
sum = -lum_m4[0];
|
|
sum += lum_m3[0] << 2;
|
|
sum += lum_m2[0] << 1;
|
|
sum += lum_m1[0] << 2;
|
|
sum += -lum[0];
|
|
dst[0] = cm[(sum + 4) >> 3];
|
|
lum_m4++;
|
|
lum_m3++;
|
|
lum_m2++;
|
|
lum_m1++;
|
|
lum++;
|
|
dst++;
|
|
}
|
|
#else
|
|
|
|
{
|
|
mmx_t rounder;
|
|
|
|
rounder.uw[0] = 4;
|
|
rounder.uw[1] = 4;
|
|
rounder.uw[2] = 4;
|
|
rounder.uw[3] = 4;
|
|
pxor_r2r (mm7, mm7);
|
|
movq_m2r (rounder, mm6);
|
|
}
|
|
for (; size > 3; size -= 4) {
|
|
DEINT_LINE_LUM lum_m4 += 4;
|
|
|
|
lum_m3 += 4;
|
|
lum_m2 += 4;
|
|
lum_m1 += 4;
|
|
lum += 4;
|
|
dst += 4;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
deinterlace_line_inplace (uint8_t * lum_m4, uint8_t * lum_m3, uint8_t * lum_m2,
|
|
uint8_t * lum_m1, uint8_t * lum, int size)
|
|
{
|
|
#ifndef HAVE_MMX
|
|
uint8_t *cm = cropTbl + MAX_NEG_CROP;
|
|
int sum;
|
|
|
|
for (; size > 0; size--) {
|
|
sum = -lum_m4[0];
|
|
sum += lum_m3[0] << 2;
|
|
sum += lum_m2[0] << 1;
|
|
lum_m4[0] = lum_m2[0];
|
|
sum += lum_m1[0] << 2;
|
|
sum += -lum[0];
|
|
lum_m2[0] = cm[(sum + 4) >> 3];
|
|
lum_m4++;
|
|
lum_m3++;
|
|
lum_m2++;
|
|
lum_m1++;
|
|
lum++;
|
|
}
|
|
#else
|
|
|
|
{
|
|
mmx_t rounder;
|
|
|
|
rounder.uw[0] = 4;
|
|
rounder.uw[1] = 4;
|
|
rounder.uw[2] = 4;
|
|
rounder.uw[3] = 4;
|
|
pxor_r2r (mm7, mm7);
|
|
movq_m2r (rounder, mm6);
|
|
}
|
|
for (; size > 3; size -= 4) {
|
|
DEINT_INPLACE_LINE_LUM lum_m4 += 4;
|
|
|
|
lum_m3 += 4;
|
|
lum_m2 += 4;
|
|
lum_m1 += 4;
|
|
lum += 4;
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
|
|
top field is copied as is, but the bottom field is deinterlaced
|
|
against the top field. */
|
|
#if 0
|
|
static void
|
|
deinterlace_bottom_field (uint8_t * dst, int dst_wrap,
|
|
const uint8_t * src1, int src_wrap, int width, int height)
|
|
{
|
|
const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
|
|
int y;
|
|
|
|
src_m2 = src1;
|
|
src_m1 = src1;
|
|
src_0 = &src_m1[src_wrap];
|
|
src_p1 = &src_0[src_wrap];
|
|
src_p2 = &src_p1[src_wrap];
|
|
for (y = 0; y < (height - 2); y += 2) {
|
|
memcpy (dst, src_m1, width);
|
|
dst += dst_wrap;
|
|
deinterlace_line (dst, src_m2, src_m1, src_0, src_p1, src_p2, width);
|
|
src_m2 = src_0;
|
|
src_m1 = src_p1;
|
|
src_0 = src_p2;
|
|
src_p1 += 2 * src_wrap;
|
|
src_p2 += 2 * src_wrap;
|
|
dst += dst_wrap;
|
|
}
|
|
memcpy (dst, src_m1, width);
|
|
dst += dst_wrap;
|
|
/* do last line */
|
|
deinterlace_line (dst, src_m2, src_m1, src_0, src_0, src_0, width);
|
|
}
|
|
|
|
static void
|
|
deinterlace_bottom_field_inplace (uint8_t * src1, int src_wrap,
|
|
int width, int height)
|
|
{
|
|
uint8_t *src_m1, *src_0, *src_p1, *src_p2;
|
|
int y;
|
|
uint8_t *buf;
|
|
|
|
buf = (uint8_t *) av_malloc (width);
|
|
|
|
src_m1 = src1;
|
|
memcpy (buf, src_m1, width);
|
|
src_0 = &src_m1[src_wrap];
|
|
src_p1 = &src_0[src_wrap];
|
|
src_p2 = &src_p1[src_wrap];
|
|
for (y = 0; y < (height - 2); y += 2) {
|
|
deinterlace_line_inplace (buf, src_m1, src_0, src_p1, src_p2, width);
|
|
src_m1 = src_p1;
|
|
src_0 = src_p2;
|
|
src_p1 += 2 * src_wrap;
|
|
src_p2 += 2 * src_wrap;
|
|
}
|
|
/* do last line */
|
|
deinterlace_line_inplace (buf, src_m1, src_0, src_0, src_0, width);
|
|
av_free (buf);
|
|
}
|
|
#endif
|
|
|
|
/* deinterlace - if not supported return -1 */
|
|
#if 0
|
|
static int
|
|
avpicture_deinterlace (AVPicture * dst, const AVPicture * src,
|
|
int pix_fmt, int width, int height)
|
|
{
|
|
int i;
|
|
|
|
if (pix_fmt != PIX_FMT_YUV420P &&
|
|
pix_fmt != PIX_FMT_YUV422P &&
|
|
pix_fmt != PIX_FMT_YUV444P && pix_fmt != PIX_FMT_YUV411P)
|
|
return -1;
|
|
if ((width & 3) != 0 || (height & 3) != 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
if (i == 1) {
|
|
switch (pix_fmt) {
|
|
case PIX_FMT_YUV420P:
|
|
width >>= 1;
|
|
height >>= 1;
|
|
break;
|
|
case PIX_FMT_YUV422P:
|
|
width >>= 1;
|
|
break;
|
|
case PIX_FMT_YUV411P:
|
|
width >>= 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (src == dst) {
|
|
deinterlace_bottom_field_inplace (dst->data[i], dst->linesize[i],
|
|
width, height);
|
|
} else {
|
|
deinterlace_bottom_field (dst->data[i], dst->linesize[i],
|
|
src->data[i], src->linesize[i], width, height);
|
|
}
|
|
}
|
|
#ifdef HAVE_MMX
|
|
emms ();
|
|
#endif
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#undef FIX
|