Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > dabb57319acb4393549d883bdd5bc220 > files > 131

libgdal0-devel-1.1.8-2mdk.ppc.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta name="robots" content="noindex">
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>overview.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body bgcolor="#ffffff">
<!-- Generated by Doxygen 1.2.3-20001105 on Sat Dec 21 14:02:00 2002 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="hierarchy.html">Class Hierarchy</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>overview.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/******************************************************************************</font>
00002 <font class="comment"> * $Id: overview_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $</font>
00003 <font class="comment"> *</font>
00004 <font class="comment"> * Project:  GDAL Core</font>
00005 <font class="comment"> * Purpose:  Helper code to implement overview support in different drivers.</font>
00006 <font class="comment"> * Author:   Frank Warmerdam, warmerda@home.com</font>
00007 <font class="comment"> *</font>
00008 <font class="comment"> ******************************************************************************</font>
00009 <font class="comment"> * Copyright (c) 2000, Frank Warmerdam</font>
00010 <font class="comment"> *</font>
00011 <font class="comment"> * Permission is hereby granted, free of charge, to any person obtaining a</font>
00012 <font class="comment"> * copy of this software and associated documentation files (the "Software"),</font>
00013 <font class="comment"> * to deal in the Software without restriction, including without limitation</font>
00014 <font class="comment"> * the rights to use, copy, modify, merge, publish, distribute, sublicense,</font>
00015 <font class="comment"> * and/or sell copies of the Software, and to permit persons to whom the</font>
00016 <font class="comment"> * Software is furnished to do so, subject to the following conditions:</font>
00017 <font class="comment"> *</font>
00018 <font class="comment"> * The above copyright notice and this permission notice shall be included</font>
00019 <font class="comment"> * in all copies or substantial portions of the Software.</font>
00020 <font class="comment"> *</font>
00021 <font class="comment"> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS</font>
00022 <font class="comment"> * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</font>
00023 <font class="comment"> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL</font>
00024 <font class="comment"> * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</font>
00025 <font class="comment"> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING</font>
00026 <font class="comment"> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER</font>
00027 <font class="comment"> * DEALINGS IN THE SOFTWARE.</font>
00028 <font class="comment"> ******************************************************************************</font>
00029 <font class="comment"> *</font>
00030 <font class="comment"> * $Log: overview_cpp-source.html,v $
00030 <font class="comment"> * Revision 1.13  2002/12/21 19:13:13  warmerda
00030 <font class="comment"> * updated
00030 <font class="comment"> *</font>
00031 <font class="comment"> * Revision 1.10  2002/07/09 20:33:12  warmerda</font>
00032 <font class="comment"> * expand tabs</font>
00033 <font class="comment"> *</font>
00034 <font class="comment"> * Revision 1.9  2002/04/16 17:49:29  warmerda</font>
00035 <font class="comment"> * Ensure dfRatio is assigned a value.</font>
00036 <font class="comment"> *</font>
00037 <font class="comment"> * Revision 1.8  2001/07/18 04:04:30  warmerda</font>
00038 <font class="comment"> * added CPL_CVSID</font>
00039 <font class="comment"> *</font>
00040 <font class="comment"> * Revision 1.7  2001/07/16 15:21:46  warmerda</font>
00041 <font class="comment"> * added AVERAGE_MAGPHASE option for complex images</font>
00042 <font class="comment"> *</font>
00043 <font class="comment"> * Revision 1.6  2001/01/30 22:32:42  warmerda</font>
00044 <font class="comment"> * added AVERAGE_MP (magnitude preserving averaging) overview resampling type</font>
00045 <font class="comment"> *</font>
00046 <font class="comment"> * Revision 1.5  2000/11/22 18:41:45  warmerda</font>
00047 <font class="comment"> * fixed bug in complex overview generation</font>
00048 <font class="comment"> *</font>
00049 <font class="comment"> * Revision 1.4  2000/08/18 15:25:06  warmerda</font>
00050 <font class="comment"> * added cascading overview regeneration to speed up averaged overviews</font>
00051 <font class="comment"> *</font>
00052 <font class="comment"> * Revision 1.3  2000/07/17 17:08:45  warmerda</font>
00053 <font class="comment"> * added support for complex data</font>
00054 <font class="comment"> *</font>
00055 <font class="comment"> * Revision 1.2  2000/06/26 22:17:58  warmerda</font>
00056 <font class="comment"> * added scaled progress support</font>
00057 <font class="comment"> *</font>
00058 <font class="comment"> * Revision 1.1  2000/04/21 21:54:05  warmerda</font>
00059 <font class="comment"> * New</font>
00060 <font class="comment"> *</font>
00061 <font class="comment"> */</font>
00062 
00063 <font class="preprocessor">#include "gdal_priv.h"</font>
00064 
00065 CPL_CVSID(<font class="stringliteral">"$Id: overview_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $"</font>);
00066 
00067 <font class="comment">/************************************************************************/</font>
00068 <font class="comment">/*                       GDALDownsampleChunk32R()                       */</font>
00069 <font class="comment">/************************************************************************/</font>
00070 
00071 <font class="keyword">static</font> CPLErr
00072 GDALDownsampleChunk32R( <font class="keywordtype">int</font> nSrcWidth, <font class="keywordtype">int</font> nSrcHeight, 
00073                         <font class="keywordtype">float</font> * pafChunk, <font class="keywordtype">int</font> nChunkYOff, <font class="keywordtype">int</font> nChunkYSize,
00074                         <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> * poOverview,
00075                         <font class="keyword">const</font> <font class="keywordtype">char</font> * pszResampling )<font class="keyword"></font>
00076 <font class="keyword"></font>
00077 <font class="keyword"></font>{
00078     <font class="keywordtype">int</font>      nDstYOff, nDstYOff2, nOXSize, nOYSize;
00079     <font class="keywordtype">float</font>    *pafDstScanline;
00080 
00081     nOXSize = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>();
00082     nOYSize = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>();
00083 
00084     pafDstScanline = (<font class="keywordtype">float</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nOXSize * <font class="keyword">sizeof</font>(<font class="keywordtype">float</font>));
00085 
00086 <font class="comment">/* -------------------------------------------------------------------- */</font>
00087 <font class="comment">/*      Figure out the line to start writing to, and the first line     */</font>
00088 <font class="comment">/*      to not write to.  In theory this approach should ensure that    */</font>
00089 <font class="comment">/*      every output line will be written if all input chunks are       */</font>
00090 <font class="comment">/*      processed.                                                      */</font>
00091 <font class="comment">/* -------------------------------------------------------------------- */</font>
00092     nDstYOff = (<font class="keywordtype">int</font>) (0.5 + (nChunkYOff/(<font class="keywordtype">double</font>)nSrcHeight) * nOYSize);
00093     nDstYOff2 = (<font class="keywordtype">int</font>) 
00094         (0.5 + ((nChunkYOff+nChunkYSize)/(<font class="keywordtype">double</font>)nSrcHeight) * nOYSize);
00095 
00096     <font class="keywordflow">if</font>( nChunkYOff + nChunkYSize == nSrcHeight )
00097         nDstYOff2 = nOYSize;
00098     
00099 <font class="comment">/* ==================================================================== */</font>
00100 <font class="comment">/*      Loop over destination scanlines.                                */</font>
00101 <font class="comment">/* ==================================================================== */</font>
00102     <font class="keywordflow">for</font>( <font class="keywordtype">int</font> iDstLine = nDstYOff; iDstLine &lt; nDstYOff2; iDstLine++ )
00103     {
00104         <font class="keywordtype">float</font> *pafSrcScanline;
00105         <font class="keywordtype">int</font>   nSrcYOff, nSrcYOff2, iDstPixel;
00106 
00107         nSrcYOff = (<font class="keywordtype">int</font>) (0.5 + (iDstLine/(<font class="keywordtype">double</font>)nOYSize) * nSrcHeight);
00108         <font class="keywordflow">if</font>( nSrcYOff &lt; nChunkYOff )
00109             nSrcYOff = nChunkYOff;
00110         
00111         nSrcYOff2 = (<font class="keywordtype">int</font>) (0.5 + ((iDstLine+1)/(<font class="keywordtype">double</font>)nOYSize) * nSrcHeight);
00112         <font class="keywordflow">if</font>( nSrcYOff2 &gt; nSrcHeight || iDstLine == nOYSize-1 )
00113             nSrcYOff2 = nSrcHeight;
00114         <font class="keywordflow">if</font>( nSrcYOff2 &gt; nChunkYOff + nChunkYSize )
00115             nSrcYOff2 = nChunkYOff + nChunkYSize;
00116 
00117         pafSrcScanline = pafChunk + ((nSrcYOff-nChunkYOff) * nSrcWidth);
00118 
00119 <font class="comment">/* -------------------------------------------------------------------- */</font>
00120 <font class="comment">/*      Loop over destination pixels                                    */</font>
00121 <font class="comment">/* -------------------------------------------------------------------- */</font>
00122         <font class="keywordflow">for</font>( iDstPixel = 0; iDstPixel &lt; nOXSize; iDstPixel++ )
00123         {
00124             <font class="keywordtype">int</font>   nSrcXOff, nSrcXOff2;
00125 
00126             nSrcXOff = (<font class="keywordtype">int</font>) (0.5 + (iDstPixel/(<font class="keywordtype">double</font>)nOXSize) * nSrcWidth);
00127             nSrcXOff2 = (<font class="keywordtype">int</font>) 
00128                 (0.5 + ((iDstPixel+1)/(<font class="keywordtype">double</font>)nOXSize) * nSrcWidth);
00129             <font class="keywordflow">if</font>( nSrcXOff2 &gt; nSrcWidth )
00130                 nSrcXOff2 = nSrcWidth;
00131             
00132             <font class="keywordflow">if</font>( EQUALN(pszResampling,<font class="stringliteral">"NEAR"</font>,4) )
00133             {
00134                 pafDstScanline[iDstPixel] = pafSrcScanline[nSrcXOff];
00135             }
00136             <font class="keywordflow">else</font> <font class="keywordflow">if</font>( EQUALN(pszResampling,<font class="stringliteral">"AVER"</font>,4) )
00137             {
00138                 <font class="keywordtype">double</font> dfTotal = 0.0;
00139                 <font class="keywordtype">int</font>    nCount = 0, iX, iY;
00140 
00141                 <font class="keywordflow">for</font>( iY = nSrcYOff; iY &lt; nSrcYOff2; iY++ )
00142                  {
00143                     <font class="keywordflow">for</font>( iX = nSrcXOff; iX &lt; nSrcXOff2; iX++ )
00144                     {
00145                         dfTotal += pafSrcScanline[iX+(iY-nSrcYOff)*nSrcWidth];
00146                         nCount++;
00147                     }
00148                 }
00149                 
00150                 CPLAssert( nCount &gt; 0 );
00151                 <font class="keywordflow">if</font>( nCount == 0 )
00152                 {
00153                     pafDstScanline[iDstPixel] = 0.0;
00154                 }
00155                 <font class="keywordflow">else</font>
00156                     pafDstScanline[iDstPixel] = dfTotal / nCount;
00157             }
00158         }
00159 
00160         poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a9">RasterIO</a>( GF_Write, 0, iDstLine, nOXSize, 1, 
00161                               pafDstScanline, nOXSize, 1, GDT_Float32, 
00162                               0, 0 );
00163     }
00164 
00165     CPLFree( pafDstScanline );
00166 
00167     <font class="keywordflow">return</font> CE_None;
00168 }
00169 
00170 <font class="comment">/************************************************************************/</font>
00171 <font class="comment">/*                       GDALDownsampleChunkC32R()                      */</font>
00172 <font class="comment">/************************************************************************/</font>
00173 
00174 <font class="keyword">static</font> CPLErr
00175 GDALDownsampleChunkC32R( <font class="keywordtype">int</font> nSrcWidth, <font class="keywordtype">int</font> nSrcHeight, 
00176                          <font class="keywordtype">float</font> * pafChunk, <font class="keywordtype">int</font> nChunkYOff, <font class="keywordtype">int</font> nChunkYSize,
00177                          <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> * poOverview,
00178                          <font class="keyword">const</font> <font class="keywordtype">char</font> * pszResampling )<font class="keyword"></font>
00179 <font class="keyword">    </font>
00180 <font class="keyword"></font>{
00181     <font class="keywordtype">int</font>      nDstYOff, nDstYOff2, nOXSize, nOYSize;
00182     <font class="keywordtype">float</font>    *pafDstScanline;
00183 
00184     nOXSize = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>();
00185     nOYSize = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>();
00186 
00187     pafDstScanline = (<font class="keywordtype">float</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nOXSize * <font class="keyword">sizeof</font>(<font class="keywordtype">float</font>) * 2);
00188 
00189 <font class="comment">/* -------------------------------------------------------------------- */</font>
00190 <font class="comment">/*      Figure out the line to start writing to, and the first line     */</font>
00191 <font class="comment">/*      to not write to.  In theory this approach should ensure that    */</font>
00192 <font class="comment">/*      every output line will be written if all input chunks are       */</font>
00193 <font class="comment">/*      processed.                                                      */</font>
00194 <font class="comment">/* -------------------------------------------------------------------- */</font>
00195     nDstYOff = (<font class="keywordtype">int</font>) (0.5 + (nChunkYOff/(<font class="keywordtype">double</font>)nSrcHeight) * nOYSize);
00196     nDstYOff2 = (<font class="keywordtype">int</font>) 
00197         (0.5 + ((nChunkYOff+nChunkYSize)/(<font class="keywordtype">double</font>)nSrcHeight) * nOYSize);
00198 
00199     <font class="keywordflow">if</font>( nChunkYOff + nChunkYSize == nSrcHeight )
00200         nDstYOff2 = nOYSize;
00201     
00202 <font class="comment">/* ==================================================================== */</font>
00203 <font class="comment">/*      Loop over destination scanlines.                                */</font>
00204 <font class="comment">/* ==================================================================== */</font>
00205     <font class="keywordflow">for</font>( <font class="keywordtype">int</font> iDstLine = nDstYOff; iDstLine &lt; nDstYOff2; iDstLine++ )
00206     {
00207         <font class="keywordtype">float</font> *pafSrcScanline;
00208         <font class="keywordtype">int</font>   nSrcYOff, nSrcYOff2, iDstPixel;
00209 
00210         nSrcYOff = (<font class="keywordtype">int</font>) (0.5 + (iDstLine/(<font class="keywordtype">double</font>)nOYSize) * nSrcHeight);
00211         <font class="keywordflow">if</font>( nSrcYOff &lt; nChunkYOff )
00212             nSrcYOff = nChunkYOff;
00213         
00214         nSrcYOff2 = (<font class="keywordtype">int</font>) (0.5 + ((iDstLine+1)/(<font class="keywordtype">double</font>)nOYSize) * nSrcHeight);
00215         <font class="keywordflow">if</font>( nSrcYOff2 &gt; nSrcHeight || iDstLine == nOYSize-1 )
00216             nSrcYOff2 = nSrcHeight;
00217         <font class="keywordflow">if</font>( nSrcYOff2 &gt; nChunkYOff + nChunkYSize )
00218             nSrcYOff2 = nChunkYOff + nChunkYSize;
00219 
00220         pafSrcScanline = pafChunk + ((nSrcYOff-nChunkYOff) * nSrcWidth) * 2;
00221 
00222 <font class="comment">/* -------------------------------------------------------------------- */</font>
00223 <font class="comment">/*      Loop over destination pixels                                    */</font>
00224 <font class="comment">/* -------------------------------------------------------------------- */</font>
00225         <font class="keywordflow">for</font>( iDstPixel = 0; iDstPixel &lt; nOXSize; iDstPixel++ )
00226         {
00227             <font class="keywordtype">int</font>   nSrcXOff, nSrcXOff2;
00228 
00229             nSrcXOff = (<font class="keywordtype">int</font>) (0.5 + (iDstPixel/(<font class="keywordtype">double</font>)nOXSize) * nSrcWidth);
00230             nSrcXOff2 = (<font class="keywordtype">int</font>) 
00231                 (0.5 + ((iDstPixel+1)/(<font class="keywordtype">double</font>)nOXSize) * nSrcWidth);
00232             <font class="keywordflow">if</font>( nSrcXOff2 &gt; nSrcWidth )
00233                 nSrcXOff2 = nSrcWidth;
00234             
00235             <font class="keywordflow">if</font>( EQUALN(pszResampling,<font class="stringliteral">"NEAR"</font>,4) )
00236             {
00237                 pafDstScanline[iDstPixel*2] = pafSrcScanline[nSrcXOff*2];
00238                 pafDstScanline[iDstPixel*2+1] = pafSrcScanline[nSrcXOff*2+1];
00239             }
00240             <font class="keywordflow">else</font> <font class="keywordflow">if</font>( EQUAL(pszResampling,<font class="stringliteral">"AVERAGE_MAGPHASE"</font>) )
00241             {
00242                 <font class="keywordtype">double</font> dfTotalR = 0.0, dfTotalI = 0.0, dfTotalM = 0.0;
00243                 <font class="keywordtype">int</font>    nCount = 0, iX, iY;
00244 
00245                 <font class="keywordflow">for</font>( iY = nSrcYOff; iY &lt; nSrcYOff2; iY++ )
00246                 {
00247                     <font class="keywordflow">for</font>( iX = nSrcXOff; iX &lt; nSrcXOff2; iX++ )
00248                     {
00249                         <font class="keywordtype">double</font>  dfR, dfI;
00250 
00251                         dfR = pafSrcScanline[iX*2+(iY-nSrcYOff)*nSrcWidth*2];
00252                         dfI = pafSrcScanline[iX*2+(iY-nSrcYOff)*nSrcWidth*2+1];
00253                         dfTotalR += dfR;
00254                         dfTotalI += dfI;
00255                         dfTotalM += sqrt( dfR*dfR + dfI*dfI );
00256                         nCount++;
00257                     }
00258                 }
00259                 
00260                 CPLAssert( nCount &gt; 0 );
00261                 <font class="keywordflow">if</font>( nCount == 0 )
00262                 {
00263                     pafDstScanline[iDstPixel*2] = 0.0;
00264                     pafDstScanline[iDstPixel*2+1] = 0.0;
00265                 }
00266                 <font class="keywordflow">else</font>
00267                 {
00268                     <font class="keywordtype">double</font>      dfM, dfDesiredM, dfRatio=1.0;
00269 
00270                     pafDstScanline[iDstPixel*2  ] = dfTotalR / nCount;
00271                     pafDstScanline[iDstPixel*2+1] = dfTotalI / nCount;
00272                     
00273                     dfM = sqrt(pafDstScanline[iDstPixel*2  ]*pafDstScanline[iDstPixel*2  ]
00274                              + pafDstScanline[iDstPixel*2+1]*pafDstScanline[iDstPixel*2+1]);
00275                     dfDesiredM = dfTotalM / nCount;
00276                     <font class="keywordflow">if</font>( dfM != 0.0 )
00277                         dfRatio = dfDesiredM / dfM;
00278 
00279                     pafDstScanline[iDstPixel*2  ] *= dfRatio;
00280                     pafDstScanline[iDstPixel*2+1] *= dfRatio;
00281                 }
00282             }
00283             <font class="keywordflow">else</font> <font class="keywordflow">if</font>( EQUALN(pszResampling,<font class="stringliteral">"AVER"</font>,4) )
00284             {
00285                 <font class="keywordtype">double</font> dfTotalR = 0.0, dfTotalI = 0.0;
00286                 <font class="keywordtype">int</font>    nCount = 0, iX, iY;
00287 
00288                 <font class="keywordflow">for</font>( iY = nSrcYOff; iY &lt; nSrcYOff2; iY++ )
00289                 {
00290                     <font class="keywordflow">for</font>( iX = nSrcXOff; iX &lt; nSrcXOff2; iX++ )
00291                     {
00292                         dfTotalR += pafSrcScanline[iX*2+(iY-nSrcYOff)*nSrcWidth*2];
00293                         dfTotalI += pafSrcScanline[iX*2+(iY-nSrcYOff)*nSrcWidth*2+1];
00294                         nCount++;
00295                     }
00296                 }
00297                 
00298                 CPLAssert( nCount &gt; 0 );
00299                 <font class="keywordflow">if</font>( nCount == 0 )
00300                 {
00301                     pafDstScanline[iDstPixel*2] = 0.0;
00302                     pafDstScanline[iDstPixel*2+1] = 0.0;
00303                 }
00304                 <font class="keywordflow">else</font>
00305                 {
00306                     pafDstScanline[iDstPixel*2  ] = dfTotalR / nCount;
00307                     pafDstScanline[iDstPixel*2+1] = dfTotalI / nCount;
00308                 }
00309             }
00310         }
00311 
00312         poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a9">RasterIO</a>( GF_Write, 0, iDstLine, nOXSize, 1, 
00313                               pafDstScanline, nOXSize, 1, GDT_CFloat32, 
00314                               0, 0 );
00315     }
00316 
00317     CPLFree( pafDstScanline );
00318 
00319     <font class="keywordflow">return</font> CE_None;
00320 }
00321 
00322 <font class="comment">/************************************************************************/</font>
00323 <font class="comment">/*                  GDALRegenerateCascadingOverviews()                  */</font>
00324 <font class="comment">/*                                                                      */</font>
00325 <font class="comment">/*      Generate a list of overviews in order from largest to           */</font>
00326 <font class="comment">/*      smallest, computing each from the next larger.                  */</font>
00327 <font class="comment">/************************************************************************/</font>
00328 
00329 <font class="keyword">static</font> CPLErr
00330 GDALRegenerateCascadingOverviews( 
00331     <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *poSrcBand, <font class="keywordtype">int</font> nOverviews, <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> **papoOvrBands, 
00332     <font class="keyword">const</font> <font class="keywordtype">char</font> * pszResampling, 
00333     GDALProgressFunc pfnProgress, <font class="keywordtype">void</font> * pProgressData )<font class="keyword"></font>
00334 <font class="keyword"></font>
00335 <font class="keyword"></font>{
00336 <font class="comment">/* -------------------------------------------------------------------- */</font>
00337 <font class="comment">/*      First, we must put the overviews in order from largest to       */</font>
00338 <font class="comment">/*      smallest.                                                       */</font>
00339 <font class="comment">/* -------------------------------------------------------------------- */</font>
00340     <font class="keywordtype">int</font>   i, j;
00341 
00342     <font class="keywordflow">for</font>( i = 0; i &lt; nOverviews-1; i++ )
00343     {
00344         <font class="keywordflow">for</font>( j = 0; j &lt; nOverviews - i - 1; j++ )
00345         {
00346 
00347             <font class="keywordflow">if</font>( papoOvrBands[j]-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>() 
00348                 * (<font class="keywordtype">float</font>) papoOvrBands[j]-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>() &lt;
00349                 papoOvrBands[j+1]-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>()
00350                 * (<font class="keywordtype">float</font>) papoOvrBands[j+1]-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>() )
00351             {
00352                 <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> * poTempBand;
00353 
00354                 poTempBand = papoOvrBands[j];
00355                 papoOvrBands[j] = papoOvrBands[j+1];
00356                 papoOvrBands[j+1] = poTempBand;
00357             }
00358         }
00359     }
00360 
00361 <font class="comment">/* -------------------------------------------------------------------- */</font>
00362 <font class="comment">/*      Count total pixels so we can prepare appropriate scaled         */</font>
00363 <font class="comment">/*      progress functions.                                             */</font>
00364 <font class="comment">/* -------------------------------------------------------------------- */</font>
00365     <font class="keywordtype">double</font>       dfTotalPixels = 0.0;
00366 
00367     <font class="keywordflow">for</font>( i = 0; i &lt; nOverviews; i++ )
00368     {
00369         dfTotalPixels += papoOvrBands[i]-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>()
00370             * (<font class="keywordtype">double</font>) papoOvrBands[i]-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>();
00371     }
00372 
00373 <font class="comment">/* -------------------------------------------------------------------- */</font>
00374 <font class="comment">/*      Generate all the bands.                                         */</font>
00375 <font class="comment">/* -------------------------------------------------------------------- */</font>
00376     <font class="keywordtype">double</font>      dfPixelsProcessed = 0.0;
00377 
00378     <font class="keywordflow">for</font>( i = 0; i &lt; nOverviews; i++ )
00379     {
00380         <font class="keywordtype">void</font>    *pScaledProgressData;
00381         <font class="keywordtype">double</font>  dfPixels;
00382         <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *poBaseBand;
00383         CPLErr  eErr;
00384 
00385         <font class="keywordflow">if</font>( i == 0 )
00386             poBaseBand = poSrcBand;
00387         <font class="keywordflow">else</font>
00388             poBaseBand = papoOvrBands[i-1];
00389 
00390         dfPixels = papoOvrBands[i]-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>() 
00391             * (<font class="keywordtype">double</font>) papoOvrBands[i]-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>();
00392 
00393         pScaledProgressData = GDALCreateScaledProgress( 
00394             dfPixelsProcessed / dfTotalPixels,
00395             (dfPixelsProcessed + dfPixels) / dfTotalPixels, 
00396             pfnProgress, pProgressData );
00397 
00398         eErr = GDALRegenerateOverviews( poBaseBand, 1, papoOvrBands + i, 
00399                                         pszResampling, 
00400                                         GDALScaledProgress, 
00401                                         pScaledProgressData );
00402         GDALDestroyScaledProgress( pScaledProgressData );
00403 
00404         <font class="keywordflow">if</font>( eErr != CE_None )
00405             <font class="keywordflow">return</font> eErr;
00406 
00407         dfPixelsProcessed += dfPixels;
00408     }
00409 
00410     <font class="keywordflow">return</font> CE_None;
00411 }
00412 
00413 <font class="comment">/************************************************************************/</font>
00414 <font class="comment">/*                      GDALRegenerateOverviews()                       */</font>
00415 <font class="comment">/************************************************************************/</font>
00416 CPLErr 
00417 GDALRegenerateOverviews( <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *poSrcBand,
00418                          <font class="keywordtype">int</font> nOverviews, <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> **papoOvrBands, 
00419                          <font class="keyword">const</font> <font class="keywordtype">char</font> * pszResampling, 
00420                          GDALProgressFunc pfnProgress, <font class="keywordtype">void</font> * pProgressData )<font class="keyword"></font>
00421 <font class="keyword"></font>
00422 <font class="keyword"></font>{
00423     <font class="keywordtype">int</font>    nFullResYChunk, nWidth;
00424     <font class="keywordtype">int</font>    nFRXBlockSize, nFRYBlockSize;
00425     GDALDataType eType;
00426 
00427 <font class="comment">/* -------------------------------------------------------------------- */</font>
00428 <font class="comment">/*      If we are operating on multiple overviews, and using            */</font>
00429 <font class="comment">/*      averaging, lets do them in cascading order to reduce the        */</font>
00430 <font class="comment">/*      amount of computation.                                          */</font>
00431 <font class="comment">/* -------------------------------------------------------------------- */</font>
00432     <font class="keywordflow">if</font>( EQUALN(pszResampling,<font class="stringliteral">"AVER"</font>,4) &amp;&amp; nOverviews &gt; 1 )
00433         <font class="keywordflow">return</font> GDALRegenerateCascadingOverviews( poSrcBand, 
00434                                                  nOverviews, papoOvrBands,
00435                                                  pszResampling, 
00436                                                  pfnProgress,
00437                                                  pProgressData );
00438 
00439 <font class="comment">/* -------------------------------------------------------------------- */</font>
00440 <font class="comment">/*      Setup one horizontal swath to read from the raw buffer.         */</font>
00441 <font class="comment">/* -------------------------------------------------------------------- */</font>
00442     <font class="keywordtype">float</font> *pafChunk;
00443 
00444     poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a7">GetBlockSize</a>( &amp;nFRXBlockSize, &amp;nFRYBlockSize );
00445     
00446     <font class="keywordflow">if</font>( nFRYBlockSize &lt; 4 || nFRYBlockSize &gt; 256 )
00447         nFullResYChunk = 32;
00448     <font class="keywordflow">else</font>
00449         nFullResYChunk = nFRYBlockSize;
00450 
00451     <font class="keywordflow">if</font>( GDALDataTypeIsComplex( poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a6">GetRasterDataType</a>() ) )
00452         eType = GDT_CFloat32;
00453     <font class="keywordflow">else</font>
00454         eType = GDT_Float32;
00455 
00456     nWidth = poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>();
00457     pafChunk = (<font class="keywordtype">float</font> *) 
00458         VSIMalloc((GDALGetDataTypeSize(eType)/8) * nFullResYChunk * nWidth );
00459 
00460     <font class="keywordflow">if</font>( pafChunk == NULL )
00461     {
00462         <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_OutOfMemory, 
00463                   <font class="stringliteral">"Out of memory in GDALRegenerateOverviews()."</font> );
00464 
00465         <font class="keywordflow">return</font> CE_Failure;
00466     }
00467     
00468 <font class="comment">/* -------------------------------------------------------------------- */</font>
00469 <font class="comment">/*      Loop over image operating on chunks.                            */</font>
00470 <font class="comment">/* -------------------------------------------------------------------- */</font>
00471     <font class="keywordtype">int</font>  nChunkYOff = 0;
00472 
00473     <font class="keywordflow">for</font>( nChunkYOff = 0; 
00474          nChunkYOff &lt; poSrcBand-&gt;GetYSize(); 
00475          nChunkYOff += nFullResYChunk )
00476     {
00477         <font class="keywordflow">if</font>( !pfnProgress( nChunkYOff / (<font class="keywordtype">double</font>) poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>(), 
00478                           NULL, pProgressData ) )
00479         {
00480             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_UserInterrupt, <font class="stringliteral">"User terminated"</font> );
00481             <font class="keywordflow">return</font> CE_Failure;
00482         }
00483 
00484         <font class="keywordflow">if</font>( nFullResYChunk + nChunkYOff &gt; poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>() )
00485             nFullResYChunk = poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>() - nChunkYOff;
00486         
00487         <font class="comment">/* read chunk */</font>
00488         poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a9">RasterIO</a>( GF_Read, 0, nChunkYOff, nWidth, nFullResYChunk, 
00489                              pafChunk, nWidth, nFullResYChunk, eType,
00490                              0, 0 );
00491         
00492         <font class="keywordflow">for</font>( <font class="keywordtype">int</font> iOverview = 0; iOverview &lt; nOverviews; iOverview++ )
00493         {
00494             <font class="keywordflow">if</font>( eType == GDT_Float32 )
00495                 GDALDownsampleChunk32R(nWidth, poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>(), 
00496                                        pafChunk, nChunkYOff, nFullResYChunk,
00497                                        papoOvrBands[iOverview], pszResampling);
00498             <font class="keywordflow">else</font>
00499                 GDALDownsampleChunkC32R(nWidth, poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>(), 
00500                                        pafChunk, nChunkYOff, nFullResYChunk,
00501                                        papoOvrBands[iOverview], pszResampling);
00502         }
00503     }
00504 
00505     VSIFree( pafChunk );
00506     
00507 <font class="comment">/* -------------------------------------------------------------------- */</font>
00508 <font class="comment">/*      Renormalized overview mean / stddev if needed.                  */</font>
00509 <font class="comment">/* -------------------------------------------------------------------- */</font>
00510     <font class="keywordflow">if</font>( EQUAL(pszResampling,<font class="stringliteral">"AVERAGE_MP"</font>) )
00511     {
00512         GDALOverviewMagnitudeCorrection( (GDALRasterBandH) poSrcBand, 
00513                                          nOverviews, 
00514                                          (GDALRasterBandH *) papoOvrBands,
00515                                          GDALDummyProgress, NULL );
00516     }
00517 
00518 <font class="comment">/* -------------------------------------------------------------------- */</font>
00519 <font class="comment">/*      It can be important to flush out data to overviews.             */</font>
00520 <font class="comment">/* -------------------------------------------------------------------- */</font>
00521     <font class="keywordflow">for</font>( <font class="keywordtype">int</font> iOverview = 0; iOverview &lt; nOverviews; iOverview++ )
00522         papoOvrBands[iOverview]-&gt;<a class="code" href="class_GDALRasterBand.html#a13">FlushCache</a>();
00523 
00524     pfnProgress( 1.0, NULL, pProgressData );
00525 
00526     <font class="keywordflow">return</font> CE_None;
00527 }
00528 
00529 <font class="comment">/************************************************************************/</font>
00530 <font class="comment">/*                        GDALComputeBandStats()                        */</font>
00531 <font class="comment">/************************************************************************/</font>
00532 
00533 CPLErr
00534 GDALComputeBandStats( GDALRasterBandH hSrcBand,
00535                       <font class="keywordtype">int</font> nSampleStep,
00536                       <font class="keywordtype">double</font> *pdfMean, <font class="keywordtype">double</font> *pdfStdDev, 
00537                       GDALProgressFunc pfnProgress, 
00538                       <font class="keywordtype">void</font> *pProgressData )<font class="keyword"></font>
00539 <font class="keyword"></font>
00540 <font class="keyword"></font>{
00541     <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *poSrcBand = (<a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *) hSrcBand;
00542     <font class="keywordtype">int</font>         iLine, nWidth, nHeight;
00543     GDALDataType eType = poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a6">GetRasterDataType</a>();
00544     GDALDataType eWrkType;
00545     <font class="keywordtype">int</font>         bComplex;
00546     <font class="keywordtype">float</font>       *pafData;
00547     <font class="keywordtype">double</font>      dfSum=0.0, dfSum2=0.0;
00548     <font class="keywordtype">int</font>         nSamples = 0;
00549 
00550     nWidth = poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>();
00551     nHeight = poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>();
00552 
00553     <font class="keywordflow">if</font>( nSampleStep &gt;= nHeight )
00554         nSampleStep = 1;
00555 
00556     bComplex = GDALDataTypeIsComplex(eType);
00557     <font class="keywordflow">if</font>( bComplex )
00558     {
00559         pafData = (<font class="keywordtype">float</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nWidth * 2 * <font class="keyword">sizeof</font>(<font class="keywordtype">float</font>));
00560         eWrkType = GDT_CFloat32;
00561     }
00562     <font class="keywordflow">else</font>
00563     {
00564         pafData = (<font class="keywordtype">float</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nWidth * <font class="keyword">sizeof</font>(<font class="keywordtype">float</font>));
00565         eWrkType = GDT_Float32;
00566     }
00567 
00568 <font class="comment">/* -------------------------------------------------------------------- */</font>
00569 <font class="comment">/*      Loop over all sample lines.                                     */</font>
00570 <font class="comment">/* -------------------------------------------------------------------- */</font>
00571     <font class="keywordflow">for</font>( iLine = 0; iLine &lt; nHeight; iLine += nSampleStep )
00572     {
00573         <font class="keywordtype">int</font>     iPixel;
00574 
00575         <font class="keywordflow">if</font>( !pfnProgress( iLine / (<font class="keywordtype">double</font>) nHeight,
00576                           NULL, pProgressData ) )
00577         {
00578             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_UserInterrupt, <font class="stringliteral">"User terminated"</font> );
00579             CPLFree( pafData );
00580             <font class="keywordflow">return</font> CE_Failure;
00581         }
00582 
00583         poSrcBand-&gt;<a class="code" href="class_GDALRasterBand.html#a9">RasterIO</a>( GF_Read, 0, iLine, nWidth, 1,
00584                              pafData, nWidth, 1, eWrkType,
00585                              0, 0 );
00586 
00587         <font class="keywordflow">for</font>( iPixel = 0; iPixel &lt; nWidth; iPixel++ )
00588         {
00589             <font class="keywordtype">float</font>       fValue;
00590 
00591             <font class="keywordflow">if</font>( bComplex )
00592             {
00593                 <font class="comment">// Compute the magnitude of the complex value.</font>
00594 
00595                 fValue = sqrt(pafData[iPixel*2  ] * pafData[iPixel*2  ]
00596                             + pafData[iPixel*2+1] * pafData[iPixel*2+1]);
00597             }
00598             <font class="keywordflow">else</font>
00599             {
00600                 fValue = pafData[iPixel];
00601             }
00602 
00603             dfSum  += fValue;
00604             dfSum2 += fValue * fValue;
00605         }
00606 
00607         nSamples += nWidth;
00608     }
00609 
00610     <font class="keywordflow">if</font>( !pfnProgress( 1.0, NULL, pProgressData ) )
00611     {
00612         <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_UserInterrupt, <font class="stringliteral">"User terminated"</font> );
00613         CPLFree( pafData );
00614         <font class="keywordflow">return</font> CE_Failure;
00615     }
00616 
00617 <font class="comment">/* -------------------------------------------------------------------- */</font>
00618 <font class="comment">/*      Produce the result values.                                      */</font>
00619 <font class="comment">/* -------------------------------------------------------------------- */</font>
00620     <font class="keywordflow">if</font>( pdfMean != NULL )
00621         *pdfMean = dfSum / nSamples;
00622 
00623     <font class="keywordflow">if</font>( pdfStdDev != NULL )
00624     {
00625         <font class="keywordtype">double</font>  dfMean = dfSum / nSamples;
00626 
00627         *pdfStdDev = sqrt((dfSum2 / nSamples) - (dfMean * dfMean));
00628     }
00629 
00630     CPLFree( pafData );
00631 
00632     <font class="keywordflow">return</font> CE_None;
00633 }
00634 
00635 <font class="comment">/************************************************************************/</font>
00636 <font class="comment">/*                  GDALOverviewMagnitudeCorrection()                   */</font>
00637 <font class="comment">/*                                                                      */</font>
00638 <font class="comment">/*      Correct the mean and standard deviation of the overviews of     */</font>
00639 <font class="comment">/*      the given band to match the base layer approximately.           */</font>
00640 <font class="comment">/************************************************************************/</font>
00641 
00642 CPLErr
00643 GDALOverviewMagnitudeCorrection( GDALRasterBandH hBaseBand, 
00644                                  <font class="keywordtype">int</font> nOverviewCount,
00645                                  GDALRasterBandH *pahOverviews,
00646                                  GDALProgressFunc pfnProgress, 
00647                                  <font class="keywordtype">void</font> *pProgressData )<font class="keyword"></font>
00648 <font class="keyword"></font>
00649 <font class="keyword"></font>{
00650     CPLErr      eErr;
00651     <font class="keywordtype">double</font>      dfOrigMean, dfOrigStdDev;
00652 
00653 <font class="comment">/* -------------------------------------------------------------------- */</font>
00654 <font class="comment">/*      Compute mean/stddev for source raster.                          */</font>
00655 <font class="comment">/* -------------------------------------------------------------------- */</font>
00656     eErr = GDALComputeBandStats( hBaseBand, 2, &amp;dfOrigMean, &amp;dfOrigStdDev, 
00657                                  pfnProgress, pProgressData );
00658 
00659     <font class="keywordflow">if</font>( eErr != CE_None )
00660         <font class="keywordflow">return</font> eErr;
00661     
00662 <font class="comment">/* -------------------------------------------------------------------- */</font>
00663 <font class="comment">/*      Loop on overview bands.                                         */</font>
00664 <font class="comment">/* -------------------------------------------------------------------- */</font>
00665     <font class="keywordtype">int</font>         iOverview;
00666 
00667     <font class="keywordflow">for</font>( iOverview = 0; iOverview &lt; nOverviewCount; iOverview++ )
00668     {
00669         <a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *poOverview = (<a class="code" href="class_GDALRasterBand.html">GDALRasterBand</a> *)pahOverviews[iOverview];
00670         <font class="keywordtype">double</font>  dfOverviewMean, dfOverviewStdDev;
00671         <font class="keywordtype">double</font>  dfGain;
00672 
00673         eErr = GDALComputeBandStats( pahOverviews[iOverview], 1, 
00674                                      &amp;dfOverviewMean, &amp;dfOverviewStdDev, 
00675                                      pfnProgress, pProgressData );
00676 
00677         <font class="keywordflow">if</font>( eErr != CE_None )
00678             <font class="keywordflow">return</font> eErr;
00679 
00680         <font class="keywordflow">if</font>( dfOrigStdDev &lt; 0.0001 )
00681             dfGain = 1.0;
00682         <font class="keywordflow">else</font>
00683             dfGain = dfOrigStdDev / dfOverviewStdDev;
00684 
00685 <font class="comment">/* -------------------------------------------------------------------- */</font>
00686 <font class="comment">/*      Apply gain and offset.                                          */</font>
00687 <font class="comment">/* -------------------------------------------------------------------- */</font>
00688         GDALDataType    eWrkType, eType = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a6">GetRasterDataType</a>();
00689         <font class="keywordtype">int</font>             iLine, nWidth, nHeight, bComplex;
00690         <font class="keywordtype">float</font>           *pafData;
00691 
00692         nWidth = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a2">GetXSize</a>();
00693         nHeight = poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a3">GetYSize</a>();
00694 
00695         bComplex = GDALDataTypeIsComplex(eType);
00696         <font class="keywordflow">if</font>( bComplex )
00697         {
00698             pafData = (<font class="keywordtype">float</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nWidth * 2 * <font class="keyword">sizeof</font>(<font class="keywordtype">float</font>));
00699             eWrkType = GDT_CFloat32;
00700         }
00701         <font class="keywordflow">else</font>
00702         {
00703             pafData = (<font class="keywordtype">float</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nWidth * <font class="keyword">sizeof</font>(<font class="keywordtype">float</font>));
00704             eWrkType = GDT_Float32;
00705         }
00706 
00707         <font class="keywordflow">for</font>( iLine = 0; iLine &lt; nHeight; iLine++ )
00708         {
00709             <font class="keywordtype">int</font> iPixel;
00710             
00711             <font class="keywordflow">if</font>( !pfnProgress( iLine / (<font class="keywordtype">double</font>) nHeight,
00712                               NULL, pProgressData ) )
00713             {
00714                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_UserInterrupt, <font class="stringliteral">"User terminated"</font> );
00715                 CPLFree( pafData );
00716                 <font class="keywordflow">return</font> CE_Failure;
00717             }
00718 
00719             poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a9">RasterIO</a>( GF_Read, 0, iLine, nWidth, 1,
00720                                   pafData, nWidth, 1, eWrkType,
00721                                   0, 0 );
00722             
00723             <font class="keywordflow">for</font>( iPixel = 0; iPixel &lt; nWidth; iPixel++ )
00724             {
00725                 <font class="keywordflow">if</font>( bComplex )
00726                 {
00727                     pafData[iPixel*2] *= dfGain;
00728                     pafData[iPixel*2+1] *= dfGain;
00729                 }
00730                 <font class="keywordflow">else</font>
00731                 {
00732                     pafData[iPixel] = (pafData[iPixel]-dfOverviewMean)*dfGain 
00733                         + dfOrigMean;
00734 
00735                 }
00736             }
00737 
00738             poOverview-&gt;<a class="code" href="class_GDALRasterBand.html#a9">RasterIO</a>( GF_Write, 0, iLine, nWidth, 1,
00739                                   pafData, nWidth, 1, eWrkType,
00740                                   0, 0 );
00741         }
00742 
00743         <font class="keywordflow">if</font>( !pfnProgress( 1.0, NULL, pProgressData ) )
00744         {
00745             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_UserInterrupt, <font class="stringliteral">"User terminated"</font> );
00746             CPLFree( pafData );
00747             <font class="keywordflow">return</font> CE_Failure;
00748         }
00749         
00750         CPLFree( pafData );
00751     }
00752 
00753     <font class="keywordflow">return</font> CE_None;
00754 }
</div></pre><hr><address><small>Generated at Sat Dec 21 14:02:00 2002 for GDAL by
<a href="http://www.stack.nl/~dimitri/doxygen/index.html">
<img src="doxygen.gif" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.3-20001105 written by <a href="mailto:dimitri@stack.nl">Dimitri van Heesch</a>,
 &copy;&nbsp;1997-2000</small></address>
</body>
</html>