📄 h261dec.c
字号:
return (H261_ERROR); }}#endif // TESTING#ifdef ANNOTATE_PICTURE// saveOrRestoreReconPicturestatic 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 ))// annotateMacroblockstatic 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 crossstatic 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 whitestatic 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 blackstatic void markPixel( PIXEL *pixel ){ if (*pixel < BLACK_THRESHOLD) { *pixel = WHITE; } else { *pixel = BLACK; }}///////////// Graphics routines /////////////#include <stdlib.h>#include <math.h>// Static function declarationsstatic 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 vectorstatic 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -