h261dec.c

来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,645 行 · 第 1/5 页

C
1,645
字号
        return (H261_ERROR);
    }
}
#endif // TESTING

#ifdef ANNOTATE_PICTURE
// saveOrRestoreReconPicture
static void saveOrRestoreReconPicture( PICTURE *pic,    // Picture to be saved or restored
                                       int  restore     // Save if 0, otherwise restore
                                     )
{
#define MAX_BYTES   ((176*144*3)/2)
    int             nBytes;
    static PIXEL    savePic[MAX_BYTES];
    
    nBytes = (pic->y.nhor * pic->y.nvert * 3) >> 1;
    // Packed format is assumed
    if (nBytes > MAX_BYTES) {
        H261ErrMsg("Error in saveOrRestoreReconPicture\n");
        exit(0);
    } else if (restore) {   // Restore the saved picture
        memcpy( pic->y.ptr, savePic, nBytes ); /* Flawfinder: ignore */
    } else {                // Save picture for next decoding
        memcpy( savePic, pic->y.ptr, nBytes ); /* Flawfinder: ignore */
    }
}


// annotatePicture - Draw motion vectors etc.
static void annotatePicture( PICTURE *pic, MACROBLOCK_DESCR mb[])
{
    int     xSize, ySize, numMb, i, x, y;
    PIXEL   *upperLeft;
    
    xSize = pic->y.nhor;
    ySize = pic->y.nvert;
    numMb = (xSize * ySize) >> 8;
    for (i = 0; i < numMb; ++i) {
        x = 16 * mb[i].x;
        y = 16 * mb[i].y;
        upperLeft = pic->y.ptr + x + y * pic->y.hoffset;
        annotateMacroblock( upperLeft, pic->y.hoffset, &mb[i],
                            -x, xSize - 1 - x,
                            -y, ySize - 1 - y );
    }
}

#define WHITE   (255)
#define BLACK   (0)
#define BLACK_THRESHOLD (192)   // Paint with black if pixel is brighter than threshold
// Limit x to interval [low,high]
#define LIMIT( low, x, high )    max( low, min( x, high ))

// annotateMacroblock
static void annotateMacroblock( PIXEL data[], int xdim, MACROBLOCK_DESCR *mb,
                                int xMin, int xMax, int yMin, int yMax )
{

    switch (mb->mtype)
    {
    case MTYPE_SKIP:
        // Do nothing
        break;
    case MTYPE263_INTER:
    case MTYPE263_INTER_Q:
        // Draw motion vector
        drawMv( &data[7 + 7 * xdim], xdim, mb->mv_x, mb->mv_y,
                xMin-7, xMax-7, yMin-7, yMax-7 );
        break;
    case MTYPE263_INTER4V:
        // Draw a "plus"
        plusMb( data, xdim );
        // Draw 4 motion vectors
        drawMv( &data[3 + 3 * xdim], xdim, mb->blkMvX[0], mb->blkMvY[0],
                xMin-3, xMax-3, yMin-3, yMax-3 );
        drawMv( &data[11 + 3 * xdim], xdim, mb->blkMvX[1], mb->blkMvY[1],
                xMin-11, xMax-11, yMin-3, yMax-3 );
        drawMv( &data[3 + 11 * xdim], xdim, mb->blkMvX[2], mb->blkMvY[2],
                xMin-3, xMax-3, yMin-11, yMax-11 );
        drawMv( &data[11 + 11 * xdim], xdim, mb->blkMvX[3], mb->blkMvY[3],
                xMin-11, xMax-11, yMin-11, yMax-11 );
        break;
    case MTYPE263_INTRA:
    case MTYPE263_INTRA_Q:
        //  Draw motion vector and mark block with a cross
        drawMv( &data[7 + 7 * xdim], xdim, mb->mv_x, mb->mv_y,
                xMin-7, xMax-7, yMin-7, yMax-7 );
        crossMb( data, xdim );
        break;
    default:
        // Fill block with white
        fillMb( data, xdim );
        break;
    }
}


// drawMv - Draw motion vector starting in (0,0)
static void drawMv( PIXEL data[], int xdim, int mvX, int mvY,
                    int xMin, int xMax, int yMin, int yMax )
{
    if (mvX == 0  &&  mvY == 0) {
        // Draw a circle
        markPixel( &data[-xdim] );
        markPixel( &data[-xdim + 1] );
        markPixel( &data[-1] );
        markPixel( &data[2] );
        markPixel( &data[xdim - 1] );
        markPixel( &data[xdim + 2] );
        markPixel( &data[2*xdim] );
        markPixel( &data[2*xdim+1] );
    } else {    // Draw motion vector
        // Divide by 2 (one frac. bit); round "away" from 0
        /*if (mvX > 0) ++mvX;
        mvX >>= 1;
        if (mvY > 0) ++mvY;
        mvY >>= 1;*/    // Leave mv's scaled up by factor of 2
        // Clip to picture rectangle
        mvX = LIMIT( xMin, mvX, xMax );
        mvY = LIMIT( yMin, mvY, yMax );
        DrawVector( data, xdim, 0, 0, mvX, mvY );
    }
}


// plusMb - Mark block with a "plus"
static void plusMb( PIXEL data[], int xdim )
{
    int col;
    
    // Horizontal line
    data += 7 * xdim;
    for (col = 5; col <= 9; ++col) {
        markPixel( &data[col] );
    }
    // Vertical line
    markPixel( &data[7 - 2 * xdim] );
    markPixel( &data[7 - 1 * xdim] );
    markPixel( &data[7 + 1 * xdim] );
    markPixel( &data[7 + 2 * xdim] );
}


// crossMb - Mark block with a cross
static void crossMb( PIXEL data[], int xdim )
{
    int row;
    
    for (row = 0; row < 16; ++row) {
        markPixel( &data[row] );
        markPixel( &data[15 - row] );
        data += xdim;
    }
}


// fillMb - Fill block with white
static void fillMb( PIXEL data[], int xdim )
{
    int row, col;
    
    for (row = 0; row < 16; ++row) {
        for (col = 0; col < 16; ++col) {
            markPixel( &data[col] );
        }
        data += xdim;
    }
}


// markPixel - Set pixel to white if < 192, otherwise set it to black
static void markPixel( PIXEL *pixel )
{
    if (*pixel < BLACK_THRESHOLD) {
        *pixel = WHITE;
    } else {
        *pixel = BLACK;
    }
}

///////////// Graphics routines /////////////

#include <stdlib.h>
#include <math.h>

// Static function declarations
static int DrawVector( unsigned char data[], int xdim, int x1, int y1, int x2, int y2 );
static int drawVec( unsigned char data[], int xdim, int x1, int y1 );

// DrawVector - Draw vector from (x1,y1) to (x2,y2)
static int DrawVector( unsigned char data[], int xdim, int x1, int y1, int x2, int y2 )
{
    int x, y;
    
    if (y1 == y2) {         // Draw horizontal line
        data += y1 * xdim;
        for (x = min(x1,x2); x <= max(x1,x2); ++x)  markPixel( &data[x] );
    } else if (x1 == x2) {  // Draw vertical line
        data += min(y1,y2) * xdim;
        for (y = min(y1,y2); y <= max(y1,y2); ++y) {
            markPixel( &data[x1] );
            data += xdim;
        }
    } else if (x2 > x1) {   // Use (x1,y1) as origin
        data += x1 + y1 * xdim;
        drawVec( data, xdim, x2-x1, y2-y1 );
    } else {                // Use (x2,y2) as origin
        data += x2 + y2 * xdim;
        drawVec( data, xdim, x1-x2, y1-y2 );
    }
    return(1);
}


// drawVec - Draw vector from origin to (x1,y1)
//  Assumes that x1 > 0, and y1 != 0
//  Draw pixels that are within 0.5 units distance of vector
static int drawVec( unsigned char data[], int xdim, int x1, int y1 )
{
    int x, y, xLast, xNew;
    float   fX1, fY1, fNorm, fA, fB, fXstep, fX, fDist;
    
    if (y1 < 0) {
        y1 = -y1;
        xdim = -xdim;
    }
    // Now, both x1 and y1 are >0
    // Compute equation for line:  ax + by = 0, where (a,b) is normal vector of length 1
    // The distance between (x,y) and the line is the inner product: abs(ax + by)
    fX1 = (float)x1;
    fY1 = (float)y1;
    fNorm = (float) sqrt( fX1*fX1 + fY1*fY1);
    fA = -fY1 / fNorm;  // fA < 0
    fB = fX1 / fNorm;   // fB > 0
    fXstep = fX1 / fY1; // x increment per row
    // First row
    fX = (float)(0.5 * fXstep);  // Intersection with y=0.5
    xLast = (int)fX;    // Truncate (Note: fX > 0; int always truncates towards zero)
    for (x = 0; x <= xLast; ++x)  markPixel( &data[x] );
    // Intermediate rows
    for (y = 1; y < y1; ++y) {
        data += xdim;
        // Check distance to (xLast, y)
        fDist = fA * (float)xLast + fB * (float)y;  // fDist > 0
        if (fDist < 0.4999) {
            markPixel( &data[xLast] );
        } else if (fDist + fA - fB > -0.4999) {     // Check distance to (xLast+1, y-1)
            //fDist = fA * (float)(xLast+1) + fB * (float)(y-1);  // fDist < 0
            markPixel( &data[xLast+1 - xdim] );
        }
        fX += fXstep;   // Intersection with y+0.5
        xNew = (int)fX;
        for (x = xLast + 1; x <= xNew; ++x)  markPixel( &data[x] );
        xLast = xNew;
    }
    // Last row (y = y1)
    data += xdim;
    // Check distance to (xLast, y1)
    fDist = fA * (float)xLast + fB * (float)y1; // fDist > 0
    if (fDist < 0.4999) {
        markPixel( &data[xLast] );
    } else if (fDist + fA - fB > -0.4999) {     // Check distance to (xLast+1, y1-1)
        markPixel( &data[xLast+1 - xdim] );
    }
    for (x = xLast + 1; x <= x1; ++x)  markPixel( &data[x] );
    
    return(1);
}

#endif  /* ANNOTATE_PICTURE */

/*
// Compute checksums for picture (used for debugging only)
static int checkPicture( PICTURE pic );
static int checkComponent( COMPONENT comp );

static PIXEL	encPic[176*144], decPic[176*144], diffPic[176*144];

extern int storePicture( PICTURE pic, int picNum )
{
	int		i, j;
	PIXEL	*in, *out;

	in = pic.y.ptr;
	if (picNum == 0)
		out = encPic;
	else
		out = decPic;
    for (i = 0; i < pic.y.nvert; i++) {
        for (j = 0; j < pic.y.nhor; j++) {
			out[j] = in[j];
        }
		in += pic.y.hoffset;
		out += pic.y.nhor;
    }
	return( 1 );
}

static int checkPicture( PICTURE pic )
{
	int	        y, cb, cr, i;
    static int  sum = 0;

	storePicture( pic, 1 );
	y = checkComponent( pic.y );
	cb = checkComponent( pic.cb );
	cr = checkComponent( pic.cr );
	sum += y + cb + cr;
	for (i = 0; i < 176*144; ++i)
		diffPic[i] = encPic[i] - decPic[i];
	return( sum );
}

static int checkComponent( COMPONENT comp )
{
    int		i, j, sum;
    PIXEL   *p;

	sum = 0, p = comp.ptr;
    for (i = 0; i < comp.nvert; i++) {
        for (j = 0; j < comp.nhor; j++) {
			sum += p[j];
        }
		p += comp.hoffset;
    }
	return( sum );
}
*/

⌨️ 快捷键说明

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