Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

AniGauss.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_AniGauss_h
00002 #define Impala_Core_Array_AniGauss_h
00003 
00004 #include "Util/Math.h"
00005 #include "Core/Array/Arrays.h"
00006 #include "Core/Array/Set.h"
00007 
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Array
00013 {
00014 
00015 
00016 #ifndef M_PI
00017 #define M_PI 3.14159265358979323846
00018 #endif
00019 
00020 
00021 /* define the input buffer type, e.g. "float" */
00022 #define SRCTYPE Real64
00023 
00024 /* define the output buffer type, should be at least "float" */
00025 #define DSTTYPE Real64
00026 
00027 
00028 
00029 static inline void
00030 TriggsM(double *filter, double *M)
00031 {
00032     double scale;
00033     double a1, a2, a3;
00034 
00035     a3 = filter[0];
00036     a2 = filter[1];
00037     a1 = filter[2];
00038 
00039     scale = 1.0/((1.0+a1-a2+a3)*(1.0-a1-a2-a3)*(1.0+a2+(a1-a3)*a3));
00040     M[0] = scale*(-a3*a1+1.0-a3*a3-a2);
00041     M[1] = scale*(a3+a1)*(a2+a3*a1);
00042     M[2] = scale*a3*(a1+a3*a2);
00043     M[3] = scale*(a1+a3*a2);
00044     M[4] = -scale*(a2-1.0)*(a2+a3*a1);
00045     M[5] = -scale*a3*(a3*a1+a3*a3+a2-1.0);
00046     M[6] = scale*(a3*a1+a2+a1*a1-a2*a2);
00047     M[7] = scale*(a1*a2+a3*a2*a2-a1*a3*a3-a3*a3*a3-a3*a2+a3);
00048     M[8] = scale*a3*(a1+a3*a2);
00049 }
00050 
00051 
00052 /**************************************
00053  * the low level filtering operations *
00054  **************************************/
00055 
00056 /*
00057    all filters work in-place on the output buffer (DSTTYPE), except for the
00058    xline filter, which runs over the input (SRCTYPE)
00059    Note that the xline filter can also work in-place, in which case src=dst
00060    and SRCTYPE should be DSTTYPE
00061 */
00062 
00063 static inline void
00064 f_iir_xline_filter(SRCTYPE *src, DSTTYPE *dest, int sx, int sy, double *filter)
00065 {
00066     int      i, j;
00067     double   b1, b2, b3;
00068     double   pix, p1, p2, p3;
00069     double   sum, sumsq;
00070     double   iplus, uplus, vplus;
00071     double   unp, unp1, unp2;
00072     double   M[9];
00073 
00074     sumsq = filter[3];
00075     sum = sumsq*sumsq;
00076 
00077     for (i = 0; i < sy; i++) {
00078                 /* causal filter */
00079         b1 = filter[2]; b2 = filter[1]; b3 = filter[0];
00080                 p1 = *src/sumsq; p2 = p1; p3 = p1;
00081 
00082         iplus = src[sx-1];
00083         for (j = 0; j < sx; j++) {
00084             pix = *src++ + b1*p1 + b2*p2 + b3*p3;
00085             *dest++ = pix;
00086             p3 = p2; p2 = p1; p1 = pix; /* update history */
00087         }
00088 
00089                 /* anti-causal filter */
00090 
00091         /* apply Triggs border condition */
00092         uplus = iplus/(1.0-b1-b2-b3);
00093         b1 = filter[4]; b2 = filter[5]; b3 = filter[6];
00094         vplus = uplus/(1.0-b1-b2-b3);
00095 
00096         unp = p1-uplus;
00097         unp1 = p2-uplus;
00098         unp2 = p3-uplus;
00099 
00100         TriggsM(filter, M);
00101 
00102         pix = M[0]*unp+M[1]*unp1+M[2]*unp2 + vplus;
00103         p1  = M[3]*unp+M[4]*unp1+M[5]*unp2 + vplus;
00104         p2  = M[6]*unp+M[7]*unp1+M[8]*unp2 + vplus;
00105         pix *= sum; p1 *= sum; p2 *= sum;
00106 
00107         *(--dest) = pix;
00108         p3 = p2; p2 = p1; p1 = pix;
00109 
00110         for (j = sx-2; j >= 0; j--) {
00111             pix = sum * *(--dest) + b1*p1 + b2*p2 + b3*p3;
00112             *dest = pix;
00113             p3 = p2; p2 = p1; p1 = pix;
00114         }
00115         dest += sx;
00116         }
00117 }
00118 
00119 static inline void
00120 f_iir_yline_filter(DSTTYPE *src, DSTTYPE *dest, int sx, int sy, double *filter)
00121 {
00122     double   *p0, *p1, *p2, *p3, *pswap;
00123     double   *buf0, *buf1, *buf2, *buf3;
00124     double   *uplusbuf;
00125     int      i, j;
00126     double   b1, b2, b3;
00127     double   pix;
00128     double   sum, sumsq;
00129     double   uplus, vplus;
00130     double   unp, unp1, unp2;
00131     double   M[9];
00132 
00133     sumsq = filter[3];
00134     sum = sumsq*sumsq;
00135 
00136     uplusbuf = (double*) malloc(sx*sizeof(*uplusbuf));
00137 
00138     buf0 = (double*) malloc(sx*sizeof(*buf0));
00139     buf1 = (double*) malloc(sx*sizeof(*buf1));
00140     buf2 = (double*) malloc(sx*sizeof(*buf2));
00141     buf3 = (double*) malloc(sx*sizeof(*buf3));
00142 
00143     p0 = buf0; p1 = buf1; p2 = buf2; p3 = buf3;
00144 
00145     /* causal filter */
00146     b1 = filter[2]; b2 = filter[1]; b3 = filter[0];
00147 
00148     /* border first line*/
00149     for (j = 0; j < sx; j++) {
00150         pix = *src++/sumsq;
00151                 p1[j] = pix; p2[j] = pix; p3[j] = pix;
00152     }
00153     /* calc last line for Triggs boundary condition */
00154     src += (sy-2)*sx;
00155     for (j = 0; j < sx; j++)
00156         uplusbuf[j] = *src++/(1.0-b1-b2-b3);
00157     src -= sy*sx;
00158 
00159     for (i = 0; i < sy; i++) {
00160         for (j = 0; j < sx; j++) {
00161             pix = *src++ + b1*p1[j] + b2*p2[j] + b3*p3[j];
00162             *dest++ = pix;
00163             p0[j] = pix;
00164         }
00165 
00166         /* shift history */
00167                 pswap = p3; p3 = p2; p2 = p1; p1 = p0; p0 = pswap;
00168     }
00169 
00170 
00171     /* anti-causal filter */
00172 
00173     /* apply Triggs border condition */
00174     b1 = filter[4]; b2 = filter[5]; b3 = filter[6];
00175     TriggsM(filter, M);
00176 
00177     /* first line */
00178     p0 = uplusbuf;
00179     for (j = sx-1; j >= 0; j--) {
00180         uplus = p0[j];
00181         vplus = uplus/(1.0-b1-b2-b3);
00182 
00183         unp = p1[j]-uplus;
00184         unp1 = p2[j]-uplus;
00185         unp2 = p3[j]-uplus;
00186         pix = M[0]*unp+M[1]*unp1+M[2]*unp2 + vplus;
00187         pix *= sum;
00188         *(--dest) = pix;
00189         p1[j] = pix;
00190         pix  = M[3]*unp+M[4]*unp1+M[5]*unp2 + vplus;
00191         p2[j] = pix*sum;
00192         pix  = M[6]*unp+M[7]*unp1+M[8]*unp2 + vplus;
00193         p3[j] = pix*sum;
00194     }
00195 
00196     for (i = sy-2; i >= 0; i--) {
00197         for (j = sx-1; j >= 0; j--) {
00198             pix = sum * *(--dest) + b1*p1[j] + b2*p2[j] + b3*p3[j];
00199             *dest = pix;
00200             p0[j] = pix;
00201         }
00202 
00203         /* shift history */
00204                 pswap = p3; p3 = p2; p2 = p1; p1 = p0; p0 = pswap;
00205     }
00206 
00207     free(buf0);
00208     free(buf1);
00209     free(buf2);
00210     free(buf3);
00211     free(uplusbuf);
00212 }
00213 
00214 
00215 static inline void
00216 f_iir_tline_filter(DSTTYPE *src, DSTTYPE *dest, int sx, int sy,
00217                    double *filter, double tanp)
00218 {
00219     double   *p0, *p1, *p2, *p3;
00220     double   *buf0, *buf1, *buf2, *buf3;
00221     double   *uplusbuf;
00222     int      i, j;
00223     double   b1, b2, b3;
00224     double   sum, sumsq;
00225     double   uplus, vplus;
00226     double   unp, unp1, unp2;
00227     double   M[9];
00228     double   pix, prev, val;
00229     double   res, prevres;
00230     double   xf;
00231     int      x;
00232     double   c, d;
00233     double   e, f;
00234     int      q4 = 0;
00235 
00236     /* check filter direction towards first or fourth quadrant */
00237     if (tanp <= 0.0) {
00238         q4 = 1;
00239         tanp = -tanp;
00240     }
00241     
00242     /* alloc buffer for Triggs boundary condition */
00243     uplusbuf = (double*) malloc(sx*sizeof(*uplusbuf));
00244 
00245     /* alloc recursion line buffers */
00246     buf0 = (double*) malloc((sx+sy*tanp+2)*sizeof(*buf0));
00247     buf1 = (double*) malloc((sx+sy*tanp+2)*sizeof(*buf1));
00248     buf2 = (double*) malloc((sx+sy*tanp+2)*sizeof(*buf2));
00249     buf3 = (double*) malloc((sx+sy*tanp+2)*sizeof(*buf3));
00250 
00251     if (q4) {
00252         buf0 += (int)(sy*tanp+1);
00253         buf1 += (int)(sy*tanp+1);
00254         buf2 += (int)(sy*tanp+1);
00255         buf3 += (int)(sy*tanp+1);
00256     }
00257 
00258     sumsq = filter[3];
00259     sum = sumsq*sumsq;
00260 
00261     /* causal filter */
00262     b1 = filter[2]; b2 = filter[1]; b3 = filter[0];
00263 
00264     /* first line */
00265     p1 = buf1; p2 = buf2; p3 = buf3;
00266     for (j = 0; j < sx; j++) {
00267         pix = *src++;
00268         *dest++ = pix; *p1++ = pix; *p2++ = pix; *p3++ = pix;
00269     }
00270 
00271     /* calc last line for Triggs boundary condition */
00272     src += (sy-2)*sx;
00273     for (j = 0; j < sx; j++)
00274         uplusbuf[j] = *src++ * sumsq/(1.0-b1-b2-b3);
00275     src -= (sy-1)*sx;
00276 
00277     x = 0;
00278     for (i = 1; i < sy; i++) {
00279         xf = i*tanp;
00280 
00281         /* border handling at image corner */
00282         if (q4) {
00283             p1 = buf1-x; p2 = buf2-x; p3 = buf3-x;
00284             for (j=1; j <= (int)(xf)-x; j++) {
00285                 p1[-j] = p1[0];
00286                 p2[-j] = p2[0];
00287                 p3[-j] = p3[0];
00288             }
00289         }
00290         else {
00291             p1 = buf1+x; p2 = buf2+x; p3 = buf3+x;
00292             for (j=1; j <= (int)(xf)-x; j++) {
00293                 p1[sx+j-1] = p1[sx-1];
00294                 p2[sx+j-1] = p2[sx-1];
00295                 p3[sx+j-1] = p3[sx-1];
00296             }
00297         }
00298 
00299         /* calc interpolation coefficients */
00300         x = (int)xf;
00301         c = xf-(double)x;
00302         d = 1.0-c;
00303 
00304         e = c; f = d;
00305         if (!q4) {
00306             res = d; d = c; c = res;
00307             res = f; f = e; e = res;
00308         }
00309 
00310         c *= sumsq; d *= sumsq;
00311 
00312         /* set buffers at start */
00313         if (q4) {
00314             p0 = buf0-x; p1 = buf1-x; p2 = buf2-x; p3 = buf3-x;
00315         }
00316         else {
00317             p0 = buf0+x; p1 = buf1+x; p2 = buf2+x; p3 = buf3+x;
00318         }
00319         prev = *src;
00320         prevres = sumsq*prev + b1 * *p1 + b2 * *p2 + b3 * *p3;
00321 
00322         /* run the filter */
00323         for (j = 0; j < sx; j++) {
00324             pix = *src++;
00325             val = c*pix+d*prev;
00326             prev = pix;
00327 
00328             res = val + b1 * *p1++ + b2 * *p2++ + b3 * *p3++;
00329             *p0++ = res;
00330             *dest++ = f*res+e*prevres;
00331             prevres = res;
00332         }
00333 
00334         /* shift history */
00335         p0 = buf3; buf3 = buf2; buf2 = buf1; buf1 = buf0; buf0 = p0;
00336     }
00337 
00338     /* anti-causal */
00339 
00340     /* apply Triggs border condition */
00341     b1 = filter[4]; b2 = filter[5]; b3 = filter[6];
00342     TriggsM(filter, M);
00343 
00344     /* first line */
00345     x = (int)((sy-1)*tanp);
00346     if (q4) {
00347         p1 = buf1+sx-x; p2 = buf2+sx-x; p3 = buf3+sx-x;
00348     }
00349     else {
00350         p1 = buf1+sx+x; p2 = buf2+sx+x; p3 = buf3+sx+x;
00351     }
00352     p0 = uplusbuf+sx;
00353     for (j = 0; j < sx; j++) {
00354         uplus = *(--p0);
00355         vplus = uplus/(1.0-b1-b2-b3);
00356 
00357         unp = *(--p1)-uplus;
00358         unp1 = *(--p2)-uplus;
00359         unp2 = *(--p3)-uplus;
00360         pix = M[0]*unp+M[1]*unp1+M[2]*unp2 + vplus;
00361         pix *= sumsq;
00362         *(--dest) = pix; *p1 = pix;
00363         pix  = M[3]*unp+M[4]*unp1+M[5]*unp2 + vplus;
00364         *p2 = pix*sumsq;
00365         pix  = M[6]*unp+M[7]*unp1+M[8]*unp2 + vplus;
00366         *p3 = pix*sumsq;
00367     }
00368 
00369     for (i = sy-2; i >= 0; i--) {
00370         xf = i*tanp;
00371 
00372         /* border handling at image corner */
00373         if (q4) {
00374             p1 = buf1-x; p2 = buf2-x; p3 = buf3-x;
00375             for (j=1; j <= x-(int)(xf); j++) {
00376                 p1[sx+j-1] = p1[sx-1];
00377                 p2[sx+j-1] = p2[sx-1];
00378                 p3[sx+j-1] = p3[sx-1];
00379             }
00380         }
00381         else {
00382             p1 = buf1+x; p2 = buf2+x; p3 = buf3+x;
00383             for (j=1; j <= x-(int)(xf); j++) {
00384                 p1[-j] = p1[0];
00385                 p2[-j] = p2[0];
00386                 p3[-j] = p3[0];
00387             }
00388         }
00389 
00390         /* calc interpolation coefficients */
00391         x = (int)xf;
00392         c = xf-(double)x;
00393         d = 1.0-c;
00394 
00395         e = c; f = d;
00396         c *= sumsq; d *= sumsq;
00397 
00398         if (!q4) {
00399             res = d; d = c; c = res;
00400             res = f; f = e; e = res;
00401         }
00402 
00403         /* set buffers at start */
00404         if (q4) {
00405             p0 = buf0+sx-x; p1 = buf1+sx-x; p2 = buf2+sx-x; p3 = buf3+sx-x;
00406         }
00407         else {
00408             p0 = buf0+sx+x; p1 = buf1+sx+x; p2 = buf2+sx+x; p3 = buf3+sx+x;
00409         }
00410         prev = *(dest-1);
00411         prevres = sumsq*prev + b1 * *(p1-1) + b2 * *(p2-1) + b3 * *(p3-1);
00412 
00413         /* run the filter */
00414         for (j = 0; j < sx; j++) {
00415             pix = *(--dest);
00416             val = d*pix+c*prev;
00417             prev = pix;
00418 
00419             res = val + b1 * *(--p1) + b2 * *(--p2) + b3 * *(--p3);
00420             *(--p0) = res;
00421             *dest = e*res+f*prevres;
00422             prevres = res;
00423         }
00424 
00425         /* shift history */
00426         p0 = buf3; buf3 = buf2; buf2 = buf1; buf1 = buf0; buf0 = p0;
00427     }
00428 
00429     if (q4) {
00430         buf0 -= (int)(sy*tanp+1);
00431         buf1 -= (int)(sy*tanp+1);
00432         buf2 -= (int)(sy*tanp+1);
00433         buf3 -= (int)(sy*tanp+1);
00434     }
00435     free(buf0);
00436     free(buf1);
00437     free(buf2);
00438     free(buf3);
00439     free(uplusbuf);
00440 }
00441 
00442 /* rotated [-1,0,1] derivative filter */
00443 static void
00444 f_iir_derivative_filter(DSTTYPE *src, DSTTYPE *dest, int sx, int sy,
00445     double phi, int order)
00446 {
00447    int                          i, j;
00448    DSTTYPE   *prev, *center, *next;
00449    DSTTYPE   *buf, *pstore;
00450    double  pn, pc, pp;
00451    double  cn, cc, cp;
00452    double  nn, nc, np;
00453    double  cosp, sinp;
00454 
00455    buf = (DSTTYPE*) malloc(sx*sizeof(*buf));
00456 
00457    sinp = 0.5*sin(phi); cosp = 0.5*cos(phi);
00458 
00459    center = src; prev = src; next = src+sx;
00460    for (i = 0; i < sy; i++) {
00461         pstore = buf;
00462         pn = *prev++; cn = *center++; nn = *next++;
00463         pp = pn; pc = pn;
00464         cp = cn; cc = cn;
00465         np = pn; nc = nn;
00466         *pstore++ = cc;
00467         for (j = 1; j < sx; j++) {
00468             pn = *prev++;
00469             cn = *center++;
00470             nn = *next++;
00471             *dest++ = sinp*(pc-nc)+cosp*(cn-cp);
00472             pp = pc; pc = pn;
00473             cp = cc; cc = cn;
00474             np = pc; nc = nn;
00475             *pstore++ = cc;
00476         }
00477         *dest++ = sinp*(pc-nc)+cosp*(cn-cp);
00478         prev = buf;
00479         if (i==sy-2)
00480             next -= sx;
00481     }
00482 
00483    free(buf);
00484 }
00485 
00486 void YvVfilterCoef(double sigma, double *filter)
00487 {
00488     /* the recipe in the Young-van Vliet paper:
00489      * I.T. Young, L.J. van Vliet, M. van Ginkel, Recursive Gabor filtering.
00490      * IEEE Trans. Sig. Proc., vol. 50, pp. 2799-2805, 2002.
00491      *
00492      * (this is an improvement over Young-Van Vliet, Sig. Proc. 44, 1995)
00493      */
00494 
00495         double q, qsq;
00496     double scale;
00497     double B, b1, b2, b3;
00498 
00499         /* initial values */
00500         double m0 = 1.16680, m1 = 1.10783, m2 = 1.40586;
00501         double m1sq = m1*m1, m2sq = m2*m2;
00502 
00503         /* calculate q */
00504         if(sigma < 3.556)
00505                 q = -0.2568 + 0.5784 * sigma + 0.0561 * sigma * sigma;
00506         else
00507                 q = 2.5091 + 0.9804 * (sigma - 3.556);
00508 
00509         qsq = q*q;
00510 
00511         /* calculate scale, and b[0,1,2,3] */
00512         scale = (m0 + q) * (m1sq + m2sq + 2*m1*q + qsq);
00513         b1 = -q * (2*m0*m1 + m1sq + m2sq + (2*m0 + 4*m1) * q + 3*qsq) / scale;
00514         b2 = qsq * (m0 + 2*m1 + 3*q) / scale;
00515         b3 = - qsq * q / scale;
00516     
00517         /* calculate B */
00518         B = (m0 * (m1sq + m2sq))/scale;
00519 
00520         /* fill in filter */
00521     filter[0] = -b3;
00522     filter[1] = -b2;
00523     filter[2] = -b1;
00524     filter[3] = B;
00525     filter[4] = -b1;
00526     filter[5] = -b2;
00527     filter[6] = -b3;
00528 }
00529 
00530 /*
00531  *  the main function:
00532  *    anigauss(inbuf, outbuf, bufwidth, bufheight, sigma_v, sigma_u, phi,
00533  *       derivative_order_v, derivative_order_u);
00534  *
00535  *  v-axis = short axis
00536  *  u-axis = long axis
00537  *  phi = orientation angle in degrees
00538  *
00539  *  for example, anisotropic data smoothing:
00540  *    anigauss(inptr, outptr, 512, 512, 3.0, 7.0, 30.0, 0, 0);
00541  *
00542  *  or, anisotropic edge detection:
00543  *    anigauss(inptr, outptr, 512, 512, 3.0, 7.0, 30.0, 1, 0);
00544  *
00545  *  or, anisotropic line detection:
00546  *    anigauss(inptr, outptr, 512, 512, 3.0, 7.0, 30.0, 2, 0);
00547  *
00548  *  or, in-place anisotropic data smoothing:
00549  *    anigauss(bufptr, bufptr, 512, 512, 3.0, 7.0, 30.0, 0, 0);
00550  *
00551  */
00552 static inline void
00553 anigauss(SRCTYPE *input, DSTTYPE *output, int sizex, int sizey,
00554          double sigmav, double sigmau, double phi, int orderv, int orderu)
00555 {
00556     double      filter[7];
00557     double sigmax, sigmay, tanp;
00558     double su2, sv2;
00559     double phirad;
00560     double a11, a21, a22;
00561     int    i;
00562 
00563     su2 = sigmau*sigmau;
00564     sv2 = sigmav*sigmav;
00565     phirad = phi*M_PI/180.;
00566 
00567     a11 = cos(phirad)*cos(phirad)*su2 + sin(phirad)*sin(phirad)*sv2;
00568     a21 = cos(phirad)*sin(phirad)*(su2-sv2);
00569     a22 = cos(phirad)*cos(phirad)*sv2 + sin(phirad)*sin(phirad)*su2;
00570 
00571     sigmax = sqrt(a11-a21*a21/a22);
00572     tanp = a21/a22;
00573     sigmay = sqrt(a22);
00574 
00575     /* calculate filter coefficients of x-direction*/
00576     YvVfilterCoef(sigmax, filter);
00577 
00578     /* filter in the x-direction */
00579     f_iir_xline_filter(input,output,sizex,sizey,filter);
00580 
00581     /* calculate filter coefficients in tanp-direction */
00582     YvVfilterCoef(sigmay, filter);
00583 
00584     if (tanp != 0.0) {
00585         /* filter in the tanp-direction */
00586          f_iir_tline_filter(output,output,sizex,sizey,filter, tanp);
00587     }
00588     else {
00589         /* isotropic filter or anisotropic filter aligned with grid */
00590          f_iir_yline_filter(output,output,sizex,sizey,filter);
00591     }
00592 
00593     /* do the derivative filter: [-1,0,1] rotated over phi */
00594     for(i=0; i<orderv; i++)
00595         f_iir_derivative_filter(output, output, sizex, sizey, phirad-M_PI/2., 1);
00596     for(i=0; i<orderu; i++)
00597         f_iir_derivative_filter(output, output, sizex, sizey, phirad, 1);
00598 }
00599 
00610 inline void
00611 AniGauss(Array2dScalarReal64*& dst, Array2dScalarReal64* src, Real64 sigmaV,
00612          Real64 sigmaU, Real64 phi, int orderV, int orderU)
00613 {
00614     // We need array's without borders for anigauss
00615     if ((dst == 0) || (dst->BW() != 0) || (dst->BH() != 0))
00616     {
00617         if (dst)
00618             delete dst;
00619         dst = new Array2dScalarReal64(src->CW(), src->CH(), 0, 0);
00620     }
00621     if ((src->BW() == 0) && (src->BH() == 0))
00622     {
00623         anigauss(src->PB(), dst->PB(), src->W(), src->H(), sigmaV, sigmaU, phi,
00624                  orderV, orderU);
00625     }
00626     else
00627     {
00628         Set(dst, src);
00629         anigauss(dst->PB(), dst->PB(), dst->W(), dst->H(), sigmaV, sigmaU, phi,
00630                  orderV, orderU);
00631     }
00632 }
00633 
00634 #undef SRCTYPE
00635 #undef DSTTYPE
00636 
00637 } // namespace Array
00638 } // namespace Core
00639 } // namespace Impala
00640 
00641 #endif

Generated on Fri Mar 19 09:30:43 2010 for ImpalaSrc by  doxygen 1.5.1