📄 dcttestc.c
字号:
* - an array of DCTArray entities, each of which contains a block to be inverse DCT'd
* out
* - an initialised array of DCTArray entries to hold the result of the inverse DCT'ing
* the number of entries in the array must be at least the number of entries
* referenced by the array in
* numberBlocks
* - the number of DCTArray entries in the array in and the number of blocks returned
* after the function call in out
* Return Values
* ------ ------
* TRUE - the coding operation was successful
* FALSE - some error occurred (memory allocation?)
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static Boolean RDCTFast( DCTArray in[ ], DCTArray out[ ], unsigned int numberBlocks )
{
int *dctBlockPtr ;
int *dctBlock ;
unsigned int x, y ;
unsigned int bCounter ;
if( ( !in ) || ( !out ) ) {
fprintf( stderr, "[RDCTFast] Error in arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return FALSE ;
}
CREATEDCTBLOCK( dctBlockPtr, dctBlock, numberBlocks ) ;
if( !dctBlock ) {
return FALSE ;
}
for( bCounter = 0 ; bCounter < numberBlocks ; bCounter += 1 ) {
for( y = 0; y < 8; y += 1 ) {
for( x = 0; x < 8; x += 1 ) {
PRERDCT( dctBlock, in[ bCounter ][ y ][ x ], x, y, bCounter ) ;
}
}
}
rdct_fast( dctBlock, numberBlocks ) ;
for( bCounter = 0 ; bCounter < numberBlocks ; bCounter += 1 ) {
for( y = 0; y < 8; y += 1 ) {
for( x = 0; x < 8; x += 1 ) {
POSTRDCT( dctBlock, out[ bCounter ][ y ][ x ], x, y, bCounter ) ;
}
}
}
free( ( void * ) dctBlockPtr ) ;
return TRUE ;
}
/**** SetMaxXYPosition **************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* find the position for the maximum value in the given 2D square array and return
* both the position and the calculated maximum value
*
* Inputs
* ------
* in
* - a square 2D array of integers to find the maximum value in and position
* N
* - the size of one dimension of the given array which equates to both the number
* of rows and columns in the given array (thus only square arrays work)
* x, y
* - pointers to integer locations to hold the x and y coordinates into the array
* where the maximum value is to be found
* Outputs
* -------
* x, y
* - the (x,y) location for the returned maximum value in the given array
* Return Values
* ------ ------
* int - the maximum value found (not absolute)
* 0 - some error occurred, no test available since max may be zero
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static int SetMaxXYPosition( IArray iArray, unsigned int N, unsigned int *x, unsigned int *y )
{
unsigned int i, j ;
int max = 0 ;
int newMax ;
if( ( !iArray ) || ( !x ) || ( !y ) ) {
fprintf( stderr, "[SetMaxXYPosition] Error in arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return 0 ;
}
for( j = 0 ; j < N ; j += 1 ) {
for( i = 0 ; i < N ; i += 1 ) {
if( ( newMax = MAX( max, iArray[ j ][ i ] ) ) > max ) {
max = newMax ;
*x = i ;
*y = j ;
}
}
}
return max ;
}
/**** Transform *********************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* forward or inverse DCT transform the given array of data using either ARM or C
* routines and if the global option for status messages is on, print the codecs
* current process at appropriate times
*
* Inputs
* ------
* outIArray
* - an initialised 2D array of integers to hold the result of the coding process
* which should reference at least as many 2D entries as the input array
* inIArray
* - a square 2D array of input integers that are to be (i)DCT coded
* N
* - the size of one dimension of the given array which equates to both the number
* of rows and columns in the given array (thus only square arrays work)
* also defines the dimensions for the output array and hence number of entries
* numberBlocks
* - the number of blocks that should be coded with each call to the ARM routines
* this value should be divide exactly into (N*N)/(BLOCKSIZE*BLOCKSIZE) else the
* coding will be incomplete (not all blocks will be coded, outputs less than
* expected)
* arm
* - TRUE : use the ARM routines for transform
* FALSE : use the C routines for transform (much much slower!)
* forward
* - TRUE : the input data should be forward DCT'd
* FALSE : the input data is the result of a forward DCT and should be inverse DCT'd
* Outputs
* -------
* outIArray
* - a square 2D array of N*N integers that are the result of the coding
* undefined if FALSE returned (see Return Values)
* Return Values
* ------ ------
* TRUE - the coding process was successful, outIArray is valid
* FALSE - some error occurred, outIArray does not contain valid data
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static Boolean Transform( IArray outIArray, IArray inIArray, unsigned int N, unsigned int numberBlocks, Boolean arm, Boolean forward )
{
unsigned int nDivBlock = N/BLOCKSIZE ;
unsigned int itersPerLoop = -1 ;
unsigned int iterations = 0 ;
unsigned int iBlock, jBlock ;
unsigned int i, j ;
unsigned int rowi ;
unsigned int columnj ;
DCTArray dctIn, dctOut ;
DCTArray *dctInArrayPtr, *dctOutArrayPtr ;
DCTCosArray dctCosArray ;
TimeStruct timeStruct ;
unsigned int blockIters ;
unsigned int noBCounter ;
unsigned int totNumBlocks ;
unsigned int blocksRemaining ;
if( ( !inIArray ) || ( !outIArray ) ) {
fprintf( stderr, "[Transform] Error in arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return FALSE ;
}
if( gStatus[ 0 ] == '1' ) {
if( arm ) {
itersPerLoop = N * N * PIDOFFSET ;
/* this will not give any timing information during coding set as is */
}
else {
itersPerLoop = 4*PIDOFFSET ;
}
}
printf( "Calculating the " ) ;
if( forward ) {
printf( "forward DCT " ) ;
}
else {
printf( "inverse DCT " ) ;
}
printf( "for the image " ) ;
if( arm ) {
printf( "(ARM-based)" ) ;
}
else {
printf( "(C-based)" ) ;
}
printf( "...\n" ) ;
if( arm ) {
if( ( dctInArrayPtr = MakeDCTArrayPtr( numberBlocks ) ) == NULL ) {
fprintf( stderr, "\nError in memory allocation, aborting.\n\n" ) ;
return FALSE ;
}
if( ( dctOutArrayPtr = MakeDCTArrayPtr( numberBlocks ) ) == NULL ) {
fprintf( stderr, "\nError in memory allocation, aborting.\n\n" ) ;
free( ( void * ) dctInArrayPtr ) ;
return FALSE ;
}
blockIters = ( N * N )/( BLOCKSIZE * BLOCKSIZE ) ;
for( noBCounter = 0 ; noBCounter < blockIters ; noBCounter += numberBlocks ) {
blocksRemaining = numberBlocks ;
while( blocksRemaining ) {
totNumBlocks = noBCounter + ( numberBlocks - blocksRemaining ) ;
rowi = ( totNumBlocks / nDivBlock ) * BLOCKSIZE ;
columnj = ( totNumBlocks % nDivBlock ) * BLOCKSIZE ;
for( j = 0 ; j < BLOCKSIZE ; j += 1 ) {
for( i = 0 ; i < BLOCKSIZE ; i += 1 ) {
dctInArrayPtr[ numberBlocks - blocksRemaining ][ j ][ i ] = inIArray[ j + columnj ][ i + rowi ] ;
}
}
blocksRemaining -= 1 ;
if( gStatus[ 0 ] == '1' ) {
if( iterations%itersPerLoop == 0 ) {
if( iterations > 0 ) {
PrintIterationTimes( ( nDivBlock * nDivBlock ) - totNumBlocks, itersPerLoop, &timeStruct ) ;
}
else {
InitialiseTimeStructure( &timeStruct ) ;
}
}
iterations += 1 ;
}
}
if( forward ) {
if( !FDCTFast( dctInArrayPtr, dctOutArrayPtr, numberBlocks ) ) {
free( ( void * ) dctInArrayPtr ) ;
free( ( void * ) dctOutArrayPtr ) ;
return FALSE ;
}
}
else {
if( !RDCTFast( dctInArrayPtr, dctOutArrayPtr, numberBlocks ) ) {
free( ( void * ) dctInArrayPtr ) ;
free( ( void * ) dctOutArrayPtr ) ;
return FALSE ;
}
}
blocksRemaining = numberBlocks ;
while( blocksRemaining ) {
totNumBlocks = noBCounter + ( numberBlocks - blocksRemaining ) ;
rowi = ( totNumBlocks / nDivBlock ) * BLOCKSIZE ;
columnj = ( totNumBlocks % nDivBlock ) * BLOCKSIZE ;
for( j = 0 ; j < BLOCKSIZE ; j += 1 ) {
for( i = 0 ; i < BLOCKSIZE ; i += 1 ) {
outIArray[ j + columnj ][ i + rowi ] = dctOutArrayPtr[ numberBlocks - blocksRemaining ][ j ][ i ] ;
}
}
blocksRemaining -= 1 ;
}
}
free( ( void * ) dctInArrayPtr ) ;
free( ( void * ) dctOutArrayPtr ) ;
}
else {
DCTCosArrayInit( dctCosArray ) ;
for( jBlock = 0 ; jBlock < nDivBlock ; jBlock += 1 ) {
for( iBlock = 0 ; iBlock < nDivBlock ; iBlock += 1 ) {
rowi = iBlock * BLOCKSIZE ;
columnj = jBlock * BLOCKSIZE ;
for( j = 0 ; j < BLOCKSIZE ; j += 1 ) {
for( i = 0 ; i < BLOCKSIZE ; i += 1 ) {
dctIn[ j ][ i ] = inIArray[ j + columnj ][ i + rowi ] ;
}
}
if( gStatus[ 0 ] == '1' ) {
if( iterations%itersPerLoop == 0 ) {
if( iterations > 0 ) {
PrintIterationTimes( ( nDivBlock * nDivBlock ) - ( jBlock * nDivBlock + iBlock ), itersPerLoop, &timeStruct ) ;
}
else {
InitialiseTimeStructure( &timeStruct ) ;
}
}
iterations += 1 ;
}
if( forward ) {
FDCTReal( dctCosArray, dctIn, dctOut ) ;
}
else {
RDCTReal( dctCosArray, dctIn, dctOut ) ;
}
for( j = 0 ; j < BLOCKSIZE ; j += 1 ) {
for( i = 0 ; i < BLOCKSIZE ; i += 1 ) {
outIArray[ j + columnj ][ i + rowi ] = dctOut[ j ][ i ] ;
}
}
}
}
}
printf( "\nThe " ) ;
if( forward ) {
printf( "forward DCT " ) ;
}
else {
printf( "inverse DCT " ) ;
}
printf( "has been calculated.\n\n" ) ;
return TRUE ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -