transfrm_ref.c
来自「Motion JPEG编解码器源代码」· C语言 代码 · 共 250 行
C
250 行
/* transfrm.c, Low-level Architecture neutral DCT/iDCT and prediction difference / addition routines *//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * *//* Modifications and enhancements (C) 2000/2001 Andrew Stevens *//* These modifications are 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., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */#include <config.h>#include <math.h>#include "mjpeg_types.h"#include "mjpeg_logging.h"#include "transfrm_ref.h"#include "cpu_accel.h"#include "simd.h"#if defined(HAVE_ASM_MMX)extern void init_x86_transform();#endif#ifdef HAVE_ALTIVEC#include "../utils/altivec/altivec_transform.h"#endifvoid fdct( int16_t *blk );void idct( int16_t *blk );void init_fdct (void);void init_idct (void);/* Pointers to version of transform and prediction manipulation routines to be used.. */void (*pfdct)( int16_t * blk );void (*pidct)( int16_t * blk );void (*padd_pred) (uint8_t *pred, uint8_t *cur, int lx, int16_t *blk);void (*psub_pred) (uint8_t *pred, uint8_t *cur, int lx, int16_t *blk);int (*pfield_dct_best)( uint8_t *cur_lum_mb, uint8_t *pred_lum_mb, int stride);int field_dct_best( uint8_t *cur_lum_mb, uint8_t *pred_lum_mb, int stride ){ /* * calculate prediction error (cur-pred) for top (blk0) * and bottom field (blk1) */ double r,d; int rowoffs = 0; int sumtop, sumbot, sumsqtop, sumsqbot, sumbottop; int j,i; int topvar, botvar; sumtop = sumsqtop = sumbot = sumsqbot = sumbottop = 0; for (j=0; j<8; j++) { for (i=0; i<16; i++) { register int toppix = cur_lum_mb[rowoffs+i] - pred_lum_mb[rowoffs+i]; register int botpix = cur_lum_mb[rowoffs+stride+i] - pred_lum_mb[rowoffs+stride+i]; sumtop += toppix; sumsqtop += toppix*toppix; sumbot += botpix; sumsqbot += botpix*botpix; sumbottop += toppix*botpix; } rowoffs += (stride<<1); } /* Calculate Variances top and bottom. If they're of similar sign estimate correlation if its good use frame DCT otherwise use field. */ r = 0.0; topvar = sumsqtop-sumtop*sumtop/128; botvar = sumsqbot-sumbot*sumbot/128; if (!((topvar>0) ^ (botvar>0))) { d = ((double) topvar) * ((double)botvar); r = (sumbottop-(sumtop*sumbot)/128); if (r>0.5*sqrt(d)) return 0; /* frame DCT */ else return 1; /* field DCT */ } return 1; /* field DCT */}/* add prediction and prediction error, saturate to 0...255 */void add_pred(uint8_t *pred, uint8_t *cur, int lx, int16_t *blk){ int i, j; for (j=0; j<8; j++) { for (i=0; i<8; i++) { int16_t rawsum = blk[i] + pred[i]; cur[i] = (rawsum<0) ? 0 : ((rawsum>255) ? 255 : rawsum); } blk+= 8; cur+= lx; pred+= lx; }}/* subtract prediction from block data *//* static */void sub_pred(uint8_t *pred, uint8_t *cur, int lx, int16_t *blk){ int i, j; for (j=0; j<8; j++) { for (i=0; i<8; i++) blk[i] = cur[i] - pred[i]; blk+= 8; cur+= lx; pred+= lx; }}/* Initialise DCT transformation routines. Selects the appropriate architecture dependent SIMD routines and initialises pre-computed tables */void init_transform(void){ int flags; flags = cpu_accel(); pfdct = fdct; pidct = idct; padd_pred = add_pred; psub_pred = sub_pred; pfield_dct_best = field_dct_best;#if defined(HAVE_ASM_MMX) if( flags & ACCEL_X86_MMX ) { init_x86_transform(); }#endif#ifdef HAVE_ALTIVEC if (flags > 0) {#if ALTIVEC_TEST_TRANSFORM# if defined(ALTIVEC_BENCHMARK) mjpeg_info("SETTING AltiVec BENCHMARK for TRANSFORM!");# elif defined(ALTIVEC_VERIFY) mjpeg_info("SETTING AltiVec VERIFY for TRANSFORM!");# endif#else mjpeg_info("SETTING AltiVec for TRANSFORM!");#endif#if ALTIVEC_TEST_FUNCTION(fdct) pfdct = ALTIVEC_TEST_SUFFIX(fdct);#else pfdct = ALTIVEC_SUFFIX(fdct);#endif#if ALTIVEC_TEST_FUNCTION(idct) pidct = ALTIVEC_TEST_SUFFIX(idct);#else pidct = ALTIVEC_SUFFIX(idct);#endif#if ALTIVEC_TEST_FUNCTION(add_pred) padd_pred = ALTIVEC_TEST_SUFFIX(add_pred);#else padd_pred = ALTIVEC_SUFFIX(add_pred);#endif#if ALTIVEC_TEST_FUNCTION(sub_pred) psub_pred = ALTIVEC_TEST_SUFFIX(sub_pred);#else psub_pred = ALTIVEC_SUFFIX(sub_pred);#endif#if ALTIVEC_TEST_FUNCTION(field_dct_best) pfield_dct_best = ALTIVEC_TEST_SUFFIX(field_dct_best);#else pfield_dct_best = ALTIVEC_SUFFIX(field_dct_best);#endif }#endif /* HAVE_ALTIVEC */ init_fdct(); init_idct();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?