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 }