Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
vp_warpA330N.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 VPWarpA330N (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 RGBIntPixel *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     RGBIntPixel *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 r_acc, g_acc, b_acc;
00175     int r_acc_int, g_acc_int, b_acc_int;
00176                         
00177     double denom;
00178     int c;
00179 
00180 #ifdef DEBUG
00181     {
00182         int y;
00183 
00184         for (y = 0; y < out_height; y++) {
00185             out_ptr = out_image + y*out_bytes_per_scan;
00186             for (x = 0; x < out_width; x++) {
00187                 for (c = 0; c < ((3) + (0)); c++)
00188                     *out_ptr++ = 255;
00189             }
00190         }
00191     }
00192 #endif
00193 
00194     
00195     VPComputeWarpTables();
00196 
00197     
00198     
00199     VPAffineImageOverlap(in_width, in_height, out_width, out_height,
00200                          warp_matrix, 2., full_overlap, part_overlap);
00201 
00202     
00203     out_ptr = out_image;
00204     out_scan_y = 0;
00205     denom = 1. / (warp_matrix[0][0] * warp_matrix[1][1] -
00206                   warp_matrix[0][1] * warp_matrix[1][0]);
00207     in_x_incr = warp_matrix[1][1]*denom;
00208     in_y_incr = -warp_matrix[1][0]*denom;
00209     if (in_x_incr < 0) {
00210         in_x_incr_int = (int)ceil(in_x_incr);
00211         in_x_incr_dlt = -1;
00212     } else {
00213         in_x_incr_int = (int)floor(in_x_incr);
00214         in_x_incr_dlt = 1;
00215     }
00216     if (in_y_incr < 0) {
00217         in_y_incr_int = (int)ceil(in_y_incr);
00218         in_y_incr_dlt = -1;
00219     } else {
00220         in_y_incr_int = (int)floor(in_y_incr);
00221         in_y_incr_dlt = 1;
00222     }
00223     xfrac_incr = FLTFRAC_TO_FIX31(in_x_incr - in_x_incr_int);
00224     yfrac_incr = FLTFRAC_TO_FIX31(in_y_incr - in_y_incr_int);
00225     for (region = 0; region < 9; region++) {
00226         
00227         if (part_overlap[region].miny >= out_height) {
00228             break;
00229         }
00230 
00231         
00232 
00233         if (part_overlap[region].x_top_lft >
00234             part_overlap[region].x_top_rgt) {
00235             c = (part_overlap[region].maxy - part_overlap[region].miny + 1) *
00236                 out_bytes_per_scan;
00237             bzero(out_ptr, c);
00238             out_ptr += c;
00239             out_scan_y += part_overlap[region].maxy -
00240                           part_overlap[region].miny + 1;
00241             continue;
00242         }
00243 
00244         
00245         scans_to_next_vertex = part_overlap[region].maxy -
00246                                part_overlap[region].miny + 1;
00247         x_lft_full = full_overlap[region].x_top_lft;
00248         x_rgt_full = full_overlap[region].x_top_rgt;
00249         x_lft_part = part_overlap[region].x_top_lft;
00250         x_rgt_part = part_overlap[region].x_top_rgt;
00251         if (x_lft_full > x_rgt_full)
00252             no_full_pixels = 1;
00253         else
00254             no_full_pixels = 0;
00255         ASSERT(scans_to_next_vertex > 0);
00256         ASSERT(out_scan_y == part_overlap[region].miny);
00257         while (scans_to_next_vertex > 0) {
00258             
00259 
00260             lft_zero_cnt = (int)floor(x_lft_part);
00261             if (lft_zero_cnt < 0)
00262                 lft_zero_cnt = 0;
00263             else if (lft_zero_cnt > out_width)
00264                 lft_zero_cnt = out_width;
00265             if (no_full_pixels) {
00266                 lft_edge_cnt = (int)ceil(x_rgt_part);
00267                 if (lft_edge_cnt < 0)
00268                     lft_edge_cnt = 0;
00269                 else if (lft_edge_cnt > out_width)
00270                     lft_edge_cnt = out_width;
00271                 lft_edge_cnt -= lft_zero_cnt;
00272                 if (lft_edge_cnt < 0)
00273                     lft_edge_cnt = 0;
00274                 full_cnt = 0;
00275                 rgt_edge_cnt = 0;
00276                 rgt_zero_cnt = out_width - lft_zero_cnt - lft_edge_cnt;
00277             } else {
00278                 lft_edge_cnt = (int)ceil(x_lft_full);
00279                 if (lft_edge_cnt < 0)
00280                     lft_edge_cnt = 0;
00281                 else if (lft_edge_cnt > out_width)
00282                     lft_edge_cnt = out_width;
00283                 lft_edge_cnt -= lft_zero_cnt;
00284                 if (lft_edge_cnt < 0)
00285                     lft_edge_cnt = 0;
00286                 full_cnt = (int)floor(x_rgt_full);
00287                 if (full_cnt < 0)
00288                     full_cnt = 0;
00289                 else if (full_cnt > out_width)
00290                     full_cnt = out_width;
00291                 full_cnt -= lft_edge_cnt + lft_zero_cnt;
00292                 if (full_cnt < 0)
00293                     full_cnt = 0;
00294                 rgt_edge_cnt = (int)ceil(x_rgt_part);
00295                 if (rgt_edge_cnt < 0)
00296                     rgt_edge_cnt = 0;
00297                 else if (rgt_edge_cnt > out_width)
00298                     rgt_edge_cnt = out_width;
00299                 rgt_edge_cnt -= full_cnt + lft_edge_cnt + lft_zero_cnt;
00300                 if (rgt_edge_cnt < 0)
00301                     rgt_edge_cnt = 0;
00302                 rgt_zero_cnt = out_width - lft_zero_cnt - lft_edge_cnt - 
00303                                full_cnt - rgt_edge_cnt;
00304             }
00305 
00306             
00307 
00308             in_x = ((lft_zero_cnt - warp_matrix[0][2]) * warp_matrix[1][1] -
00309                     (out_scan_y - warp_matrix[1][2])*warp_matrix[0][1])*denom;
00310             in_y = (-(lft_zero_cnt - warp_matrix[0][2]) * warp_matrix[1][0] +
00311                     (out_scan_y - warp_matrix[1][2])*warp_matrix[0][0])*denom;
00312             in_x_int = (int)floor(in_x);
00313             in_y_int = (int)floor(in_y);
00314             in_ptr = (RGBIntPixel *)(((char *)in_image + in_y_int *
00315                                        in_bytes_per_scan)) + in_x_int;
00316 
00317             
00318             xfrac = FLTFRAC_TO_FIX31(in_x - in_x_int);
00319             yfrac = FLTFRAC_TO_FIX31(in_y - in_y_int);
00320 
00321             
00322             if (lft_zero_cnt > 0) {
00323                 bzero(out_ptr, lft_zero_cnt * ((3) + (0)));
00324                 out_ptr += lft_zero_cnt * ((3) + (0));
00325             }
00326 
00327             
00328             for (x = lft_zero_cnt; x < lft_zero_cnt + lft_edge_cnt; x++) {
00329                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00330                                      [FIX31_TO_WGTIND(xfrac)];
00331                 
00332         r_acc = g_acc = b_acc = 0;
00333         ;
00334                 if (in_x_int >= 0 && in_x_int < in_width) {
00335                     if (in_y_int >= 0 && in_y_int < in_height) {
00336                         
00337         
00338                 r_acc += (wptr[0]) * (in_ptr[0].rclrflt);
00339                 g_acc += (wptr[0]) * (in_ptr[0].gclrflt);
00340                 b_acc += (wptr[0]) * (in_ptr[0].bclrflt);
00341         ;
00342                     }
00343                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00344                         
00345         
00346                 r_acc += (wptr[2]) * (in_ptr[in_width].rclrflt);
00347                 g_acc += (wptr[2]) * (in_ptr[in_width].gclrflt);
00348                 b_acc += (wptr[2]) * (in_ptr[in_width].bclrflt);
00349         ;
00350                     }
00351                 }
00352                 if (in_x_int+1 >= 0 && in_x_int+1 < in_width) {
00353                     if (in_y_int >= 0 && in_y_int < in_height) {
00354                         
00355         
00356                 r_acc += (wptr[1]) * (in_ptr[1].rclrflt);
00357                 g_acc += (wptr[1]) * (in_ptr[1].gclrflt);
00358                 b_acc += (wptr[1]) * (in_ptr[1].bclrflt);
00359         ;
00360                     }
00361                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00362                         
00363         
00364                 r_acc += (wptr[3]) * (in_ptr[in_width + 1].rclrflt);
00365                 g_acc += (wptr[3]) * (in_ptr[in_width + 1].gclrflt);
00366                 b_acc += (wptr[3]) * (in_ptr[in_width + 1].bclrflt);
00367         ;
00368                     }
00369                 }
00370                 
00371             
00372                 r_acc_int = r_acc;
00373                 if (r_acc_int > 255)
00374                     r_acc_int = 255;
00375                 ((out_ptr)[0]) = r_acc_int;
00376                 g_acc_int = g_acc;
00377                 if (g_acc_int > 255)
00378                     g_acc_int = 255;
00379                 ((out_ptr)[1]) = g_acc_int;
00380                 b_acc_int = b_acc;
00381                 if (b_acc_int > 255)
00382                     b_acc_int = 255;
00383                 ((out_ptr)[2]) = b_acc_int;
00384             ;
00385                 out_ptr += ((3) + (0));
00386                 xfrac += xfrac_incr;
00387                 yfrac += yfrac_incr;
00388                 if (xfrac < 0) {
00389                     xfrac &= 0x7fffffff;
00390                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00391                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00392                 } else {
00393                     in_x_int += in_x_incr_int;
00394                     in_ptr += in_x_incr_int;
00395                 }
00396                 if (yfrac < 0) {
00397                     yfrac &= 0x7fffffff;
00398                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00399                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00400                 } else {
00401                     in_y_int += in_y_incr_int;
00402                     in_ptr += in_width * in_y_incr_int;
00403                 }
00404             }
00405 
00406             
00407             for (x = lft_zero_cnt + lft_edge_cnt;
00408                  x < lft_zero_cnt + lft_edge_cnt + full_cnt; x++) {
00409                 ASSERT(in_x_int >= 0 && in_x_int < in_width-1);
00410                 ASSERT(in_y_int >= 0 && in_y_int < in_height-1);
00411                 ASSERT((RGBIntPixel *)(((char *)in_image + in_y_int *
00412                                 in_bytes_per_scan)) + in_x_int == in_ptr);
00413                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00414                                      [FIX31_TO_WGTIND(xfrac)];
00415                 
00416         
00417                 r_acc = (wptr[0]) * (in_ptr[0].rclrflt) +
00418                         (wptr[2]) * (in_ptr[in_width].rclrflt) +        
00419                         (wptr[1]) * (in_ptr[1].rclrflt) +
00420                         (wptr[3]) * (in_ptr[in_width+1].rclrflt);
00421                 g_acc = (wptr[0]) * (in_ptr[0].gclrflt) +
00422                         (wptr[2]) * (in_ptr[in_width].gclrflt) +        
00423                         (wptr[1]) * (in_ptr[1].gclrflt) +
00424                         (wptr[3]) * (in_ptr[in_width+1].gclrflt);
00425                 b_acc = (wptr[0]) * (in_ptr[0].bclrflt) +
00426                         (wptr[2]) * (in_ptr[in_width].bclrflt) +        
00427                         (wptr[1]) * (in_ptr[1].bclrflt) +
00428                         (wptr[3]) * (in_ptr[in_width+1].bclrflt);
00429         ;
00430                 
00431             
00432                 r_acc_int = r_acc;
00433                 if (r_acc_int > 255)
00434                     r_acc_int = 255;
00435                 ((out_ptr)[0]) = r_acc_int;
00436                 g_acc_int = g_acc;
00437                 if (g_acc_int > 255)
00438                     g_acc_int = 255;
00439                 ((out_ptr)[1]) = g_acc_int;
00440                 b_acc_int = b_acc;
00441                 if (b_acc_int > 255)
00442                     b_acc_int = 255;
00443                 ((out_ptr)[2]) = b_acc_int;
00444             ;
00445                 out_ptr += ((3) + (0));
00446                 xfrac += xfrac_incr;
00447                 yfrac += yfrac_incr;
00448                 if (xfrac < 0) {
00449                     xfrac &= 0x7fffffff;
00450                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00451                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00452                 } else {
00453                     in_x_int += in_x_incr_int;
00454                     in_ptr += in_x_incr_int;
00455                 }
00456                 if (yfrac < 0) {
00457                     yfrac &= 0x7fffffff;
00458                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00459                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00460                 } else {
00461                     in_y_int += in_y_incr_int;
00462                     in_ptr += in_width * in_y_incr_int;
00463                 }
00464             }
00465 
00466             
00467             for (x = lft_zero_cnt + lft_edge_cnt + full_cnt;
00468                  x < lft_zero_cnt + lft_edge_cnt + full_cnt + rgt_edge_cnt;
00469                  x++) {
00470                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00471                                      [FIX31_TO_WGTIND(xfrac)];
00472                 
00473         r_acc = g_acc = b_acc = 0;
00474         ;
00475                 if (in_x_int >= 0 && in_x_int < in_width) {
00476                     if (in_y_int >= 0 && in_y_int < in_height) {
00477                         
00478         
00479                 r_acc += (wptr[0]) * (in_ptr[0].rclrflt);
00480                 g_acc += (wptr[0]) * (in_ptr[0].gclrflt);
00481                 b_acc += (wptr[0]) * (in_ptr[0].bclrflt);
00482         ;
00483                     }
00484                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00485                         
00486         
00487                 r_acc += (wptr[2]) * (in_ptr[in_width].rclrflt);
00488                 g_acc += (wptr[2]) * (in_ptr[in_width].gclrflt);
00489                 b_acc += (wptr[2]) * (in_ptr[in_width].bclrflt);
00490         ;
00491                     }
00492                 }
00493                 if (in_x_int+1 >= 0 && in_x_int+1 < in_width) {
00494                     if (in_y_int >= 0 && in_y_int < in_height) {
00495                         
00496         
00497                 r_acc += (wptr[1]) * (in_ptr[1].rclrflt);
00498                 g_acc += (wptr[1]) * (in_ptr[1].gclrflt);
00499                 b_acc += (wptr[1]) * (in_ptr[1].bclrflt);
00500         ;
00501                     }
00502                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00503                         
00504         
00505                 r_acc += (wptr[3]) * (in_ptr[in_width + 1].rclrflt);
00506                 g_acc += (wptr[3]) * (in_ptr[in_width + 1].gclrflt);
00507                 b_acc += (wptr[3]) * (in_ptr[in_width + 1].bclrflt);
00508         ;
00509                     }
00510                 }
00511                 
00512             
00513                 r_acc_int = r_acc;
00514                 if (r_acc_int > 255)
00515                     r_acc_int = 255;
00516                 ((out_ptr)[0]) = r_acc_int;
00517                 g_acc_int = g_acc;
00518                 if (g_acc_int > 255)
00519                     g_acc_int = 255;
00520                 ((out_ptr)[1]) = g_acc_int;
00521                 b_acc_int = b_acc;
00522                 if (b_acc_int > 255)
00523                     b_acc_int = 255;
00524                 ((out_ptr)[2]) = b_acc_int;
00525             ;
00526                 out_ptr += ((3) + (0));
00527                 xfrac += xfrac_incr;
00528                 yfrac += yfrac_incr;
00529                 if (xfrac < 0) {
00530                     xfrac &= 0x7fffffff;
00531                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00532                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00533                 } else {
00534                     in_x_int += in_x_incr_int;
00535                     in_ptr += in_x_incr_int;
00536                 }
00537                 if (yfrac < 0) {
00538                     yfrac &= 0x7fffffff;
00539                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00540                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00541                 } else {
00542                     in_y_int += in_y_incr_int;
00543                     in_ptr += in_width * in_y_incr_int;
00544                 }
00545             }
00546 
00547             
00548             if (rgt_zero_cnt > 0) {
00549                 bzero(out_ptr, rgt_zero_cnt * ((3) + (0)));
00550                 out_ptr += rgt_zero_cnt * ((3) + (0));
00551             }
00552 
00553             
00554             scans_to_next_vertex--;
00555             out_scan_y++;
00556             out_ptr += out_bytes_per_scan - out_width * ((3) + (0));
00557             x_lft_full += full_overlap[region].x_incr_lft;
00558             x_rgt_full += full_overlap[region].x_incr_rgt;
00559             x_lft_part += part_overlap[region].x_incr_lft;
00560             x_rgt_part += part_overlap[region].x_incr_rgt;
00561         } 
00562     } 
00563     ASSERT(out_scan_y == out_height);
00564 }