Leptonica 1.68
C Image Processing Library

roplow.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines