Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 /* 00017 * roplow.c 00018 * 00019 * Low level dest-only 00020 * void rasteropUniLow() 00021 * static void rasteropUniWordAlignedlLow() 00022 * static void rasteropUniGeneralLow() 00023 * 00024 * Low level src and dest 00025 * void rasteropLow() 00026 * static void rasteropWordAlignedLow() 00027 * static void rasteropVAlignedLow() 00028 * static void rasteropGeneralLow() 00029 * 00030 */ 00031 00032 #include <stdio.h> 00033 #include <stdlib.h> 00034 #include <string.h> 00035 #include "allheaders.h" 00036 00037 #define COMBINE_PARTIAL(d, s, m) ( ((d) & ~(m)) | ((s) & (m)) ) 00038 00039 static const l_int32 SHIFT_LEFT = 0; 00040 static const l_int32 SHIFT_RIGHT = 1; 00041 00042 static void rasteropUniWordAlignedLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, 00043 l_int32 dy, l_int32 dw, l_int32 dh, 00044 l_int32 op); 00045 00046 static void rasteropUniGeneralLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, 00047 l_int32 dy, l_int32 dw, l_int32 dh, 00048 l_int32 op); 00049 00050 static void rasteropWordAlignedLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, 00051 l_int32 dy, l_int32 dw, l_int32 dh, 00052 l_int32 op, l_uint32 *datas, l_int32 swpl, 00053 l_int32 sx, l_int32 sy); 00054 00055 static void rasteropVAlignedLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, 00056 l_int32 dy, l_int32 dw, l_int32 dh, 00057 l_int32 op, l_uint32 *datas, l_int32 swpl, 00058 l_int32 sx, l_int32 sy); 00059 00060 static void rasteropGeneralLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, 00061 l_int32 dy, l_int32 dw, l_int32 dh, 00062 l_int32 op, l_uint32 *datas, l_int32 swpl, 00063 l_int32 sx, l_int32 sy); 00064 00065 00066 static const l_uint32 lmask32[] = {0x0, 00067 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 00068 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, 00069 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 00070 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 00071 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 00072 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, 00073 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 00074 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff}; 00075 00076 static const l_uint32 rmask32[] = {0x0, 00077 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 00078 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 00079 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 00080 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 00081 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 00082 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 00083 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 00084 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; 00085 00086 00087 /*--------------------------------------------------------------------* 00088 * Low-level dest-only rasterops * 00089 *--------------------------------------------------------------------*/ 00090 /*! 00091 * rasteropUniLow() 00092 * 00093 * Input: datad (ptr to dest image data) 00094 * dpixw (width of dest) 00095 * dpixh (height of dest) 00096 * depth (depth of src and dest) 00097 * dwpl (wpl of dest) 00098 * dx (x val of UL corner of dest rectangle) 00099 * dy (y val of UL corner of dest rectangle) 00100 * dw (width of dest rectangle) 00101 * dh (height of dest rectangle) 00102 * op (op code) 00103 * Return: void 00104 * 00105 * Action: scales width, performs clipping, checks alignment, and 00106 * dispatches for the rasterop. 00107 */ 00108 void 00109 rasteropUniLow(l_uint32 *datad, 00110 l_int32 dpixw, 00111 l_int32 dpixh, 00112 l_int32 depth, 00113 l_int32 dwpl, 00114 l_int32 dx, 00115 l_int32 dy, 00116 l_int32 dw, 00117 l_int32 dh, 00118 l_int32 op) 00119 { 00120 l_int32 dhangw, dhangh; 00121 00122 /* -------------------------------------------------------* 00123 * scale horizontal dimensions by depth 00124 * -------------------------------------------------------*/ 00125 if (depth != 1) { 00126 dpixw *= depth; 00127 dx *= depth; 00128 dw *= depth; 00129 } 00130 00131 /* -------------------------------------------------------* 00132 * clip rectangle to dest image 00133 * -------------------------------------------------------*/ 00134 /* first, clip horizontally (dx, dw) */ 00135 if (dx < 0) { 00136 dw += dx; /* reduce dw */ 00137 dx = 0; 00138 } 00139 dhangw = dx + dw - dpixw; /* rect ovhang dest to right */ 00140 if (dhangw > 0) 00141 dw -= dhangw; /* reduce dw */ 00142 00143 /* then, clip vertically (dy, dh) */ 00144 if (dy < 0) { 00145 dh += dy; /* reduce dh */ 00146 dy = 0; 00147 } 00148 dhangh = dy + dh - dpixh; /* rect ovhang dest below */ 00149 if (dhangh > 0) 00150 dh -= dhangh; /* reduce dh */ 00151 00152 /* if clipped entirely, quit */ 00153 if ((dw <= 0) || (dh <= 0)) 00154 return; 00155 00156 /* -------------------------------------------------------* 00157 * dispatch to aligned or non-aligned blitters 00158 * -------------------------------------------------------*/ 00159 if ((dx & 31) == 0) 00160 rasteropUniWordAlignedLow(datad, dwpl, dx, dy, dw, dh, op); 00161 else 00162 rasteropUniGeneralLow(datad, dwpl, dx, dy, dw, dh, op); 00163 return; 00164 } 00165 00166 00167 00168 /*--------------------------------------------------------------------* 00169 * Static low-level uni rasterop with word alignment * 00170 *--------------------------------------------------------------------*/ 00171 /*! 00172 * rasteropUniWordAlignedLow() 00173 * 00174 * Input: datad (ptr to dest image data) 00175 * dwpl (wpl of dest) 00176 * dx (x val of UL corner of dest rectangle) 00177 * dy (y val of UL corner of dest rectangle) 00178 * dw (width of dest rectangle) 00179 * dh (height of dest rectangle) 00180 * op (op code) 00181 * Return: void 00182 * 00183 * This is called when the dest rect is left aligned 00184 * on (32-bit) word boundaries. That is: dx & 31 == 0. 00185 * 00186 * We make an optimized implementation of this because 00187 * it is a common case: e.g., operating on a full dest image. 00188 */ 00189 static void 00190 rasteropUniWordAlignedLow(l_uint32 *datad, 00191 l_int32 dwpl, 00192 l_int32 dx, 00193 l_int32 dy, 00194 l_int32 dw, 00195 l_int32 dh, 00196 l_int32 op) 00197 { 00198 l_int32 nfullw; /* number of full words */ 00199 l_uint32 *pfword; /* ptr to first word */ 00200 l_int32 lwbits; /* number of ovrhang bits in last partial word */ 00201 l_uint32 lwmask; /* mask for last partial word */ 00202 l_uint32 *lined; 00203 l_int32 i, j; 00204 00205 /*--------------------------------------------------------* 00206 * Preliminary calculations * 00207 *--------------------------------------------------------*/ 00208 nfullw = dw >> 5; 00209 lwbits = dw & 31; 00210 if (lwbits) 00211 lwmask = lmask32[lwbits]; 00212 pfword = datad + dwpl * dy + (dx >> 5); 00213 00214 00215 /*--------------------------------------------------------* 00216 * Now we're ready to do the ops * 00217 *--------------------------------------------------------*/ 00218 switch (op) 00219 { 00220 case PIX_CLR: 00221 for (i = 0; i < dh; i++) { 00222 lined = pfword + i * dwpl; 00223 for (j = 0; j < nfullw; j++) 00224 *lined++ = 0x0; 00225 if (lwbits) 00226 *lined = COMBINE_PARTIAL(*lined, 0x0, lwmask); 00227 } 00228 break; 00229 case PIX_SET: 00230 for (i = 0; i < dh; i++) { 00231 lined = pfword + i * dwpl; 00232 for (j = 0; j < nfullw; j++) 00233 *lined++ = 0xffffffff; 00234 if (lwbits) 00235 *lined = COMBINE_PARTIAL(*lined, 0xffffffff, lwmask); 00236 } 00237 break; 00238 case PIX_NOT(PIX_DST): 00239 for (i = 0; i < dh; i++) { 00240 lined = pfword + i * dwpl; 00241 for (j = 0; j < nfullw; j++) { 00242 *lined = ~(*lined); 00243 lined++; 00244 } 00245 if (lwbits) 00246 *lined = COMBINE_PARTIAL(*lined, ~(*lined), lwmask); 00247 } 00248 break; 00249 default: 00250 fprintf(stderr, "Operation %d not permitted here!\n", op); 00251 } 00252 00253 return; 00254 } 00255 00256 00257 /*--------------------------------------------------------------------* 00258 * Static low-level uni rasterop without word alignment * 00259 *--------------------------------------------------------------------*/ 00260 /*! 00261 * rasteropUniGeneralLow() 00262 * 00263 * Input: datad (ptr to dest image data) 00264 * dwpl (wpl of dest) 00265 * dx (x val of UL corner of dest rectangle) 00266 * dy (y val of UL corner of dest rectangle) 00267 * dw (width of dest rectangle) 00268 * dh (height of dest rectangle) 00269 * op (op code) 00270 * Return: void 00271 */ 00272 static void 00273 rasteropUniGeneralLow(l_uint32 *datad, 00274 l_int32 dwpl, 00275 l_int32 dx, 00276 l_int32 dy, 00277 l_int32 dw, 00278 l_int32 dh, 00279 l_int32 op) 00280 { 00281 l_int32 dfwpartb; /* boolean (1, 0) if first dest word is partial */ 00282 l_int32 dfwpart2b; /* boolean (1, 0) if first dest word is doubly partial */ 00283 l_uint32 dfwmask; /* mask for first partial dest word */ 00284 l_int32 dfwbits; /* first word dest bits in ovrhang */ 00285 l_uint32 *pdfwpart; /* ptr to first partial dest word */ 00286 l_int32 dfwfullb; /* boolean (1, 0) if there exists a full dest word */ 00287 l_int32 dnfullw; /* number of full words in dest */ 00288 l_uint32 *pdfwfull; /* ptr to first full dest word */ 00289 l_int32 dlwpartb; /* boolean (1, 0) if last dest word is partial */ 00290 l_uint32 dlwmask; /* mask for last partial dest word */ 00291 l_int32 dlwbits; /* last word dest bits in ovrhang */ 00292 l_uint32 *pdlwpart; /* ptr to last partial dest word */ 00293 l_int32 i, j; 00294 00295 00296 /*--------------------------------------------------------* 00297 * Preliminary calculations * 00298 *--------------------------------------------------------*/ 00299 /* is the first word partial? */ 00300 if ((dx & 31) == 0) { /* if not */ 00301 dfwpartb = 0; 00302 dfwbits = 0; 00303 } 00304 else { /* if so */ 00305 dfwpartb = 1; 00306 dfwbits = 32 - (dx & 31); 00307 dfwmask = rmask32[dfwbits]; 00308 pdfwpart = datad + dwpl * dy + (dx >> 5); 00309 } 00310 00311 /* is the first word doubly partial? */ 00312 if (dw >= dfwbits) /* if not */ 00313 dfwpart2b = 0; 00314 else { /* if so */ 00315 dfwpart2b = 1; 00316 dfwmask &= lmask32[32 - dfwbits + dw]; 00317 } 00318 00319 /* is there a full dest word? */ 00320 if (dfwpart2b == 1) { /* not */ 00321 dfwfullb = 0; 00322 dnfullw = 0; 00323 } 00324 else { 00325 dnfullw = (dw - dfwbits) >> 5; 00326 if (dnfullw == 0) /* if not */ 00327 dfwfullb = 0; 00328 else { /* if so */ 00329 dfwfullb = 1; 00330 if (dfwpartb) 00331 pdfwfull = pdfwpart + 1; 00332 else 00333 pdfwfull = datad + dwpl * dy + (dx >> 5); 00334 } 00335 } 00336 00337 /* is the last word partial? */ 00338 dlwbits = (dx + dw) & 31; 00339 if (dfwpart2b == 1 || dlwbits == 0) /* if not */ 00340 dlwpartb = 0; 00341 else { 00342 dlwpartb = 1; 00343 dlwmask = lmask32[dlwbits]; 00344 if (dfwpartb) 00345 pdlwpart = pdfwpart + 1 + dnfullw; 00346 else 00347 pdlwpart = datad + dwpl * dy + (dx >> 5) + dnfullw; 00348 } 00349 00350 00351 /*--------------------------------------------------------* 00352 * Now we're ready to do the ops * 00353 *--------------------------------------------------------*/ 00354 switch (op) 00355 { 00356 case PIX_CLR: 00357 /* do the first partial word */ 00358 if (dfwpartb) { 00359 for (i = 0; i < dh; i++) { 00360 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 0x0, dfwmask); 00361 pdfwpart += dwpl; 00362 } 00363 } 00364 00365 /* do the full words */ 00366 if (dfwfullb) { 00367 for (i = 0; i < dh; i++) { 00368 for (j = 0; j < dnfullw; j++) 00369 *(pdfwfull + j) = 0x0; 00370 pdfwfull += dwpl; 00371 } 00372 } 00373 00374 /* do the last partial word */ 00375 if (dlwpartb) { 00376 for (i = 0; i < dh; i++) { 00377 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 0x0, dlwmask); 00378 pdlwpart += dwpl; 00379 } 00380 } 00381 break; 00382 case PIX_SET: 00383 /* do the first partial word */ 00384 if (dfwpartb) { 00385 for (i = 0; i < dh; i++) { 00386 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 0xffffffff, dfwmask); 00387 pdfwpart += dwpl; 00388 } 00389 } 00390 00391 /* do the full words */ 00392 if (dfwfullb) { 00393 for (i = 0; i < dh; i++) { 00394 for (j = 0; j < dnfullw; j++) 00395 *(pdfwfull + j) = 0xffffffff; 00396 pdfwfull += dwpl; 00397 } 00398 } 00399 00400 /* do the last partial word */ 00401 if (dlwpartb) { 00402 for (i = 0; i < dh; i++) { 00403 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 0xffffffff, dlwmask); 00404 pdlwpart += dwpl; 00405 } 00406 } 00407 break; 00408 case PIX_NOT(PIX_DST): 00409 /* do the first partial word */ 00410 if (dfwpartb) { 00411 for (i = 0; i < dh; i++) { 00412 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, ~(*pdfwpart), dfwmask); 00413 pdfwpart += dwpl; 00414 } 00415 } 00416 00417 /* do the full words */ 00418 if (dfwfullb) { 00419 for (i = 0; i < dh; i++) { 00420 for (j = 0; j < dnfullw; j++) 00421 *(pdfwfull + j) = ~(*(pdfwfull + j)); 00422 pdfwfull += dwpl; 00423 } 00424 } 00425 00426 /* do the last partial word */ 00427 if (dlwpartb) { 00428 for (i = 0; i < dh; i++) { 00429 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, ~(*pdlwpart), dlwmask); 00430 pdlwpart += dwpl; 00431 } 00432 } 00433 break; 00434 default: 00435 fprintf(stderr, "Operation %d not permitted here!\n", op); 00436 } 00437 00438 return; 00439 } 00440 00441 00442 00443 /*--------------------------------------------------------------------* 00444 * Low-level src and dest rasterops * 00445 *--------------------------------------------------------------------*/ 00446 /*! 00447 * rasteropLow() 00448 * 00449 * Input: datad (ptr to dest image data) 00450 * dpixw (width of dest) 00451 * dpixh (height of dest) 00452 * depth (depth of src and dest) 00453 * dwpl (wpl of dest) 00454 * dx (x val of UL corner of dest rectangle) 00455 * dy (y val of UL corner of dest rectangle) 00456 * dw (width of dest rectangle) 00457 * dh (height of dest rectangle) 00458 * op (op code) 00459 * datas (ptr to src image data) 00460 * spixw (width of src) 00461 * spixh (height of src) 00462 * swpl (wpl of src) 00463 * sx (x val of UL corner of src rectangle) 00464 * sy (y val of UL corner of src rectangle) 00465 * Return: void 00466 * 00467 * Action: Scales width, performs clipping, checks alignment, and 00468 * dispatches for the rasterop. 00469 * 00470 * Warning: the two images must have equal depth. This is not checked. 00471 */ 00472 void 00473 rasteropLow(l_uint32 *datad, 00474 l_int32 dpixw, 00475 l_int32 dpixh, 00476 l_int32 depth, 00477 l_int32 dwpl, 00478 l_int32 dx, 00479 l_int32 dy, 00480 l_int32 dw, 00481 l_int32 dh, 00482 l_int32 op, 00483 l_uint32 *datas, 00484 l_int32 spixw, 00485 l_int32 spixh, 00486 l_int32 swpl, 00487 l_int32 sx, 00488 l_int32 sy) 00489 { 00490 l_int32 dhangw, shangw, dhangh, shangh; 00491 00492 /* -------------------------------------------------------* 00493 * scale horizontal dimensions by depth 00494 * -------------------------------------------------------*/ 00495 if (depth != 1) { 00496 dpixw *= depth; 00497 dx *= depth; 00498 dw *= depth; 00499 spixw *= depth; 00500 sx *= depth; 00501 } 00502 00503 00504 /* -------------------------------------------------------* 00505 * clip to max rectangle within both src and dest 00506 * -------------------------------------------------------*/ 00507 /* first, clip horizontally (sx, dx, dw) */ 00508 if (dx < 0) { 00509 sx -= dx; /* increase sx */ 00510 dw += dx; /* reduce dw */ 00511 dx = 0; 00512 } 00513 if (sx < 0) { 00514 dx -= sx; /* increase dx */ 00515 dw += sx; /* reduce dw */ 00516 sx = 0; 00517 } 00518 dhangw = dx + dw - dpixw; /* rect ovhang dest to right */ 00519 if (dhangw > 0) 00520 dw -= dhangw; /* reduce dw */ 00521 shangw = sx + dw - spixw; /* rect ovhang src to right */ 00522 if (shangw > 0) 00523 dw -= shangw; /* reduce dw */ 00524 00525 /* then, clip vertically (sy, dy, dh) */ 00526 if (dy < 0) { 00527 sy -= dy; /* increase sy */ 00528 dh += dy; /* reduce dh */ 00529 dy = 0; 00530 } 00531 if (sy < 0) { 00532 dy -= sy; /* increase dy */ 00533 dh += sy; /* reduce dh */ 00534 sy = 0; 00535 } 00536 dhangh = dy + dh - dpixh; /* rect ovhang dest below */ 00537 if (dhangh > 0) 00538 dh -= dhangh; /* reduce dh */ 00539 shangh = sy + dh - spixh; /* rect ovhang src below */ 00540 if (shangh > 0) 00541 dh -= shangh; /* reduce dh */ 00542 00543 /* if clipped entirely, quit */ 00544 if ((dw <= 0) || (dh <= 0)) 00545 return; 00546 00547 /* -------------------------------------------------------* 00548 * dispatch to aligned or non-aligned blitters 00549 * -------------------------------------------------------*/ 00550 if (((dx & 31) == 0) && ((sx & 31) == 0)) 00551 rasteropWordAlignedLow(datad, dwpl, dx, dy, dw, dh, op, 00552 datas, swpl, sx, sy); 00553 else if ((dx & 31) == (sx & 31)) 00554 rasteropVAlignedLow(datad, dwpl, dx, dy, dw, dh, op, 00555 datas, swpl, sx, sy); 00556 else 00557 rasteropGeneralLow(datad, dwpl, dx, dy, dw, dh, op, 00558 datas, swpl, sx, sy); 00559 00560 return; 00561 } 00562 00563 00564 /*--------------------------------------------------------------------* 00565 * Static low-level rasterop with vertical word alignment * 00566 *--------------------------------------------------------------------*/ 00567 /*! 00568 * rasteropWordAlignedLow() 00569 * 00570 * Input: datad (ptr to dest image data) 00571 * dwpl (wpl of dest) 00572 * dx (x val of UL corner of dest rectangle) 00573 * dy (y val of UL corner of dest rectangle) 00574 * dw (width of dest rectangle) 00575 * dh (height of dest rectangle) 00576 * op (op code) 00577 * datas (ptr to src image data) 00578 * swpl (wpl of src) 00579 * sx (x val of UL corner of src rectangle) 00580 * sy (y val of UL corner of src rectangle) 00581 * Return: void 00582 * 00583 * This is called when both the src and dest rects 00584 * are left aligned on (32-bit) word boundaries. 00585 * That is: dx & 31 == 0 and sx & 31 == 0 00586 * 00587 * We make an optimized implementation of this because 00588 * it is a common case: e.g., two images are rasterop'd 00589 * starting from their UL corners (0,0). 00590 */ 00591 static void 00592 rasteropWordAlignedLow(l_uint32 *datad, 00593 l_int32 dwpl, 00594 l_int32 dx, 00595 l_int32 dy, 00596 l_int32 dw, 00597 l_int32 dh, 00598 l_int32 op, 00599 l_uint32 *datas, 00600 l_int32 swpl, 00601 l_int32 sx, 00602 l_int32 sy) 00603 { 00604 l_int32 nfullw; /* number of full words */ 00605 l_uint32 *psfword; /* ptr to first src word */ 00606 l_uint32 *pdfword; /* ptr to first dest word */ 00607 l_int32 lwbits; /* number of ovrhang bits in last partial word */ 00608 l_uint32 lwmask; /* mask for last partial word */ 00609 l_uint32 *lines, *lined; 00610 l_int32 i, j; 00611 00612 00613 /*--------------------------------------------------------* 00614 * Preliminary calculations * 00615 *--------------------------------------------------------*/ 00616 nfullw = dw >> 5; 00617 lwbits = dw & 31; 00618 if (lwbits) 00619 lwmask = lmask32[lwbits]; 00620 psfword = datas + swpl * sy + (sx >> 5); 00621 pdfword = datad + dwpl * dy + (dx >> 5); 00622 00623 /*--------------------------------------------------------* 00624 * Now we're ready to do the ops * 00625 *--------------------------------------------------------*/ 00626 switch (op) 00627 { 00628 case PIX_SRC: 00629 for (i = 0; i < dh; i++) { 00630 lines = psfword + i * swpl; 00631 lined = pdfword + i * dwpl; 00632 for (j = 0; j < nfullw; j++) { 00633 *lined = *lines; 00634 lined++; 00635 lines++; 00636 } 00637 if (lwbits) 00638 *lined = COMBINE_PARTIAL(*lined, *lines, lwmask); 00639 } 00640 break; 00641 case PIX_NOT(PIX_SRC): 00642 for (i = 0; i < dh; i++) { 00643 lines = psfword + i * swpl; 00644 lined = pdfword + i * dwpl; 00645 for (j = 0; j < nfullw; j++) { 00646 *lined = ~(*lines); 00647 lined++; 00648 lines++; 00649 } 00650 if (lwbits) 00651 *lined = COMBINE_PARTIAL(*lined, ~(*lines), lwmask); 00652 } 00653 break; 00654 case (PIX_SRC | PIX_DST): 00655 for (i = 0; i < dh; i++) { 00656 lines = psfword + i * swpl; 00657 lined = pdfword + i * dwpl; 00658 for (j = 0; j < nfullw; j++) { 00659 *lined = (*lines | *lined); 00660 lined++; 00661 lines++; 00662 } 00663 if (lwbits) 00664 *lined = COMBINE_PARTIAL(*lined, (*lines | *lined), lwmask); 00665 } 00666 break; 00667 case (PIX_SRC & PIX_DST): 00668 for (i = 0; i < dh; i++) { 00669 lines = psfword + i * swpl; 00670 lined = pdfword + i * dwpl; 00671 for (j = 0; j < nfullw; j++) { 00672 *lined = (*lines & *lined); 00673 lined++; 00674 lines++; 00675 } 00676 if (lwbits) 00677 *lined = COMBINE_PARTIAL(*lined, (*lines & *lined), lwmask); 00678 } 00679 break; 00680 case (PIX_SRC ^ PIX_DST): 00681 for (i = 0; i < dh; i++) { 00682 lines = psfword + i * swpl; 00683 lined = pdfword + i * dwpl; 00684 for (j = 0; j < nfullw; j++) { 00685 *lined = (*lines ^ *lined); 00686 lined++; 00687 lines++; 00688 } 00689 if (lwbits) 00690 *lined = COMBINE_PARTIAL(*lined, (*lines ^ *lined), lwmask); 00691 } 00692 break; 00693 case (PIX_NOT(PIX_SRC) | PIX_DST): 00694 for (i = 0; i < dh; i++) { 00695 lines = psfword + i * swpl; 00696 lined = pdfword + i * dwpl; 00697 for (j = 0; j < nfullw; j++) { 00698 *lined = (~(*lines) | *lined); 00699 lined++; 00700 lines++; 00701 } 00702 if (lwbits) 00703 *lined = COMBINE_PARTIAL(*lined, (~(*lines) | *lined), lwmask); 00704 } 00705 break; 00706 case (PIX_NOT(PIX_SRC) & PIX_DST): 00707 for (i = 0; i < dh; i++) { 00708 lines = psfword + i * swpl; 00709 lined = pdfword + i * dwpl; 00710 for (j = 0; j < nfullw; j++) { 00711 *lined = (~(*lines) & *lined); 00712 lined++; 00713 lines++; 00714 } 00715 if (lwbits) 00716 *lined = COMBINE_PARTIAL(*lined, (~(*lines) & *lined), lwmask); 00717 } 00718 break; 00719 case (PIX_SRC | PIX_NOT(PIX_DST)): 00720 for (i = 0; i < dh; i++) { 00721 lines = psfword + i * swpl; 00722 lined = pdfword + i * dwpl; 00723 for (j = 0; j < nfullw; j++) { 00724 *lined = (*lines | ~(*lined)); 00725 lined++; 00726 lines++; 00727 } 00728 if (lwbits) 00729 *lined = COMBINE_PARTIAL(*lined, (*lines | ~(*lined)), lwmask); 00730 } 00731 break; 00732 case (PIX_SRC & PIX_NOT(PIX_DST)): 00733 for (i = 0; i < dh; i++) { 00734 lines = psfword + i * swpl; 00735 lined = pdfword + i * dwpl; 00736 for (j = 0; j < nfullw; j++) { 00737 *lined = (*lines & ~(*lined)); 00738 lined++; 00739 lines++; 00740 } 00741 if (lwbits) 00742 *lined = COMBINE_PARTIAL(*lined, (*lines & ~(*lined)), lwmask); 00743 } 00744 break; 00745 case (PIX_NOT(PIX_SRC | PIX_DST)): 00746 for (i = 0; i < dh; i++) { 00747 lines = psfword + i * swpl; 00748 lined = pdfword + i * dwpl; 00749 for (j = 0; j < nfullw; j++) { 00750 *lined = ~(*lines | *lined); 00751 lined++; 00752 lines++; 00753 } 00754 if (lwbits) 00755 *lined = COMBINE_PARTIAL(*lined, ~(*lines | *lined), lwmask); 00756 } 00757 break; 00758 case (PIX_NOT(PIX_SRC & PIX_DST)): 00759 for (i = 0; i < dh; i++) { 00760 lines = psfword + i * swpl; 00761 lined = pdfword + i * dwpl; 00762 for (j = 0; j < nfullw; j++) { 00763 *lined = ~(*lines & *lined); 00764 lined++; 00765 lines++; 00766 } 00767 if (lwbits) 00768 *lined = COMBINE_PARTIAL(*lined, ~(*lines & *lined), lwmask); 00769 } 00770 break; 00771 /* this is three cases: ~(s ^ d), ~s ^ d, s ^ ~d */ 00772 case (PIX_NOT(PIX_SRC ^ PIX_DST)): 00773 for (i = 0; i < dh; i++) { 00774 lines = psfword + i * swpl; 00775 lined = pdfword + i * dwpl; 00776 for (j = 0; j < nfullw; j++) { 00777 *lined = ~(*lines ^ *lined); 00778 lined++; 00779 lines++; 00780 } 00781 if (lwbits) 00782 *lined = COMBINE_PARTIAL(*lined, ~(*lines ^ *lined), lwmask); 00783 } 00784 break; 00785 default: 00786 fprintf(stderr, "Operation %d invalid\n", op); 00787 } 00788 00789 return; 00790 } 00791 00792 00793 00794 /*--------------------------------------------------------------------* 00795 * Static low-level rasterop with vertical word alignment * 00796 *--------------------------------------------------------------------*/ 00797 /*! 00798 * rasteropVAlignedLow() 00799 * 00800 * Input: datad (ptr to dest image data) 00801 * dwpl (wpl of dest) 00802 * dx (x val of UL corner of dest rectangle) 00803 * dy (y val of UL corner of dest rectangle) 00804 * dw (width of dest rectangle) 00805 * dh (height of dest rectangle) 00806 * op (op code) 00807 * datas (ptr to src image data) 00808 * swpl (wpl of src) 00809 * sx (x val of UL corner of src rectangle) 00810 * sy (y val of UL corner of src rectangle) 00811 * Return: void 00812 * 00813 * This is called when the left side of the src and dest 00814 * rects have the same alignment relative to (32-bit) word 00815 * boundaries; i.e., (dx & 31) == (sx & 31) 00816 */ 00817 static void 00818 rasteropVAlignedLow(l_uint32 *datad, 00819 l_int32 dwpl, 00820 l_int32 dx, 00821 l_int32 dy, 00822 l_int32 dw, 00823 l_int32 dh, 00824 l_int32 op, 00825 l_uint32 *datas, 00826 l_int32 swpl, 00827 l_int32 sx, 00828 l_int32 sy) 00829 { 00830 l_int32 dfwpartb; /* boolean (1, 0) if first dest word is partial */ 00831 l_int32 dfwpart2b; /* boolean (1, 0) if first dest word is doubly partial */ 00832 l_uint32 dfwmask; /* mask for first partial dest word */ 00833 l_int32 dfwbits; /* first word dest bits in ovrhang */ 00834 l_uint32 *pdfwpart; /* ptr to first partial dest word */ 00835 l_uint32 *psfwpart; /* ptr to first partial src word */ 00836 l_int32 dfwfullb; /* boolean (1, 0) if there exists a full dest word */ 00837 l_int32 dnfullw; /* number of full words in dest */ 00838 l_uint32 *pdfwfull; /* ptr to first full dest word */ 00839 l_uint32 *psfwfull; /* ptr to first full src word */ 00840 l_int32 dlwpartb; /* boolean (1, 0) if last dest word is partial */ 00841 l_uint32 dlwmask; /* mask for last partial dest word */ 00842 l_int32 dlwbits; /* last word dest bits in ovrhang */ 00843 l_uint32 *pdlwpart; /* ptr to last partial dest word */ 00844 l_uint32 *pslwpart; /* ptr to last partial src word */ 00845 l_int32 i, j; 00846 00847 00848 /*--------------------------------------------------------* 00849 * Preliminary calculations * 00850 *--------------------------------------------------------*/ 00851 /* is the first word partial? */ 00852 if ((dx & 31) == 0) { /* if not */ 00853 dfwpartb = 0; 00854 dfwbits = 0; 00855 } 00856 else { /* if so */ 00857 dfwpartb = 1; 00858 dfwbits = 32 - (dx & 31); 00859 dfwmask = rmask32[dfwbits]; 00860 pdfwpart = datad + dwpl * dy + (dx >> 5); 00861 psfwpart = datas + swpl * sy + (sx >> 5); 00862 } 00863 00864 /* is the first word doubly partial? */ 00865 if (dw >= dfwbits) /* if not */ 00866 dfwpart2b = 0; 00867 else { /* if so */ 00868 dfwpart2b = 1; 00869 dfwmask &= lmask32[32 - dfwbits + dw]; 00870 } 00871 00872 /* is there a full dest word? */ 00873 if (dfwpart2b == 1) { /* not */ 00874 dfwfullb = 0; 00875 dnfullw = 0; 00876 } 00877 else { 00878 dnfullw = (dw - dfwbits) >> 5; 00879 if (dnfullw == 0) /* if not */ 00880 dfwfullb = 0; 00881 else { /* if so */ 00882 dfwfullb = 1; 00883 if (dfwpartb) { 00884 pdfwfull = pdfwpart + 1; 00885 psfwfull = psfwpart + 1; 00886 } 00887 else { 00888 pdfwfull = datad + dwpl * dy + (dx >> 5); 00889 psfwfull = datas + swpl * sy + (sx >> 5); 00890 } 00891 } 00892 } 00893 00894 /* is the last word partial? */ 00895 dlwbits = (dx + dw) & 31; 00896 if (dfwpart2b == 1 || dlwbits == 0) /* if not */ 00897 dlwpartb = 0; 00898 else { 00899 dlwpartb = 1; 00900 dlwmask = lmask32[dlwbits]; 00901 if (dfwpartb) { 00902 pdlwpart = pdfwpart + 1 + dnfullw; 00903 pslwpart = psfwpart + 1 + dnfullw; 00904 } 00905 else { 00906 pdlwpart = datad + dwpl * dy + (dx >> 5) + dnfullw; 00907 pslwpart = datas + swpl * sy + (sx >> 5) + dnfullw; 00908 } 00909 } 00910 00911 00912 /*--------------------------------------------------------* 00913 * Now we're ready to do the ops * 00914 *--------------------------------------------------------*/ 00915 switch (op) 00916 { 00917 case PIX_SRC: 00918 /* do the first partial word */ 00919 if (dfwpartb) { 00920 for (i = 0; i < dh; i++) { 00921 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, *psfwpart, dfwmask); 00922 pdfwpart += dwpl; 00923 psfwpart += swpl; 00924 } 00925 } 00926 00927 /* do the full words */ 00928 if (dfwfullb) { 00929 for (i = 0; i < dh; i++) { 00930 for (j = 0; j < dnfullw; j++) 00931 *(pdfwfull + j) = *(psfwfull + j); 00932 pdfwfull += dwpl; 00933 psfwfull += swpl; 00934 } 00935 } 00936 00937 /* do the last partial word */ 00938 if (dlwpartb) { 00939 for (i = 0; i < dh; i++) { 00940 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, *pslwpart, dlwmask); 00941 pdlwpart += dwpl; 00942 pslwpart += swpl; 00943 } 00944 } 00945 break; 00946 case PIX_NOT(PIX_SRC): 00947 /* do the first partial word */ 00948 if (dfwpartb) { 00949 for (i = 0; i < dh; i++) { 00950 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, ~(*psfwpart), dfwmask); 00951 pdfwpart += dwpl; 00952 psfwpart += swpl; 00953 } 00954 } 00955 00956 /* do the full words */ 00957 if (dfwfullb) { 00958 for (i = 0; i < dh; i++) { 00959 for (j = 0; j < dnfullw; j++) 00960 *(pdfwfull + j) = ~(*(psfwfull + j)); 00961 pdfwfull += dwpl; 00962 psfwfull += swpl; 00963 } 00964 } 00965 00966 /* do the last partial word */ 00967 if (dlwpartb) { 00968 for (i = 0; i < dh; i++) { 00969 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, ~(*pslwpart), dlwmask); 00970 pdlwpart += dwpl; 00971 pslwpart += swpl; 00972 } 00973 } 00974 break; 00975 case (PIX_SRC | PIX_DST): 00976 /* do the first partial word */ 00977 if (dfwpartb) { 00978 for (i = 0; i < dh; i++) { 00979 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 00980 (*psfwpart | *pdfwpart), dfwmask); 00981 pdfwpart += dwpl; 00982 psfwpart += swpl; 00983 } 00984 } 00985 00986 /* do the full words */ 00987 if (dfwfullb) { 00988 for (i = 0; i < dh; i++) { 00989 for (j = 0; j < dnfullw; j++) 00990 *(pdfwfull + j) |= *(psfwfull + j); 00991 pdfwfull += dwpl; 00992 psfwfull += swpl; 00993 } 00994 } 00995 00996 /* do the last partial word */ 00997 if (dlwpartb) { 00998 for (i = 0; i < dh; i++) { 00999 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01000 (*pslwpart | *pdlwpart), dlwmask); 01001 pdlwpart += dwpl; 01002 pslwpart += swpl; 01003 } 01004 } 01005 break; 01006 case (PIX_SRC & PIX_DST): 01007 /* do the first partial word */ 01008 if (dfwpartb) { 01009 for (i = 0; i < dh; i++) { 01010 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01011 (*psfwpart & *pdfwpart), dfwmask); 01012 pdfwpart += dwpl; 01013 psfwpart += swpl; 01014 } 01015 } 01016 01017 /* do the full words */ 01018 if (dfwfullb) { 01019 for (i = 0; i < dh; i++) { 01020 for (j = 0; j < dnfullw; j++) 01021 *(pdfwfull + j) &= *(psfwfull + j); 01022 pdfwfull += dwpl; 01023 psfwfull += swpl; 01024 } 01025 } 01026 01027 /* do the last partial word */ 01028 if (dlwpartb) { 01029 for (i = 0; i < dh; i++) { 01030 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01031 (*pslwpart & *pdlwpart), dlwmask); 01032 pdlwpart += dwpl; 01033 pslwpart += swpl; 01034 } 01035 } 01036 break; 01037 case (PIX_SRC ^ PIX_DST): 01038 /* do the first partial word */ 01039 if (dfwpartb) { 01040 for (i = 0; i < dh; i++) { 01041 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01042 (*psfwpart ^ *pdfwpart), dfwmask); 01043 pdfwpart += dwpl; 01044 psfwpart += swpl; 01045 } 01046 } 01047 01048 /* do the full words */ 01049 if (dfwfullb) { 01050 for (i = 0; i < dh; i++) { 01051 for (j = 0; j < dnfullw; j++) 01052 *(pdfwfull + j) ^= *(psfwfull + j); 01053 pdfwfull += dwpl; 01054 psfwfull += swpl; 01055 } 01056 } 01057 01058 /* do the last partial word */ 01059 if (dlwpartb) { 01060 for (i = 0; i < dh; i++) { 01061 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01062 (*pslwpart ^ *pdlwpart), dlwmask); 01063 pdlwpart += dwpl; 01064 pslwpart += swpl; 01065 } 01066 } 01067 break; 01068 case (PIX_NOT(PIX_SRC) | PIX_DST): 01069 /* do the first partial word */ 01070 if (dfwpartb) { 01071 for (i = 0; i < dh; i++) { 01072 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01073 (~(*psfwpart) | *pdfwpart), dfwmask); 01074 pdfwpart += dwpl; 01075 psfwpart += swpl; 01076 } 01077 } 01078 01079 /* do the full words */ 01080 if (dfwfullb) { 01081 for (i = 0; i < dh; i++) { 01082 for (j = 0; j < dnfullw; j++) 01083 *(pdfwfull + j) |= ~(*(psfwfull + j)); 01084 pdfwfull += dwpl; 01085 psfwfull += swpl; 01086 } 01087 } 01088 01089 /* do the last partial word */ 01090 if (dlwpartb) { 01091 for (i = 0; i < dh; i++) { 01092 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01093 (~(*pslwpart) | *pdlwpart), dlwmask); 01094 pdlwpart += dwpl; 01095 pslwpart += swpl; 01096 } 01097 } 01098 break; 01099 case (PIX_NOT(PIX_SRC) & PIX_DST): 01100 /* do the first partial word */ 01101 if (dfwpartb) { 01102 for (i = 0; i < dh; i++) { 01103 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01104 (~(*psfwpart) & *pdfwpart), dfwmask); 01105 pdfwpart += dwpl; 01106 psfwpart += swpl; 01107 } 01108 } 01109 01110 /* do the full words */ 01111 if (dfwfullb) { 01112 for (i = 0; i < dh; i++) { 01113 for (j = 0; j < dnfullw; j++) 01114 *(pdfwfull + j) &= ~(*(psfwfull + j)); 01115 pdfwfull += dwpl; 01116 psfwfull += swpl; 01117 } 01118 } 01119 01120 /* do the last partial word */ 01121 if (dlwpartb) { 01122 for (i = 0; i < dh; i++) { 01123 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01124 (~(*pslwpart) & *pdlwpart), dlwmask); 01125 pdlwpart += dwpl; 01126 pslwpart += swpl; 01127 } 01128 } 01129 break; 01130 case (PIX_SRC | PIX_NOT(PIX_DST)): 01131 /* do the first partial word */ 01132 if (dfwpartb) { 01133 for (i = 0; i < dh; i++) { 01134 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01135 (*psfwpart | ~(*pdfwpart)), dfwmask); 01136 pdfwpart += dwpl; 01137 psfwpart += swpl; 01138 } 01139 } 01140 01141 /* do the full words */ 01142 if (dfwfullb) { 01143 for (i = 0; i < dh; i++) { 01144 for (j = 0; j < dnfullw; j++) 01145 *(pdfwfull + j) = *(psfwfull + j) | ~(*(pdfwfull + j)); 01146 pdfwfull += dwpl; 01147 psfwfull += swpl; 01148 } 01149 } 01150 01151 /* do the last partial word */ 01152 if (dlwpartb) { 01153 for (i = 0; i < dh; i++) { 01154 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01155 (*pslwpart | ~(*pdlwpart)), dlwmask); 01156 pdlwpart += dwpl; 01157 pslwpart += swpl; 01158 } 01159 } 01160 break; 01161 case (PIX_SRC & PIX_NOT(PIX_DST)): 01162 /* do the first partial word */ 01163 if (dfwpartb) { 01164 for (i = 0; i < dh; i++) { 01165 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01166 (*psfwpart & ~(*pdfwpart)), dfwmask); 01167 pdfwpart += dwpl; 01168 psfwpart += swpl; 01169 } 01170 } 01171 01172 /* do the full words */ 01173 if (dfwfullb) { 01174 for (i = 0; i < dh; i++) { 01175 for (j = 0; j < dnfullw; j++) 01176 *(pdfwfull + j) = *(psfwfull + j) & ~(*(pdfwfull + j)); 01177 pdfwfull += dwpl; 01178 psfwfull += swpl; 01179 } 01180 } 01181 01182 /* do the last partial word */ 01183 if (dlwpartb) { 01184 for (i = 0; i < dh; i++) { 01185 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01186 (*pslwpart & ~(*pdlwpart)), dlwmask); 01187 pdlwpart += dwpl; 01188 pslwpart += swpl; 01189 } 01190 } 01191 break; 01192 case (PIX_NOT(PIX_SRC | PIX_DST)): 01193 /* do the first partial word */ 01194 if (dfwpartb) { 01195 for (i = 0; i < dh; i++) { 01196 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01197 ~(*psfwpart | *pdfwpart), dfwmask); 01198 pdfwpart += dwpl; 01199 psfwpart += swpl; 01200 } 01201 } 01202 01203 /* do the full words */ 01204 if (dfwfullb) { 01205 for (i = 0; i < dh; i++) { 01206 for (j = 0; j < dnfullw; j++) 01207 *(pdfwfull + j) = ~(*(psfwfull + j) | *(pdfwfull + j)); 01208 pdfwfull += dwpl; 01209 psfwfull += swpl; 01210 } 01211 } 01212 01213 /* do the last partial word */ 01214 if (dlwpartb) { 01215 for (i = 0; i < dh; i++) { 01216 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01217 ~(*pslwpart | *pdlwpart), dlwmask); 01218 pdlwpart += dwpl; 01219 pslwpart += swpl; 01220 } 01221 } 01222 break; 01223 case (PIX_NOT(PIX_SRC & PIX_DST)): 01224 /* do the first partial word */ 01225 if (dfwpartb) { 01226 for (i = 0; i < dh; i++) { 01227 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01228 ~(*psfwpart & *pdfwpart), dfwmask); 01229 pdfwpart += dwpl; 01230 psfwpart += swpl; 01231 } 01232 } 01233 01234 /* do the full words */ 01235 if (dfwfullb) { 01236 for (i = 0; i < dh; i++) { 01237 for (j = 0; j < dnfullw; j++) 01238 *(pdfwfull + j) = ~(*(psfwfull + j) & *(pdfwfull + j)); 01239 pdfwfull += dwpl; 01240 psfwfull += swpl; 01241 } 01242 } 01243 01244 /* do the last partial word */ 01245 if (dlwpartb) { 01246 for (i = 0; i < dh; i++) { 01247 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01248 ~(*pslwpart & *pdlwpart), dlwmask); 01249 pdlwpart += dwpl; 01250 pslwpart += swpl; 01251 } 01252 } 01253 break; 01254 /* this is three cases: ~(s ^ d), ~s ^ d, s ^ ~d */ 01255 case (PIX_NOT(PIX_SRC ^ PIX_DST)): 01256 /* do the first partial word */ 01257 if (dfwpartb) { 01258 for (i = 0; i < dh; i++) { 01259 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01260 ~(*psfwpart ^ *pdfwpart), dfwmask); 01261 pdfwpart += dwpl; 01262 psfwpart += swpl; 01263 } 01264 } 01265 01266 /* do the full words */ 01267 if (dfwfullb) { 01268 for (i = 0; i < dh; i++) { 01269 for (j = 0; j < dnfullw; j++) 01270 *(pdfwfull + j) = ~(*(psfwfull + j) ^ *(pdfwfull + j)); 01271 pdfwfull += dwpl; 01272 psfwfull += swpl; 01273 } 01274 } 01275 01276 /* do the last partial word */ 01277 if (dlwpartb) { 01278 for (i = 0; i < dh; i++) { 01279 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01280 ~(*pslwpart ^ *pdlwpart), dlwmask); 01281 pdlwpart += dwpl; 01282 pslwpart += swpl; 01283 } 01284 } 01285 break; 01286 default: 01287 fprintf(stderr, "Operation %x invalid\n", op); 01288 } 01289 01290 return; 01291 } 01292 01293 01294 /*--------------------------------------------------------------------* 01295 * Static low-level rasterop without vertical word alignment * 01296 *--------------------------------------------------------------------*/ 01297 /*! 01298 * rasteropGeneralLow() 01299 * 01300 * Input: datad (ptr to dest image data) 01301 * dwpl (wpl of dest) 01302 * dx (x val of UL corner of dest rectangle) 01303 * dy (y val of UL corner of dest rectangle) 01304 * dw (width of dest rectangle) 01305 * dh (height of dest rectangle) 01306 * op (op code) 01307 * datas (ptr to src image data) 01308 * swpl (wpl of src) 01309 * sx (x val of UL corner of src rectangle) 01310 * sy (y val of UL corner of src rectangle) 01311 * Return: void 01312 * 01313 * This is called when the src and dest rects are 01314 * do not have the same (32-bit) word alignment. 01315 * 01316 * The method is a generalization of rasteropVAlignLow(). 01317 * There, the src image pieces were directly merged 01318 * with the dest. Here, we shift the source bits 01319 * to fill words that are aligned with the dest, and 01320 * then use those "source words" exactly in place 01321 * of the source words that were used in rasteropVAlignLow(). 01322 * 01323 * The critical parameter is thus the shift required 01324 * for the src. Consider the left edge of the rectangle. 01325 * The overhang into the src and dest words are found, 01326 * and the difference is exactly this shift. There are 01327 * two separate cases, depending on whether the src pixels 01328 * are shifted left or right. If the src overhang is 01329 * larger than the dest overhang, the src is shifted to 01330 * the right, a number of pixels equal to the shift are 01331 * left over for filling the next dest word, if necessary. 01332 * But if the dest overhang is larger than the src, 01333 * the src is shifted to the left, and it may also be 01334 * necessary to shift an equal number of pixels in from 01335 * the next src word. However, in both cases, after 01336 * the first partial (or complete) dest word has been 01337 * filled, the next src pixels will come from a left 01338 * shift that exhausts the pixels in the src word. 01339 */ 01340 static void 01341 rasteropGeneralLow(l_uint32 *datad, 01342 l_int32 dwpl, 01343 l_int32 dx, 01344 l_int32 dy, 01345 l_int32 dw, 01346 l_int32 dh, 01347 l_int32 op, 01348 l_uint32 *datas, 01349 l_int32 swpl, 01350 l_int32 sx, 01351 l_int32 sy) 01352 { 01353 l_int32 dfwpartb; /* boolean (1, 0) if first dest word is partial */ 01354 l_int32 dfwpart2b; /* boolean (1, 0) if 1st dest word is doubly partial */ 01355 l_uint32 dfwmask; /* mask for first partial dest word */ 01356 l_int32 dfwbits; /* first word dest bits in overhang; 0-31 */ 01357 l_int32 dhang; /* dest overhang in first partial word, */ 01358 /* or 0 if dest is word aligned (same as dfwbits) */ 01359 l_uint32 *pdfwpart; /* ptr to first partial dest word */ 01360 l_uint32 *psfwpart; /* ptr to first partial src word */ 01361 l_int32 dfwfullb; /* boolean (1, 0) if there exists a full dest word */ 01362 l_int32 dnfullw; /* number of full words in dest */ 01363 l_uint32 *pdfwfull; /* ptr to first full dest word */ 01364 l_uint32 *psfwfull; /* ptr to first full src word */ 01365 l_int32 dlwpartb; /* boolean (1, 0) if last dest word is partial */ 01366 l_uint32 dlwmask; /* mask for last partial dest word */ 01367 l_int32 dlwbits; /* last word dest bits in ovrhang */ 01368 l_uint32 *pdlwpart; /* ptr to last partial dest word */ 01369 l_uint32 *pslwpart; /* ptr to last partial src word */ 01370 l_uint32 sword; /* compose src word aligned with the dest words */ 01371 l_int32 sfwbits; /* first word src bits in overhang (1-32), */ 01372 /* or 32 if src is word aligned */ 01373 l_int32 shang; /* source overhang in the first partial word, */ 01374 /* or 0 if src is word aligned (not same as sfwbits) */ 01375 l_int32 sleftshift; /* bits to shift left for source word to align */ 01376 /* with the dest. Also the number of bits that */ 01377 /* get shifted to the right to align with the dest. */ 01378 l_int32 srightshift; /* bits to shift right for source word to align */ 01379 /* with dest. Also, the number of bits that get */ 01380 /* shifted left to align with the dest. */ 01381 l_int32 srightmask; /* mask for selecting sleftshift bits that have */ 01382 /* been shifted right by srightshift bits */ 01383 l_int32 sfwshiftdir; /* either SHIFT_LEFT or SHIFT_RIGHT */ 01384 l_int32 sfwaddb; /* boolean: do we need an additional sfw right shift? */ 01385 l_int32 slwaddb; /* boolean: do we need an additional slw right shift? */ 01386 l_int32 i, j; 01387 01388 01389 /*--------------------------------------------------------* 01390 * Preliminary calculations * 01391 *--------------------------------------------------------*/ 01392 /* To get alignment of src with dst (e.g., in the 01393 * full words) the src must do a left shift of its 01394 * relative overhang in the current src word, 01395 * and OR that with a right shift of 01396 * (31 - relative overhang) from the next src word. 01397 * We find the absolute overhangs, the relative overhangs, 01398 * the required shifts and the src mask */ 01399 if ((sx & 31) == 0) 01400 shang = 0; 01401 else 01402 shang = 32 - (sx & 31); 01403 if ((dx & 31) == 0) 01404 dhang = 0; 01405 else 01406 dhang = 32 - (dx & 31); 01407 01408 if (shang == 0 && dhang == 0) { /* this should be treated by an 01409 aligned operation, not by 01410 this general rasterop! */ 01411 sleftshift = 0; 01412 srightshift = 0; 01413 srightmask = rmask32[0]; 01414 } 01415 else { 01416 if (dhang > shang) 01417 sleftshift = dhang - shang; 01418 else 01419 sleftshift = 32 - (shang - dhang); 01420 srightshift = 32 - sleftshift; 01421 srightmask = rmask32[sleftshift]; 01422 } 01423 01424 /* is the first dest word partial? */ 01425 if ((dx & 31) == 0) { /* if not */ 01426 dfwpartb = 0; 01427 dfwbits = 0; 01428 } 01429 else { /* if so */ 01430 dfwpartb = 1; 01431 dfwbits = 32 - (dx & 31); 01432 dfwmask = rmask32[dfwbits]; 01433 pdfwpart = datad + dwpl * dy + (dx >> 5); 01434 psfwpart = datas + swpl * sy + (sx >> 5); 01435 sfwbits = 32 - (sx & 31); 01436 if (dfwbits > sfwbits) { 01437 sfwshiftdir = SHIFT_LEFT; /* and shift by sleftshift */ 01438 if (dw < shang) 01439 sfwaddb = 0; 01440 else 01441 sfwaddb = 1; /* and rshift in next src word by srightshift */ 01442 } 01443 else 01444 sfwshiftdir = SHIFT_RIGHT; /* and shift by srightshift */ 01445 } 01446 01447 /* is the first dest word doubly partial? */ 01448 if (dw >= dfwbits) /* if not */ 01449 dfwpart2b = 0; 01450 else { /* if so */ 01451 dfwpart2b = 1; 01452 dfwmask &= lmask32[32 - dfwbits + dw]; 01453 } 01454 01455 /* is there a full dest word? */ 01456 if (dfwpart2b == 1) { /* not */ 01457 dfwfullb = 0; 01458 dnfullw = 0; 01459 } 01460 else { 01461 dnfullw = (dw - dfwbits) >> 5; 01462 if (dnfullw == 0) /* if not */ 01463 dfwfullb = 0; 01464 else { /* if so */ 01465 dfwfullb = 1; 01466 pdfwfull = datad + dwpl * dy + ((dx + dhang) >> 5); 01467 psfwfull = datas + swpl * sy + ((sx + dhang) >> 5); /* yes, dhang */ 01468 } 01469 } 01470 01471 /* is the last dest word partial? */ 01472 dlwbits = (dx + dw) & 31; 01473 if (dfwpart2b == 1 || dlwbits == 0) /* if not */ 01474 dlwpartb = 0; 01475 else { 01476 dlwpartb = 1; 01477 dlwmask = lmask32[dlwbits]; 01478 pdlwpart = datad + dwpl * dy + ((dx + dhang) >> 5) + dnfullw; 01479 pslwpart = datas + swpl * sy + ((sx + dhang) >> 5) + dnfullw; 01480 if (dlwbits <= srightshift) /* must be <= here !!! */ 01481 slwaddb = 0; /* we got enough bits from current src word */ 01482 else 01483 slwaddb = 1; /* must rshift in next src word by srightshift */ 01484 } 01485 01486 01487 /*--------------------------------------------------------* 01488 * Now we're ready to do the ops * 01489 *--------------------------------------------------------*/ 01490 switch (op) 01491 { 01492 case PIX_SRC: 01493 /* do the first partial word */ 01494 if (dfwpartb) { 01495 for (i = 0; i < dh; i++) 01496 { 01497 if (sfwshiftdir == SHIFT_LEFT) { 01498 sword = *psfwpart << sleftshift; 01499 if (sfwaddb) 01500 sword = COMBINE_PARTIAL(sword, 01501 *(psfwpart + 1) >> srightshift, 01502 srightmask); 01503 } 01504 else /* shift right */ 01505 sword = *psfwpart >> srightshift; 01506 01507 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, sword, dfwmask); 01508 pdfwpart += dwpl; 01509 psfwpart += swpl; 01510 } 01511 } 01512 01513 /* do the full words */ 01514 if (dfwfullb) { 01515 for (i = 0; i < dh; i++) { 01516 for (j = 0; j < dnfullw; j++) { 01517 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01518 *(psfwfull + j + 1) >> srightshift, 01519 srightmask); 01520 *(pdfwfull + j) = sword; 01521 } 01522 pdfwfull += dwpl; 01523 psfwfull += swpl; 01524 } 01525 } 01526 01527 /* do the last partial word */ 01528 if (dlwpartb) { 01529 for (i = 0; i < dh; i++) { 01530 sword = *pslwpart << sleftshift; 01531 if (slwaddb) 01532 sword = COMBINE_PARTIAL(sword, 01533 *(pslwpart + 1) >> srightshift, 01534 srightmask); 01535 01536 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, sword, dlwmask); 01537 pdlwpart += dwpl; 01538 pslwpart += swpl; 01539 } 01540 } 01541 break; 01542 case PIX_NOT(PIX_SRC): 01543 /* do the first partial word */ 01544 if (dfwpartb) { 01545 for (i = 0; i < dh; i++) 01546 { 01547 if (sfwshiftdir == SHIFT_LEFT) { 01548 sword = *psfwpart << sleftshift; 01549 if (sfwaddb) 01550 sword = COMBINE_PARTIAL(sword, 01551 *(psfwpart + 1) >> srightshift, 01552 srightmask); 01553 } 01554 else /* shift right */ 01555 sword = *psfwpart >> srightshift; 01556 01557 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, ~sword, dfwmask); 01558 pdfwpart += dwpl; 01559 psfwpart += swpl; 01560 } 01561 } 01562 01563 /* do the full words */ 01564 if (dfwfullb) { 01565 for (i = 0; i < dh; i++) { 01566 for (j = 0; j < dnfullw; j++) { 01567 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01568 *(psfwfull + j + 1) >> srightshift, 01569 srightmask); 01570 *(pdfwfull + j) = ~sword; 01571 } 01572 pdfwfull += dwpl; 01573 psfwfull += swpl; 01574 } 01575 } 01576 01577 /* do the last partial word */ 01578 if (dlwpartb) { 01579 for (i = 0; i < dh; i++) { 01580 sword = *pslwpart << sleftshift; 01581 if (slwaddb) 01582 sword = COMBINE_PARTIAL(sword, 01583 *(pslwpart + 1) >> srightshift, 01584 srightmask); 01585 01586 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, ~sword, dlwmask); 01587 pdlwpart += dwpl; 01588 pslwpart += swpl; 01589 } 01590 } 01591 break; 01592 case (PIX_SRC | PIX_DST): 01593 /* do the first partial word */ 01594 if (dfwpartb) { 01595 for (i = 0; i < dh; i++) 01596 { 01597 if (sfwshiftdir == SHIFT_LEFT) { 01598 sword = *psfwpart << sleftshift; 01599 if (sfwaddb) 01600 sword = COMBINE_PARTIAL(sword, 01601 *(psfwpart + 1) >> srightshift, 01602 srightmask); 01603 } 01604 else /* shift right */ 01605 sword = *psfwpart >> srightshift; 01606 01607 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01608 (sword | *pdfwpart), dfwmask); 01609 pdfwpart += dwpl; 01610 psfwpart += swpl; 01611 } 01612 } 01613 01614 /* do the full words */ 01615 if (dfwfullb) { 01616 for (i = 0; i < dh; i++) { 01617 for (j = 0; j < dnfullw; j++) { 01618 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01619 *(psfwfull + j + 1) >> srightshift, 01620 srightmask); 01621 *(pdfwfull + j) |= sword; 01622 } 01623 pdfwfull += dwpl; 01624 psfwfull += swpl; 01625 } 01626 } 01627 01628 /* do the last partial word */ 01629 if (dlwpartb) { 01630 for (i = 0; i < dh; i++) { 01631 sword = *pslwpart << sleftshift; 01632 if (slwaddb) 01633 sword = COMBINE_PARTIAL(sword, 01634 *(pslwpart + 1) >> srightshift, 01635 srightmask); 01636 01637 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01638 (sword | *pdlwpart), dlwmask); 01639 pdlwpart += dwpl; 01640 pslwpart += swpl; 01641 } 01642 } 01643 break; 01644 case (PIX_SRC & PIX_DST): 01645 /* do the first partial word */ 01646 if (dfwpartb) { 01647 for (i = 0; i < dh; i++) 01648 { 01649 if (sfwshiftdir == SHIFT_LEFT) { 01650 sword = *psfwpart << sleftshift; 01651 if (sfwaddb) 01652 sword = COMBINE_PARTIAL(sword, 01653 *(psfwpart + 1) >> srightshift, 01654 srightmask); 01655 } 01656 else /* shift right */ 01657 sword = *psfwpart >> srightshift; 01658 01659 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01660 (sword & *pdfwpart), dfwmask); 01661 pdfwpart += dwpl; 01662 psfwpart += swpl; 01663 } 01664 } 01665 01666 /* do the full words */ 01667 if (dfwfullb) { 01668 for (i = 0; i < dh; i++) { 01669 for (j = 0; j < dnfullw; j++) { 01670 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01671 *(psfwfull + j + 1) >> srightshift, 01672 srightmask); 01673 *(pdfwfull + j) &= sword; 01674 } 01675 pdfwfull += dwpl; 01676 psfwfull += swpl; 01677 } 01678 } 01679 01680 /* do the last partial word */ 01681 if (dlwpartb) { 01682 for (i = 0; i < dh; i++) { 01683 sword = *pslwpart << sleftshift; 01684 if (slwaddb) 01685 sword = COMBINE_PARTIAL(sword, 01686 *(pslwpart + 1) >> srightshift, 01687 srightmask); 01688 01689 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01690 (sword & *pdlwpart), dlwmask); 01691 pdlwpart += dwpl; 01692 pslwpart += swpl; 01693 } 01694 } 01695 break; 01696 case (PIX_SRC ^ PIX_DST): 01697 /* do the first partial word */ 01698 if (dfwpartb) { 01699 for (i = 0; i < dh; i++) 01700 { 01701 if (sfwshiftdir == SHIFT_LEFT) { 01702 sword = *psfwpart << sleftshift; 01703 if (sfwaddb) 01704 sword = COMBINE_PARTIAL(sword, 01705 *(psfwpart + 1) >> srightshift, 01706 srightmask); 01707 } 01708 else /* shift right */ 01709 sword = *psfwpart >> srightshift; 01710 01711 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01712 (sword ^ *pdfwpart), dfwmask); 01713 pdfwpart += dwpl; 01714 psfwpart += swpl; 01715 } 01716 } 01717 01718 /* do the full words */ 01719 if (dfwfullb) { 01720 for (i = 0; i < dh; i++) { 01721 for (j = 0; j < dnfullw; j++) { 01722 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01723 *(psfwfull + j + 1) >> srightshift, 01724 srightmask); 01725 *(pdfwfull + j) ^= sword; 01726 } 01727 pdfwfull += dwpl; 01728 psfwfull += swpl; 01729 } 01730 } 01731 01732 /* do the last partial word */ 01733 if (dlwpartb) { 01734 for (i = 0; i < dh; i++) { 01735 sword = *pslwpart << sleftshift; 01736 if (slwaddb) 01737 sword = COMBINE_PARTIAL(sword, 01738 *(pslwpart + 1) >> srightshift, 01739 srightmask); 01740 01741 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01742 (sword ^ *pdlwpart), dlwmask); 01743 pdlwpart += dwpl; 01744 pslwpart += swpl; 01745 } 01746 } 01747 break; 01748 case (PIX_NOT(PIX_SRC) | PIX_DST): 01749 /* do the first partial word */ 01750 if (dfwpartb) { 01751 for (i = 0; i < dh; i++) 01752 { 01753 if (sfwshiftdir == SHIFT_LEFT) { 01754 sword = *psfwpart << sleftshift; 01755 if (sfwaddb) 01756 sword = COMBINE_PARTIAL(sword, 01757 *(psfwpart + 1) >> srightshift, 01758 srightmask); 01759 } 01760 else /* shift right */ 01761 sword = *psfwpart >> srightshift; 01762 01763 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01764 (~sword | *pdfwpart), dfwmask); 01765 pdfwpart += dwpl; 01766 psfwpart += swpl; 01767 } 01768 } 01769 01770 /* do the full words */ 01771 if (dfwfullb) { 01772 for (i = 0; i < dh; i++) { 01773 for (j = 0; j < dnfullw; j++) { 01774 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01775 *(psfwfull + j + 1) >> srightshift, 01776 srightmask); 01777 *(pdfwfull + j) |= ~sword; 01778 } 01779 pdfwfull += dwpl; 01780 psfwfull += swpl; 01781 } 01782 } 01783 01784 /* do the last partial word */ 01785 if (dlwpartb) { 01786 for (i = 0; i < dh; i++) { 01787 sword = *pslwpart << sleftshift; 01788 if (slwaddb) 01789 sword = COMBINE_PARTIAL(sword, 01790 *(pslwpart + 1) >> srightshift, 01791 srightmask); 01792 01793 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01794 (~sword | *pdlwpart), dlwmask); 01795 pdlwpart += dwpl; 01796 pslwpart += swpl; 01797 } 01798 } 01799 break; 01800 case (PIX_NOT(PIX_SRC) & PIX_DST): 01801 /* do the first partial word */ 01802 if (dfwpartb) { 01803 for (i = 0; i < dh; i++) 01804 { 01805 if (sfwshiftdir == SHIFT_LEFT) { 01806 sword = *psfwpart << sleftshift; 01807 if (sfwaddb) 01808 sword = COMBINE_PARTIAL(sword, 01809 *(psfwpart + 1) >> srightshift, 01810 srightmask); 01811 } 01812 else /* shift right */ 01813 sword = *psfwpart >> srightshift; 01814 01815 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01816 (~sword & *pdfwpart), dfwmask); 01817 pdfwpart += dwpl; 01818 psfwpart += swpl; 01819 } 01820 } 01821 01822 /* do the full words */ 01823 if (dfwfullb) { 01824 for (i = 0; i < dh; i++) { 01825 for (j = 0; j < dnfullw; j++) { 01826 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01827 *(psfwfull + j + 1) >> srightshift, 01828 srightmask); 01829 *(pdfwfull + j) &= ~sword; 01830 } 01831 pdfwfull += dwpl; 01832 psfwfull += swpl; 01833 } 01834 } 01835 01836 /* do the last partial word */ 01837 if (dlwpartb) { 01838 for (i = 0; i < dh; i++) { 01839 sword = *pslwpart << sleftshift; 01840 if (slwaddb) 01841 sword = COMBINE_PARTIAL(sword, 01842 *(pslwpart + 1) >> srightshift, 01843 srightmask); 01844 01845 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01846 (~sword & *pdlwpart), dlwmask); 01847 pdlwpart += dwpl; 01848 pslwpart += swpl; 01849 } 01850 } 01851 break; 01852 case (PIX_SRC | PIX_NOT(PIX_DST)): 01853 /* do the first partial word */ 01854 if (dfwpartb) { 01855 for (i = 0; i < dh; i++) 01856 { 01857 if (sfwshiftdir == SHIFT_LEFT) { 01858 sword = *psfwpart << sleftshift; 01859 if (sfwaddb) 01860 sword = COMBINE_PARTIAL(sword, 01861 *(psfwpart + 1) >> srightshift, 01862 srightmask); 01863 } 01864 else /* shift right */ 01865 sword = *psfwpart >> srightshift; 01866 01867 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01868 (sword | ~(*pdfwpart)), dfwmask); 01869 pdfwpart += dwpl; 01870 psfwpart += swpl; 01871 } 01872 } 01873 01874 /* do the full words */ 01875 if (dfwfullb) { 01876 for (i = 0; i < dh; i++) { 01877 for (j = 0; j < dnfullw; j++) { 01878 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01879 *(psfwfull + j + 1) >> srightshift, 01880 srightmask); 01881 *(pdfwfull + j) = sword | ~(*(pdfwfull + j)); 01882 } 01883 pdfwfull += dwpl; 01884 psfwfull += swpl; 01885 } 01886 } 01887 01888 /* do the last partial word */ 01889 if (dlwpartb) { 01890 for (i = 0; i < dh; i++) { 01891 sword = *pslwpart << sleftshift; 01892 if (slwaddb) 01893 sword = COMBINE_PARTIAL(sword, 01894 *(pslwpart + 1) >> srightshift, 01895 srightmask); 01896 01897 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01898 (sword | ~(*pdlwpart)), dlwmask); 01899 pdlwpart += dwpl; 01900 pslwpart += swpl; 01901 } 01902 } 01903 break; 01904 case (PIX_SRC & PIX_NOT(PIX_DST)): 01905 /* do the first partial word */ 01906 if (dfwpartb) { 01907 for (i = 0; i < dh; i++) 01908 { 01909 if (sfwshiftdir == SHIFT_LEFT) { 01910 sword = *psfwpart << sleftshift; 01911 if (sfwaddb) 01912 sword = COMBINE_PARTIAL(sword, 01913 *(psfwpart + 1) >> srightshift, 01914 srightmask); 01915 } 01916 else /* shift right */ 01917 sword = *psfwpart >> srightshift; 01918 01919 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01920 (sword & ~(*pdfwpart)), dfwmask); 01921 pdfwpart += dwpl; 01922 psfwpart += swpl; 01923 } 01924 } 01925 01926 /* do the full words */ 01927 if (dfwfullb) { 01928 for (i = 0; i < dh; i++) { 01929 for (j = 0; j < dnfullw; j++) { 01930 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01931 *(psfwfull + j + 1) >> srightshift, 01932 srightmask); 01933 *(pdfwfull + j) = sword & ~(*(pdfwfull + j)); 01934 } 01935 pdfwfull += dwpl; 01936 psfwfull += swpl; 01937 } 01938 } 01939 01940 /* do the last partial word */ 01941 if (dlwpartb) { 01942 for (i = 0; i < dh; i++) { 01943 sword = *pslwpart << sleftshift; 01944 if (slwaddb) 01945 sword = COMBINE_PARTIAL(sword, 01946 *(pslwpart + 1) >> srightshift, 01947 srightmask); 01948 01949 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 01950 (sword & ~(*pdlwpart)), dlwmask); 01951 pdlwpart += dwpl; 01952 pslwpart += swpl; 01953 } 01954 } 01955 break; 01956 case (PIX_NOT(PIX_SRC | PIX_DST)): 01957 /* do the first partial word */ 01958 if (dfwpartb) { 01959 for (i = 0; i < dh; i++) 01960 { 01961 if (sfwshiftdir == SHIFT_LEFT) { 01962 sword = *psfwpart << sleftshift; 01963 if (sfwaddb) 01964 sword = COMBINE_PARTIAL(sword, 01965 *(psfwpart + 1) >> srightshift, 01966 srightmask); 01967 } 01968 else /* shift right */ 01969 sword = *psfwpart >> srightshift; 01970 01971 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 01972 ~(sword | *pdfwpart), dfwmask); 01973 pdfwpart += dwpl; 01974 psfwpart += swpl; 01975 } 01976 } 01977 01978 /* do the full words */ 01979 if (dfwfullb) { 01980 for (i = 0; i < dh; i++) { 01981 for (j = 0; j < dnfullw; j++) { 01982 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 01983 *(psfwfull + j + 1) >> srightshift, 01984 srightmask); 01985 *(pdfwfull + j) = ~(sword | *(pdfwfull + j)); 01986 } 01987 pdfwfull += dwpl; 01988 psfwfull += swpl; 01989 } 01990 } 01991 01992 /* do the last partial word */ 01993 if (dlwpartb) { 01994 for (i = 0; i < dh; i++) { 01995 sword = *pslwpart << sleftshift; 01996 if (slwaddb) 01997 sword = COMBINE_PARTIAL(sword, 01998 *(pslwpart + 1) >> srightshift, 01999 srightmask); 02000 02001 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 02002 ~(sword | *pdlwpart), dlwmask); 02003 pdlwpart += dwpl; 02004 pslwpart += swpl; 02005 } 02006 } 02007 break; 02008 case (PIX_NOT(PIX_SRC & PIX_DST)): 02009 /* do the first partial word */ 02010 if (dfwpartb) { 02011 for (i = 0; i < dh; i++) 02012 { 02013 if (sfwshiftdir == SHIFT_LEFT) { 02014 sword = *psfwpart << sleftshift; 02015 if (sfwaddb) 02016 sword = COMBINE_PARTIAL(sword, 02017 *(psfwpart + 1) >> srightshift, 02018 srightmask); 02019 } 02020 else /* shift right */ 02021 sword = *psfwpart >> srightshift; 02022 02023 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 02024 ~(sword & *pdfwpart), dfwmask); 02025 pdfwpart += dwpl; 02026 psfwpart += swpl; 02027 } 02028 } 02029 02030 /* do the full words */ 02031 if (dfwfullb) { 02032 for (i = 0; i < dh; i++) { 02033 for (j = 0; j < dnfullw; j++) { 02034 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 02035 *(psfwfull + j + 1) >> srightshift, 02036 srightmask); 02037 *(pdfwfull + j) = ~(sword & *(pdfwfull + j)); 02038 } 02039 pdfwfull += dwpl; 02040 psfwfull += swpl; 02041 } 02042 } 02043 02044 /* do the last partial word */ 02045 if (dlwpartb) { 02046 for (i = 0; i < dh; i++) { 02047 sword = *pslwpart << sleftshift; 02048 if (slwaddb) 02049 sword = COMBINE_PARTIAL(sword, 02050 *(pslwpart + 1) >> srightshift, 02051 srightmask); 02052 02053 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 02054 ~(sword & *pdlwpart), dlwmask); 02055 pdlwpart += dwpl; 02056 pslwpart += swpl; 02057 } 02058 } 02059 break; 02060 /* this is three cases: ~(s ^ d), ~s ^ d, s ^ ~d */ 02061 case (PIX_NOT(PIX_SRC ^ PIX_DST)): 02062 /* do the first partial word */ 02063 if (dfwpartb) { 02064 for (i = 0; i < dh; i++) 02065 { 02066 if (sfwshiftdir == SHIFT_LEFT) { 02067 sword = *psfwpart << sleftshift; 02068 if (sfwaddb) 02069 sword = COMBINE_PARTIAL(sword, 02070 *(psfwpart + 1) >> srightshift, 02071 srightmask); 02072 } 02073 else /* shift right */ 02074 sword = *psfwpart >> srightshift; 02075 02076 *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 02077 ~(sword ^ *pdfwpart), dfwmask); 02078 pdfwpart += dwpl; 02079 psfwpart += swpl; 02080 } 02081 } 02082 02083 /* do the full words */ 02084 if (dfwfullb) { 02085 for (i = 0; i < dh; i++) { 02086 for (j = 0; j < dnfullw; j++) { 02087 sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, 02088 *(psfwfull + j + 1) >> srightshift, 02089 srightmask); 02090 *(pdfwfull + j) = ~(sword ^ *(pdfwfull + j)); 02091 } 02092 pdfwfull += dwpl; 02093 psfwfull += swpl; 02094 } 02095 } 02096 02097 /* do the last partial word */ 02098 if (dlwpartb) { 02099 for (i = 0; i < dh; i++) { 02100 sword = *pslwpart << sleftshift; 02101 if (slwaddb) 02102 sword = COMBINE_PARTIAL(sword, 02103 *(pslwpart + 1) >> srightshift, 02104 srightmask); 02105 02106 *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 02107 ~(sword ^ *pdlwpart), dlwmask); 02108 pdlwpart += dwpl; 02109 pslwpart += swpl; 02110 } 02111 } 02112 break; 02113 default: 02114 fprintf(stderr, "Operation %x invalid\n", op); 02115 } 02116 02117 return; 02118 } 02119