Home | History | Annotate | Download | only in jbig2
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "JBig2_Image.h"
      8 #include "../../../include/fxcrt/fx_basic.h"
      9 #include "../../../include/fxcrt/fx_coordinates.h"
     10 #include <limits.h>
     11 CJBig2_Image::CJBig2_Image(FX_INT32 w, FX_INT32 h)
     12 {
     13     m_nWidth	= w;
     14     m_nHeight	= h;
     15     if (m_nWidth <= 0 || m_nHeight <= 0 || m_nWidth > INT_MAX - 31) {
     16         m_pData = NULL;
     17         m_bNeedFree = FALSE;
     18         return;
     19     }
     20     m_nStride  = ((w + 31) >> 5) << 2;
     21     if (m_nStride * m_nHeight > 0 && 104857600 / (int)m_nStride > m_nHeight) {
     22         m_pData = (FX_BYTE *)m_pModule->JBig2_Malloc2(m_nStride, m_nHeight);
     23     } else {
     24         m_pData = NULL;
     25     }
     26     m_bNeedFree = TRUE;
     27 }
     28 CJBig2_Image::CJBig2_Image(FX_INT32 w, FX_INT32 h, FX_INT32 stride, FX_BYTE*pBuf)
     29 {
     30     m_nWidth = w;
     31     m_nHeight = h;
     32     m_nStride = stride;
     33     m_pData = pBuf;
     34     m_bNeedFree = FALSE;
     35 }
     36 CJBig2_Image::CJBig2_Image(CJBig2_Image &im)
     37 {
     38     m_pModule = im.m_pModule;
     39     m_nWidth	= im.m_nWidth;
     40     m_nHeight	= im.m_nHeight;
     41     m_nStride	= im.m_nStride;
     42     if (im.m_pData) {
     43         m_pData = (FX_BYTE*)m_pModule->JBig2_Malloc2(m_nStride, m_nHeight);
     44         JBIG2_memcpy(m_pData, im.m_pData, m_nStride * m_nHeight);
     45     } else {
     46         m_pData = NULL;
     47     }
     48     m_bNeedFree = TRUE;
     49 }
     50 CJBig2_Image::~CJBig2_Image()
     51 {
     52     if(m_bNeedFree && m_pData) {
     53         m_pModule->JBig2_Free(m_pData);
     54     }
     55 }
     56 FX_BOOL CJBig2_Image::getPixel(FX_INT32 x, FX_INT32 y)
     57 {
     58     if (!m_pData) {
     59         return 0;
     60     }
     61     FX_INT32 m, n;
     62     if(x < 0 || x >= m_nWidth) {
     63         return 0;
     64     }
     65     if(y < 0 || y >= m_nHeight) {
     66         return 0;
     67     }
     68     m = y * m_nStride + (x >> 3);
     69     n = x & 7;
     70     return ((m_pData[m] >> (7 - n)) & 1);
     71 }
     72 
     73 FX_INT32 CJBig2_Image::setPixel(FX_INT32 x, FX_INT32 y, FX_BOOL v)
     74 {
     75     if (!m_pData) {
     76         return 0;
     77     }
     78     FX_INT32 m, n;
     79     if(x < 0 || x >= m_nWidth) {
     80         return 0;
     81     }
     82     if(y < 0 || y >= m_nHeight) {
     83         return 0;
     84     }
     85     m = y * m_nStride + (x >> 3);
     86     n = x & 7;
     87     if(v) {
     88         m_pData[m] |= 1 << (7 - n);
     89     } else {
     90         m_pData[m] &= ~(1 << (7 - n));
     91     }
     92     return 1;
     93 }
     94 void CJBig2_Image::copyLine(FX_INT32 hTo, FX_INT32 hFrom)
     95 {
     96     if (!m_pData) {
     97         return;
     98     }
     99     if(hFrom < 0 || hFrom >= m_nHeight) {
    100         JBIG2_memset(m_pData + hTo * m_nStride, 0, m_nStride);
    101     } else {
    102         JBIG2_memcpy(m_pData + hTo * m_nStride, m_pData + hFrom * m_nStride, m_nStride);
    103     }
    104 }
    105 void CJBig2_Image::fill(FX_BOOL v)
    106 {
    107     if (!m_pData) {
    108         return;
    109     }
    110     JBIG2_memset(m_pData, v ? 0xff : 0, m_nStride * m_nHeight);
    111 }
    112 FX_BOOL CJBig2_Image::composeTo(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op)
    113 {
    114     if (!m_pData) {
    115         return FALSE;
    116     }
    117     return composeTo_opt2(pDst, x, y, op);
    118 }
    119 FX_BOOL CJBig2_Image::composeTo(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op, const FX_RECT* pSrcRect)
    120 {
    121     if (!m_pData) {
    122         return FALSE;
    123     }
    124     if (NULL == pSrcRect || *pSrcRect == FX_RECT(0, 0, m_nWidth, m_nHeight)) {
    125         return composeTo_opt2(pDst, x, y, op);
    126     }
    127     return composeTo_opt2(pDst, x, y, op, pSrcRect);
    128 }
    129 FX_BOOL CJBig2_Image::composeTo_unopt(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op)
    130 {
    131     FX_INT32 w, h, dx, dy;
    132     FX_INT32 i, j;
    133     w = m_nWidth;
    134     h = m_nHeight;
    135     dx = dy = 0;
    136     if(x < 0) {
    137         dx += -x;
    138         w  -= -x;
    139         x = 0;
    140     }
    141     if(y < 0) {
    142         dy += -y;
    143         h  -= -y;
    144         y = 0;
    145     }
    146     if(x + w > pDst->m_nWidth) {
    147         w = pDst->m_nWidth - x;
    148     }
    149     if(y + h > pDst->m_nHeight) {
    150         h = pDst->m_nHeight - y;
    151     }
    152     switch(op) {
    153         case JBIG2_COMPOSE_OR:
    154             for(j = 0; j < h; j++) {
    155                 for(i = 0; i < w; i++) {
    156                     pDst->setPixel(x + i, y + j,
    157                                    (getPixel(i + dx, j + dy) | pDst->getPixel(x + i, y + j)) & 1);
    158                 }
    159             }
    160             break;
    161         case JBIG2_COMPOSE_AND:
    162             for(j = 0; j < h; j++) {
    163                 for(i = 0; i < w; i++) {
    164                     pDst->setPixel(x + i, y + j,
    165                                    (getPixel(i + dx, j + dy) & pDst->getPixel(x + i, y + j)) & 1);
    166                 }
    167             }
    168             break;
    169         case JBIG2_COMPOSE_XOR:
    170             for(j = 0; j < h; j++) {
    171                 for(i = 0; i < w; i++) {
    172                     pDst->setPixel(x + i, y + j,
    173                                    (getPixel(i + dx, j + dy) ^ pDst->getPixel(x + i, y + j)) & 1);
    174                 }
    175             }
    176             break;
    177         case JBIG2_COMPOSE_XNOR:
    178             for(j = 0; j < h; j++) {
    179                 for(i = 0; i < w; i++) {
    180                     pDst->setPixel(x + i, y + j,
    181                                    (~(getPixel(i + dx, j + dy) ^ pDst->getPixel(x + i, y + j))) & 1);
    182                 }
    183             }
    184             break;
    185         case JBIG2_COMPOSE_REPLACE:
    186             for(j = 0; j < h; j++) {
    187                 for(i = 0; i < w; i++) {
    188                     pDst->setPixel(x + i, y + j, getPixel(i + dx, j + dy));
    189                 }
    190             }
    191             break;
    192     }
    193     return TRUE;
    194 }
    195 
    196 FX_BOOL CJBig2_Image::composeTo_opt(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op)
    197 {
    198     FX_INT32 x0, x1, y0, y1, xx, yy;
    199     FX_BYTE *pLineSrc, *pLineDst, *srcPtr, *destPtr;
    200     FX_DWORD src0, src1, src, dest, s1, s2, m1, m2, m3;
    201     FX_BOOL oneByte;
    202     if (!m_pData) {
    203         return FALSE;
    204     }
    205     if (y < 0) {
    206         y0 = -y;
    207     } else {
    208         y0 = 0;
    209     }
    210     if (y + m_nHeight > pDst->m_nHeight) {
    211         y1 = pDst->m_nHeight - y;
    212     } else {
    213         y1 = m_nHeight;
    214     }
    215     if (y0 >= y1) {
    216         return FALSE;
    217     }
    218     if (x >= 0) {
    219         x0 = x & ~7;
    220     } else {
    221         x0 = 0;
    222     }
    223     x1 = x + m_nWidth;
    224     if (x1 > pDst->m_nWidth) {
    225         x1 = pDst->m_nWidth;
    226     }
    227     if (x0 >= x1) {
    228         return FALSE;
    229     }
    230     s1 = x & 7;
    231     s2 = 8 - s1;
    232     m1 = 0xff >> (x1 & 7);
    233     m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
    234     m3 = (0xff >> s1) & m2;
    235     oneByte = x0 == ((x1 - 1) & ~7);
    236     pLineDst = pDst->m_pData + y * pDst->m_nStride;
    237     pLineSrc = m_pData + y0 * m_nStride;
    238     if(oneByte) {
    239         if(x >= 0) {
    240             switch(op) {
    241                 case JBIG2_COMPOSE_OR: {
    242                         for (yy = y0; yy < y1; ++yy) {
    243                             destPtr = pLineDst + (x >> 3);
    244                             srcPtr = pLineSrc;
    245                             dest = *destPtr;
    246                             dest |= (*srcPtr >> s1) & m2;
    247                             *destPtr = (FX_BYTE)dest;
    248                             pLineDst += pDst->m_nStride;
    249                             pLineSrc += m_nStride;
    250                         }
    251                     }
    252                     break;
    253                 case JBIG2_COMPOSE_AND: {
    254                         for (yy = y0; yy < y1; ++yy) {
    255                             destPtr = pLineDst + (x >> 3);
    256                             srcPtr = pLineSrc;
    257                             dest = *destPtr;
    258                             dest &= ((0xff00 | *srcPtr) >> s1) | m1;
    259                             *destPtr = (FX_BYTE)dest;
    260                             pLineDst += pDst->m_nStride;
    261                             pLineSrc += m_nStride;
    262                         }
    263                     }
    264                     break;
    265                 case JBIG2_COMPOSE_XOR: {
    266                         for (yy = y0; yy < y1; ++yy) {
    267                             destPtr = pLineDst + (x >> 3);
    268                             srcPtr = pLineSrc;
    269                             dest = *destPtr;
    270                             dest ^= (*srcPtr >> s1) & m2;
    271                             *destPtr = (FX_BYTE)dest;
    272                             pLineDst += pDst->m_nStride;
    273                             pLineSrc += m_nStride;
    274                         }
    275                     }
    276                     break;
    277                 case JBIG2_COMPOSE_XNOR: {
    278                         for (yy = y0; yy < y1; ++yy) {
    279                             destPtr = pLineDst + (x >> 3);
    280                             srcPtr = pLineSrc;
    281                             dest = *destPtr;
    282                             dest ^= ((*srcPtr ^ 0xff) >> s1) & m2;
    283                             *destPtr = (FX_BYTE)dest;
    284                             pLineDst += pDst->m_nStride;
    285                             pLineSrc += m_nStride;
    286                         }
    287                     }
    288                     break;
    289                 case JBIG2_COMPOSE_REPLACE: {
    290                         for (yy = y0; yy < y1; ++yy) {
    291                             destPtr = pLineDst + (x >> 3);
    292                             srcPtr = pLineSrc;
    293                             dest = *destPtr;
    294                             dest = (dest & ~m3) | ((*srcPtr >> s1) & m3);
    295                             *destPtr = (FX_BYTE)dest;
    296                             pLineDst += pDst->m_nStride;
    297                             pLineSrc += m_nStride;
    298                         }
    299                     }
    300                     break;
    301             }
    302         } else {
    303             switch(op) {
    304                 case JBIG2_COMPOSE_OR: {
    305                         for(yy = y0; yy < y1; ++yy) {
    306                             destPtr = pLineDst;
    307                             srcPtr = pLineSrc + (-x >> 3);
    308                             dest = *destPtr;
    309                             dest |= *srcPtr & m2;
    310                             *destPtr = (FX_BYTE)dest;
    311                             pLineDst += pDst->m_nStride;
    312                             pLineSrc += m_nStride;
    313                         }
    314                     }
    315                     break;
    316                 case JBIG2_COMPOSE_AND: {
    317                         for(yy = y0; yy < y1; ++yy) {
    318                             destPtr = pLineDst;
    319                             srcPtr = pLineSrc + (-x >> 3);
    320                             dest = *destPtr;
    321                             dest &= *srcPtr | m1;
    322                             *destPtr = (FX_BYTE)dest;
    323                             pLineDst += pDst->m_nStride;
    324                             pLineSrc += m_nStride;
    325                         }
    326                     }
    327                     break;
    328                 case JBIG2_COMPOSE_XOR: {
    329                         for(yy = y0; yy < y1; ++yy) {
    330                             destPtr = pLineDst;
    331                             srcPtr = pLineSrc + (-x >> 3);
    332                             dest = *destPtr;
    333                             dest ^= *srcPtr & m2;
    334                             *destPtr = (FX_BYTE)dest;
    335                             pLineDst += pDst->m_nStride;
    336                             pLineSrc += m_nStride;
    337                         }
    338                     }
    339                     break;
    340                 case JBIG2_COMPOSE_XNOR: {
    341                         for(yy = y0; yy < y1; ++yy) {
    342                             destPtr = pLineDst;
    343                             srcPtr = pLineSrc + (-x >> 3);
    344                             dest = *destPtr;
    345                             dest ^= (*srcPtr ^ 0xff) & m2;
    346                             *destPtr = (FX_BYTE)dest;
    347                             pLineDst += pDst->m_nStride;
    348                             pLineSrc += m_nStride;
    349                         }
    350                     }
    351                     break;
    352                 case JBIG2_COMPOSE_REPLACE: {
    353                         for(yy = y0; yy < y1; ++yy) {
    354                             destPtr = pLineDst;
    355                             srcPtr = pLineSrc + (-x >> 3);
    356                             dest = *destPtr;
    357                             dest = (*srcPtr & m2) | (dest & m1);
    358                             *destPtr = (FX_BYTE)dest;
    359                             pLineDst += pDst->m_nStride;
    360                             pLineSrc += m_nStride;
    361                         }
    362                     }
    363                     break;
    364             }
    365         }
    366     } else {
    367         if(x >= 0) {
    368             switch(op) {
    369                 case JBIG2_COMPOSE_OR: {
    370                         for(yy = y0; yy < y1; ++yy) {
    371                             destPtr = pLineDst + (x >> 3);
    372                             srcPtr = pLineSrc;
    373                             src1 = *srcPtr++;
    374                             dest = *destPtr;
    375                             dest |= src1 >> s1;
    376                             *destPtr++ = (FX_BYTE)dest;
    377                             xx = x0 + 8;
    378                             for (; xx < x1 - 8; xx += 8) {
    379                                 dest = *destPtr;
    380                                 src0 = src1;
    381                                 src1 = *srcPtr++;
    382                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    383                                 dest |= src;
    384                                 *destPtr++ = (FX_BYTE)dest;
    385                             }
    386                             dest = *destPtr;
    387                             src0 = src1;
    388                             if(srcPtr - pLineSrc < m_nStride) {
    389                                 src1 = *srcPtr++;
    390                             } else {
    391                                 src1 = 0;
    392                             }
    393                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    394                             dest |= src & m2;
    395                             *destPtr = (FX_BYTE)dest;
    396                             pLineDst += pDst->m_nStride;
    397                             pLineSrc += m_nStride;
    398                         }
    399                     }
    400                     break;
    401                 case JBIG2_COMPOSE_AND: {
    402                         for(yy = y0; yy < y1; ++yy) {
    403                             destPtr = pLineDst + (x >> 3);
    404                             srcPtr = pLineSrc;
    405                             src1 = *srcPtr++;
    406                             dest = *destPtr;
    407                             dest &= (0xff00 | src1) >> s1;
    408                             *destPtr++ = (FX_BYTE)dest;
    409                             xx = x0 + 8;
    410                             for (; xx < x1 - 8; xx += 8) {
    411                                 dest = *destPtr;
    412                                 src0 = src1;
    413                                 src1 = *srcPtr++;
    414                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    415                                 dest &= src;
    416                                 *destPtr++ = (FX_BYTE)dest;
    417                             }
    418                             dest = *destPtr;
    419                             src0 = src1;
    420                             if(srcPtr - pLineSrc < m_nStride) {
    421                                 src1 = *srcPtr++;
    422                             } else {
    423                                 src1 = 0;
    424                             }
    425                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    426                             dest &= src | m1;
    427                             *destPtr = (FX_BYTE)dest;
    428                             pLineDst += pDst->m_nStride;
    429                             pLineSrc += m_nStride;
    430                         }
    431                     }
    432                     break;
    433                 case JBIG2_COMPOSE_XOR: {
    434                         for(yy = y0; yy < y1; ++yy) {
    435                             destPtr = pLineDst + (x >> 3);
    436                             srcPtr = pLineSrc;
    437                             src1 = *srcPtr++;
    438                             dest = *destPtr;
    439                             dest ^= src1 >> s1;
    440                             *destPtr++ = (FX_BYTE)dest;
    441                             xx = x0 + 8;
    442                             for (; xx < x1 - 8; xx += 8) {
    443                                 dest = *destPtr;
    444                                 src0 = src1;
    445                                 src1 = *srcPtr++;
    446                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    447                                 dest ^= src;
    448                                 *destPtr++ = (FX_BYTE)dest;
    449                             }
    450                             dest = *destPtr;
    451                             src0 = src1;
    452                             if(srcPtr - pLineSrc < m_nStride) {
    453                                 src1 = *srcPtr++;
    454                             } else {
    455                                 src1 = 0;
    456                             }
    457                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    458                             dest ^= src & m2;
    459                             *destPtr = (FX_BYTE)dest;
    460                             pLineDst += pDst->m_nStride;
    461                             pLineSrc += m_nStride;
    462                         }
    463                     }
    464                     break;
    465                 case JBIG2_COMPOSE_XNOR: {
    466                         for(yy = y0; yy < y1; ++yy) {
    467                             destPtr = pLineDst + (x >> 3);
    468                             srcPtr = pLineSrc;
    469                             src1 = *srcPtr++;
    470                             dest = *destPtr;
    471                             dest ^= (src1 ^ 0xff) >> s1;
    472                             *destPtr++ = (FX_BYTE)dest;
    473                             xx = x0 + 8;
    474                             for (; xx < x1 - 8; xx += 8) {
    475                                 dest = *destPtr;
    476                                 src0 = src1;
    477                                 src1 = *srcPtr++;
    478                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    479                                 dest ^= src ^ 0xff;
    480                                 *destPtr++ = (FX_BYTE)dest;
    481                             }
    482                             dest = *destPtr;
    483                             src0 = src1;
    484                             if(srcPtr - pLineSrc < m_nStride) {
    485                                 src1 = *srcPtr++;
    486                             } else {
    487                                 src1 = 0;
    488                             }
    489                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    490                             dest ^= (src ^ 0xff) & m2;
    491                             *destPtr = (FX_BYTE)dest;
    492                             pLineDst += pDst->m_nStride;
    493                             pLineSrc += m_nStride;
    494                         }
    495                     }
    496                     break;
    497                 case JBIG2_COMPOSE_REPLACE: {
    498                         for(yy = y0; yy < y1; ++yy) {
    499                             destPtr = pLineDst + (x >> 3);
    500                             srcPtr = pLineSrc;
    501                             src1 = *srcPtr++;
    502                             dest = *destPtr;
    503                             dest = (dest & (0xff << s2)) | (src1 >> s1);
    504                             *destPtr++ = (FX_BYTE)dest;
    505                             xx = x0 + 8;
    506                             for (; xx < x1 - 8; xx += 8) {
    507                                 dest = *destPtr;
    508                                 src0 = src1;
    509                                 src1 = *srcPtr++;
    510                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    511                                 dest = src;
    512                                 *destPtr++ = (FX_BYTE)dest;
    513                             }
    514                             dest = *destPtr;
    515                             src0 = src1;
    516                             if(srcPtr - pLineSrc < m_nStride) {
    517                                 src1 = *srcPtr++;
    518                             } else {
    519                                 src1 = 0;
    520                             }
    521                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    522                             dest = (src & m2) | (dest & m1);
    523                             *destPtr = (FX_BYTE)dest;
    524                             pLineDst += pDst->m_nStride;
    525                             pLineSrc += m_nStride;
    526                         }
    527                     }
    528                     break;
    529             }
    530         } else {
    531             switch(op) {
    532                 case JBIG2_COMPOSE_OR: {
    533                         for(yy = y0; yy < y1; ++yy) {
    534                             destPtr = pLineDst;
    535                             srcPtr = pLineSrc + (-x >> 3);
    536                             src1 = *srcPtr++;
    537                             xx = x0;
    538                             for (; xx < x1 - 8; xx += 8) {
    539                                 dest = *destPtr;
    540                                 src0 = src1;
    541                                 src1 = *srcPtr++;
    542                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    543                                 dest |= src;
    544                                 *destPtr++ = (FX_BYTE)dest;
    545                             }
    546                             dest = *destPtr;
    547                             src0 = src1;
    548                             if(srcPtr - pLineSrc < m_nStride) {
    549                                 src1 = *srcPtr++;
    550                             } else {
    551                                 src1 = 0;
    552                             }
    553                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    554                             dest |= src & m2;
    555                             *destPtr = (FX_BYTE)dest;
    556                             pLineDst += pDst->m_nStride;
    557                             pLineSrc += m_nStride;
    558                         }
    559                     }
    560                     break;
    561                 case JBIG2_COMPOSE_AND: {
    562                         for(yy = y0; yy < y1; ++yy) {
    563                             destPtr = pLineDst;
    564                             srcPtr = pLineSrc + (-x >> 3);
    565                             src1 = *srcPtr++;
    566                             xx = x0;
    567                             for (; xx < x1 - 8; xx += 8) {
    568                                 dest = *destPtr;
    569                                 src0 = src1;
    570                                 src1 = *srcPtr++;
    571                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    572                                 dest &= src;
    573                                 *destPtr++ = (FX_BYTE)dest;
    574                             }
    575                             dest = *destPtr;
    576                             src0 = src1;
    577                             if(srcPtr - pLineSrc < m_nStride) {
    578                                 src1 = *srcPtr++;
    579                             } else {
    580                                 src1 = 0;
    581                             }
    582                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    583                             dest &= src | m1;
    584                             *destPtr = (FX_BYTE)dest;
    585                             pLineDst += pDst->m_nStride;
    586                             pLineSrc += m_nStride;
    587                         }
    588                     }
    589                     break;
    590                 case JBIG2_COMPOSE_XOR: {
    591                         for(yy = y0; yy < y1; ++yy) {
    592                             destPtr = pLineDst;
    593                             srcPtr = pLineSrc + (-x >> 3);
    594                             src1 = *srcPtr++;
    595                             xx = x0;
    596                             for (; xx < x1 - 8; xx += 8) {
    597                                 dest = *destPtr;
    598                                 src0 = src1;
    599                                 src1 = *srcPtr++;
    600                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    601                                 dest ^= src;
    602                                 *destPtr++ = (FX_BYTE)dest;
    603                             }
    604                             dest = *destPtr;
    605                             src0 = src1;
    606                             if(srcPtr - pLineSrc < m_nStride) {
    607                                 src1 = *srcPtr++;
    608                             } else {
    609                                 src1 = 0;
    610                             }
    611                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    612                             dest ^= src & m2;
    613                             *destPtr = (FX_BYTE)dest;
    614                             pLineDst += pDst->m_nStride;
    615                             pLineSrc += m_nStride;
    616                         }
    617                     }
    618                     break;
    619                 case JBIG2_COMPOSE_XNOR: {
    620                         for(yy = y0; yy < y1; ++yy) {
    621                             destPtr = pLineDst;
    622                             srcPtr = pLineSrc + (-x >> 3);
    623                             src1 = *srcPtr++;
    624                             xx = x0;
    625                             for (; xx < x1 - 8; xx += 8) {
    626                                 dest = *destPtr;
    627                                 src0 = src1;
    628                                 src1 = *srcPtr++;
    629                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    630                                 dest ^= src ^ 0xff;
    631                                 *destPtr++ = (FX_BYTE)dest;
    632                             }
    633                             dest = *destPtr;
    634                             src0 = src1;
    635                             if(srcPtr - pLineSrc < m_nStride) {
    636                                 src1 = *srcPtr++;
    637                             } else {
    638                                 src1 = 0;
    639                             }
    640                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    641                             dest ^= (src ^ 0xff) & m2;
    642                             *destPtr = (FX_BYTE)dest;
    643                             pLineDst += pDst->m_nStride;
    644                             pLineSrc += m_nStride;
    645                         }
    646                     }
    647                     break;
    648                 case JBIG2_COMPOSE_REPLACE: {
    649                         for(yy = y0; yy < y1; ++yy) {
    650                             destPtr = pLineDst;
    651                             srcPtr = pLineSrc + (-x >> 3);
    652                             src1 = *srcPtr++;
    653                             xx = x0;
    654                             for (; xx < x1 - 8; xx += 8) {
    655                                 dest = *destPtr;
    656                                 src0 = src1;
    657                                 src1 = *srcPtr++;
    658                                 src = (((src0 << 8) | src1) >> s1) & 0xff;
    659                                 dest = src;
    660                                 *destPtr++ = (FX_BYTE)dest;
    661                             }
    662                             dest = *destPtr;
    663                             src0 = src1;
    664                             if(srcPtr - pLineSrc < m_nStride) {
    665                                 src1 = *srcPtr++;
    666                             } else {
    667                                 src1 = 0;
    668                             }
    669                             src = (((src0 << 8) | src1) >> s1) & 0xff;
    670                             dest = (src & m2) | (dest & m1);
    671                             *destPtr = (FX_BYTE)dest;
    672                             pLineDst += pDst->m_nStride;
    673                             pLineSrc += m_nStride;
    674                         }
    675                     }
    676                     break;
    677             }
    678         }
    679     }
    680     return TRUE;
    681 }
    682 FX_BOOL CJBig2_Image::composeFrom(FX_INT32 x, FX_INT32 y, CJBig2_Image *pSrc, JBig2ComposeOp op)
    683 {
    684     if (!m_pData) {
    685         return FALSE;
    686     }
    687     return pSrc->composeTo(this, x, y, op);
    688 }
    689 FX_BOOL CJBig2_Image::composeFrom(FX_INT32 x, FX_INT32 y, CJBig2_Image *pSrc, JBig2ComposeOp op, const FX_RECT* pSrcRect)
    690 {
    691     if (!m_pData) {
    692         return FALSE;
    693     }
    694     return pSrc->composeTo(this, x, y, op, pSrcRect);
    695 }
    696 CJBig2_Image *CJBig2_Image::subImage_unopt(FX_INT32 x, FX_INT32 y, FX_INT32 w, FX_INT32 h)
    697 {
    698     CJBig2_Image *pImage;
    699     FX_INT32 i, j;
    700     JBIG2_ALLOC(pImage, CJBig2_Image(w, h));
    701     for(j = 0; j < h; j++) {
    702         for(i = 0; i < w; i++) {
    703             pImage->setPixel(i, j, getPixel(x + i, y + j));
    704         }
    705     }
    706     return pImage;
    707 }
    708 #define JBIG2_GETDWORD(buf)	((FX_DWORD)(((buf)[0] << 24) | ((buf)[1] << 16) | ((buf)[2] << 8) | (buf)[3]))
    709 CJBig2_Image *CJBig2_Image::subImage(FX_INT32 x, FX_INT32 y, FX_INT32 w, FX_INT32 h)
    710 {
    711     CJBig2_Image *pImage;
    712     FX_INT32 m, n, j;
    713     FX_BYTE *pLineSrc, *pLineDst;
    714     FX_DWORD wTmp;
    715     FX_BYTE *pSrc, *pSrcEnd, *pDst, *pDstEnd;
    716     if (w == 0 || h == 0) {
    717         return NULL;
    718     }
    719     JBIG2_ALLOC(pImage, CJBig2_Image(w, h));
    720     if (!m_pData) {
    721         pImage->fill(0);
    722         return pImage;
    723     }
    724     if (!pImage->m_pData) {
    725         return pImage;
    726     }
    727     pLineSrc = m_pData + m_nStride * y;
    728     pLineDst = pImage->m_pData;
    729     m = (x >> 5) << 2;
    730     n = x & 31;
    731     if(n == 0) {
    732         for(j = 0; j < h; j++) {
    733             pSrc = pLineSrc + m;
    734             pSrcEnd = pLineSrc + m_nStride;
    735             pDst = pLineDst;
    736             pDstEnd = pLineDst + pImage->m_nStride;
    737             for(; pDst < pDstEnd; pSrc += 4, pDst += 4) {
    738                 *((FX_DWORD *)pDst) = *((FX_DWORD *)pSrc);
    739             }
    740             pLineSrc += m_nStride;
    741             pLineDst += pImage->m_nStride;
    742         }
    743     } else {
    744         for(j = 0; j < h; j++) {
    745             pSrc = pLineSrc + m;
    746             pSrcEnd = pLineSrc + m_nStride;
    747             pDst = pLineDst;
    748             pDstEnd = pLineDst + pImage->m_nStride;
    749             for(; pDst < pDstEnd; pSrc += 4, pDst += 4) {
    750                 if(pSrc + 4 < pSrcEnd) {
    751                     wTmp = (JBIG2_GETDWORD(pSrc) << n) | (JBIG2_GETDWORD(pSrc + 4) >> (32 - n));
    752                 } else {
    753                     wTmp = JBIG2_GETDWORD(pSrc) << n;
    754                 }
    755                 pDst[0] = (FX_BYTE)(wTmp >> 24);
    756                 pDst[1] = (FX_BYTE)(wTmp >> 16);
    757                 pDst[2] = (FX_BYTE)(wTmp >> 8);
    758                 pDst[3] = (FX_BYTE)wTmp;
    759             }
    760             pLineSrc += m_nStride;
    761             pLineDst += pImage->m_nStride;
    762         }
    763     }
    764     return pImage;
    765 }
    766 void CJBig2_Image::expand(FX_INT32 h, FX_BOOL v)
    767 {
    768     if (!m_pData) {
    769         return;
    770     }
    771     m_pData = (FX_BYTE*)m_pModule->JBig2_Realloc(m_pData, h * m_nStride);
    772     if(h > m_nHeight) {
    773         JBIG2_memset(m_pData + m_nHeight * m_nStride, v ? 0xff : 0, (h - m_nHeight)*m_nStride);
    774     }
    775     m_nHeight = h;
    776 }
    777 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op)
    778 {
    779     FX_INT32 xs0, ys0, xs1, ys1, xd0, yd0, xd1, yd1, xx, yy, w, h, middleDwords, lineLeft;
    780     FX_DWORD s1, d1, d2, shift, shift1, shift2, tmp, tmp1, tmp2, maskL, maskR, maskM;
    781     FX_BYTE *lineSrc, *lineDst, *sp, *dp;
    782     if (!m_pData) {
    783         return FALSE;
    784     }
    785     if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) {
    786         return FALSE;
    787     }
    788     if(y < 0) {
    789         ys0 = -y;
    790     } else {
    791         ys0 = 0;
    792     }
    793     if(y + m_nHeight > pDst->m_nHeight) {
    794         ys1 = pDst->m_nHeight - y;
    795     } else {
    796         ys1 = m_nHeight;
    797     }
    798     if(x < 0) {
    799         xs0 = -x;
    800     } else {
    801         xs0 = 0;
    802     }
    803     if(x + m_nWidth > pDst->m_nWidth) {
    804         xs1 = pDst->m_nWidth - x;
    805     } else {
    806         xs1 = m_nWidth;
    807     }
    808     if((ys0 >= ys1) || (xs0 >= xs1)) {
    809         return 0;
    810     }
    811     w = xs1 - xs0;
    812     h = ys1 - ys0;
    813     if(y < 0) {
    814         yd0 = 0;
    815     } else {
    816         yd0 = y;
    817     }
    818     if(x < 0) {
    819         xd0 = 0;
    820     } else {
    821         xd0 = x;
    822     }
    823     xd1 = xd0 + w;
    824     yd1 = yd0 + h;
    825     d1 = xd0 & 31;
    826     d2 = xd1 & 31;
    827     s1 = xs0 & 31;
    828     maskL = 0xffffffff >> d1;
    829     maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
    830     maskM = maskL & maskR;
    831     lineSrc = m_pData + ys0 * m_nStride + ((xs0 >> 5) << 2);
    832     lineLeft = m_nStride - ((xs0 >> 5) << 2);
    833     lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
    834     if((xd0 & ~31) == ((xd1 - 1) & ~31)) {
    835         if((xs0 & ~31) == ((xs1 - 1) & ~31)) {
    836             if(s1 > d1) {
    837                 shift = s1 - d1;
    838                 for(yy = yd0; yy < yd1; yy++) {
    839                     tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
    840                     tmp2 = JBIG2_GETDWORD(lineDst);
    841                     switch(op) {
    842                         case JBIG2_COMPOSE_OR:
    843                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    844                             break;
    845                         case JBIG2_COMPOSE_AND:
    846                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    847                             break;
    848                         case JBIG2_COMPOSE_XOR:
    849                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    850                             break;
    851                         case JBIG2_COMPOSE_XNOR:
    852                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    853                             break;
    854                         case JBIG2_COMPOSE_REPLACE:
    855                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    856                             break;
    857                     }
    858                     lineDst[0] = (FX_BYTE)(tmp >> 24);
    859                     lineDst[1] = (FX_BYTE)(tmp >> 16);
    860                     lineDst[2] = (FX_BYTE)(tmp >> 8);
    861                     lineDst[3] = (FX_BYTE)tmp;
    862                     lineSrc += m_nStride;
    863                     lineDst += pDst->m_nStride;
    864                 }
    865             } else {
    866                 shift = d1 - s1;
    867                 for(yy = yd0; yy < yd1; yy++) {
    868                     tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
    869                     tmp2 = JBIG2_GETDWORD(lineDst);
    870                     switch(op) {
    871                         case JBIG2_COMPOSE_OR:
    872                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    873                             break;
    874                         case JBIG2_COMPOSE_AND:
    875                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    876                             break;
    877                         case JBIG2_COMPOSE_XOR:
    878                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    879                             break;
    880                         case JBIG2_COMPOSE_XNOR:
    881                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    882                             break;
    883                         case JBIG2_COMPOSE_REPLACE:
    884                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    885                             break;
    886                     }
    887                     lineDst[0] = (FX_BYTE)(tmp >> 24);
    888                     lineDst[1] = (FX_BYTE)(tmp >> 16);
    889                     lineDst[2] = (FX_BYTE)(tmp >> 8);
    890                     lineDst[3] = (FX_BYTE)tmp;
    891                     lineSrc += m_nStride;
    892                     lineDst += pDst->m_nStride;
    893                 }
    894             }
    895         } else {
    896             shift1 = s1 - d1;
    897             shift2 = 32 - shift1;
    898             for(yy = yd0; yy < yd1; yy++) {
    899                 tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) | (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
    900                 tmp2 = JBIG2_GETDWORD(lineDst);
    901                 switch(op) {
    902                     case JBIG2_COMPOSE_OR:
    903                         tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    904                         break;
    905                     case JBIG2_COMPOSE_AND:
    906                         tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    907                         break;
    908                     case JBIG2_COMPOSE_XOR:
    909                         tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    910                         break;
    911                     case JBIG2_COMPOSE_XNOR:
    912                         tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    913                         break;
    914                     case JBIG2_COMPOSE_REPLACE:
    915                         tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    916                         break;
    917                 }
    918                 lineDst[0] = (FX_BYTE)(tmp >> 24);
    919                 lineDst[1] = (FX_BYTE)(tmp >> 16);
    920                 lineDst[2] = (FX_BYTE)(tmp >> 8);
    921                 lineDst[3] = (FX_BYTE)tmp;
    922                 lineSrc += m_nStride;
    923                 lineDst += pDst->m_nStride;
    924             }
    925         }
    926     } else {
    927         if(s1 > d1) {
    928             shift1 = s1 - d1;
    929             shift2 = 32 - shift1;
    930             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
    931             for(yy = yd0; yy < yd1; yy++) {
    932                 sp = lineSrc;
    933                 dp = lineDst;
    934                 if(d1 != 0) {
    935                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
    936                     tmp2 = JBIG2_GETDWORD(dp);
    937                     switch(op) {
    938                         case JBIG2_COMPOSE_OR:
    939                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
    940                             break;
    941                         case JBIG2_COMPOSE_AND:
    942                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
    943                             break;
    944                         case JBIG2_COMPOSE_XOR:
    945                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
    946                             break;
    947                         case JBIG2_COMPOSE_XNOR:
    948                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
    949                             break;
    950                         case JBIG2_COMPOSE_REPLACE:
    951                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
    952                             break;
    953                     }
    954                     dp[0] = (FX_BYTE)(tmp >> 24);
    955                     dp[1] = (FX_BYTE)(tmp >> 16);
    956                     dp[2] = (FX_BYTE)(tmp >> 8);
    957                     dp[3] = (FX_BYTE)tmp;
    958                     sp += 4;
    959                     dp += 4;
    960                 }
    961                 for(xx = 0; xx < middleDwords; xx++) {
    962                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
    963                     tmp2 = JBIG2_GETDWORD(dp);
    964                     switch(op) {
    965                         case JBIG2_COMPOSE_OR:
    966                             tmp = tmp1 | tmp2;
    967                             break;
    968                         case JBIG2_COMPOSE_AND:
    969                             tmp = tmp1 & tmp2;
    970                             break;
    971                         case JBIG2_COMPOSE_XOR:
    972                             tmp = tmp1 ^ tmp2;
    973                             break;
    974                         case JBIG2_COMPOSE_XNOR:
    975                             tmp = ~(tmp1 ^ tmp2);
    976                             break;
    977                         case JBIG2_COMPOSE_REPLACE:
    978                             tmp = tmp1;
    979                             break;
    980                     }
    981                     dp[0] = (FX_BYTE)(tmp >> 24);
    982                     dp[1] = (FX_BYTE)(tmp >> 16);
    983                     dp[2] = (FX_BYTE)(tmp >> 8);
    984                     dp[3] = (FX_BYTE)tmp;
    985                     sp += 4;
    986                     dp += 4;
    987                 }
    988                 if(d2 != 0) {
    989                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (
    990                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift2);
    991                     tmp2 = JBIG2_GETDWORD(dp);
    992                     switch(op) {
    993                         case JBIG2_COMPOSE_OR:
    994                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
    995                             break;
    996                         case JBIG2_COMPOSE_AND:
    997                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
    998                             break;
    999                         case JBIG2_COMPOSE_XOR:
   1000                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1001                             break;
   1002                         case JBIG2_COMPOSE_XNOR:
   1003                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1004                             break;
   1005                         case JBIG2_COMPOSE_REPLACE:
   1006                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1007                             break;
   1008                     }
   1009                     dp[0] = (FX_BYTE)(tmp >> 24);
   1010                     dp[1] = (FX_BYTE)(tmp >> 16);
   1011                     dp[2] = (FX_BYTE)(tmp >> 8);
   1012                     dp[3] = (FX_BYTE)tmp;
   1013                 }
   1014                 lineSrc += m_nStride;
   1015                 lineDst += pDst->m_nStride;
   1016             }
   1017         } else if(s1 == d1) {
   1018             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
   1019             for(yy = yd0; yy < yd1; yy++) {
   1020                 sp = lineSrc;
   1021                 dp = lineDst;
   1022                 if(d1 != 0) {
   1023                     tmp1 = JBIG2_GETDWORD(sp);
   1024                     tmp2 = JBIG2_GETDWORD(dp);
   1025                     switch(op) {
   1026                         case JBIG2_COMPOSE_OR:
   1027                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
   1028                             break;
   1029                         case JBIG2_COMPOSE_AND:
   1030                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
   1031                             break;
   1032                         case JBIG2_COMPOSE_XOR:
   1033                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
   1034                             break;
   1035                         case JBIG2_COMPOSE_XNOR:
   1036                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
   1037                             break;
   1038                         case JBIG2_COMPOSE_REPLACE:
   1039                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
   1040                             break;
   1041                     }
   1042                     dp[0] = (FX_BYTE)(tmp >> 24);
   1043                     dp[1] = (FX_BYTE)(tmp >> 16);
   1044                     dp[2] = (FX_BYTE)(tmp >> 8);
   1045                     dp[3] = (FX_BYTE)tmp;
   1046                     sp += 4;
   1047                     dp += 4;
   1048                 }
   1049                 for(xx = 0; xx < middleDwords; xx++) {
   1050                     tmp1 = JBIG2_GETDWORD(sp);
   1051                     tmp2 = JBIG2_GETDWORD(dp);
   1052                     switch(op) {
   1053                         case JBIG2_COMPOSE_OR:
   1054                             tmp = tmp1 | tmp2;
   1055                             break;
   1056                         case JBIG2_COMPOSE_AND:
   1057                             tmp = tmp1 & tmp2;
   1058                             break;
   1059                         case JBIG2_COMPOSE_XOR:
   1060                             tmp = tmp1 ^ tmp2;
   1061                             break;
   1062                         case JBIG2_COMPOSE_XNOR:
   1063                             tmp = ~(tmp1 ^ tmp2);
   1064                             break;
   1065                         case JBIG2_COMPOSE_REPLACE:
   1066                             tmp = tmp1;
   1067                             break;
   1068                     }
   1069                     dp[0] = (FX_BYTE)(tmp >> 24);
   1070                     dp[1] = (FX_BYTE)(tmp >> 16);
   1071                     dp[2] = (FX_BYTE)(tmp >> 8);
   1072                     dp[3] = (FX_BYTE)tmp;
   1073                     sp += 4;
   1074                     dp += 4;
   1075                 }
   1076                 if(d2 != 0) {
   1077                     tmp1 = JBIG2_GETDWORD(sp);
   1078                     tmp2 = JBIG2_GETDWORD(dp);
   1079                     switch(op) {
   1080                         case JBIG2_COMPOSE_OR:
   1081                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
   1082                             break;
   1083                         case JBIG2_COMPOSE_AND:
   1084                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
   1085                             break;
   1086                         case JBIG2_COMPOSE_XOR:
   1087                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1088                             break;
   1089                         case JBIG2_COMPOSE_XNOR:
   1090                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1091                             break;
   1092                         case JBIG2_COMPOSE_REPLACE:
   1093                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1094                             break;
   1095                     }
   1096                     dp[0] = (FX_BYTE)(tmp >> 24);
   1097                     dp[1] = (FX_BYTE)(tmp >> 16);
   1098                     dp[2] = (FX_BYTE)(tmp >> 8);
   1099                     dp[3] = (FX_BYTE)tmp;
   1100                 }
   1101                 lineSrc += m_nStride;
   1102                 lineDst += pDst->m_nStride;
   1103             }
   1104         } else {
   1105             shift1 = d1 - s1;
   1106             shift2 = 32 - shift1;
   1107             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
   1108             for(yy = yd0; yy < yd1; yy++) {
   1109                 sp = lineSrc;
   1110                 dp = lineDst;
   1111                 if(d1 != 0) {
   1112                     tmp1 = JBIG2_GETDWORD(sp) >> shift1;
   1113                     tmp2 = JBIG2_GETDWORD(dp);
   1114                     switch(op) {
   1115                         case JBIG2_COMPOSE_OR:
   1116                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
   1117                             break;
   1118                         case JBIG2_COMPOSE_AND:
   1119                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
   1120                             break;
   1121                         case JBIG2_COMPOSE_XOR:
   1122                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
   1123                             break;
   1124                         case JBIG2_COMPOSE_XNOR:
   1125                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
   1126                             break;
   1127                         case JBIG2_COMPOSE_REPLACE:
   1128                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
   1129                             break;
   1130                     }
   1131                     dp[0] = (FX_BYTE)(tmp >> 24);
   1132                     dp[1] = (FX_BYTE)(tmp >> 16);
   1133                     dp[2] = (FX_BYTE)(tmp >> 8);
   1134                     dp[3] = (FX_BYTE)tmp;
   1135                     dp += 4;
   1136                 }
   1137                 for(xx = 0; xx < middleDwords; xx++) {
   1138                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ((JBIG2_GETDWORD(sp + 4)) >> shift1);
   1139                     tmp2 = JBIG2_GETDWORD(dp);
   1140                     switch(op) {
   1141                         case JBIG2_COMPOSE_OR:
   1142                             tmp = tmp1 | tmp2;
   1143                             break;
   1144                         case JBIG2_COMPOSE_AND:
   1145                             tmp = tmp1 & tmp2;
   1146                             break;
   1147                         case JBIG2_COMPOSE_XOR:
   1148                             tmp = tmp1 ^ tmp2;
   1149                             break;
   1150                         case JBIG2_COMPOSE_XNOR:
   1151                             tmp = ~(tmp1 ^ tmp2);
   1152                             break;
   1153                         case JBIG2_COMPOSE_REPLACE:
   1154                             tmp = tmp1;
   1155                             break;
   1156                     }
   1157                     dp[0] = (FX_BYTE)(tmp >> 24);
   1158                     dp[1] = (FX_BYTE)(tmp >> 16);
   1159                     dp[2] = (FX_BYTE)(tmp >> 8);
   1160                     dp[3] = (FX_BYTE)tmp;
   1161                     sp += 4;
   1162                     dp += 4;
   1163                 }
   1164                 if(d2 != 0) {
   1165                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | (
   1166                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift1);
   1167                     tmp2 = JBIG2_GETDWORD(dp);
   1168                     switch(op) {
   1169                         case JBIG2_COMPOSE_OR:
   1170                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
   1171                             break;
   1172                         case JBIG2_COMPOSE_AND:
   1173                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
   1174                             break;
   1175                         case JBIG2_COMPOSE_XOR:
   1176                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1177                             break;
   1178                         case JBIG2_COMPOSE_XNOR:
   1179                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1180                             break;
   1181                         case JBIG2_COMPOSE_REPLACE:
   1182                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1183                             break;
   1184                     }
   1185                     dp[0] = (FX_BYTE)(tmp >> 24);
   1186                     dp[1] = (FX_BYTE)(tmp >> 16);
   1187                     dp[2] = (FX_BYTE)(tmp >> 8);
   1188                     dp[3] = (FX_BYTE)tmp;
   1189                 }
   1190                 lineSrc += m_nStride;
   1191                 lineDst += pDst->m_nStride;
   1192             }
   1193         }
   1194     }
   1195     return 1;
   1196 }
   1197 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op, const FX_RECT* pSrcRect)
   1198 {
   1199     FX_INT32 xs0, ys0, xs1, ys1, xd0, yd0, xd1, yd1, xx, yy, w, h, middleDwords, lineLeft;
   1200     FX_DWORD s1, d1, d2, shift, shift1, shift2, tmp, tmp1, tmp2, maskL, maskR, maskM;
   1201     FX_BYTE *lineSrc, *lineDst, *sp, *dp;
   1202     FX_INT32 sw, sh;
   1203     if (!m_pData) {
   1204         return FALSE;
   1205     }
   1206     if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) {
   1207         return FALSE;
   1208     }
   1209     sw = pSrcRect->Width();
   1210     sh = pSrcRect->Height();
   1211     if(y < 0) {
   1212         ys0 = -y;
   1213     } else {
   1214         ys0 = 0;
   1215     }
   1216     if(y + sh > pDst->m_nHeight) {
   1217         ys1 = pDst->m_nHeight - y;
   1218     } else {
   1219         ys1 = sh;
   1220     }
   1221     if(x < 0) {
   1222         xs0 = -x;
   1223     } else {
   1224         xs0 = 0;
   1225     }
   1226     if(x + sw > pDst->m_nWidth) {
   1227         xs1 = pDst->m_nWidth - x;
   1228     } else {
   1229         xs1 = sw;
   1230     }
   1231     if((ys0 >= ys1) || (xs0 >= xs1)) {
   1232         return 0;
   1233     }
   1234     w = xs1 - xs0;
   1235     h = ys1 - ys0;
   1236     if(y < 0) {
   1237         yd0 = 0;
   1238     } else {
   1239         yd0 = y;
   1240     }
   1241     if(x < 0) {
   1242         xd0 = 0;
   1243     } else {
   1244         xd0 = x;
   1245     }
   1246     xd1 = xd0 + w;
   1247     yd1 = yd0 + h;
   1248     d1 = xd0 & 31;
   1249     d2 = xd1 & 31;
   1250     s1 = xs0 & 31;
   1251     maskL = 0xffffffff >> d1;
   1252     maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
   1253     maskM = maskL & maskR;
   1254     lineSrc = m_pData + (pSrcRect->top + ys0) * m_nStride + (((xs0 + pSrcRect->left) >> 5) << 2);
   1255     lineLeft = m_nStride - ((xs0 >> 5) << 2);
   1256     lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
   1257     if((xd0 & ~31) == ((xd1 - 1) & ~31)) {
   1258         if((xs0 & ~31) == ((xs1 - 1) & ~31)) {
   1259             if(s1 > d1) {
   1260                 shift = s1 - d1;
   1261                 for(yy = yd0; yy < yd1; yy++) {
   1262                     tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
   1263                     tmp2 = JBIG2_GETDWORD(lineDst);
   1264                     switch(op) {
   1265                         case JBIG2_COMPOSE_OR:
   1266                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
   1267                             break;
   1268                         case JBIG2_COMPOSE_AND:
   1269                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
   1270                             break;
   1271                         case JBIG2_COMPOSE_XOR:
   1272                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
   1273                             break;
   1274                         case JBIG2_COMPOSE_XNOR:
   1275                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
   1276                             break;
   1277                         case JBIG2_COMPOSE_REPLACE:
   1278                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
   1279                             break;
   1280                     }
   1281                     lineDst[0] = (FX_BYTE)(tmp >> 24);
   1282                     lineDst[1] = (FX_BYTE)(tmp >> 16);
   1283                     lineDst[2] = (FX_BYTE)(tmp >> 8);
   1284                     lineDst[3] = (FX_BYTE)tmp;
   1285                     lineSrc += m_nStride;
   1286                     lineDst += pDst->m_nStride;
   1287                 }
   1288             } else {
   1289                 shift = d1 - s1;
   1290                 for(yy = yd0; yy < yd1; yy++) {
   1291                     tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
   1292                     tmp2 = JBIG2_GETDWORD(lineDst);
   1293                     switch(op) {
   1294                         case JBIG2_COMPOSE_OR:
   1295                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
   1296                             break;
   1297                         case JBIG2_COMPOSE_AND:
   1298                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
   1299                             break;
   1300                         case JBIG2_COMPOSE_XOR:
   1301                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
   1302                             break;
   1303                         case JBIG2_COMPOSE_XNOR:
   1304                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
   1305                             break;
   1306                         case JBIG2_COMPOSE_REPLACE:
   1307                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
   1308                             break;
   1309                     }
   1310                     lineDst[0] = (FX_BYTE)(tmp >> 24);
   1311                     lineDst[1] = (FX_BYTE)(tmp >> 16);
   1312                     lineDst[2] = (FX_BYTE)(tmp >> 8);
   1313                     lineDst[3] = (FX_BYTE)tmp;
   1314                     lineSrc += m_nStride;
   1315                     lineDst += pDst->m_nStride;
   1316                 }
   1317             }
   1318         } else {
   1319             shift1 = s1 - d1;
   1320             shift2 = 32 - shift1;
   1321             for(yy = yd0; yy < yd1; yy++) {
   1322                 tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) | (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
   1323                 tmp2 = JBIG2_GETDWORD(lineDst);
   1324                 switch(op) {
   1325                     case JBIG2_COMPOSE_OR:
   1326                         tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
   1327                         break;
   1328                     case JBIG2_COMPOSE_AND:
   1329                         tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
   1330                         break;
   1331                     case JBIG2_COMPOSE_XOR:
   1332                         tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
   1333                         break;
   1334                     case JBIG2_COMPOSE_XNOR:
   1335                         tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
   1336                         break;
   1337                     case JBIG2_COMPOSE_REPLACE:
   1338                         tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
   1339                         break;
   1340                 }
   1341                 lineDst[0] = (FX_BYTE)(tmp >> 24);
   1342                 lineDst[1] = (FX_BYTE)(tmp >> 16);
   1343                 lineDst[2] = (FX_BYTE)(tmp >> 8);
   1344                 lineDst[3] = (FX_BYTE)tmp;
   1345                 lineSrc += m_nStride;
   1346                 lineDst += pDst->m_nStride;
   1347             }
   1348         }
   1349     } else {
   1350         if(s1 > d1) {
   1351             shift1 = s1 - d1;
   1352             shift2 = 32 - shift1;
   1353             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
   1354             for(yy = yd0; yy < yd1; yy++) {
   1355                 sp = lineSrc;
   1356                 dp = lineDst;
   1357                 if(d1 != 0) {
   1358                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
   1359                     tmp2 = JBIG2_GETDWORD(dp);
   1360                     switch(op) {
   1361                         case JBIG2_COMPOSE_OR:
   1362                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
   1363                             break;
   1364                         case JBIG2_COMPOSE_AND:
   1365                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
   1366                             break;
   1367                         case JBIG2_COMPOSE_XOR:
   1368                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
   1369                             break;
   1370                         case JBIG2_COMPOSE_XNOR:
   1371                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
   1372                             break;
   1373                         case JBIG2_COMPOSE_REPLACE:
   1374                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
   1375                             break;
   1376                     }
   1377                     dp[0] = (FX_BYTE)(tmp >> 24);
   1378                     dp[1] = (FX_BYTE)(tmp >> 16);
   1379                     dp[2] = (FX_BYTE)(tmp >> 8);
   1380                     dp[3] = (FX_BYTE)tmp;
   1381                     sp += 4;
   1382                     dp += 4;
   1383                 }
   1384                 for(xx = 0; xx < middleDwords; xx++) {
   1385                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
   1386                     tmp2 = JBIG2_GETDWORD(dp);
   1387                     switch(op) {
   1388                         case JBIG2_COMPOSE_OR:
   1389                             tmp = tmp1 | tmp2;
   1390                             break;
   1391                         case JBIG2_COMPOSE_AND:
   1392                             tmp = tmp1 & tmp2;
   1393                             break;
   1394                         case JBIG2_COMPOSE_XOR:
   1395                             tmp = tmp1 ^ tmp2;
   1396                             break;
   1397                         case JBIG2_COMPOSE_XNOR:
   1398                             tmp = ~(tmp1 ^ tmp2);
   1399                             break;
   1400                         case JBIG2_COMPOSE_REPLACE:
   1401                             tmp = tmp1;
   1402                             break;
   1403                     }
   1404                     dp[0] = (FX_BYTE)(tmp >> 24);
   1405                     dp[1] = (FX_BYTE)(tmp >> 16);
   1406                     dp[2] = (FX_BYTE)(tmp >> 8);
   1407                     dp[3] = (FX_BYTE)tmp;
   1408                     sp += 4;
   1409                     dp += 4;
   1410                 }
   1411                 if(d2 != 0) {
   1412                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (
   1413                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift2);
   1414                     tmp2 = JBIG2_GETDWORD(dp);
   1415                     switch(op) {
   1416                         case JBIG2_COMPOSE_OR:
   1417                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
   1418                             break;
   1419                         case JBIG2_COMPOSE_AND:
   1420                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
   1421                             break;
   1422                         case JBIG2_COMPOSE_XOR:
   1423                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1424                             break;
   1425                         case JBIG2_COMPOSE_XNOR:
   1426                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1427                             break;
   1428                         case JBIG2_COMPOSE_REPLACE:
   1429                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1430                             break;
   1431                     }
   1432                     dp[0] = (FX_BYTE)(tmp >> 24);
   1433                     dp[1] = (FX_BYTE)(tmp >> 16);
   1434                     dp[2] = (FX_BYTE)(tmp >> 8);
   1435                     dp[3] = (FX_BYTE)tmp;
   1436                 }
   1437                 lineSrc += m_nStride;
   1438                 lineDst += pDst->m_nStride;
   1439             }
   1440         } else if(s1 == d1) {
   1441             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
   1442             for(yy = yd0; yy < yd1; yy++) {
   1443                 sp = lineSrc;
   1444                 dp = lineDst;
   1445                 if(d1 != 0) {
   1446                     tmp1 = JBIG2_GETDWORD(sp);
   1447                     tmp2 = JBIG2_GETDWORD(dp);
   1448                     switch(op) {
   1449                         case JBIG2_COMPOSE_OR:
   1450                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
   1451                             break;
   1452                         case JBIG2_COMPOSE_AND:
   1453                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
   1454                             break;
   1455                         case JBIG2_COMPOSE_XOR:
   1456                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
   1457                             break;
   1458                         case JBIG2_COMPOSE_XNOR:
   1459                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
   1460                             break;
   1461                         case JBIG2_COMPOSE_REPLACE:
   1462                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
   1463                             break;
   1464                     }
   1465                     dp[0] = (FX_BYTE)(tmp >> 24);
   1466                     dp[1] = (FX_BYTE)(tmp >> 16);
   1467                     dp[2] = (FX_BYTE)(tmp >> 8);
   1468                     dp[3] = (FX_BYTE)tmp;
   1469                     sp += 4;
   1470                     dp += 4;
   1471                 }
   1472                 for(xx = 0; xx < middleDwords; xx++) {
   1473                     tmp1 = JBIG2_GETDWORD(sp);
   1474                     tmp2 = JBIG2_GETDWORD(dp);
   1475                     switch(op) {
   1476                         case JBIG2_COMPOSE_OR:
   1477                             tmp = tmp1 | tmp2;
   1478                             break;
   1479                         case JBIG2_COMPOSE_AND:
   1480                             tmp = tmp1 & tmp2;
   1481                             break;
   1482                         case JBIG2_COMPOSE_XOR:
   1483                             tmp = tmp1 ^ tmp2;
   1484                             break;
   1485                         case JBIG2_COMPOSE_XNOR:
   1486                             tmp = ~(tmp1 ^ tmp2);
   1487                             break;
   1488                         case JBIG2_COMPOSE_REPLACE:
   1489                             tmp = tmp1;
   1490                             break;
   1491                     }
   1492                     dp[0] = (FX_BYTE)(tmp >> 24);
   1493                     dp[1] = (FX_BYTE)(tmp >> 16);
   1494                     dp[2] = (FX_BYTE)(tmp >> 8);
   1495                     dp[3] = (FX_BYTE)tmp;
   1496                     sp += 4;
   1497                     dp += 4;
   1498                 }
   1499                 if(d2 != 0) {
   1500                     tmp1 = JBIG2_GETDWORD(sp);
   1501                     tmp2 = JBIG2_GETDWORD(dp);
   1502                     switch(op) {
   1503                         case JBIG2_COMPOSE_OR:
   1504                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
   1505                             break;
   1506                         case JBIG2_COMPOSE_AND:
   1507                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
   1508                             break;
   1509                         case JBIG2_COMPOSE_XOR:
   1510                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1511                             break;
   1512                         case JBIG2_COMPOSE_XNOR:
   1513                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1514                             break;
   1515                         case JBIG2_COMPOSE_REPLACE:
   1516                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1517                             break;
   1518                     }
   1519                     dp[0] = (FX_BYTE)(tmp >> 24);
   1520                     dp[1] = (FX_BYTE)(tmp >> 16);
   1521                     dp[2] = (FX_BYTE)(tmp >> 8);
   1522                     dp[3] = (FX_BYTE)tmp;
   1523                 }
   1524                 lineSrc += m_nStride;
   1525                 lineDst += pDst->m_nStride;
   1526             }
   1527         } else {
   1528             shift1 = d1 - s1;
   1529             shift2 = 32 - shift1;
   1530             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
   1531             for(yy = yd0; yy < yd1; yy++) {
   1532                 sp = lineSrc;
   1533                 dp = lineDst;
   1534                 if(d1 != 0) {
   1535                     tmp1 = JBIG2_GETDWORD(sp) >> shift1;
   1536                     tmp2 = JBIG2_GETDWORD(dp);
   1537                     switch(op) {
   1538                         case JBIG2_COMPOSE_OR:
   1539                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
   1540                             break;
   1541                         case JBIG2_COMPOSE_AND:
   1542                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
   1543                             break;
   1544                         case JBIG2_COMPOSE_XOR:
   1545                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
   1546                             break;
   1547                         case JBIG2_COMPOSE_XNOR:
   1548                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
   1549                             break;
   1550                         case JBIG2_COMPOSE_REPLACE:
   1551                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
   1552                             break;
   1553                     }
   1554                     dp[0] = (FX_BYTE)(tmp >> 24);
   1555                     dp[1] = (FX_BYTE)(tmp >> 16);
   1556                     dp[2] = (FX_BYTE)(tmp >> 8);
   1557                     dp[3] = (FX_BYTE)tmp;
   1558                     dp += 4;
   1559                 }
   1560                 for(xx = 0; xx < middleDwords; xx++) {
   1561                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ((JBIG2_GETDWORD(sp + 4)) >> shift1);
   1562                     tmp2 = JBIG2_GETDWORD(dp);
   1563                     switch(op) {
   1564                         case JBIG2_COMPOSE_OR:
   1565                             tmp = tmp1 | tmp2;
   1566                             break;
   1567                         case JBIG2_COMPOSE_AND:
   1568                             tmp = tmp1 & tmp2;
   1569                             break;
   1570                         case JBIG2_COMPOSE_XOR:
   1571                             tmp = tmp1 ^ tmp2;
   1572                             break;
   1573                         case JBIG2_COMPOSE_XNOR:
   1574                             tmp = ~(tmp1 ^ tmp2);
   1575                             break;
   1576                         case JBIG2_COMPOSE_REPLACE:
   1577                             tmp = tmp1;
   1578                             break;
   1579                     }
   1580                     dp[0] = (FX_BYTE)(tmp >> 24);
   1581                     dp[1] = (FX_BYTE)(tmp >> 16);
   1582                     dp[2] = (FX_BYTE)(tmp >> 8);
   1583                     dp[3] = (FX_BYTE)tmp;
   1584                     sp += 4;
   1585                     dp += 4;
   1586                 }
   1587                 if(d2 != 0) {
   1588                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | (
   1589                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift1);
   1590                     tmp2 = JBIG2_GETDWORD(dp);
   1591                     switch(op) {
   1592                         case JBIG2_COMPOSE_OR:
   1593                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
   1594                             break;
   1595                         case JBIG2_COMPOSE_AND:
   1596                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
   1597                             break;
   1598                         case JBIG2_COMPOSE_XOR:
   1599                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1600                             break;
   1601                         case JBIG2_COMPOSE_XNOR:
   1602                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1603                             break;
   1604                         case JBIG2_COMPOSE_REPLACE:
   1605                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1606                             break;
   1607                     }
   1608                     dp[0] = (FX_BYTE)(tmp >> 24);
   1609                     dp[1] = (FX_BYTE)(tmp >> 16);
   1610                     dp[2] = (FX_BYTE)(tmp >> 8);
   1611                     dp[3] = (FX_BYTE)tmp;
   1612                 }
   1613                 lineSrc += m_nStride;
   1614                 lineDst += pDst->m_nStride;
   1615             }
   1616         }
   1617     }
   1618     return 1;
   1619 }
   1620