📄 348-351.html
字号:
<!DOCTYPE HTML PUBLIC "html.dtd"><HTML><HEAD><TITLE>The Data Compression Book-:Lossy Graphics Compression</TITLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><SCRIPT><!--function displayWindow(url, width, height) { var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes');}//--></SCRIPT></HEAD><BODY BGCOLOR="#FFFFFF" VLINK="#DD0000" TEXT="#000000" LINK="#DD0000" ALINK="#FF0000"><TD WIDTH="540" VALIGN="TOP"><!-- <CENTER><TABLE><TR><TD><FORM METHOD="GET" ACTION="http://search.itknowledge.com/excite/cgi-bin/AT-foldocsearch.cgi"><INPUT NAME="search" SIZE="20" VALUE=""><BR><CENTER><INPUT NAME="searchButton" TYPE="submit" VALUE="Glossary Search"></CENTER><INPUT NAME="source" TYPE="hidden" VALUE="local" CHECKED> <INPUT NAME="bltext" TYPE="hidden" VALUE="Back to Search"><INPUT NAME="sp" TYPE="hidden" VALUE="sp"></FORM></TD><TD><IMG SRC="http://www.itknowledge.com/images/dotclear.gif" WIDTH="15" HEIGHT="1"></TD><TD><FORM METHOD="POST" ACTION="http://search.itknowledge.com/excite/cgi-bin/AT-subscriptionsearch.cgi"><INPUT NAME="search" SIZE="20" VALUE=""><BR><CENTER><INPUT NAME="searchButton" TYPE="submit" VALUE=" Book Search "></CENTER><INPUT NAME="source" TYPE="hidden" VALUE="local" CHECKED> <INPUT NAME="backlink" TYPE="hidden" VALUE="http://search.itknowledge.com:80/excite/AT-subscriptionquery.html"><INPUT NAME="bltext" TYPE="hidden" VALUE="Back to Search"><INPUT NAME="sp" TYPE="hidden" VALUE="sp"></FORM></TD></TR></TABLE></CENTER> --><!-- ISBN=1558514341//--><!-- TITLE=The Data Compression Book-//--><!-- AUTHOR=Mark Nelson//--><!-- PUBLISHER=IDG Books Worldwide, Inc.//--><!-- IMPRINT=M & T Books//--><!-- CHAPTER=11//--><!-- PAGES=348-351//--><!-- UNASSIGNED1//--><!-- UNASSIGNED2//--><CENTER><TABLE BORDER><TR><TD><A HREF="344-348.html">Previous</A></TD><TD><A HREF="../ewtoc.html">Table of Contents</A></TD><TD><A HREF="351-355.html">Next</A></TD></TR></TABLE></CENTER><P><BR></P><H4 ALIGN="LEFT"><A NAME="Heading25"></A><FONT COLOR="#000077">Initialization</FONT></H4><P>DCT.C has single initialization routine that is called for both compression and expansion. It first sets up the quantization matrix, using the quality parameter passed to it. This uses the simple formula for defining step sizes discussed earlier.</P><P>Once the quantization matrix is set up, the next step is to set up the cosine transform matrix and the transposed cosine transform matrix These matrices are used by the forward DCT and the inverse DCT, so they can be set up in a common routine. Setting them up involves nothing more than a simple translation of the formula shown in Figure 11.8.</P><P>The final step in initialization is to initialize the run-length encoding counters used on input and output. These values are used when either outputting or inputting codes, and they track the number of consecutive zero codes that have output or will be input.</P><!-- CODE //--><PRE> void Initialize( int quality ) { int i; int j; for ( i = 0 ; i < N ; i++ ) for (j = 0 ; j < N ; j++ ) Quantum[ i ][ j ] = 1 + ( ( 1 + i + j ) * quality ); for ( j = 0 ; j < N ; j++ ) { C[ 0 ][ j ] = 1.0 / sqrt( N ); Ct[ j ][ 0 ] = C[ 0 ][ j ]; } for ( i = 1 ; i < N ; i++ ) { for ( j = 0 ; j < N ; j++ ) { C[ i ][ j ] = sqrt( 2.0 / N ) * cos( ( 2 * j + 1 ) * i * pi / ( 2.0 * N ) ) ; Ct[ j ][ i ] = C[ i ][ j ]; } } OutputRunLength = 0; InputRunLength = 0; }</PRE><!-- END CODE //--><H4 ALIGN="LEFT"><A NAME="Heading26"></A><FONT COLOR="#000077">The Forward DCT Routine</FONT></H4><P>Despite the seeming complexity of the DCT, it is accomplished in a very short routine. All it does is first perform a matrix multiplication of the input pixel data matrix by the transposed cosine transform matrix and store the result in a temporary N-by-N matrix. Then the temporary matrix is multiplied by the cosine transform matrix, and the result is stored in the output matrix, which is passed back to the caller.</P><P>Note here that all input pixel values are scaled before being multiplied by the transposed cosine transform matrix. After being scaled, they have a range of -128 to 127 instead of the zero to 255 range they had before. This is consistent with the way the JPEG algorithm handles input data.</P><!-- CODE //--><PRE> void ForwardDCT( input, output ) unsigned char *input[ N ]; int output[ N ][ N ]; { double temp[ N ][ N ]; double temp1; int i; int j; int k; /*MatrixMultiply( temp, input, Ct ); */ for ( i = 0 ; i < N ; i++ ) { for ( j = 0 ; j < N ; j++ ) { temp[ i ][ j ] = 0.0; for ( k = 0 ; k < N ; k++ ) temp[ i ][ j ] += ( input[ i ][ k ] - 128 ) * Ct[ k ] [ j ]; } } /*MatrixMultiply( output, C, temp ); */ for ( i = 0 ; i < N ; i++ ) { for ( j = 0 ; j < N ; j++ ) { temp1 = 0.0; for ( k = 0 ; k < N ; k++ ) temp1 += C[ i ][ k ] * temp[ k ][ j ]; output[ i ][ j ] = ROUND( temp1 ); } } }</PRE><!-- END CODE //--><P>Another point to observe is that we are dealing with several different data types here and a certain amount of care needs to be exercised so as not to cause problems during conversions. The input data coming from the pixel strip is unsigned character converted during the matrix multiplication to integer, then multiplied by a double. The result is stored in a double temporary matrix. Finally, the last matrix multiplication produces double values, which are then rounded to integers for storage in the output matrix. If everything goes as planned, the integers should be in the range of -1,024 to 1,023, and they are ready for quantization.</P><H4 ALIGN="LEFT"><A NAME="Heading27"></A><FONT COLOR="#000077">WriteDCTData()</FONT></H4><P>This routine is responsible for ordering the DCT result matrix into the zigzag pattern, then quantizing the data. Both of these just involve table lookups of values that have been stored either during initialization or at compile time. Then, the quantized value is rounded to the nearest integer and sent to the routine that outputs codes.</P><!-- CODE //--><PRE> void WriteDCTData( BIT_FILE *output_file, output_data[ N ][ N ] ) { int i; int row; int col; double result; for ( i = 0 ; i < ( N * N ) ; i++ ) { row = ZigZag[ i ].row; col = ZigZag[ i ].col; result = output_data[ row ][ col ] / Quantum[ row ][ col ]; OutputCode( output_file, ROUND( result ) ); } }</PRE><!-- END CODE //--><P><BR></P><CENTER><TABLE BORDER><TR><TD><A HREF="344-348.html">Previous</A></TD><TD><A HREF="../ewtoc.html">Table of Contents</A></TD><TD><A HREF="351-355.html">Next</A></TD></TR></TABLE></CENTER></TD></TR></TABLE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -