| /*====================================================================* |
| - Copyright (C) 2001 Leptonica. All rights reserved. |
| - This software is distributed in the hope that it will be |
| - useful, but with NO WARRANTY OF ANY KIND. |
| - No author or distributor accepts responsibility to anyone for the |
| - consequences of using this software, or for whether it serves any |
| - particular purpose or works at all, unless he or she says so in |
| - writing. Everyone is granted permission to copy, modify and |
| - redistribute this source code, for commercial or non-commercial |
| - purposes, with the following restrictions: (1) the origin of this |
| - source code must not be misrepresented; (2) modified versions must |
| - be plainly marked as such; and (3) this notice may not be removed |
| - or altered from any source or modified source distribution. |
| *====================================================================*/ |
| |
| /* |
| * roplow.c |
| * |
| * Low level dest-only |
| * void rasteropUniLow() |
| * static void rasteropUniWordAlignedlLow() |
| * static void rasteropUniGeneralLow() |
| * |
| * Low level src and dest |
| * void rasteropLow() |
| * static void rasteropWordAlignedLow() |
| * static void rasteropVAlignedLow() |
| * static void rasteropGeneralLow() |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "allheaders.h" |
| |
| #define COMBINE_PARTIAL(d, s, m) ( ((d) & ~(m)) | ((s) & (m)) ) |
| |
| static const l_int32 SHIFT_LEFT = 0; |
| static const l_int32 SHIFT_RIGHT = 1; |
| |
| static void rasteropUniWordAlignedLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, |
| l_int32 dy, l_int32 dw, l_int32 dh, |
| l_int32 op); |
| |
| static void rasteropUniGeneralLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, |
| l_int32 dy, l_int32 dw, l_int32 dh, |
| l_int32 op); |
| |
| static void rasteropWordAlignedLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, |
| l_int32 dy, l_int32 dw, l_int32 dh, |
| l_int32 op, l_uint32 *datas, l_int32 swpl, |
| l_int32 sx, l_int32 sy); |
| |
| static void rasteropVAlignedLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, |
| l_int32 dy, l_int32 dw, l_int32 dh, |
| l_int32 op, l_uint32 *datas, l_int32 swpl, |
| l_int32 sx, l_int32 sy); |
| |
| static void rasteropGeneralLow(l_uint32 *datad, l_int32 dwpl, l_int32 dx, |
| l_int32 dy, l_int32 dw, l_int32 dh, |
| l_int32 op, l_uint32 *datas, l_int32 swpl, |
| l_int32 sx, l_int32 sy); |
| |
| |
| static const l_uint32 lmask32[] = {0x0, |
| 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, |
| 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, |
| 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, |
| 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, |
| 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, |
| 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, |
| 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, |
| 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff}; |
| |
| static const l_uint32 rmask32[] = {0x0, |
| 0x00000001, 0x00000003, 0x00000007, 0x0000000f, |
| 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, |
| 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, |
| 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, |
| 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, |
| 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, |
| 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, |
| 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; |
| |
| |
| /*--------------------------------------------------------------------* |
| * Low-level dest-only rasterops * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropUniLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dpixw (width of dest) |
| * dpixh (height of dest) |
| * depth (depth of src and dest) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * Return: void |
| * |
| * Action: scales width, performs clipping, checks alignment, and |
| * dispatches for the rasterop. |
| */ |
| void |
| rasteropUniLow(l_uint32 *datad, |
| l_int32 dpixw, |
| l_int32 dpixh, |
| l_int32 depth, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op) |
| { |
| l_int32 dhangw, dhangh; |
| |
| /* -------------------------------------------------------* |
| * scale horizontal dimensions by depth |
| * -------------------------------------------------------*/ |
| if (depth != 1) { |
| dpixw *= depth; |
| dx *= depth; |
| dw *= depth; |
| } |
| |
| /* -------------------------------------------------------* |
| * clip rectangle to dest image |
| * -------------------------------------------------------*/ |
| /* first, clip horizontally (dx, dw) */ |
| if (dx < 0) { |
| dw += dx; /* reduce dw */ |
| dx = 0; |
| } |
| dhangw = dx + dw - dpixw; /* rect ovhang dest to right */ |
| if (dhangw > 0) |
| dw -= dhangw; /* reduce dw */ |
| |
| /* then, clip vertically (dy, dh) */ |
| if (dy < 0) { |
| dh += dy; /* reduce dh */ |
| dy = 0; |
| } |
| dhangh = dy + dh - dpixh; /* rect ovhang dest below */ |
| if (dhangh > 0) |
| dh -= dhangh; /* reduce dh */ |
| |
| /* if clipped entirely, quit */ |
| if ((dw <= 0) || (dh <= 0)) |
| return; |
| |
| /* -------------------------------------------------------* |
| * dispatch to aligned or non-aligned blitters |
| * -------------------------------------------------------*/ |
| if ((dx & 31) == 0) |
| rasteropUniWordAlignedLow(datad, dwpl, dx, dy, dw, dh, op); |
| else |
| rasteropUniGeneralLow(datad, dwpl, dx, dy, dw, dh, op); |
| return; |
| } |
| |
| |
| |
| /*--------------------------------------------------------------------* |
| * Static low-level uni rasterop with word alignment * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropUniWordAlignedLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * Return: void |
| * |
| * This is called when the dest rect is left aligned |
| * on (32-bit) word boundaries. That is: dx & 31 == 0. |
| * |
| * We make an optimized implementation of this because |
| * it is a common case: e.g., operating on a full dest image. |
| */ |
| static void |
| rasteropUniWordAlignedLow(l_uint32 *datad, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op) |
| { |
| l_int32 nfullw; /* number of full words */ |
| l_uint32 *pfword; /* ptr to first word */ |
| l_int32 lwbits; /* number of ovrhang bits in last partial word */ |
| l_uint32 lwmask; /* mask for last partial word */ |
| l_uint32 *lined; |
| l_int32 i, j; |
| |
| /*--------------------------------------------------------* |
| * Preliminary calculations * |
| *--------------------------------------------------------*/ |
| nfullw = dw >> 5; |
| lwbits = dw & 31; |
| if (lwbits) |
| lwmask = lmask32[lwbits]; |
| pfword = datad + dwpl * dy + (dx >> 5); |
| |
| |
| /*--------------------------------------------------------* |
| * Now we're ready to do the ops * |
| *--------------------------------------------------------*/ |
| switch (op) |
| { |
| case PIX_CLR: |
| for (i = 0; i < dh; i++) { |
| lined = pfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) |
| *lined++ = 0x0; |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, 0x0, lwmask); |
| } |
| break; |
| case PIX_SET: |
| for (i = 0; i < dh; i++) { |
| lined = pfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) |
| *lined++ = 0xffffffff; |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, 0xffffffff, lwmask); |
| } |
| break; |
| case PIX_NOT(PIX_DST): |
| for (i = 0; i < dh; i++) { |
| lined = pfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = ~(*lined); |
| lined++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, ~(*lined), lwmask); |
| } |
| break; |
| default: |
| fprintf(stderr, "Operation %d not permitted here!\n", op); |
| } |
| |
| return; |
| } |
| |
| |
| /*--------------------------------------------------------------------* |
| * Static low-level uni rasterop without word alignment * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropUniGeneralLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * Return: void |
| */ |
| static void |
| rasteropUniGeneralLow(l_uint32 *datad, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op) |
| { |
| l_int32 dfwpartb; /* boolean (1, 0) if first dest word is partial */ |
| l_int32 dfwpart2b; /* boolean (1, 0) if first dest word is doubly partial */ |
| l_uint32 dfwmask; /* mask for first partial dest word */ |
| l_int32 dfwbits; /* first word dest bits in ovrhang */ |
| l_uint32 *pdfwpart; /* ptr to first partial dest word */ |
| l_int32 dfwfullb; /* boolean (1, 0) if there exists a full dest word */ |
| l_int32 dnfullw; /* number of full words in dest */ |
| l_uint32 *pdfwfull; /* ptr to first full dest word */ |
| l_int32 dlwpartb; /* boolean (1, 0) if last dest word is partial */ |
| l_uint32 dlwmask; /* mask for last partial dest word */ |
| l_int32 dlwbits; /* last word dest bits in ovrhang */ |
| l_uint32 *pdlwpart; /* ptr to last partial dest word */ |
| l_int32 i, j; |
| |
| |
| /*--------------------------------------------------------* |
| * Preliminary calculations * |
| *--------------------------------------------------------*/ |
| /* is the first word partial? */ |
| if ((dx & 31) == 0) { /* if not */ |
| dfwpartb = 0; |
| dfwbits = 0; |
| } |
| else { /* if so */ |
| dfwpartb = 1; |
| dfwbits = 32 - (dx & 31); |
| dfwmask = rmask32[dfwbits]; |
| pdfwpart = datad + dwpl * dy + (dx >> 5); |
| } |
| |
| /* is the first word doubly partial? */ |
| if (dw >= dfwbits) /* if not */ |
| dfwpart2b = 0; |
| else { /* if so */ |
| dfwpart2b = 1; |
| dfwmask &= lmask32[32 - dfwbits + dw]; |
| } |
| |
| /* is there a full dest word? */ |
| if (dfwpart2b == 1) { /* not */ |
| dfwfullb = 0; |
| dnfullw = 0; |
| } |
| else { |
| dnfullw = (dw - dfwbits) >> 5; |
| if (dnfullw == 0) /* if not */ |
| dfwfullb = 0; |
| else { /* if so */ |
| dfwfullb = 1; |
| if (dfwpartb) |
| pdfwfull = pdfwpart + 1; |
| else |
| pdfwfull = datad + dwpl * dy + (dx >> 5); |
| } |
| } |
| |
| /* is the last word partial? */ |
| dlwbits = (dx + dw) & 31; |
| if (dfwpart2b == 1 || dlwbits == 0) /* if not */ |
| dlwpartb = 0; |
| else { |
| dlwpartb = 1; |
| dlwmask = lmask32[dlwbits]; |
| if (dfwpartb) |
| pdlwpart = pdfwpart + 1 + dnfullw; |
| else |
| pdlwpart = datad + dwpl * dy + (dx >> 5) + dnfullw; |
| } |
| |
| |
| /*--------------------------------------------------------* |
| * Now we're ready to do the ops * |
| *--------------------------------------------------------*/ |
| switch (op) |
| { |
| case PIX_CLR: |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 0x0, dfwmask); |
| pdfwpart += dwpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = 0x0; |
| pdfwfull += dwpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 0x0, dlwmask); |
| pdlwpart += dwpl; |
| } |
| } |
| break; |
| case PIX_SET: |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, 0xffffffff, dfwmask); |
| pdfwpart += dwpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = 0xffffffff; |
| pdfwfull += dwpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, 0xffffffff, dlwmask); |
| pdlwpart += dwpl; |
| } |
| } |
| break; |
| case PIX_NOT(PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, ~(*pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = ~(*(pdfwfull + j)); |
| pdfwfull += dwpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, ~(*pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| } |
| } |
| break; |
| default: |
| fprintf(stderr, "Operation %d not permitted here!\n", op); |
| } |
| |
| return; |
| } |
| |
| |
| |
| /*--------------------------------------------------------------------* |
| * Low-level src and dest rasterops * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dpixw (width of dest) |
| * dpixh (height of dest) |
| * depth (depth of src and dest) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * datas (ptr to src image data) |
| * spixw (width of src) |
| * spixh (height of src) |
| * swpl (wpl of src) |
| * sx (x val of UL corner of src rectangle) |
| * sy (y val of UL corner of src rectangle) |
| * Return: void |
| * |
| * Action: Scales width, performs clipping, checks alignment, and |
| * dispatches for the rasterop. |
| * |
| * Warning: the two images must have equal depth. This is not checked. |
| */ |
| void |
| rasteropLow(l_uint32 *datad, |
| l_int32 dpixw, |
| l_int32 dpixh, |
| l_int32 depth, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op, |
| l_uint32 *datas, |
| l_int32 spixw, |
| l_int32 spixh, |
| l_int32 swpl, |
| l_int32 sx, |
| l_int32 sy) |
| { |
| l_int32 dhangw, shangw, dhangh, shangh; |
| |
| /* -------------------------------------------------------* |
| * scale horizontal dimensions by depth |
| * -------------------------------------------------------*/ |
| if (depth != 1) { |
| dpixw *= depth; |
| dx *= depth; |
| dw *= depth; |
| spixw *= depth; |
| sx *= depth; |
| } |
| |
| |
| /* -------------------------------------------------------* |
| * clip to max rectangle within both src and dest |
| * -------------------------------------------------------*/ |
| /* first, clip horizontally (sx, dx, dw) */ |
| if (dx < 0) { |
| sx -= dx; /* increase sx */ |
| dw += dx; /* reduce dw */ |
| dx = 0; |
| } |
| if (sx < 0) { |
| dx -= sx; /* increase dx */ |
| dw += sx; /* reduce dw */ |
| sx = 0; |
| } |
| dhangw = dx + dw - dpixw; /* rect ovhang dest to right */ |
| if (dhangw > 0) |
| dw -= dhangw; /* reduce dw */ |
| shangw = sx + dw - spixw; /* rect ovhang src to right */ |
| if (shangw > 0) |
| dw -= shangw; /* reduce dw */ |
| |
| /* then, clip vertically (sy, dy, dh) */ |
| if (dy < 0) { |
| sy -= dy; /* increase sy */ |
| dh += dy; /* reduce dh */ |
| dy = 0; |
| } |
| if (sy < 0) { |
| dy -= sy; /* increase dy */ |
| dh += sy; /* reduce dh */ |
| sy = 0; |
| } |
| dhangh = dy + dh - dpixh; /* rect ovhang dest below */ |
| if (dhangh > 0) |
| dh -= dhangh; /* reduce dh */ |
| shangh = sy + dh - spixh; /* rect ovhang src below */ |
| if (shangh > 0) |
| dh -= shangh; /* reduce dh */ |
| |
| /* if clipped entirely, quit */ |
| if ((dw <= 0) || (dh <= 0)) |
| return; |
| |
| /* -------------------------------------------------------* |
| * dispatch to aligned or non-aligned blitters |
| * -------------------------------------------------------*/ |
| if (((dx & 31) == 0) && ((sx & 31) == 0)) |
| rasteropWordAlignedLow(datad, dwpl, dx, dy, dw, dh, op, |
| datas, swpl, sx, sy); |
| else if ((dx & 31) == (sx & 31)) |
| rasteropVAlignedLow(datad, dwpl, dx, dy, dw, dh, op, |
| datas, swpl, sx, sy); |
| else |
| rasteropGeneralLow(datad, dwpl, dx, dy, dw, dh, op, |
| datas, swpl, sx, sy); |
| |
| return; |
| } |
| |
| |
| /*--------------------------------------------------------------------* |
| * Static low-level rasterop with vertical word alignment * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropWordAlignedLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * datas (ptr to src image data) |
| * swpl (wpl of src) |
| * sx (x val of UL corner of src rectangle) |
| * sy (y val of UL corner of src rectangle) |
| * Return: void |
| * |
| * This is called when both the src and dest rects |
| * are left aligned on (32-bit) word boundaries. |
| * That is: dx & 31 == 0 and sx & 31 == 0 |
| * |
| * We make an optimized implementation of this because |
| * it is a common case: e.g., two images are rasterop'd |
| * starting from their UL corners (0,0). |
| */ |
| static void |
| rasteropWordAlignedLow(l_uint32 *datad, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op, |
| l_uint32 *datas, |
| l_int32 swpl, |
| l_int32 sx, |
| l_int32 sy) |
| { |
| l_int32 nfullw; /* number of full words */ |
| l_uint32 *psfword; /* ptr to first src word */ |
| l_uint32 *pdfword; /* ptr to first dest word */ |
| l_int32 lwbits; /* number of ovrhang bits in last partial word */ |
| l_uint32 lwmask; /* mask for last partial word */ |
| l_uint32 *lines, *lined; |
| l_int32 i, j; |
| |
| |
| /*--------------------------------------------------------* |
| * Preliminary calculations * |
| *--------------------------------------------------------*/ |
| nfullw = dw >> 5; |
| lwbits = dw & 31; |
| if (lwbits) |
| lwmask = lmask32[lwbits]; |
| psfword = datas + swpl * sy + (sx >> 5); |
| pdfword = datad + dwpl * dy + (dx >> 5); |
| |
| /*--------------------------------------------------------* |
| * Now we're ready to do the ops * |
| *--------------------------------------------------------*/ |
| switch (op) |
| { |
| case PIX_SRC: |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = *lines; |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, *lines, lwmask); |
| } |
| break; |
| case PIX_NOT(PIX_SRC): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = ~(*lines); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, ~(*lines), lwmask); |
| } |
| break; |
| case (PIX_SRC | PIX_DST): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (*lines | *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (*lines | *lined), lwmask); |
| } |
| break; |
| case (PIX_SRC & PIX_DST): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (*lines & *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (*lines & *lined), lwmask); |
| } |
| break; |
| case (PIX_SRC ^ PIX_DST): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (*lines ^ *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (*lines ^ *lined), lwmask); |
| } |
| break; |
| case (PIX_NOT(PIX_SRC) | PIX_DST): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (~(*lines) | *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (~(*lines) | *lined), lwmask); |
| } |
| break; |
| case (PIX_NOT(PIX_SRC) & PIX_DST): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (~(*lines) & *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (~(*lines) & *lined), lwmask); |
| } |
| break; |
| case (PIX_SRC | PIX_NOT(PIX_DST)): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (*lines | ~(*lined)); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (*lines | ~(*lined)), lwmask); |
| } |
| break; |
| case (PIX_SRC & PIX_NOT(PIX_DST)): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = (*lines & ~(*lined)); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, (*lines & ~(*lined)), lwmask); |
| } |
| break; |
| case (PIX_NOT(PIX_SRC | PIX_DST)): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = ~(*lines | *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, ~(*lines | *lined), lwmask); |
| } |
| break; |
| case (PIX_NOT(PIX_SRC & PIX_DST)): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = ~(*lines & *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, ~(*lines & *lined), lwmask); |
| } |
| break; |
| /* this is three cases: ~(s ^ d), ~s ^ d, s ^ ~d */ |
| case (PIX_NOT(PIX_SRC ^ PIX_DST)): |
| for (i = 0; i < dh; i++) { |
| lines = psfword + i * swpl; |
| lined = pdfword + i * dwpl; |
| for (j = 0; j < nfullw; j++) { |
| *lined = ~(*lines ^ *lined); |
| lined++; |
| lines++; |
| } |
| if (lwbits) |
| *lined = COMBINE_PARTIAL(*lined, ~(*lines ^ *lined), lwmask); |
| } |
| break; |
| default: |
| fprintf(stderr, "Operation %d invalid\n", op); |
| } |
| |
| return; |
| } |
| |
| |
| |
| /*--------------------------------------------------------------------* |
| * Static low-level rasterop with vertical word alignment * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropVAlignedLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * datas (ptr to src image data) |
| * swpl (wpl of src) |
| * sx (x val of UL corner of src rectangle) |
| * sy (y val of UL corner of src rectangle) |
| * Return: void |
| * |
| * This is called when the left side of the src and dest |
| * rects have the same alignment relative to (32-bit) word |
| * boundaries; i.e., (dx & 31) == (sx & 31) |
| */ |
| static void |
| rasteropVAlignedLow(l_uint32 *datad, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op, |
| l_uint32 *datas, |
| l_int32 swpl, |
| l_int32 sx, |
| l_int32 sy) |
| { |
| l_int32 dfwpartb; /* boolean (1, 0) if first dest word is partial */ |
| l_int32 dfwpart2b; /* boolean (1, 0) if first dest word is doubly partial */ |
| l_uint32 dfwmask; /* mask for first partial dest word */ |
| l_int32 dfwbits; /* first word dest bits in ovrhang */ |
| l_uint32 *pdfwpart; /* ptr to first partial dest word */ |
| l_uint32 *psfwpart; /* ptr to first partial src word */ |
| l_int32 dfwfullb; /* boolean (1, 0) if there exists a full dest word */ |
| l_int32 dnfullw; /* number of full words in dest */ |
| l_uint32 *pdfwfull; /* ptr to first full dest word */ |
| l_uint32 *psfwfull; /* ptr to first full src word */ |
| l_int32 dlwpartb; /* boolean (1, 0) if last dest word is partial */ |
| l_uint32 dlwmask; /* mask for last partial dest word */ |
| l_int32 dlwbits; /* last word dest bits in ovrhang */ |
| l_uint32 *pdlwpart; /* ptr to last partial dest word */ |
| l_uint32 *pslwpart; /* ptr to last partial src word */ |
| l_int32 i, j; |
| |
| |
| /*--------------------------------------------------------* |
| * Preliminary calculations * |
| *--------------------------------------------------------*/ |
| /* is the first word partial? */ |
| if ((dx & 31) == 0) { /* if not */ |
| dfwpartb = 0; |
| dfwbits = 0; |
| } |
| else { /* if so */ |
| dfwpartb = 1; |
| dfwbits = 32 - (dx & 31); |
| dfwmask = rmask32[dfwbits]; |
| pdfwpart = datad + dwpl * dy + (dx >> 5); |
| psfwpart = datas + swpl * sy + (sx >> 5); |
| } |
| |
| /* is the first word doubly partial? */ |
| if (dw >= dfwbits) /* if not */ |
| dfwpart2b = 0; |
| else { /* if so */ |
| dfwpart2b = 1; |
| dfwmask &= lmask32[32 - dfwbits + dw]; |
| } |
| |
| /* is there a full dest word? */ |
| if (dfwpart2b == 1) { /* not */ |
| dfwfullb = 0; |
| dnfullw = 0; |
| } |
| else { |
| dnfullw = (dw - dfwbits) >> 5; |
| if (dnfullw == 0) /* if not */ |
| dfwfullb = 0; |
| else { /* if so */ |
| dfwfullb = 1; |
| if (dfwpartb) { |
| pdfwfull = pdfwpart + 1; |
| psfwfull = psfwpart + 1; |
| } |
| else { |
| pdfwfull = datad + dwpl * dy + (dx >> 5); |
| psfwfull = datas + swpl * sy + (sx >> 5); |
| } |
| } |
| } |
| |
| /* is the last word partial? */ |
| dlwbits = (dx + dw) & 31; |
| if (dfwpart2b == 1 || dlwbits == 0) /* if not */ |
| dlwpartb = 0; |
| else { |
| dlwpartb = 1; |
| dlwmask = lmask32[dlwbits]; |
| if (dfwpartb) { |
| pdlwpart = pdfwpart + 1 + dnfullw; |
| pslwpart = psfwpart + 1 + dnfullw; |
| } |
| else { |
| pdlwpart = datad + dwpl * dy + (dx >> 5) + dnfullw; |
| pslwpart = datas + swpl * sy + (sx >> 5) + dnfullw; |
| } |
| } |
| |
| |
| /*--------------------------------------------------------* |
| * Now we're ready to do the ops * |
| *--------------------------------------------------------*/ |
| switch (op) |
| { |
| case PIX_SRC: |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, *psfwpart, dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = *(psfwfull + j); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, *pslwpart, dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case PIX_NOT(PIX_SRC): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, ~(*psfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = ~(*(psfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, ~(*pslwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC | PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (*psfwpart | *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) |= *(psfwfull + j); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (*pslwpart | *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC & PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (*psfwpart & *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) &= *(psfwfull + j); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (*pslwpart & *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC ^ PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (*psfwpart ^ *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) ^= *(psfwfull + j); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (*pslwpart ^ *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC) | PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (~(*psfwpart) | *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) |= ~(*(psfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (~(*pslwpart) | *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC) & PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (~(*psfwpart) & *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) &= ~(*(psfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (~(*pslwpart) & *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC | PIX_NOT(PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (*psfwpart | ~(*pdfwpart)), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = *(psfwfull + j) | ~(*(pdfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (*pslwpart | ~(*pdlwpart)), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC & PIX_NOT(PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (*psfwpart & ~(*pdfwpart)), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = *(psfwfull + j) & ~(*(pdfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (*pslwpart & ~(*pdlwpart)), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC | PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| ~(*psfwpart | *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = ~(*(psfwfull + j) | *(pdfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| ~(*pslwpart | *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC & PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| ~(*psfwpart & *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = ~(*(psfwfull + j) & *(pdfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| ~(*pslwpart & *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| /* this is three cases: ~(s ^ d), ~s ^ d, s ^ ~d */ |
| case (PIX_NOT(PIX_SRC ^ PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| ~(*psfwpart ^ *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) |
| *(pdfwfull + j) = ~(*(psfwfull + j) ^ *(pdfwfull + j)); |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| ~(*pslwpart ^ *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| default: |
| fprintf(stderr, "Operation %x invalid\n", op); |
| } |
| |
| return; |
| } |
| |
| |
| /*--------------------------------------------------------------------* |
| * Static low-level rasterop without vertical word alignment * |
| *--------------------------------------------------------------------*/ |
| /*! |
| * rasteropGeneralLow() |
| * |
| * Input: datad (ptr to dest image data) |
| * dwpl (wpl of dest) |
| * dx (x val of UL corner of dest rectangle) |
| * dy (y val of UL corner of dest rectangle) |
| * dw (width of dest rectangle) |
| * dh (height of dest rectangle) |
| * op (op code) |
| * datas (ptr to src image data) |
| * swpl (wpl of src) |
| * sx (x val of UL corner of src rectangle) |
| * sy (y val of UL corner of src rectangle) |
| * Return: void |
| * |
| * This is called when the src and dest rects are |
| * do not have the same (32-bit) word alignment. |
| * |
| * The method is a generalization of rasteropVAlignLow(). |
| * There, the src image pieces were directly merged |
| * with the dest. Here, we shift the source bits |
| * to fill words that are aligned with the dest, and |
| * then use those "source words" exactly in place |
| * of the source words that were used in rasteropVAlignLow(). |
| * |
| * The critical parameter is thus the shift required |
| * for the src. Consider the left edge of the rectangle. |
| * The overhang into the src and dest words are found, |
| * and the difference is exactly this shift. There are |
| * two separate cases, depending on whether the src pixels |
| * are shifted left or right. If the src overhang is |
| * larger than the dest overhang, the src is shifted to |
| * the right, a number of pixels equal to the shift are |
| * left over for filling the next dest word, if necessary. |
| * But if the dest overhang is larger than the src, |
| * the src is shifted to the left, and it may also be |
| * necessary to shift an equal number of pixels in from |
| * the next src word. However, in both cases, after |
| * the first partial (or complete) dest word has been |
| * filled, the next src pixels will come from a left |
| * shift that exhausts the pixels in the src word. |
| */ |
| static void |
| rasteropGeneralLow(l_uint32 *datad, |
| l_int32 dwpl, |
| l_int32 dx, |
| l_int32 dy, |
| l_int32 dw, |
| l_int32 dh, |
| l_int32 op, |
| l_uint32 *datas, |
| l_int32 swpl, |
| l_int32 sx, |
| l_int32 sy) |
| { |
| l_int32 dfwpartb; /* boolean (1, 0) if first dest word is partial */ |
| l_int32 dfwpart2b; /* boolean (1, 0) if 1st dest word is doubly partial */ |
| l_uint32 dfwmask; /* mask for first partial dest word */ |
| l_int32 dfwbits; /* first word dest bits in overhang; 0-31 */ |
| l_int32 dhang; /* dest overhang in first partial word, */ |
| /* or 0 if dest is word aligned (same as dfwbits) */ |
| l_uint32 *pdfwpart; /* ptr to first partial dest word */ |
| l_uint32 *psfwpart; /* ptr to first partial src word */ |
| l_int32 dfwfullb; /* boolean (1, 0) if there exists a full dest word */ |
| l_int32 dnfullw; /* number of full words in dest */ |
| l_uint32 *pdfwfull; /* ptr to first full dest word */ |
| l_uint32 *psfwfull; /* ptr to first full src word */ |
| l_int32 dlwpartb; /* boolean (1, 0) if last dest word is partial */ |
| l_uint32 dlwmask; /* mask for last partial dest word */ |
| l_int32 dlwbits; /* last word dest bits in ovrhang */ |
| l_uint32 *pdlwpart; /* ptr to last partial dest word */ |
| l_uint32 *pslwpart; /* ptr to last partial src word */ |
| l_uint32 sword; /* compose src word aligned with the dest words */ |
| l_int32 sfwbits; /* first word src bits in overhang (1-32), */ |
| /* or 32 if src is word aligned */ |
| l_int32 shang; /* source overhang in the first partial word, */ |
| /* or 0 if src is word aligned (not same as sfwbits) */ |
| l_int32 sleftshift; /* bits to shift left for source word to align */ |
| /* with the dest. Also the number of bits that */ |
| /* get shifted to the right to align with the dest. */ |
| l_int32 srightshift; /* bits to shift right for source word to align */ |
| /* with dest. Also, the number of bits that get */ |
| /* shifted left to align with the dest. */ |
| l_int32 srightmask; /* mask for selecting sleftshift bits that have */ |
| /* been shifted right by srightshift bits */ |
| l_int32 sfwshiftdir; /* either SHIFT_LEFT or SHIFT_RIGHT */ |
| l_int32 sfwaddb; /* boolean: do we need an additional sfw right shift? */ |
| l_int32 slwaddb; /* boolean: do we need an additional slw right shift? */ |
| l_int32 i, j; |
| |
| |
| /*--------------------------------------------------------* |
| * Preliminary calculations * |
| *--------------------------------------------------------*/ |
| /* To get alignment of src with dst (e.g., in the |
| * full words) the src must do a left shift of its |
| * relative overhang in the current src word, |
| * and OR that with a right shift of |
| * (31 - relative overhang) from the next src word. |
| * We find the absolute overhangs, the relative overhangs, |
| * the required shifts and the src mask */ |
| if ((sx & 31) == 0) |
| shang = 0; |
| else |
| shang = 32 - (sx & 31); |
| if ((dx & 31) == 0) |
| dhang = 0; |
| else |
| dhang = 32 - (dx & 31); |
| |
| if (shang == 0 && dhang == 0) { /* this should be treated by an |
| aligned operation, not by |
| this general rasterop! */ |
| sleftshift = 0; |
| srightshift = 0; |
| srightmask = rmask32[0]; |
| } |
| else { |
| if (dhang > shang) |
| sleftshift = dhang - shang; |
| else |
| sleftshift = 32 - (shang - dhang); |
| srightshift = 32 - sleftshift; |
| srightmask = rmask32[sleftshift]; |
| } |
| |
| /* is the first dest word partial? */ |
| if ((dx & 31) == 0) { /* if not */ |
| dfwpartb = 0; |
| dfwbits = 0; |
| } |
| else { /* if so */ |
| dfwpartb = 1; |
| dfwbits = 32 - (dx & 31); |
| dfwmask = rmask32[dfwbits]; |
| pdfwpart = datad + dwpl * dy + (dx >> 5); |
| psfwpart = datas + swpl * sy + (sx >> 5); |
| sfwbits = 32 - (sx & 31); |
| if (dfwbits > sfwbits) { |
| sfwshiftdir = SHIFT_LEFT; /* and shift by sleftshift */ |
| if (dw < shang) |
| sfwaddb = 0; |
| else |
| sfwaddb = 1; /* and rshift in next src word by srightshift */ |
| } |
| else |
| sfwshiftdir = SHIFT_RIGHT; /* and shift by srightshift */ |
| } |
| |
| /* is the first dest word doubly partial? */ |
| if (dw >= dfwbits) /* if not */ |
| dfwpart2b = 0; |
| else { /* if so */ |
| dfwpart2b = 1; |
| dfwmask &= lmask32[32 - dfwbits + dw]; |
| } |
| |
| /* is there a full dest word? */ |
| if (dfwpart2b == 1) { /* not */ |
| dfwfullb = 0; |
| dnfullw = 0; |
| } |
| else { |
| dnfullw = (dw - dfwbits) >> 5; |
| if (dnfullw == 0) /* if not */ |
| dfwfullb = 0; |
| else { /* if so */ |
| dfwfullb = 1; |
| pdfwfull = datad + dwpl * dy + ((dx + dhang) >> 5); |
| psfwfull = datas + swpl * sy + ((sx + dhang) >> 5); /* yes, dhang */ |
| } |
| } |
| |
| /* is the last dest word partial? */ |
| dlwbits = (dx + dw) & 31; |
| if (dfwpart2b == 1 || dlwbits == 0) /* if not */ |
| dlwpartb = 0; |
| else { |
| dlwpartb = 1; |
| dlwmask = lmask32[dlwbits]; |
| pdlwpart = datad + dwpl * dy + ((dx + dhang) >> 5) + dnfullw; |
| pslwpart = datas + swpl * sy + ((sx + dhang) >> 5) + dnfullw; |
| if (dlwbits <= srightshift) /* must be <= here !!! */ |
| slwaddb = 0; /* we got enough bits from current src word */ |
| else |
| slwaddb = 1; /* must rshift in next src word by srightshift */ |
| } |
| |
| |
| /*--------------------------------------------------------* |
| * Now we're ready to do the ops * |
| *--------------------------------------------------------*/ |
| switch (op) |
| { |
| case PIX_SRC: |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, sword, dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, sword, dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case PIX_NOT(PIX_SRC): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, ~sword, dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = ~sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, ~sword, dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC | PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (sword | *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) |= sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (sword | *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC & PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (sword & *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) &= sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (sword & *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC ^ PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (sword ^ *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) ^= sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (sword ^ *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC) | PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (~sword | *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) |= ~sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (~sword | *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC) & PIX_DST): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (~sword & *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) &= ~sword; |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (~sword & *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC | PIX_NOT(PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (sword | ~(*pdfwpart)), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = sword | ~(*(pdfwfull + j)); |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (sword | ~(*pdlwpart)), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_SRC & PIX_NOT(PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| (sword & ~(*pdfwpart)), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = sword & ~(*(pdfwfull + j)); |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| (sword & ~(*pdlwpart)), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC | PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| ~(sword | *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = ~(sword | *(pdfwfull + j)); |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| ~(sword | *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| case (PIX_NOT(PIX_SRC & PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| ~(sword & *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = ~(sword & *(pdfwfull + j)); |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| ~(sword & *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| /* this is three cases: ~(s ^ d), ~s ^ d, s ^ ~d */ |
| case (PIX_NOT(PIX_SRC ^ PIX_DST)): |
| /* do the first partial word */ |
| if (dfwpartb) { |
| for (i = 0; i < dh; i++) |
| { |
| if (sfwshiftdir == SHIFT_LEFT) { |
| sword = *psfwpart << sleftshift; |
| if (sfwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(psfwpart + 1) >> srightshift, |
| srightmask); |
| } |
| else /* shift right */ |
| sword = *psfwpart >> srightshift; |
| |
| *pdfwpart = COMBINE_PARTIAL(*pdfwpart, |
| ~(sword ^ *pdfwpart), dfwmask); |
| pdfwpart += dwpl; |
| psfwpart += swpl; |
| } |
| } |
| |
| /* do the full words */ |
| if (dfwfullb) { |
| for (i = 0; i < dh; i++) { |
| for (j = 0; j < dnfullw; j++) { |
| sword = COMBINE_PARTIAL(*(psfwfull + j) << sleftshift, |
| *(psfwfull + j + 1) >> srightshift, |
| srightmask); |
| *(pdfwfull + j) = ~(sword ^ *(pdfwfull + j)); |
| } |
| pdfwfull += dwpl; |
| psfwfull += swpl; |
| } |
| } |
| |
| /* do the last partial word */ |
| if (dlwpartb) { |
| for (i = 0; i < dh; i++) { |
| sword = *pslwpart << sleftshift; |
| if (slwaddb) |
| sword = COMBINE_PARTIAL(sword, |
| *(pslwpart + 1) >> srightshift, |
| srightmask); |
| |
| *pdlwpart = COMBINE_PARTIAL(*pdlwpart, |
| ~(sword ^ *pdlwpart), dlwmask); |
| pdlwpart += dwpl; |
| pslwpart += swpl; |
| } |
| } |
| break; |
| default: |
| fprintf(stderr, "Operation %x invalid\n", op); |
| } |
| |
| return; |
| } |
| |