Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
vp_warpA331R.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 VPWarpA331R (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         float opc_acc; int opc_acc_int;         
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) + (1)); 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) + (1)));
00324                 out_ptr += lft_zero_cnt * ((3) + (1));
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         opc_acc = 0;;
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         opc_acc += (wptr[0]) * (in_ptr[0].opcflt);;
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         opc_acc += (wptr[2]) * (in_ptr[in_width].opcflt);;
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         opc_acc += (wptr[1]) * (in_ptr[1].opcflt);;
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         opc_acc += (wptr[3]) * (in_ptr[in_width + 1].opcflt);;
00368                     }
00369                 }
00370                 
00371             
00372         opc_acc_int = opc_acc * (float)255.;
00373         if (opc_acc_int > 255)
00374             opc_acc_int = 255;
00375         ((out_ptr)[0]) = opc_acc_int;
00376             
00377                 r_acc_int = r_acc;
00378                 if (r_acc_int > 255)
00379                     r_acc_int = 255;
00380                 ((out_ptr)[1+2]) = r_acc_int;
00381                 g_acc_int = g_acc;
00382                 if (g_acc_int > 255)
00383                     g_acc_int = 255;
00384                 ((out_ptr)[1+1]) = g_acc_int;
00385                 b_acc_int = b_acc;
00386                 if (b_acc_int > 255)
00387                     b_acc_int = 255;
00388                 ((out_ptr)[1+0]) = b_acc_int;;
00389                 out_ptr += ((3) + (1));
00390                 xfrac += xfrac_incr;
00391                 yfrac += yfrac_incr;
00392                 if (xfrac < 0) {
00393                     xfrac &= 0x7fffffff;
00394                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00395                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00396                 } else {
00397                     in_x_int += in_x_incr_int;
00398                     in_ptr += in_x_incr_int;
00399                 }
00400                 if (yfrac < 0) {
00401                     yfrac &= 0x7fffffff;
00402                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00403                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00404                 } else {
00405                     in_y_int += in_y_incr_int;
00406                     in_ptr += in_width * in_y_incr_int;
00407                 }
00408             }
00409 
00410             
00411             for (x = lft_zero_cnt + lft_edge_cnt;
00412                  x < lft_zero_cnt + lft_edge_cnt + full_cnt; x++) {
00413                 ASSERT(in_x_int >= 0 && in_x_int < in_width-1);
00414                 ASSERT(in_y_int >= 0 && in_y_int < in_height-1);
00415                 ASSERT((RGBIntPixel *)(((char *)in_image + in_y_int *
00416                                 in_bytes_per_scan)) + in_x_int == in_ptr);
00417                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00418                                      [FIX31_TO_WGTIND(xfrac)];
00419                 
00420         
00421                 r_acc = (wptr[0]) * (in_ptr[0].rclrflt) +
00422                         (wptr[2]) * (in_ptr[in_width].rclrflt) +        
00423                         (wptr[1]) * (in_ptr[1].rclrflt) +
00424                         (wptr[3]) * (in_ptr[in_width+1].rclrflt);
00425                 g_acc = (wptr[0]) * (in_ptr[0].gclrflt) +
00426                         (wptr[2]) * (in_ptr[in_width].gclrflt) +        
00427                         (wptr[1]) * (in_ptr[1].gclrflt) +
00428                         (wptr[3]) * (in_ptr[in_width+1].gclrflt);
00429                 b_acc = (wptr[0]) * (in_ptr[0].bclrflt) +
00430                         (wptr[2]) * (in_ptr[in_width].bclrflt) +        
00431                         (wptr[1]) * (in_ptr[1].bclrflt) +
00432                         (wptr[3]) * (in_ptr[in_width+1].bclrflt);
00433         
00434         opc_acc = (wptr[0]) * (in_ptr[0].opcflt) +
00435                   (wptr[2]) * (in_ptr[in_width].opcflt) +       
00436                   (wptr[1]) * (in_ptr[1].opcflt) +
00437                   (wptr[3]) * (in_ptr[in_width+1].opcflt);;
00438                 
00439             
00440         opc_acc_int = opc_acc * (float)255.;
00441         if (opc_acc_int > 255)
00442             opc_acc_int = 255;
00443         ((out_ptr)[0]) = opc_acc_int;
00444             
00445                 r_acc_int = r_acc;
00446                 if (r_acc_int > 255)
00447                     r_acc_int = 255;
00448                 ((out_ptr)[1+2]) = r_acc_int;
00449                 g_acc_int = g_acc;
00450                 if (g_acc_int > 255)
00451                     g_acc_int = 255;
00452                 ((out_ptr)[1+1]) = g_acc_int;
00453                 b_acc_int = b_acc;
00454                 if (b_acc_int > 255)
00455                     b_acc_int = 255;
00456                 ((out_ptr)[1+0]) = b_acc_int;;
00457                 out_ptr += ((3) + (1));
00458                 xfrac += xfrac_incr;
00459                 yfrac += yfrac_incr;
00460                 if (xfrac < 0) {
00461                     xfrac &= 0x7fffffff;
00462                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00463                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00464                 } else {
00465                     in_x_int += in_x_incr_int;
00466                     in_ptr += in_x_incr_int;
00467                 }
00468                 if (yfrac < 0) {
00469                     yfrac &= 0x7fffffff;
00470                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00471                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00472                 } else {
00473                     in_y_int += in_y_incr_int;
00474                     in_ptr += in_width * in_y_incr_int;
00475                 }
00476             }
00477 
00478             
00479             for (x = lft_zero_cnt + lft_edge_cnt + full_cnt;
00480                  x < lft_zero_cnt + lft_edge_cnt + full_cnt + rgt_edge_cnt;
00481                  x++) {
00482                 wptr = VPBilirpWeight[FIX31_TO_WGTIND(yfrac)]
00483                                      [FIX31_TO_WGTIND(xfrac)];
00484                 
00485         r_acc = g_acc = b_acc = 0;
00486         opc_acc = 0;;
00487                 if (in_x_int >= 0 && in_x_int < in_width) {
00488                     if (in_y_int >= 0 && in_y_int < in_height) {
00489                         
00490         
00491                 r_acc += (wptr[0]) * (in_ptr[0].rclrflt);
00492                 g_acc += (wptr[0]) * (in_ptr[0].gclrflt);
00493                 b_acc += (wptr[0]) * (in_ptr[0].bclrflt);
00494         opc_acc += (wptr[0]) * (in_ptr[0].opcflt);;
00495                     }
00496                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00497                         
00498         
00499                 r_acc += (wptr[2]) * (in_ptr[in_width].rclrflt);
00500                 g_acc += (wptr[2]) * (in_ptr[in_width].gclrflt);
00501                 b_acc += (wptr[2]) * (in_ptr[in_width].bclrflt);
00502         opc_acc += (wptr[2]) * (in_ptr[in_width].opcflt);;
00503                     }
00504                 }
00505                 if (in_x_int+1 >= 0 && in_x_int+1 < in_width) {
00506                     if (in_y_int >= 0 && in_y_int < in_height) {
00507                         
00508         
00509                 r_acc += (wptr[1]) * (in_ptr[1].rclrflt);
00510                 g_acc += (wptr[1]) * (in_ptr[1].gclrflt);
00511                 b_acc += (wptr[1]) * (in_ptr[1].bclrflt);
00512         opc_acc += (wptr[1]) * (in_ptr[1].opcflt);;
00513                     }
00514                     if (in_y_int+1 >= 0 && in_y_int+1 < in_height) {
00515                         
00516         
00517                 r_acc += (wptr[3]) * (in_ptr[in_width + 1].rclrflt);
00518                 g_acc += (wptr[3]) * (in_ptr[in_width + 1].gclrflt);
00519                 b_acc += (wptr[3]) * (in_ptr[in_width + 1].bclrflt);
00520         opc_acc += (wptr[3]) * (in_ptr[in_width + 1].opcflt);;
00521                     }
00522                 }
00523                 
00524             
00525         opc_acc_int = opc_acc * (float)255.;
00526         if (opc_acc_int > 255)
00527             opc_acc_int = 255;
00528         ((out_ptr)[0]) = opc_acc_int;
00529             
00530                 r_acc_int = r_acc;
00531                 if (r_acc_int > 255)
00532                     r_acc_int = 255;
00533                 ((out_ptr)[1+2]) = r_acc_int;
00534                 g_acc_int = g_acc;
00535                 if (g_acc_int > 255)
00536                     g_acc_int = 255;
00537                 ((out_ptr)[1+1]) = g_acc_int;
00538                 b_acc_int = b_acc;
00539                 if (b_acc_int > 255)
00540                     b_acc_int = 255;
00541                 ((out_ptr)[1+0]) = b_acc_int;;
00542                 out_ptr += ((3) + (1));
00543                 xfrac += xfrac_incr;
00544                 yfrac += yfrac_incr;
00545                 if (xfrac < 0) {
00546                     xfrac &= 0x7fffffff;
00547                     in_x_int += in_x_incr_int + in_x_incr_dlt;
00548                     in_ptr += in_x_incr_int + in_x_incr_dlt;
00549                 } else {
00550                     in_x_int += in_x_incr_int;
00551                     in_ptr += in_x_incr_int;
00552                 }
00553                 if (yfrac < 0) {
00554                     yfrac &= 0x7fffffff;
00555                     in_y_int += in_y_incr_int + in_y_incr_dlt;
00556                     in_ptr += in_width * (in_y_incr_int + in_y_incr_dlt);
00557                 } else {
00558                     in_y_int += in_y_incr_int;
00559                     in_ptr += in_width * in_y_incr_int;
00560                 }
00561             }
00562 
00563             
00564             if (rgt_zero_cnt > 0) {
00565                 bzero(out_ptr, rgt_zero_cnt * ((3) + (1)));
00566                 out_ptr += rgt_zero_cnt * ((3) + (1));
00567             }
00568 
00569             
00570             scans_to_next_vertex--;
00571             out_scan_y++;
00572             out_ptr += out_bytes_per_scan - out_width * ((3) + (1));
00573             x_lft_full += full_overlap[region].x_incr_lft;
00574             x_rgt_full += full_overlap[region].x_incr_rgt;
00575             x_lft_part += part_overlap[region].x_incr_lft;
00576             x_rgt_part += part_overlap[region].x_incr_rgt;
00577         } 
00578     } 
00579     ASSERT(out_scan_y == out_height);
00580 }