📄 image.cpp
字号:
/**************************************************************************
*
* XVID MPEG-4 VIDEO CODEC
* image stuff
*
* This program is an implementation of a part of one or more MPEG-4
* Video tools as specified in ISO/IEC 14496-2 standard. Those intending
* to use this software module in hardware or software products are
* advised that its use may infringe existing patents or copyrights, and
* any such use would be at such party's own risk. The original
* developer of this software module and his/her company, and subsequent
* editors and their companies, will have no liability for use of this
* software or modifications or derivatives thereof.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*************************************************************************/
#include "stdafx.h"
#include "image.h"
#include "ffImgfmt.h"
#include "Tconfig.h"
#include "simd.h"
#include "ffdebug.h"
typedef void (packedFunc)(uint8_t * x_ptr,
stride_t x_stride,
uint8_t * y_src,
uint8_t * v_src,
uint8_t * u_src,
stride_t y_stride,
stride_t uv_stride,
int width,
int height);
typedef packedFunc *packedFuncPtr;
static packedFuncPtr yuyv_to_yv12;
static packedFuncPtr uyvy_to_yv12;
static packedFuncPtr yuyvi_to_yv12;
static packedFuncPtr uyvyi_to_yv12;
static packedFuncPtr yv12_to_yuyv;
static packedFuncPtr yv12_to_uyvy;
static packedFuncPtr yv12_to_yuyvi;
static packedFuncPtr yv12_to_uyvyi;
typedef void (planarFunc) (uint8_t * y_dst, uint8_t * u_dst, uint8_t * v_dst,
stride_t y_dst_stride, stride_t uv_dst_stride,
const uint8_t * y_src, const uint8_t * u_src, const uint8_t * v_src,
stride_t y_src_stride, stride_t uv_src_stride,
int width, int height);
typedef planarFunc *planarFuncPtr;
static planarFuncPtr yv12_to_yv12;
/* yv12 to yv12 copy function */
static void yv12_to_yv12_c(uint8_t * y_dst, uint8_t * u_dst, uint8_t * v_dst,
stride_t y_dst_stride, stride_t uv_dst_stride,
const uint8_t * y_src, const uint8_t * u_src, const uint8_t * v_src,
stride_t y_src_stride, stride_t uv_src_stride,
int width, int height)
{
int width2 = width / 2;
int height2 = height / 2;
int y;
for (y = height; y; y--) {
memcpy(y_dst, y_src, width);
y_src += y_src_stride;
y_dst += y_dst_stride;
}
for (y = height2; y; y--) {
memcpy(u_dst, u_src, width2);
u_src += uv_src_stride;
u_dst += uv_dst_stride;
}
for (y = height2; y; y--) {
memcpy(v_dst, v_src, width2);
v_src += uv_src_stride;
v_dst += uv_dst_stride;
}
}
enum {CCIR=1,JPEG=2};
template<int CCIR> struct YUV_RGB_DATA
{
static int32_t RGB_Y_tab[256];
static int32_t B_U_tab[256];
static int32_t G_U_tab[256];
static int32_t G_V_tab[256];
static int32_t R_V_tab[256];
static const double Y_R_IN,Y_G_IN,Y_B_IN;static const int Y_ADD_IN;
static const double U_R_IN,U_G_IN,U_B_IN;static const int U_ADD_IN;
static const double V_R_IN,V_G_IN,V_B_IN;static const int V_ADD_IN;
static const double RGB_Y_OUT,B_U_OUT;static const int Y_ADD_OUT;
static const double G_U_OUT,G_V_OUT;static const int U_ADD_OUT;
static const double R_V_OUT;static const int V_ADD_OUT;
static const int Y_ADD,U_ADD,V_ADD;
static const __int64 Y_SUB,U_SUB,V_SUB,Y_MUL,UG_MUL,VG_MUL,UB_MUL,VR_MUL,y_mul,u_mul,v_mul;
};
/* rgb -> yuv def's
this following constants are "official spec"
Video Demystified" (ISBN 1-878707-09-4)
rgb<->yuv _is_ lossy, since most programs do the conversion differently
SCALEBITS/FIX taken from ffmpeg
*/
#define MAKE_M64_16(d,c,b,a) uint64_t(short(d))+(uint64_t(short(c))<<16)+(uint64_t(short(b))<<32)+(uint64_t(short(a))<<48)
#define MAKE_M64_16_1(a) MAKE_M64_16(a,a,a,a)
#define FIX(a) int((a)*256+0.5)
#define FIX64(a) int((a)*64+0.5)
//-------------------- ccir --------------------
template<> const int YUV_RGB_DATA<CCIR>::Y_ADD=16;
template<> const int YUV_RGB_DATA<CCIR>::U_ADD=128;
template<> const int YUV_RGB_DATA<CCIR>::V_ADD=128;
template<> int32_t YUV_RGB_DATA<CCIR>::RGB_Y_tab[256]={};
template<> int32_t YUV_RGB_DATA<CCIR>::B_U_tab[256]={};
template<> int32_t YUV_RGB_DATA<CCIR>::G_U_tab[256]={};
template<> int32_t YUV_RGB_DATA<CCIR>::G_V_tab[256]={};
template<> int32_t YUV_RGB_DATA<CCIR>::R_V_tab[256]={};
template<> const double YUV_RGB_DATA<CCIR>::Y_R_IN=0.299*219.0/255.0;
template<> const double YUV_RGB_DATA<CCIR>::Y_G_IN=0.587*219.0/255.0;
template<> const double YUV_RGB_DATA<CCIR>::Y_B_IN=0.114*219.0/255.0;
template<> const int YUV_RGB_DATA<CCIR>::Y_ADD_IN=16;
template<> const double YUV_RGB_DATA<CCIR>::U_R_IN=0.16874*224.0/255.0;
template<> const double YUV_RGB_DATA<CCIR>::U_G_IN=0.33126*224.0/255.0;
template<> const double YUV_RGB_DATA<CCIR>::U_B_IN=0.50000*224.0/255.0;
template<> const int YUV_RGB_DATA<CCIR>::U_ADD_IN=128;
template<> const double YUV_RGB_DATA<CCIR>::V_R_IN=0.50000*224.0/255.0;
template<> const double YUV_RGB_DATA<CCIR>::V_G_IN=0.41869*224.0/255.0;
template<> const double YUV_RGB_DATA<CCIR>::V_B_IN=0.08131*224.0/255.0;
template<> const int YUV_RGB_DATA<CCIR>::V_ADD_IN=128;
template<> const double YUV_RGB_DATA<CCIR>::RGB_Y_OUT=1.164;
template<> const double YUV_RGB_DATA<CCIR>::B_U_OUT =1.77200*255.0/224.0;
template<> const int YUV_RGB_DATA<CCIR>::Y_ADD_OUT =16;
template<> const double YUV_RGB_DATA<CCIR>::G_U_OUT =0.34414*255.0/224.0;
template<> const double YUV_RGB_DATA<CCIR>::G_V_OUT =0.71414*255.0/224.0;
template<> const int YUV_RGB_DATA<CCIR>::U_ADD_OUT =128;
template<> const double YUV_RGB_DATA<CCIR>::R_V_OUT =1.40200*255.0/224.0;
template<> const int YUV_RGB_DATA<CCIR>::V_ADD_OUT =128;
template<> const __int64 YUV_RGB_DATA<CCIR>::Y_SUB= MAKE_M64_16_1(Y_ADD);
template<> const __int64 YUV_RGB_DATA<CCIR>::U_SUB= MAKE_M64_16_1(U_ADD);
template<> const __int64 YUV_RGB_DATA<CCIR>::V_SUB= MAKE_M64_16_1(V_ADD);
template<> const __int64 YUV_RGB_DATA<CCIR>::Y_MUL= MAKE_M64_16_1(FIX64(RGB_Y_OUT));
template<> const __int64 YUV_RGB_DATA<CCIR>::UG_MUL= MAKE_M64_16_1(FIX64(G_U_OUT));
template<> const __int64 YUV_RGB_DATA<CCIR>::VG_MUL= MAKE_M64_16_1(FIX64(G_V_OUT));
template<> const __int64 YUV_RGB_DATA<CCIR>::UB_MUL= MAKE_M64_16_1(FIX64(B_U_OUT));
template<> const __int64 YUV_RGB_DATA<CCIR>::VR_MUL= MAKE_M64_16_1(FIX64(R_V_OUT));
// FIX(Y_B FIX(Y_G) FIX(Y_R)
template<> const __int64 YUV_RGB_DATA<CCIR>::y_mul= MAKE_M64_16( FIX(Y_B_IN)/* 25*/, FIX(Y_G_IN)/*129*/, FIX(Y_R_IN)/* 66*/, 0);
template<> const __int64 YUV_RGB_DATA<CCIR>::u_mul= MAKE_M64_16( FIX(U_B_IN)/*112*/,-FIX(U_G_IN)/*-74*/,-FIX(U_R_IN)/*-38*/, 0);
template<> const __int64 YUV_RGB_DATA<CCIR>::v_mul= MAKE_M64_16(-FIX(V_B_IN)/*-18*/,-FIX(V_G_IN)/*-94*/, FIX(V_R_IN)/*112*/, 0);
//-------------------- jpeg --------------------
template<> const int YUV_RGB_DATA<JPEG>::Y_ADD=0;
template<> const int YUV_RGB_DATA<JPEG>::U_ADD=128;
template<> const int YUV_RGB_DATA<JPEG>::V_ADD=128;
template<> int32_t YUV_RGB_DATA<JPEG>::RGB_Y_tab[256]={};
template<> int32_t YUV_RGB_DATA<JPEG>::B_U_tab[256]={};
template<> int32_t YUV_RGB_DATA<JPEG>::G_U_tab[256]={};
template<> int32_t YUV_RGB_DATA<JPEG>::G_V_tab[256]={};
template<> int32_t YUV_RGB_DATA<JPEG>::R_V_tab[256]={};
template<> const double YUV_RGB_DATA<JPEG>::Y_R_IN=0.299;
template<> const double YUV_RGB_DATA<JPEG>::Y_G_IN=0.587;
template<> const double YUV_RGB_DATA<JPEG>::Y_B_IN=0.114;
template<> const int YUV_RGB_DATA<JPEG>::Y_ADD_IN=0;
template<> const double YUV_RGB_DATA<JPEG>::U_R_IN=0.16874;
template<> const double YUV_RGB_DATA<JPEG>::U_G_IN=0.33126;
template<> const double YUV_RGB_DATA<JPEG>::U_B_IN=0.50000;
template<> const int YUV_RGB_DATA<JPEG>::U_ADD_IN=128;
template<> const double YUV_RGB_DATA<JPEG>::V_R_IN=0.50000;
template<> const double YUV_RGB_DATA<JPEG>::V_G_IN=0.41869;
template<> const double YUV_RGB_DATA<JPEG>::V_B_IN=0.08131;
template<> const int YUV_RGB_DATA<JPEG>::V_ADD_IN=128;
template<> const double YUV_RGB_DATA<JPEG>::RGB_Y_OUT=1;
template<> const double YUV_RGB_DATA<JPEG>::B_U_OUT =1.77200;
template<> const int YUV_RGB_DATA<JPEG>::Y_ADD_OUT =0;
template<> const double YUV_RGB_DATA<JPEG>::G_U_OUT =0.34414;
template<> const double YUV_RGB_DATA<JPEG>::G_V_OUT =0.71414;
template<> const int YUV_RGB_DATA<JPEG>::U_ADD_OUT =128;
template<> const double YUV_RGB_DATA<JPEG>::R_V_OUT =1.40200;
template<> const int YUV_RGB_DATA<JPEG>::V_ADD_OUT =128;
template<> const __int64 YUV_RGB_DATA<JPEG>::Y_SUB= MAKE_M64_16_1(Y_ADD);
template<> const __int64 YUV_RGB_DATA<JPEG>::U_SUB= MAKE_M64_16_1(U_ADD);
template<> const __int64 YUV_RGB_DATA<JPEG>::V_SUB= MAKE_M64_16_1(V_ADD);
template<> const __int64 YUV_RGB_DATA<JPEG>::Y_MUL= MAKE_M64_16_1(FIX64(RGB_Y_OUT));
template<> const __int64 YUV_RGB_DATA<JPEG>::UG_MUL= MAKE_M64_16_1(FIX64(G_U_OUT));
template<> const __int64 YUV_RGB_DATA<JPEG>::VG_MUL= MAKE_M64_16_1(FIX64(G_V_OUT));
template<> const __int64 YUV_RGB_DATA<JPEG>::UB_MUL= MAKE_M64_16_1(FIX64(B_U_OUT));
template<> const __int64 YUV_RGB_DATA<JPEG>::VR_MUL= MAKE_M64_16_1(FIX64(R_V_OUT));
// FIX(Y_B FIX(Y_G) FIX(Y_R)
template<> const __int64 YUV_RGB_DATA<JPEG>::y_mul= MAKE_M64_16( FIX(Y_B_IN), FIX(Y_G_IN), FIX(Y_R_IN), 0);
template<> const __int64 YUV_RGB_DATA<JPEG>::u_mul= MAKE_M64_16( FIX(U_B_IN),-FIX(U_G_IN),-FIX(U_R_IN), 0);
template<> const __int64 YUV_RGB_DATA<JPEG>::v_mul= MAKE_M64_16(-FIX(V_B_IN),-FIX(V_G_IN), FIX(V_R_IN), 0);
#undef FIX
#undef FIX64
#undef MAKE_M64_16_1
#undef MAKE_M64_16
struct RGB555
{
static __forceinline uint16_t MK(int R,int G,int B)
{
return (uint16_t)(((limit_uint8(R) << 7) & 0x7c00) |
((limit_uint8(G) << 2) & 0x03e0) |
((limit_uint8(B) >> 3) & 0x001f));
}
static __forceinline uint32_t B(uint32_t RGB) {return (RGB << 3) & 0xf8;}
static __forceinline uint32_t G(uint32_t RGB) {return (RGB >> 2) & 0xf8;}
static __forceinline uint32_t R(uint32_t RGB) {return (RGB >> 7) & 0xf8;}
};
struct RGB565
{
static __forceinline uint16_t MK(int R,int G,int B)
{
return (uint16_t)(((limit_uint8(R) << 8) & 0xf800) |
((limit_uint8(G) << 3) & 0x07e0) |
((limit_uint8(B) >> 3) & 0x001f));
}
static __forceinline uint32_t B(uint32_t RGB) {return (RGB << 3) & 0xf8;}
static __forceinline uint32_t G(uint32_t RGB) {return (RGB >> 3) & 0xfc;}
static __forceinline uint32_t R(uint32_t RGB) {return (RGB >> 8) & 0xf8;}
};
static const int SCALEBITS_OUT=13;
static const int SCALEBITS_IN=8;
#define FIX_IN(x) ((uint16_t) ((x) * (1L<<SCALEBITS_IN) + 0.5))
template<int SIZE,int PIXELS,int VPIXELS,class C1,int C2,int C3,int C4,int CCIR> struct TMAKE_COLORSPACE
{
template<int ROW> static __forceinline void WRITE_RGB16(uint8_t *x_ptr,stride_t x_stride,
uint8_t *y_ptr,stride_t y_stride,
int r[2],int g[2],int b[2],
const int b_u,const int g_uv,const int r_v)
{
int rgb_y = YUV_RGB_DATA<CCIR>::RGB_Y_tab[ y_ptr[y_stride*(ROW) + 0] ];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -