⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bw3.c

📁 视频601芯片的驱动源码,你可以完全掌控该芯片了,对于其它多媒体芯片的设计具有参考价值
💻 C
字号:
/*------------------------------------------------------------------------

$Workfile: BW3.C $
$Date: 3/11/96 12:51p $
$Revision: 2 $
* Purpose:	
*			Bin Width Calculation.			
* Notes:       
*
$History: BW3.C $
 * 
 * *****************  Version 2  *****************
 * User: Stevel       Date: 3/11/96    Time: 12:51p
 * Updated in $/601cman
 * Add DLLEXPORT keyword to export functions for diagnostic test
 * 
 * *****************  Version 1  *****************
 * User: Stevel       Date: 3/06/96    Time: 7:50p
 * Created in $/601cman
 * Initial release

  
    This code and information is provided "as is" without warranty of any
    kind, either expressed or implied, including but not limited to the
    implied warranties of merchantability and/or fitness for a particular
    purpose.
  
    1996 Analog Devices, Inc. 
  
-------------------------------------------------------------------------*/

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>

#define NBLOCKS 42

#include "bit-prec.h"
#include "bw.h"
#include "bw3tab.c"


#ifdef sgi
#define LOG10(X) log10f(X)
#else
#define LOG10(X) log10(X)
#endif

///////////////////////////////////////////////////////////////////////////
// Signal flag used by Bin Width Calculator
///////////////////////////////////////////////////////////////////////////
extern int	   	*pBWrdyFlg;

///////////////////////////////////////////////////////////////////////////
// Configuration Parameters
///////////////////////////////////////////////////////////////////////////
BWCconfig config_rec;

static real levels0[6]  = {0.4f, 0.3f, 0.25f, 0.2f, 0.15f, 0.1f};
static yuv_bias0[3]     = {1, 1.25f, 1.25f};
static real diag_hor_vert0[3] = {1.2f, 1.0f, 1.0f};

static real levels1[6]  = {96.0f, 64.0f, 32.0f, 16.0f, 8.0f, 4.0f};
static yuv_bias1[3]     = {1, 2, 2};
static real diag_hor_vert1[3] = {1.2f, 1.0f, 1.0f};

static real bw_min[NBLOCKS];
static real bw_max[NBLOCKS];
static int block_sizes[NBLOCKS];
static real block_weights[NBLOCKS];

///////////////////////////////////////////////////////////////////////////
// Local function prototypes
///////////////////////////////////////////////////////////////////////////
static real estimate_bpp (real bw[]);
static void tau2bw       (real tau, real bw[]);
static void expand_statistics (BWCinput *ip);
static void init_block_sizes (int img_width, int img_height);

///////////////////////////////////////////////////////////////////////////
// Local variables for Bin Width Calculator
///////////////////////////////////////////////////////////////////////////
BWCinput 	inrec;		// Input for the Bin Width Calculator
BWCoutput 	outrec;		// Ouput from the Bin Width Calculator
BWCinit 	init_rec;	// 

//=========================================================================
// Function to configure the Bin Width Calculator
//=========================================================================
DLLEXPORT void bw_config()
{
    int bn, lev, dir, color;
    config_rec.BppPrecision = 0.05f;
    config_rec.BppFeedbackParm[0] = 0.0f;
    config_rec.BppFeedbackParm[1] = 0.0f;
    
    for (bn=0; bn<3; bn++) {
	bw_min[bn] = levels0[0] * yuv_bias0[bn];
	bw_max[bn] = levels1[0] * yuv_bias1[bn];
    }
    
    for (lev=1; lev<6; lev++) {
	for (dir=0; dir<3; dir++) {
	    for (color=0; color<3; color++) {
		if (bn < NBLOCKS) {
		    bw_min[bn] = levels0[lev]
			* diag_hor_vert0[dir]
			    * yuv_bias0[color];
		    bw_max[bn] = levels1[lev]
			* diag_hor_vert1[dir]
			    * yuv_bias1[color];
		    bn++;
		}
	    }
	}
    }
}

//=========================================================================
// Function to convert Tau to Bin Width values
//=========================================================================
static void tau2bw(real tau, real bw[])
{
    int bn;
    for (bn=0; bn<NBLOCKS; bn++)
	bw[bn] = (1.0-tau) * bw_min[bn] + tau * bw_max[bn];
}



///////////////////////////////////////////////////////////////////////////
// P24 actually corresponds to 10 bit shift: 
// there are 14 bits built in into 9.7 precision of the wavelet transform. 
///////////////////////////////////////////////////////////////////////////
static real b0 = 0.01f;
static real b1 = 100.0f;


#define P24    1024.0f
#define P26    (4.0*P24)
#define P28    (4.0*P26)
#define P30    (4.0*P28)
#define P32    (4.0*P30)



static real v2scale[NBLOCKS] = {
    P32, P32, P32,
    P30, P30, P30, P30, P30, P30, P30, P30, P30, 
    P28, P28, P28, P28, P28, P28, P28, P28, P28, 
    P26, P26, P26, P26, P26, P26, P26, P26, P26, 
    P24, P24, P24, P24, P24, P24, P24, P24, P24, 
    P24, P24, P24
};

static real v2scale_log[NBLOCKS];


///////////////////////////////////////////////////////////////////////////
// Internal Variables 
///////////////////////////////////////////////////////////////////////////
real rate0, rate1; 
static real b1log;
static real lbw_scale;
static real v2log[NBLOCKS]; /* half log of deviations */

//=========================================================================
// Bin Width Calculation
//=========================================================================
DLLEXPORT void bw_compute (BWCinput *in, BWCoutput *out)
{
    real
	bw_cur[NBLOCKS],
	tau_low = 0.0,
	tau_high = 1.0,
	tau_mid, rhigh, rmid, rlow;
    int done, bn;

    expand_statistics(in);
    tau2bw (tau_high, bw_cur);
    rlow  = estimate_bpp(bw_cur);
    if (rlow < rate0) {
	tau2bw (tau_low, bw_cur);
	rhigh = estimate_bpp(bw_cur);
	if (rate1 < rhigh)
	{
	    for (done=0; ! done; ) {
		tau_mid = 0.5f*(tau_low + tau_high);
		tau2bw (tau_mid, bw_cur);
		rmid = estimate_bpp(bw_cur);
		if (rmid < rate0) {
		    rlow     = rmid;
		    tau_high = tau_mid;
		}
		else if (rmid > rate1) {
		    rhigh    = rmid;
		    tau_low  = tau_mid;
		}
		else
		    done = 1;
	    }
	}
    }
    for (bn=0; bn<NBLOCKS; bn++) {
	real
	    bw = bw_cur[bn],
	    bwr = 1.0/bw;
	out->BWCoeff[bn]  = FLOAT2BW(bw);
	out->RBWCoeff[bn] = FLOAT2BWI(bwr);
	out->FieldDecim = 0;
    }

}


//=========================================================================
// Function to initialize the Bin Width Calculator
//=========================================================================
static real bpp_table[NBLOCKS][NPT];

DLLEXPORT void bw_init (BWCinit *init_rec)
{
    int bn;

    switch (init_rec->ImgType) {
      case GENERAL:
	memcpy(bpp_table, general_bpp_table,   sizeof(bpp_table));
	break;
      case NATURAL:
	memcpy(bpp_table, natural_bpp_table,   sizeof(bpp_table));
	break;
      case SYNTHETIC:
	memcpy(bpp_table, synthetic_bpp_table, sizeof(bpp_table));
	break;
      default:
	abort();
    }
    rate0 = (1.0 - config_rec.BppPrecision) * init_rec -> Bpp;
    rate1 = (1.0 + config_rec.BppPrecision) * init_rec -> Bpp;
    
    b1log = LOG10(b1);
    lbw_scale = ((real)(NPT-1)) / (b1log - LOG10(b0));

    init_block_sizes(init_rec->ImageWidth, init_rec->ImageHeight);

    for (bn=0; bn<NBLOCKS; bn++) {
	v2scale_log[bn] = LOG10(v2scale[bn]/(real)block_sizes[bn]);
    }
    /* Adjust bpp's according to block size */
    
    for (bn=0; bn<NBLOCKS; bn++) {
	int i;
	real weight = block_weights[bn];
	for (i=0; i<NPT; i++) {
	    bpp_table[bn][i] *= weight;
	}
    }
}

//=========================================================================
// Function to calculate the compression ratio
//=========================================================================
static real estimate_bpp (real bw[])
{
    real total_bpp = 0.0f, bwl;
    int bn;
    for (bn=0; bn<NBLOCKS; bn++) {
	real
	    *cb_table = bpp_table[bn],
	    cbw = bw[bn],
	    bw_log  = LOG10(cbw), bpp;

	bwl = (b1log - bw_log + v2log[bn]) * lbw_scale;
	if (bwl > NPT-1) {
	    bpp = cb_table[NPT-1] + 
		(bwl-NPT+1) * (cb_table[NPT-1] - cb_table[NPT-2]);
	}
	else if (bwl < 0) {
	    bpp = cb_table[0] + bwl * (cb_table[1]-cb_table[0]);
	    if (bpp<0)
		bpp = 0;
	}
        else {
	    int 
		bi0 = bwl,
		bi1 = bi0+1;
	    real bfrac = bwl - bi0;
	    
	    bpp = cb_table[bi0] +
		bfrac * (cb_table[bi1] - cb_table[bi0]);
	}
	total_bpp += bpp;
    }
    return total_bpp;
}

//=========================================================================
// Function to expand the statistics (what does this mean ?)
//=========================================================================
static void expand_statistics (BWCinput *ip)
{
    int bn;
    for (bn=0; bn<NBLOCKS; bn++) {
	real v2;

	/* ADV601 doesn't do the rounding, so we have to adhjust */

	v2 = 0.5 + ((real)(ip->SumOfSq[bn]));
	v2log[bn] = 0.5 * (LOG10(v2) + v2scale_log[bn]) ;
    }
}

//=========================================================================
// Function to initialize the block size
//=========================================================================
static void init_block_sizes (int img_width, int img_height)
{
    real image_size = img_width * img_height;
    int 
	h = img_height, w = img_width,
	h1 = (h+1)/2, h1b = h - h1,
	w1 = (w+1)/2, w1r = w - w1,
	nn = 0, lev, bn;

    /******** Set Luminance Block Sizes */

    block_sizes[nn] = w1r * h;
    w = w1;
    for (lev=1; lev < 5; lev++) {
	int 
	    h1 = (h+1)/2, h1b = h - h1,
	    w1 = (w+1)/2, w1r = w - w1;
	block_sizes[nn+3] = h1b * w1r;
	block_sizes[nn+6] = h1  * w1r;
	block_sizes[nn+9] = h1b * w1;
	h = h1;
	w = w1;
	nn += 9;
    }
    block_sizes[nn+3] = h * w;
    
    /******** Set Chrominance Block Sizes */
    w = img_width;
    h = img_height;
    w1r = w/2;
    w1 = w-w1r;
    w1r = w1/2;
    w1 = w1-w1r;
    w = w1;
    nn = 1;
    block_sizes[nn] = block_sizes[nn+1] = w1r * h;
    for (lev=1; lev < 5; lev++) {
	int 
	    h1 = (h+1)/2, h1b = h - h1,
	    w1 = (w+1)/2, w1r = w - w1;
	block_sizes[nn+3] = block_sizes[nn+4]  = h1b * w1r;
	block_sizes[nn+6] = block_sizes[nn+7]  = h1  * w1r;
	block_sizes[nn+9] = block_sizes[nn+10] = h1b * w1;
	h = h1;
	w = w1;
	nn += 9;
    }
    block_sizes[nn+3] = block_sizes[nn+4] = h*w;
    for (bn=0; bn<NBLOCKS; bn++) 
	block_weights[bn] = ((real)block_sizes[bn])/image_size;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -