Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
vp_warpA110N.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 #include "vp_global.h"
00056 
00057 
00058 
00059     
00060     
00061     
00062     
00063     
00064 
00065     
00066     
00067     
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075     
00076     
00077     
00078     
00079     
00080 
00081 
00082 
00083 
00084 
00085     
00086     
00087     
00088     
00089     
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100         
00101 
00102 
00103 #define FLTFRAC_TO_FIX31(f)     ((int)((f) * 2147483648.))
00104 
00105 
00106 #define FIX31_TO_WGTIND(f)      ((f) >> (31 - WARP_WEIGHT_INDEX_BITS))
00107 
00108 extern float VPBilirpWeight[WARP_WEIGHT_ENTRIES][WARP_WEIGHT_ENTRIES][4];
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 void
00119 VPWarpA110N (in_image, in_width, in_height, in_bytes_per_scan,
00120           out_image, out_width, out_height, out_bytes_per_scan,
00121           warp_matrix)
00122 GrayIntPixel *in_image;         
00123 int in_width;                   
00124 int in_height;
00125 int in_bytes_per_scan;          
00126 char *out_image;                
00127 int out_width;                  
00128 int out_height;
00129 int out_bytes_per_scan;         
00130 vpMatrix3 warp_matrix;          
00131                                 
00132                                 
00133 {
00134     Trapezoid full_overlap[9];  
00135 
00136 
00137     Trapezoid part_overlap[9];  
00138 
00139 
00140     int region;                 
00141     char *out_ptr;              
00142     int out_scan_y;             
00143     int scans_to_next_vertex;   
00144 
00145     GrayIntPixel *in_ptr;       
00146     double x_lft_full, x_rgt_full; 
00147     double x_lft_part, x_rgt_part; 
00148     int no_full_pixels;         
00149     double in_x, in_y;          
00150 
00151     int in_x_int, in_y_int;     
00152 
00153 
00154     int xfrac, yfrac;           
00155 
00156 
00157     int xfrac_incr, yfrac_incr; 
00158 
00159 
00160     double in_x_incr, in_y_incr;
00161 
00162 
00163 
00164     int in_x_incr_int, in_y_incr_int; 
00165     int in_x_incr_dlt, in_y_incr_dlt; 
00166     float *wptr;                
00167     int lft_zero_cnt;           
00168     int lft_edge_cnt;           
00169     int full_cnt;               
00170     int rgt_edge_cnt;           
00171     int rgt_zero_cnt;           
00172     int x;                      
00173     
00174         float gray_acc; int gray_acc_int;
00175                         
00176     double denom;
00177     int c;
00178 
00179 #ifdef DEBUG
00180     {
00181         int y;
00182 
00183         for (y = 0; y < out_height; y++) {
00184             out_ptr = out_image + y*out_bytes_per_scan;
00185             for (x = 0; x < out_width; x++) {
00186                 for (c = 0; c < ((1) + (0)); c++)
00187                     *out_ptr++ = 255;
00188             }
00189         }
00190     }
00191 #endif
00192 
00193     
00194     VPComputeWarpTables();
00195 
00196     
00197     
00198     VPAffineImageOverlap(in_width, in_height, out_width, out_height,
00199                          warp_matrix, 2., full_overlap, part_overlap);
00200 
00201     
00202     out_ptr = out_image;
00203     out_scan_y = 0;
00204     denom = 1. / (warp_matrix[0][0] * warp_matrix[1][1] -
00205                   warp_matrix[0][1] * warp_matrix[1][0]);
00206     in_x_incr = warp_matrix[1][1]*denom;
00207     in_y_incr = -warp_matrix[1][0]*denom;
00208     if (in_x_incr < 0) {
00209         in_x_incr_int = (int)ceil(in_x_incr);
00210         in_x_incr_dlt = -1;
00211     } else {
00212         in_x_incr_int = (int)floor(in_x_incr);
00213         in_x_incr_dlt = 1;
00214     }
00215     if (in_y_incr < 0) {
00216         in_y_incr_int = (int)ceil(in_y_incr);
00217         in_y_incr_dlt = -1;
00218     } else {
00219         in_y_incr_int = (int)floor(in_y_incr);
00220         in_y_incr_dlt = 1;
00221     }
00222     xfrac_incr = FLTFRAC_TO_FIX31(in_x_incr - in_x_incr_int);
00223     yfrac_incr = FLTFRAC_TO_FIX31(in_y_incr - in_y_incr_int);
00224     for (region = 0; region < 9; region++) {
00225         
00226         if (part_overlap[region].miny >= out_height) {
00227             break;
00228         }
00229 
00230         
00231 
00232         if (part_overlap[region].x_top_lft >
00233             part_overlap[region].x_top_rgt) {
00234             c = (part_overlap[region].maxy - part_overlap[region].miny + 1) *
00235                 out_bytes_per_scan;
00236             bzero(out_ptr, c);
00237             out_ptr += c;
00238             out_scan_y += part_overlap[region].maxy -
00239                           part_overlap[region].miny + 1;
00240             continue;
00241         }
00242 
00243         
00244         scans_to_next_vertex = part_overlap[region].maxy -
00245                                part_overlap[region].miny + 1;
00246         x_lft_full = full_overlap[region].x_top_lft;
00247         x_rgt_full = full_overlap[region].x_top_rgt;
00248         x_lft_part = part_overlap[region].x_top_lft;
00249         x_rgt_part = part_overlap[region].x_top_rgt;
00250         if (x_lft_full > x_rgt_full)
00251             no_full_pixels = 1;
00252         else
00253             no_full_pixels = 0;
00254         ASSERT(scans_to_next_vertex > 0);
00255         ASSERT(out_scan_y == part_overlap[region].miny);
00256         while (scans_to_next_vertex > 0) {
00257             
00258 
00259             lft_zero_cnt = (int)floor(x_lft_part);
00260             if (lft_zero_cnt < 0)
00261                 lft_zero_cnt = 0;
00262             else if (lft_zero_cnt > out_width)
00263                 lft_zero_cnt = out_width;
00264             if (no_full_pixels) {
00265                 lft_edge_cnt = (int)ceil(x_rgt_part);
00266                 if (lft_edge_cnt < 0)
00267                     lft_edge_cnt = 0;
00268                 else if (lft_edge_cnt > out_width)
00269                     lft_edge_cnt = out_width;
00270                 lft_edge_cnt -= lft_zero_cnt;
00271                 if (lft_edge_cnt < 0)
00272                     lft_edge_cnt = 0;
00273                 full_cnt = 0;
00274                 rgt_edge_cnt = 0;
00275                 rgt_zero_cnt = out_width - lft_zero_cnt - lft_edge_cnt;
00276             } else {
00277                 lft_edge_cnt = (int)ceil(x_lft_full);
00278                 if (lft_edge_cnt < 0)
00279                     lft_edge_cnt = 0;
00280                 else if (lft_edge_cnt > out_width)
00281                     lft_edge_cnt = out_width;
00282                 lft_edge_cnt -= lft_zero_cnt;
00283                 if (lft_edge_cnt < 0)
00284                     lft_edge_cnt = 0;
00285                 full_cnt = (int)floor(x_rgt_full);
00286                 if (full_cnt < 0)
00287                     full_cnt = 0;
00288                 else if (full_cnt > out_width)
00289                     full_cnt = out_width;
00290                 full_cnt -= lft_edge_cnt + lft_zero_cnt;
00291                 if (full_cnt < 0)
00292                     full_cnt = 0;
00293                 rgt_edge_cnt = (int)ceil(x_rgt_part);
00294                 if (rgt_edge_cnt < 0)
00295                     rgt_edge_cnt = 0;
00296                 else if (rgt_edge_cnt > out_width)
00297                     rgt_edge_cnt = out_width;
00298                 rgt_edge_cnt -= full_cnt + lft_edge_cnt + lft_zero_cnt;
00299                 if (rgt_edge_cnt < 0)
00300                     rgt_edge_cnt = 0;
00301                 rgt_zero_cnt = out_width - lft_zero_cnt - lft_edge_cnt - 
00302                                full_cnt - rgt_edge_cnt;
00303             }
00304 
00305             
00306 
00307             in_x = ((lft_zero_cnt - warp_matrix[0][2]) * warp_matrix[1][1] -
00308                     (out_scan_y - warp_matrix[1][2])*warp_matrix[0][1])*denom;
00309             in_y = (-(lft_zero_cnt - warp_matrix[0][2]) * warp_matrix[1][0] +
00310                     (out_scan_y - warp_matrix[1][2])*warp_matrix[0][0])*denom;
00311             in_x_int = (int)floor(in_x);
00312             in_y_int = (int)floor(in_y);
00313             in_ptr = (GrayIntPixel *)(((char *)in_image + in_y_int *
00314                                        in_bytes_per_scan)) + in_x_int;
00315 
00316             
00317             xfrac = FLTFRAC_TO_FIX31(in_x - in_x_int);
00318             yfrac = FLTFRAC_TO_FIX31(in_y - in_y_int);
00319 
00320             
00321             if (lft_zero_cnt > 0) {
00322                 bzero(out_ptr, lft_zero_cnt * ((1) + (0)));
00323                 out_ptr += lft_zero_cnt * ((1) + (0));
00324             }
00325 
00326             
00327             for (x = lft_zero_cnt; x < lft_zero_cnt + lft_edge_cnt; x++) {
00328                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00329                                      [FIX31_TO_WGTIND(xfrac)];
00330                 
00331         gray_acc = 0;
00332         ;
00333                 if (in_x_int >= 0 && in_x_int < in_width) {
00334                     if (in_y_int >= 0 && in_y_int < in_height) {
00335                         
00336         gray_acc += (wptr[0]) * (in_ptr[0].clrflt);
00337         ;
00338                     }
00339                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00340                         
00341         gray_acc += (wptr[2]) * (in_ptr[in_width].clrflt);
00342         ;
00343                     }
00344                 }
00345                 if (in_x_int+1 >= 0 && in_x_int+1 < in_width) {
00346                     if (in_y_int >= 0 && in_y_int < in_height) {
00347                         
00348         gray_acc += (wptr[1]) * (in_ptr[1].clrflt);
00349         ;
00350                     }
00351                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00352                         
00353         gray_acc += (wptr[3]) * (in_ptr[in_width + 1].clrflt);
00354         ;
00355                     }
00356                 }
00357                 
00358             
00359         gray_acc_int = gray_acc;
00360         if (gray_acc_int > 255)
00361             gray_acc_int = 255;
00362         ((out_ptr)[0]) = gray_acc_int;
00363             ;
00364                 out_ptr += ((1) + (0));
00365                 xfrac += xfrac_incr;
00366                 yfrac += yfrac_incr;
00367                 if (xfrac < 0) {
00368                     xfrac &= 0x7fffffff;
00369                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00370                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00371                 } else {
00372                     in_x_int += in_x_incr_int;
00373                     in_ptr += in_x_incr_int;
00374                 }
00375                 if (yfrac < 0) {
00376                     yfrac &= 0x7fffffff;
00377                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00378                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00379                 } else {
00380                     in_y_int += in_y_incr_int;
00381                     in_ptr += in_width * in_y_incr_int;
00382                 }
00383             }
00384 
00385             
00386             for (x = lft_zero_cnt + lft_edge_cnt;
00387                  x < lft_zero_cnt + lft_edge_cnt + full_cnt; x++) {
00388                 ASSERT(in_x_int >= 0 && in_x_int < in_width-1);
00389                 ASSERT(in_y_int >= 0 && in_y_int < in_height-1);
00390                 ASSERT((GrayIntPixel *)(((char *)in_image + in_y_int *
00391                                 in_bytes_per_scan)) + in_x_int == in_ptr);
00392                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00393                                      [FIX31_TO_WGTIND(xfrac)];
00394                 
00395         
00396         gray_acc = (wptr[0]) * (in_ptr[0].clrflt) +
00397                    (wptr[2]) * (in_ptr[in_width].clrflt) +      
00398                    (wptr[1]) * (in_ptr[1].clrflt) +
00399                    (wptr[3]) * (in_ptr[in_width+1].clrflt);
00400         ;
00401                 
00402             
00403         gray_acc_int = gray_acc;
00404         if (gray_acc_int > 255)
00405             gray_acc_int = 255;
00406         ((out_ptr)[0]) = gray_acc_int;
00407             ;
00408                 out_ptr += ((1) + (0));
00409                 xfrac += xfrac_incr;
00410                 yfrac += yfrac_incr;
00411                 if (xfrac < 0) {
00412                     xfrac &= 0x7fffffff;
00413                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00414                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00415                 } else {
00416                     in_x_int += in_x_incr_int;
00417                     in_ptr += in_x_incr_int;
00418                 }
00419                 if (yfrac < 0) {
00420                     yfrac &= 0x7fffffff;
00421                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00422                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00423                 } else {
00424                     in_y_int += in_y_incr_int;
00425                     in_ptr += in_width * in_y_incr_int;
00426                 }
00427             }
00428 
00429             
00430             for (x = lft_zero_cnt + lft_edge_cnt + full_cnt;
00431                  x < lft_zero_cnt + lft_edge_cnt + full_cnt + rgt_edge_cnt;
00432                  x++) {
00433                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00434                                      [FIX31_TO_WGTIND(xfrac)];
00435                 
00436         gray_acc = 0;
00437         ;
00438                 if (in_x_int >= 0 && in_x_int < in_width) {
00439                     if (in_y_int >= 0 && in_y_int < in_height) {
00440                         
00441         gray_acc += (wptr[0]) * (in_ptr[0].clrflt);
00442         ;
00443                     }
00444                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00445                         
00446         gray_acc += (wptr[2]) * (in_ptr[in_width].clrflt);
00447         ;
00448                     }
00449                 }
00450                 if (in_x_int+1 >= 0 && in_x_int+1 < in_width) {
00451                     if (in_y_int >= 0 && in_y_int < in_height) {
00452                         
00453         gray_acc += (wptr[1]) * (in_ptr[1].clrflt);
00454         ;
00455                     }
00456                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00457                         
00458         gray_acc += (wptr[3]) * (in_ptr[in_width + 1].clrflt);
00459         ;
00460                     }
00461                 }
00462                 
00463             
00464         gray_acc_int = gray_acc;
00465         if (gray_acc_int > 255)
00466             gray_acc_int = 255;
00467         ((out_ptr)[0]) = gray_acc_int;
00468             ;
00469                 out_ptr += ((1) + (0));
00470                 xfrac += xfrac_incr;
00471                 yfrac += yfrac_incr;
00472                 if (xfrac < 0) {
00473                     xfrac &= 0x7fffffff;
00474                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00475                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00476                 } else {
00477                     in_x_int += in_x_incr_int;
00478                     in_ptr += in_x_incr_int;
00479                 }
00480                 if (yfrac < 0) {
00481                     yfrac &= 0x7fffffff;
00482                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00483                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00484                 } else {
00485                     in_y_int += in_y_incr_int;
00486                     in_ptr += in_width * in_y_incr_int;
00487                 }
00488             }
00489 
00490             
00491             if (rgt_zero_cnt > 0) {
00492                 bzero(out_ptr, rgt_zero_cnt * ((1) + (0)));
00493                 out_ptr += rgt_zero_cnt * ((1) + (0));
00494             }
00495 
00496             
00497             scans_to_next_vertex--;
00498             out_scan_y++;
00499             out_ptr += out_bytes_per_scan - out_width * ((1) + (0));
00500             x_lft_full += full_overlap[region].x_incr_lft;
00501             x_rgt_full += full_overlap[region].x_incr_rgt;
00502             x_lft_part += part_overlap[region].x_incr_lft;
00503             x_rgt_part += part_overlap[region].x_incr_rgt;
00504         } 
00505     } 
00506     ASSERT(out_scan_y == out_height);
00507 }