📄 dcttestc.c
字号:
/*
* Discrete Cosine Transform test harness
* Copyright (C) ARM Limited 1998-1999. All rights reserved.
*/
#include <time.h>
#include "dctc.h"
#include "dcts.h"
#include "dcttestc.h"
#include "arrayc.h"
#include "custredc.h"
#include "errorc.h"
#include "fileutlc.h"
#include "optionsc.h"
#include "pgmc.h"
#include "printinc.h"
#include "timingc.h"
#define DCT_OPTIONS 6
#define PIDOFFSET 1
/* result printing adjustment for PID card */
/* for example, set to 4 for an ARM7TDMI PID card or 1 for ARMulator */
/* define global variables ('g' prefix) for user options */
static char gStatus[ LIMIT ] = "1" ;
static char gResults[ LIMIT ] = "1" ;
static unsigned int GetN( unsigned int width, unsigned int height ) ;
static unsigned int GetNumberBlocks( unsigned int N ) ;
static void Menu( unsigned int numberOptions ) ;
static void PerformOption( unsigned int option ) ;
static int SetMaxXYPosition( IArray iArray, unsigned int N, unsigned int *x, unsigned int *y ) ;
static Boolean Transform( IArray outIArray, IArray inIArray, unsigned int N, unsigned int numberBlocks, Boolean arm, Boolean forward ) ;
/**** Codec *************************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* perform the entire coding image from reading the users image in to performing both
* the forward dct immediately followed by the inverse dct, write the fully transformed
* image back to a users file, calculate error information and write an error image to
* to the users file
*
* all files are given by the user during the operations at run time
*
* a set of image data is printed to the screen after coding to show the results if
* the global option for users results printing has been set (the block printed is that
* which contains the maximum DCT value
*
* Inputs
* ------
* option
* - the coding option being performed (when to use ARM or C routines)
* pgmReadString
* - an optional string containing the operation that is be performed on the image
* to be non-specific pass NULL
* Return Values
* ------ ------
* TRUE - the coding operation and all file operations were successful
* FALSE - some error occurred, operations failed
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static Boolean Codec( unsigned int option, char *pgmReadString )
{
UCArray charIn ;
unsigned int width ;
unsigned int height ;
unsigned int N ;
IArray inIArray ;
IArray dctIArray ;
IArray idctIArray ;
UCArray charOut ;
IArray errIArray ;
UCArray charError ;
unsigned int i, j ;
unsigned int x, y ;
unsigned int procBeforeCoding ;
unsigned int procAfterCoding ;
unsigned int procTimeCoding ;
unsigned int procBeforeDecoding ;
unsigned int procAfterDecoding ;
unsigned int procTimeDecoding ;
unsigned int hrs, mins, secs ;
Boolean arm ;
int iCharOut ;
unsigned int maxAbsErr ;
unsigned int mse ;
unsigned int numberBlocks ;
if( ( charIn = ReadPGM( pgmReadString, &width, &height ) ) == NULL ) {
return FALSE ;
}
if( ( N = GetN( width, height ) ) == 0 ) {
FreeUCArray( charIn, N ) ;
return FALSE ;
}
inIArray = MakeIArray( N, N ) ;
dctIArray = MakeIArray( N, N ) ;
idctIArray = MakeIArray( N, N ) ;
charOut = MakeUCArray( N, N ) ;
errIArray = MakeIArray( N, N ) ;
charError = MakeUCArray( N, N ) ;
if( ( !inIArray ) ||
( !dctIArray ) ||
( !idctIArray ) ||
( !charOut ) ||
( !errIArray ) ||
( !charError ) ) {
/* FreeXArray aborts correctly if NULL, so just pass on and let FreeXArray check */
FreeUCArray( charIn, N ) ;
FreeIArray( inIArray, N ) ;
FreeIArray( dctIArray, N ) ;
FreeIArray( idctIArray, N ) ;
FreeUCArray( charOut, N ) ;
FreeIArray( errIArray, N ) ;
FreeUCArray( charError, N ) ;
return FALSE ;
}
for( j = 0; j < N; j += 1 ) {
for( i = 0; i < N; i += 1 ) {
inIArray[ j ][ i ] = ( int )charIn[ j ][ i ] ;
}
}
switch( option ) {
case 2 :
case 3 :
case 4 :
numberBlocks = GetNumberBlocks( N ) ;
break ;
default :
numberBlocks = 1 ;
break ;
}
printf( "Coding the image.\n\n" ) ;
switch( option ) {
case 2 :
case 4 :
arm = TRUE ;
break ;
case 1 :
case 3 :
default :
arm = FALSE ;
break ;
}
procBeforeCoding = clock( )/CLOCKS_PER_SEC ;
/* important that the clock retrieval is done either side of transformation so
that most accurate clock for actual coding is obtained */
if( !Transform( dctIArray, inIArray, N, numberBlocks, arm, TRUE ) ) {
FreeUCArray( charIn, N ) ;
FreeIArray( inIArray, N ) ;
FreeIArray( dctIArray, N ) ;
FreeIArray( idctIArray, N ) ;
FreeUCArray( charOut, N ) ;
FreeIArray( errIArray, N ) ;
FreeUCArray( charError, N ) ;
return FALSE ;
}
procAfterCoding = clock( )/CLOCKS_PER_SEC ;
SetMaxXYPosition( dctIArray, N, &x, &y ) ;
if( gResults[ 0 ] == '1' ) {
printf( "Position of maximum value in DCT array is (%d, %d)\n\n", x, y ) ;
}
x -= x%BLOCKSIZE ; /* want top left corner of block containing max */
y -= y%BLOCKSIZE ;
printf( "Decoding the image.\n\n" ) ;
switch( option ) {
case 2 :
case 3 :
arm = TRUE ;
break ;
case 1 :
case 4 :
default :
arm = FALSE ;
break ;
}
procBeforeDecoding = clock( )/CLOCKS_PER_SEC ;
if( !Transform( idctIArray, dctIArray, N, numberBlocks, arm, FALSE ) ) {
FreeUCArray( charIn, N ) ;
FreeIArray( inIArray, N ) ;
FreeIArray( dctIArray, N ) ;
FreeIArray( idctIArray, N ) ;
FreeUCArray( charOut, N ) ;
FreeIArray( errIArray, N ) ;
FreeUCArray( charError, N ) ;
return FALSE ;
}
procAfterDecoding = clock( )/CLOCKS_PER_SEC ;
if( procBeforeCoding != -1 ) { /* clock not available if -1 */
procTimeCoding = procAfterCoding - procBeforeCoding ;
GetHrsMinsSecs( procTimeCoding, &hrs, &mins, &secs ) ;
printf( "The time to code the image was %d hrs %d mins %d secs\n\n", hrs, mins, secs ) ;
procTimeDecoding = procAfterDecoding - procBeforeDecoding ;
GetHrsMinsSecs( procTimeDecoding, &hrs, &mins, &secs ) ;
printf( "The time to decode the image was %d hrs %d mins %d secs\n\n", hrs, mins, secs ) ;
GetHrsMinsSecs( procTimeCoding + procTimeDecoding, &hrs, &mins, &secs ) ;
printf( "The total time to code/decode the image was %d hrs %d mins %d secs\n\n", hrs, mins, secs ) ;
}
for( j = 0 ; j < N ; j += 1 ) {
for( i = 0 ; i < N ; i += 1 ) {
iCharOut = idctIArray[ j ][ i ] ;
if( iCharOut < 0 ) {
iCharOut = 0 ;
}
else if( iCharOut > 255 ) {
iCharOut = 255 ;
}
charOut[ j ][ i ] = ( unsigned char )iCharOut ;
}
}
while( !WritePGM( charOut, N, N, "transformed" ) ) ;
ARRAYERROR2D( inIArray, idctIArray, errIArray, N, N, maxAbsErr, mse, int ) ;
printf( "Maximum absolute error value calculated as '%d'\n\n", maxAbsErr ) ;
printf( "The mean squared error between the original and decoded images is '%d'\n\n", mse ) ;
if( gResults[ 0 ] == '1' ) {
printf( "Calculating error image information...\n\n" ) ;
}
for( j = 0 ; j < N ; j += 1 ) {
for( i = 0 ; i < N ; i += 1 ) {
/* move all values to range 0..255 */
charError[ j ][ i ] = ( unsigned char )( ( int )( ( ( ( float )( abs( errIArray[ j ][ i ] ) ) )/( ( float ) maxAbsErr ) ) * 255.0 ) ) ;
}
}
while( !WritePGM( charError, N, N, "error" ) ) ;
if( gResults[ 0 ] == '1' ) {
printf( "The block printouts for each stage refer to the block with DC at (%d, %d).\n", x, y ) ;
PRINTARRAY2D( charIn, x, BLOCKSIZE, y, BLOCKSIZE, CHA, BLOCKSIZE,
"The original 'character' image.\nNOTE: some characters are invisible, one causes the system bell to sound" ) ;
PRINTARRAY2D( inIArray, x, BLOCKSIZE, y, BLOCKSIZE, INT, BLOCKSIZE, "The 'character' image as 'int's" ) ;
PRINTARRAY2D( dctIArray, x, BLOCKSIZE, y, BLOCKSIZE, INT, BLOCKSIZE, "The DCT of the 'int' image" ) ;
PRINTARRAY2D( idctIArray, x, BLOCKSIZE, y, BLOCKSIZE, INT, BLOCKSIZE, "The IDCT image (back to image as 'int's)" ) ;
PRINTARRAY2D( charOut, x, BLOCKSIZE, y, BLOCKSIZE, CHA, BLOCKSIZE,
"The final 'character' image.\nNOTE: some characters are invisible, one causes the system bell to sound" ) ;
PRINTARRAY2D( charError, x, BLOCKSIZE, y, BLOCKSIZE, CHA, BLOCKSIZE,
"The 'error' image.\nNOTE: some characters are invisible, one causes the system bell to sound" ) ;
}
FreeUCArray( charIn, N ) ;
FreeIArray( inIArray, N ) ;
FreeIArray( dctIArray, N ) ;
FreeIArray( idctIArray, N ) ;
FreeUCArray( charOut, N ) ;
FreeIArray( errIArray, N ) ;
FreeUCArray( charError, N ) ;
return TRUE ;
}
/**** dct_main **********************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* initialise the application then loop whilst the user is still working
*
* Return Values
* ------ ------
* 0 - application terminated correctly
* 1 - some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
int dct_main( int argc, char **argv )
{
unsigned int option ;
char newStdIn[ ] = "stdin" ;
char newStdOut[ ] = "stdout" ;
char newStdErr[ ] = "stderr" ;
unsigned int stdio = 0 ;
if( ChangeStdIO( &argc, &argv, newStdIn, stdin ) == STDINID ) {
stdio |= ( 1 << STDINID ) ;
}
if( ChangeStdIO( &argc, &argv, newStdOut, stdout ) == STDOUTID ) {
stdio |= ( 1 << STDOUTID ) ;
}
if( ChangeStdIO( &argc, &argv, newStdErr, stderr ) == STDERRID ) {
stdio |= ( 1 << STDERRID ) ;
}
printf( "A program to code still images in 'pgm' format.\n\n" ) ;
printf( "The coding operation is carried out using the Discrete Cosine Transform.\n\n" ) ;
printf( "The block size used in the DCT is 8 x 8.\n\n" ) ;
printf( "There are two 'options' available:\n\n" ) ;
printf( "1. Status messages can be given to display the codec's process.\n" ) ;
printf( " These identify the current process being performed on the image,\n" ) ;
printf( " however, the coding/decoding process will take more time.\n" ) ;
printf( "2. The block with the maximum DCT value can be used to display results at\n" ) ;
printf( " the end of the coding process and how the image has been affected.\n\n" ) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -