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 <limits.h>
      8 
      9 #include "JBig2_Image.h"
     10 #include "core/include/fxcrt/fx_coordinates.h"
     11 #include "core/include/fxcrt/fx_safe_types.h"
     12 
     13 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h) {
     14   m_nWidth = w;
     15   m_nHeight = h;
     16   if (m_nWidth <= 0 || m_nHeight <= 0 || m_nWidth > INT_MAX - 31) {
     17     m_pData = NULL;
     18     m_bNeedFree = FALSE;
     19     return;
     20   }
     21   m_nStride = ((w + 31) >> 5) << 2;
     22   if (m_nStride * m_nHeight > 0 && 104857600 / (int)m_nStride > m_nHeight) {
     23     m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
     24   } else {
     25     m_pData = NULL;
     26   }
     27   m_bNeedFree = TRUE;
     28 }
     29 CJBig2_Image::CJBig2_Image(int32_t w,
     30                            int32_t h,
     31                            int32_t stride,
     32                            uint8_t* pBuf) {
     33   m_nWidth = w;
     34   m_nHeight = h;
     35   m_nStride = stride;
     36   m_pData = pBuf;
     37   m_bNeedFree = FALSE;
     38 }
     39 CJBig2_Image::CJBig2_Image(const CJBig2_Image& im) {
     40   m_nWidth = im.m_nWidth;
     41   m_nHeight = im.m_nHeight;
     42   m_nStride = im.m_nStride;
     43   if (im.m_pData) {
     44     m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight);
     45     JBIG2_memcpy(m_pData, im.m_pData, m_nStride * m_nHeight);
     46   } else {
     47     m_pData = NULL;
     48   }
     49   m_bNeedFree = TRUE;
     50 }
     51 CJBig2_Image::~CJBig2_Image() {
     52   if (m_bNeedFree) {
     53     FX_Free(m_pData);
     54   }
     55 }
     56 FX_BOOL CJBig2_Image::getPixel(int32_t x, int32_t y) {
     57   if (!m_pData) {
     58     return 0;
     59   }
     60   int32_t m, n;
     61   if (x < 0 || x >= m_nWidth) {
     62     return 0;
     63   }
     64   if (y < 0 || y >= m_nHeight) {
     65     return 0;
     66   }
     67   m = y * m_nStride + (x >> 3);
     68   n = x & 7;
     69   return ((m_pData[m] >> (7 - n)) & 1);
     70 }
     71 
     72 int32_t CJBig2_Image::setPixel(int32_t x, int32_t y, FX_BOOL v) {
     73   if (!m_pData) {
     74     return 0;
     75   }
     76   int32_t m, n;
     77   if (x < 0 || x >= m_nWidth) {
     78     return 0;
     79   }
     80   if (y < 0 || y >= m_nHeight) {
     81     return 0;
     82   }
     83   m = y * m_nStride + (x >> 3);
     84   n = x & 7;
     85   if (v) {
     86     m_pData[m] |= 1 << (7 - n);
     87   } else {
     88     m_pData[m] &= ~(1 << (7 - n));
     89   }
     90   return 1;
     91 }
     92 void CJBig2_Image::copyLine(int32_t hTo, int32_t hFrom) {
     93   if (!m_pData) {
     94     return;
     95   }
     96   if (hFrom < 0 || hFrom >= m_nHeight) {
     97     JBIG2_memset(m_pData + hTo * m_nStride, 0, m_nStride);
     98   } else {
     99     JBIG2_memcpy(m_pData + hTo * m_nStride, m_pData + hFrom * m_nStride,
    100                  m_nStride);
    101   }
    102 }
    103 void CJBig2_Image::fill(FX_BOOL v) {
    104   if (!m_pData) {
    105     return;
    106   }
    107   JBIG2_memset(m_pData, v ? 0xff : 0, m_nStride * m_nHeight);
    108 }
    109 FX_BOOL CJBig2_Image::composeTo(CJBig2_Image* pDst,
    110                                 int32_t x,
    111                                 int32_t y,
    112                                 JBig2ComposeOp op) {
    113   if (!m_pData) {
    114     return FALSE;
    115   }
    116   return composeTo_opt2(pDst, x, y, op);
    117 }
    118 FX_BOOL CJBig2_Image::composeTo(CJBig2_Image* pDst,
    119                                 int32_t x,
    120                                 int32_t y,
    121                                 JBig2ComposeOp op,
    122                                 const FX_RECT* pSrcRect) {
    123   if (!m_pData) {
    124     return FALSE;
    125   }
    126   if (NULL == pSrcRect || *pSrcRect == FX_RECT(0, 0, m_nWidth, m_nHeight)) {
    127     return composeTo_opt2(pDst, x, y, op);
    128   }
    129   return composeTo_opt2(pDst, x, y, op, pSrcRect);
    130 }
    131 
    132 FX_BOOL CJBig2_Image::composeFrom(int32_t x,
    133                                   int32_t y,
    134                                   CJBig2_Image* pSrc,
    135                                   JBig2ComposeOp op) {
    136   if (!m_pData) {
    137     return FALSE;
    138   }
    139   return pSrc->composeTo(this, x, y, op);
    140 }
    141 FX_BOOL CJBig2_Image::composeFrom(int32_t x,
    142                                   int32_t y,
    143                                   CJBig2_Image* pSrc,
    144                                   JBig2ComposeOp op,
    145                                   const FX_RECT* pSrcRect) {
    146   if (!m_pData) {
    147     return FALSE;
    148   }
    149   return pSrc->composeTo(this, x, y, op, pSrcRect);
    150 }
    151 #define JBIG2_GETDWORD(buf) \
    152   ((FX_DWORD)(((buf)[0] << 24) | ((buf)[1] << 16) | ((buf)[2] << 8) | (buf)[3]))
    153 CJBig2_Image* CJBig2_Image::subImage(int32_t x,
    154                                      int32_t y,
    155                                      int32_t w,
    156                                      int32_t h) {
    157   int32_t m, n, j;
    158   uint8_t *pLineSrc, *pLineDst;
    159   FX_DWORD wTmp;
    160   uint8_t *pSrc, *pSrcEnd, *pDst, *pDstEnd;
    161   if (w == 0 || h == 0) {
    162     return NULL;
    163   }
    164   CJBig2_Image* pImage = new CJBig2_Image(w, h);
    165   if (!m_pData) {
    166     pImage->fill(0);
    167     return pImage;
    168   }
    169   if (!pImage->m_pData) {
    170     return pImage;
    171   }
    172   pLineSrc = m_pData + m_nStride * y;
    173   pLineDst = pImage->m_pData;
    174   m = (x >> 5) << 2;
    175   n = x & 31;
    176   if (n == 0) {
    177     for (j = 0; j < h; j++) {
    178       pSrc = pLineSrc + m;
    179       pSrcEnd = pLineSrc + m_nStride;
    180       pDst = pLineDst;
    181       pDstEnd = pLineDst + pImage->m_nStride;
    182       for (; pDst < pDstEnd; pSrc += 4, pDst += 4) {
    183         *((FX_DWORD*)pDst) = *((FX_DWORD*)pSrc);
    184       }
    185       pLineSrc += m_nStride;
    186       pLineDst += pImage->m_nStride;
    187     }
    188   } else {
    189     for (j = 0; j < h; j++) {
    190       pSrc = pLineSrc + m;
    191       pSrcEnd = pLineSrc + m_nStride;
    192       pDst = pLineDst;
    193       pDstEnd = pLineDst + pImage->m_nStride;
    194       for (; pDst < pDstEnd; pSrc += 4, pDst += 4) {
    195         if (pSrc + 4 < pSrcEnd) {
    196           wTmp = (JBIG2_GETDWORD(pSrc) << n) |
    197                  (JBIG2_GETDWORD(pSrc + 4) >> (32 - n));
    198         } else {
    199           wTmp = JBIG2_GETDWORD(pSrc) << n;
    200         }
    201         pDst[0] = (uint8_t)(wTmp >> 24);
    202         pDst[1] = (uint8_t)(wTmp >> 16);
    203         pDst[2] = (uint8_t)(wTmp >> 8);
    204         pDst[3] = (uint8_t)wTmp;
    205       }
    206       pLineSrc += m_nStride;
    207       pLineDst += pImage->m_nStride;
    208     }
    209   }
    210   return pImage;
    211 }
    212 void CJBig2_Image::expand(int32_t h, FX_BOOL v) {
    213   if (!m_pData || h <= m_nHeight) {
    214     return;
    215   }
    216   FX_DWORD dwH = pdfium::base::checked_cast<FX_DWORD>(h);
    217   FX_DWORD dwStride = pdfium::base::checked_cast<FX_DWORD>(m_nStride);
    218   FX_DWORD dwHeight = pdfium::base::checked_cast<FX_DWORD>(m_nHeight);
    219   FX_SAFE_DWORD safeMemSize = dwH;
    220   safeMemSize *= dwStride;
    221   if (!safeMemSize.IsValid()) {
    222     return;
    223   }
    224   // The guaranteed reallocated memory is to be < 4GB (unsigned int).
    225   m_pData = FX_Realloc(uint8_t, m_pData, safeMemSize.ValueOrDie());
    226 
    227   // The result of dwHeight * dwStride doesn't overflow after the
    228   // checking of safeMemSize.
    229   // The same as the result of (dwH - dwHeight) * dwStride) because
    230   // dwH - dwHeight is always less than dwH(h) which is checked in
    231   // the calculation of dwH * dwStride.
    232   JBIG2_memset(m_pData + dwHeight * dwStride, v ? 0xff : 0,
    233                (dwH - dwHeight) * dwStride);
    234   m_nHeight = h;
    235 }
    236 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst,
    237                                      int32_t x,
    238                                      int32_t y,
    239                                      JBig2ComposeOp op) {
    240   int32_t xs0 = 0, ys0 = 0, xs1 = 0, ys1 = 0, xd0 = 0, yd0 = 0, xd1 = 0,
    241           yd1 = 0, xx = 0, yy = 0, w = 0, h = 0, middleDwords = 0, lineLeft = 0;
    242 
    243   FX_DWORD s1 = 0, d1 = 0, d2 = 0, shift = 0, shift1 = 0, shift2 = 0, tmp = 0,
    244            tmp1 = 0, tmp2 = 0, maskL = 0, maskR = 0, maskM = 0;
    245 
    246   uint8_t *lineSrc = NULL, *lineDst = NULL, *sp = NULL, *dp = NULL;
    247 
    248   if (!m_pData) {
    249     return FALSE;
    250   }
    251   if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) {
    252     return FALSE;
    253   }
    254   if (y < 0) {
    255     ys0 = -y;
    256   }
    257   if (y + m_nHeight > pDst->m_nHeight) {
    258     ys1 = pDst->m_nHeight - y;
    259   } else {
    260     ys1 = m_nHeight;
    261   }
    262   if (x < 0) {
    263     xs0 = -x;
    264   }
    265   if (x + m_nWidth > pDst->m_nWidth) {
    266     xs1 = pDst->m_nWidth - x;
    267   } else {
    268     xs1 = m_nWidth;
    269   }
    270   if ((ys0 >= ys1) || (xs0 >= xs1)) {
    271     return 0;
    272   }
    273   w = xs1 - xs0;
    274   h = ys1 - ys0;
    275   if (y >= 0) {
    276     yd0 = y;
    277   }
    278   if (x >= 0) {
    279     xd0 = x;
    280   }
    281   xd1 = xd0 + w;
    282   yd1 = yd0 + h;
    283   d1 = xd0 & 31;
    284   d2 = xd1 & 31;
    285   s1 = xs0 & 31;
    286   maskL = 0xffffffff >> d1;
    287   maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
    288   maskM = maskL & maskR;
    289   lineSrc = m_pData + ys0 * m_nStride + ((xs0 >> 5) << 2);
    290   lineLeft = m_nStride - ((xs0 >> 5) << 2);
    291   lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
    292   if ((xd0 & ~31) == ((xd1 - 1) & ~31)) {
    293     if ((xs0 & ~31) == ((xs1 - 1) & ~31)) {
    294       if (s1 > d1) {
    295         shift = s1 - d1;
    296         for (yy = yd0; yy < yd1; yy++) {
    297           tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
    298           tmp2 = JBIG2_GETDWORD(lineDst);
    299           switch (op) {
    300             case JBIG2_COMPOSE_OR:
    301               tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    302               break;
    303             case JBIG2_COMPOSE_AND:
    304               tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    305               break;
    306             case JBIG2_COMPOSE_XOR:
    307               tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    308               break;
    309             case JBIG2_COMPOSE_XNOR:
    310               tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    311               break;
    312             case JBIG2_COMPOSE_REPLACE:
    313               tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    314               break;
    315           }
    316           lineDst[0] = (uint8_t)(tmp >> 24);
    317           lineDst[1] = (uint8_t)(tmp >> 16);
    318           lineDst[2] = (uint8_t)(tmp >> 8);
    319           lineDst[3] = (uint8_t)tmp;
    320           lineSrc += m_nStride;
    321           lineDst += pDst->m_nStride;
    322         }
    323       } else {
    324         shift = d1 - s1;
    325         for (yy = yd0; yy < yd1; yy++) {
    326           tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
    327           tmp2 = JBIG2_GETDWORD(lineDst);
    328           switch (op) {
    329             case JBIG2_COMPOSE_OR:
    330               tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    331               break;
    332             case JBIG2_COMPOSE_AND:
    333               tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    334               break;
    335             case JBIG2_COMPOSE_XOR:
    336               tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    337               break;
    338             case JBIG2_COMPOSE_XNOR:
    339               tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    340               break;
    341             case JBIG2_COMPOSE_REPLACE:
    342               tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    343               break;
    344           }
    345           lineDst[0] = (uint8_t)(tmp >> 24);
    346           lineDst[1] = (uint8_t)(tmp >> 16);
    347           lineDst[2] = (uint8_t)(tmp >> 8);
    348           lineDst[3] = (uint8_t)tmp;
    349           lineSrc += m_nStride;
    350           lineDst += pDst->m_nStride;
    351         }
    352       }
    353     } else {
    354       shift1 = s1 - d1;
    355       shift2 = 32 - shift1;
    356       for (yy = yd0; yy < yd1; yy++) {
    357         tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) |
    358                (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
    359         tmp2 = JBIG2_GETDWORD(lineDst);
    360         switch (op) {
    361           case JBIG2_COMPOSE_OR:
    362             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    363             break;
    364           case JBIG2_COMPOSE_AND:
    365             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    366             break;
    367           case JBIG2_COMPOSE_XOR:
    368             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    369             break;
    370           case JBIG2_COMPOSE_XNOR:
    371             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    372             break;
    373           case JBIG2_COMPOSE_REPLACE:
    374             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    375             break;
    376         }
    377         lineDst[0] = (uint8_t)(tmp >> 24);
    378         lineDst[1] = (uint8_t)(tmp >> 16);
    379         lineDst[2] = (uint8_t)(tmp >> 8);
    380         lineDst[3] = (uint8_t)tmp;
    381         lineSrc += m_nStride;
    382         lineDst += pDst->m_nStride;
    383       }
    384     }
    385   } else {
    386     if (s1 > d1) {
    387       shift1 = s1 - d1;
    388       shift2 = 32 - shift1;
    389       middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
    390       for (yy = yd0; yy < yd1; yy++) {
    391         sp = lineSrc;
    392         dp = lineDst;
    393         if (d1 != 0) {
    394           tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
    395                  (JBIG2_GETDWORD(sp + 4) >> shift2);
    396           tmp2 = JBIG2_GETDWORD(dp);
    397           switch (op) {
    398             case JBIG2_COMPOSE_OR:
    399               tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
    400               break;
    401             case JBIG2_COMPOSE_AND:
    402               tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
    403               break;
    404             case JBIG2_COMPOSE_XOR:
    405               tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
    406               break;
    407             case JBIG2_COMPOSE_XNOR:
    408               tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
    409               break;
    410             case JBIG2_COMPOSE_REPLACE:
    411               tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
    412               break;
    413           }
    414           dp[0] = (uint8_t)(tmp >> 24);
    415           dp[1] = (uint8_t)(tmp >> 16);
    416           dp[2] = (uint8_t)(tmp >> 8);
    417           dp[3] = (uint8_t)tmp;
    418           sp += 4;
    419           dp += 4;
    420         }
    421         for (xx = 0; xx < middleDwords; xx++) {
    422           tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
    423                  (JBIG2_GETDWORD(sp + 4) >> shift2);
    424           tmp2 = JBIG2_GETDWORD(dp);
    425           switch (op) {
    426             case JBIG2_COMPOSE_OR:
    427               tmp = tmp1 | tmp2;
    428               break;
    429             case JBIG2_COMPOSE_AND:
    430               tmp = tmp1 & tmp2;
    431               break;
    432             case JBIG2_COMPOSE_XOR:
    433               tmp = tmp1 ^ tmp2;
    434               break;
    435             case JBIG2_COMPOSE_XNOR:
    436               tmp = ~(tmp1 ^ tmp2);
    437               break;
    438             case JBIG2_COMPOSE_REPLACE:
    439               tmp = tmp1;
    440               break;
    441           }
    442           dp[0] = (uint8_t)(tmp >> 24);
    443           dp[1] = (uint8_t)(tmp >> 16);
    444           dp[2] = (uint8_t)(tmp >> 8);
    445           dp[3] = (uint8_t)tmp;
    446           sp += 4;
    447           dp += 4;
    448         }
    449         if (d2 != 0) {
    450           tmp1 =
    451               (JBIG2_GETDWORD(sp) << shift1) |
    452               (((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >>
    453                shift2);
    454           tmp2 = JBIG2_GETDWORD(dp);
    455           switch (op) {
    456             case JBIG2_COMPOSE_OR:
    457               tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
    458               break;
    459             case JBIG2_COMPOSE_AND:
    460               tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
    461               break;
    462             case JBIG2_COMPOSE_XOR:
    463               tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
    464               break;
    465             case JBIG2_COMPOSE_XNOR:
    466               tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
    467               break;
    468             case JBIG2_COMPOSE_REPLACE:
    469               tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
    470               break;
    471           }
    472           dp[0] = (uint8_t)(tmp >> 24);
    473           dp[1] = (uint8_t)(tmp >> 16);
    474           dp[2] = (uint8_t)(tmp >> 8);
    475           dp[3] = (uint8_t)tmp;
    476         }
    477         lineSrc += m_nStride;
    478         lineDst += pDst->m_nStride;
    479       }
    480     } else if (s1 == d1) {
    481       middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
    482       for (yy = yd0; yy < yd1; yy++) {
    483         sp = lineSrc;
    484         dp = lineDst;
    485         if (d1 != 0) {
    486           tmp1 = JBIG2_GETDWORD(sp);
    487           tmp2 = JBIG2_GETDWORD(dp);
    488           switch (op) {
    489             case JBIG2_COMPOSE_OR:
    490               tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
    491               break;
    492             case JBIG2_COMPOSE_AND:
    493               tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
    494               break;
    495             case JBIG2_COMPOSE_XOR:
    496               tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
    497               break;
    498             case JBIG2_COMPOSE_XNOR:
    499               tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
    500               break;
    501             case JBIG2_COMPOSE_REPLACE:
    502               tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
    503               break;
    504           }
    505           dp[0] = (uint8_t)(tmp >> 24);
    506           dp[1] = (uint8_t)(tmp >> 16);
    507           dp[2] = (uint8_t)(tmp >> 8);
    508           dp[3] = (uint8_t)tmp;
    509           sp += 4;
    510           dp += 4;
    511         }
    512         for (xx = 0; xx < middleDwords; xx++) {
    513           tmp1 = JBIG2_GETDWORD(sp);
    514           tmp2 = JBIG2_GETDWORD(dp);
    515           switch (op) {
    516             case JBIG2_COMPOSE_OR:
    517               tmp = tmp1 | tmp2;
    518               break;
    519             case JBIG2_COMPOSE_AND:
    520               tmp = tmp1 & tmp2;
    521               break;
    522             case JBIG2_COMPOSE_XOR:
    523               tmp = tmp1 ^ tmp2;
    524               break;
    525             case JBIG2_COMPOSE_XNOR:
    526               tmp = ~(tmp1 ^ tmp2);
    527               break;
    528             case JBIG2_COMPOSE_REPLACE:
    529               tmp = tmp1;
    530               break;
    531           }
    532           dp[0] = (uint8_t)(tmp >> 24);
    533           dp[1] = (uint8_t)(tmp >> 16);
    534           dp[2] = (uint8_t)(tmp >> 8);
    535           dp[3] = (uint8_t)tmp;
    536           sp += 4;
    537           dp += 4;
    538         }
    539         if (d2 != 0) {
    540           tmp1 = JBIG2_GETDWORD(sp);
    541           tmp2 = JBIG2_GETDWORD(dp);
    542           switch (op) {
    543             case JBIG2_COMPOSE_OR:
    544               tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
    545               break;
    546             case JBIG2_COMPOSE_AND:
    547               tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
    548               break;
    549             case JBIG2_COMPOSE_XOR:
    550               tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
    551               break;
    552             case JBIG2_COMPOSE_XNOR:
    553               tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
    554               break;
    555             case JBIG2_COMPOSE_REPLACE:
    556               tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
    557               break;
    558           }
    559           dp[0] = (uint8_t)(tmp >> 24);
    560           dp[1] = (uint8_t)(tmp >> 16);
    561           dp[2] = (uint8_t)(tmp >> 8);
    562           dp[3] = (uint8_t)tmp;
    563         }
    564         lineSrc += m_nStride;
    565         lineDst += pDst->m_nStride;
    566       }
    567     } else {
    568       shift1 = d1 - s1;
    569       shift2 = 32 - shift1;
    570       middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
    571       for (yy = yd0; yy < yd1; yy++) {
    572         sp = lineSrc;
    573         dp = lineDst;
    574         if (d1 != 0) {
    575           tmp1 = JBIG2_GETDWORD(sp) >> shift1;
    576           tmp2 = JBIG2_GETDWORD(dp);
    577           switch (op) {
    578             case JBIG2_COMPOSE_OR:
    579               tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
    580               break;
    581             case JBIG2_COMPOSE_AND:
    582               tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
    583               break;
    584             case JBIG2_COMPOSE_XOR:
    585               tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
    586               break;
    587             case JBIG2_COMPOSE_XNOR:
    588               tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
    589               break;
    590             case JBIG2_COMPOSE_REPLACE:
    591               tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
    592               break;
    593           }
    594           dp[0] = (uint8_t)(tmp >> 24);
    595           dp[1] = (uint8_t)(tmp >> 16);
    596           dp[2] = (uint8_t)(tmp >> 8);
    597           dp[3] = (uint8_t)tmp;
    598           dp += 4;
    599         }
    600         for (xx = 0; xx < middleDwords; xx++) {
    601           tmp1 = (JBIG2_GETDWORD(sp) << shift2) |
    602                  ((JBIG2_GETDWORD(sp + 4)) >> shift1);
    603           tmp2 = JBIG2_GETDWORD(dp);
    604           switch (op) {
    605             case JBIG2_COMPOSE_OR:
    606               tmp = tmp1 | tmp2;
    607               break;
    608             case JBIG2_COMPOSE_AND:
    609               tmp = tmp1 & tmp2;
    610               break;
    611             case JBIG2_COMPOSE_XOR:
    612               tmp = tmp1 ^ tmp2;
    613               break;
    614             case JBIG2_COMPOSE_XNOR:
    615               tmp = ~(tmp1 ^ tmp2);
    616               break;
    617             case JBIG2_COMPOSE_REPLACE:
    618               tmp = tmp1;
    619               break;
    620           }
    621           dp[0] = (uint8_t)(tmp >> 24);
    622           dp[1] = (uint8_t)(tmp >> 16);
    623           dp[2] = (uint8_t)(tmp >> 8);
    624           dp[3] = (uint8_t)tmp;
    625           sp += 4;
    626           dp += 4;
    627         }
    628         if (d2 != 0) {
    629           tmp1 =
    630               (JBIG2_GETDWORD(sp) << shift2) |
    631               (((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >>
    632                shift1);
    633           tmp2 = JBIG2_GETDWORD(dp);
    634           switch (op) {
    635             case JBIG2_COMPOSE_OR:
    636               tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
    637               break;
    638             case JBIG2_COMPOSE_AND:
    639               tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
    640               break;
    641             case JBIG2_COMPOSE_XOR:
    642               tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
    643               break;
    644             case JBIG2_COMPOSE_XNOR:
    645               tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
    646               break;
    647             case JBIG2_COMPOSE_REPLACE:
    648               tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
    649               break;
    650           }
    651           dp[0] = (uint8_t)(tmp >> 24);
    652           dp[1] = (uint8_t)(tmp >> 16);
    653           dp[2] = (uint8_t)(tmp >> 8);
    654           dp[3] = (uint8_t)tmp;
    655         }
    656         lineSrc += m_nStride;
    657         lineDst += pDst->m_nStride;
    658       }
    659     }
    660   }
    661   return 1;
    662 }
    663 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst,
    664                                      int32_t x,
    665                                      int32_t y,
    666                                      JBig2ComposeOp op,
    667                                      const FX_RECT* pSrcRect) {
    668   int32_t xs0, ys0, xs1, ys1, xd0, yd0, xd1, yd1, xx, yy, w, h, middleDwords,
    669       lineLeft;
    670   FX_DWORD s1, d1, d2, shift, shift1, shift2, tmp, tmp1, tmp2, maskL, maskR,
    671       maskM;
    672   uint8_t *lineSrc, *lineDst, *sp, *dp;
    673   int32_t sw, sh;
    674   if (!m_pData) {
    675     return FALSE;
    676   }
    677   if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) {
    678     return FALSE;
    679   }
    680   sw = pSrcRect->Width();
    681   sh = pSrcRect->Height();
    682   if (y < 0) {
    683     ys0 = -y;
    684   } else {
    685     ys0 = 0;
    686   }
    687   if (y + sh > pDst->m_nHeight) {
    688     ys1 = pDst->m_nHeight - y;
    689   } else {
    690     ys1 = sh;
    691   }
    692   if (x < 0) {
    693     xs0 = -x;
    694   } else {
    695     xs0 = 0;
    696   }
    697   if (x + sw > pDst->m_nWidth) {
    698     xs1 = pDst->m_nWidth - x;
    699   } else {
    700     xs1 = sw;
    701   }
    702   if ((ys0 >= ys1) || (xs0 >= xs1)) {
    703     return 0;
    704   }
    705   w = xs1 - xs0;
    706   h = ys1 - ys0;
    707   if (y < 0) {
    708     yd0 = 0;
    709   } else {
    710     yd0 = y;
    711   }
    712   if (x < 0) {
    713     xd0 = 0;
    714   } else {
    715     xd0 = x;
    716   }
    717   xd1 = xd0 + w;
    718   yd1 = yd0 + h;
    719   d1 = xd0 & 31;
    720   d2 = xd1 & 31;
    721   s1 = xs0 & 31;
    722   maskL = 0xffffffff >> d1;
    723   maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
    724   maskM = maskL & maskR;
    725   lineSrc = m_pData + (pSrcRect->top + ys0) * m_nStride +
    726             (((xs0 + pSrcRect->left) >> 5) << 2);
    727   lineLeft = m_nStride - ((xs0 >> 5) << 2);
    728   lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
    729   if ((xd0 & ~31) == ((xd1 - 1) & ~31)) {
    730     if ((xs0 & ~31) == ((xs1 - 1) & ~31)) {
    731       if (s1 > d1) {
    732         shift = s1 - d1;
    733         for (yy = yd0; yy < yd1; yy++) {
    734           tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
    735           tmp2 = JBIG2_GETDWORD(lineDst);
    736           switch (op) {
    737             case JBIG2_COMPOSE_OR:
    738               tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    739               break;
    740             case JBIG2_COMPOSE_AND:
    741               tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    742               break;
    743             case JBIG2_COMPOSE_XOR:
    744               tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    745               break;
    746             case JBIG2_COMPOSE_XNOR:
    747               tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    748               break;
    749             case JBIG2_COMPOSE_REPLACE:
    750               tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    751               break;
    752           }
    753           lineDst[0] = (uint8_t)(tmp >> 24);
    754           lineDst[1] = (uint8_t)(tmp >> 16);
    755           lineDst[2] = (uint8_t)(tmp >> 8);
    756           lineDst[3] = (uint8_t)tmp;
    757           lineSrc += m_nStride;
    758           lineDst += pDst->m_nStride;
    759         }
    760       } else {
    761         shift = d1 - s1;
    762         for (yy = yd0; yy < yd1; yy++) {
    763           tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
    764           tmp2 = JBIG2_GETDWORD(lineDst);
    765           switch (op) {
    766             case JBIG2_COMPOSE_OR:
    767               tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    768               break;
    769             case JBIG2_COMPOSE_AND:
    770               tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    771               break;
    772             case JBIG2_COMPOSE_XOR:
    773               tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    774               break;
    775             case JBIG2_COMPOSE_XNOR:
    776               tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    777               break;
    778             case JBIG2_COMPOSE_REPLACE:
    779               tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    780               break;
    781           }
    782           lineDst[0] = (uint8_t)(tmp >> 24);
    783           lineDst[1] = (uint8_t)(tmp >> 16);
    784           lineDst[2] = (uint8_t)(tmp >> 8);
    785           lineDst[3] = (uint8_t)tmp;
    786           lineSrc += m_nStride;
    787           lineDst += pDst->m_nStride;
    788         }
    789       }
    790     } else {
    791       shift1 = s1 - d1;
    792       shift2 = 32 - shift1;
    793       for (yy = yd0; yy < yd1; yy++) {
    794         tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) |
    795                (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
    796         tmp2 = JBIG2_GETDWORD(lineDst);
    797         switch (op) {
    798           case JBIG2_COMPOSE_OR:
    799             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
    800             break;
    801           case JBIG2_COMPOSE_AND:
    802             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
    803             break;
    804           case JBIG2_COMPOSE_XOR:
    805             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
    806             break;
    807           case JBIG2_COMPOSE_XNOR:
    808             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
    809             break;
    810           case JBIG2_COMPOSE_REPLACE:
    811             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
    812             break;
    813         }
    814         lineDst[0] = (uint8_t)(tmp >> 24);
    815         lineDst[1] = (uint8_t)(tmp >> 16);
    816         lineDst[2] = (uint8_t)(tmp >> 8);
    817         lineDst[3] = (uint8_t)tmp;
    818         lineSrc += m_nStride;
    819         lineDst += pDst->m_nStride;
    820       }
    821     }
    822   } else {
    823     if (s1 > d1) {
    824       shift1 = s1 - d1;
    825       shift2 = 32 - shift1;
    826       middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
    827       for (yy = yd0; yy < yd1; yy++) {
    828         sp = lineSrc;
    829         dp = lineDst;
    830         if (d1 != 0) {
    831           tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
    832                  (JBIG2_GETDWORD(sp + 4) >> shift2);
    833           tmp2 = JBIG2_GETDWORD(dp);
    834           switch (op) {
    835             case JBIG2_COMPOSE_OR:
    836               tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
    837               break;
    838             case JBIG2_COMPOSE_AND:
    839               tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
    840               break;
    841             case JBIG2_COMPOSE_XOR:
    842               tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
    843               break;
    844             case JBIG2_COMPOSE_XNOR:
    845               tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
    846               break;
    847             case JBIG2_COMPOSE_REPLACE:
    848               tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
    849               break;
    850           }
    851           dp[0] = (uint8_t)(tmp >> 24);
    852           dp[1] = (uint8_t)(tmp >> 16);
    853           dp[2] = (uint8_t)(tmp >> 8);
    854           dp[3] = (uint8_t)tmp;
    855           sp += 4;
    856           dp += 4;
    857         }
    858         for (xx = 0; xx < middleDwords; xx++) {
    859           tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
    860                  (JBIG2_GETDWORD(sp + 4) >> shift2);
    861           tmp2 = JBIG2_GETDWORD(dp);
    862           switch (op) {
    863             case JBIG2_COMPOSE_OR:
    864               tmp = tmp1 | tmp2;
    865               break;
    866             case JBIG2_COMPOSE_AND:
    867               tmp = tmp1 & tmp2;
    868               break;
    869             case JBIG2_COMPOSE_XOR:
    870               tmp = tmp1 ^ tmp2;
    871               break;
    872             case JBIG2_COMPOSE_XNOR:
    873               tmp = ~(tmp1 ^ tmp2);
    874               break;
    875             case JBIG2_COMPOSE_REPLACE:
    876               tmp = tmp1;
    877               break;
    878           }
    879           dp[0] = (uint8_t)(tmp >> 24);
    880           dp[1] = (uint8_t)(tmp >> 16);
    881           dp[2] = (uint8_t)(tmp >> 8);
    882           dp[3] = (uint8_t)tmp;
    883           sp += 4;
    884           dp += 4;
    885         }
    886         if (d2 != 0) {
    887           tmp1 =
    888               (JBIG2_GETDWORD(sp) << shift1) |
    889               (((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >>
    890                shift2);
    891           tmp2 = JBIG2_GETDWORD(dp);
    892           switch (op) {
    893             case JBIG2_COMPOSE_OR:
    894               tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
    895               break;
    896             case JBIG2_COMPOSE_AND:
    897               tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
    898               break;
    899             case JBIG2_COMPOSE_XOR:
    900               tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
    901               break;
    902             case JBIG2_COMPOSE_XNOR:
    903               tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
    904               break;
    905             case JBIG2_COMPOSE_REPLACE:
    906               tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
    907               break;
    908           }
    909           dp[0] = (uint8_t)(tmp >> 24);
    910           dp[1] = (uint8_t)(tmp >> 16);
    911           dp[2] = (uint8_t)(tmp >> 8);
    912           dp[3] = (uint8_t)tmp;
    913         }
    914         lineSrc += m_nStride;
    915         lineDst += pDst->m_nStride;
    916       }
    917     } else if (s1 == d1) {
    918       middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
    919       for (yy = yd0; yy < yd1; yy++) {
    920         sp = lineSrc;
    921         dp = lineDst;
    922         if (d1 != 0) {
    923           tmp1 = JBIG2_GETDWORD(sp);
    924           tmp2 = JBIG2_GETDWORD(dp);
    925           switch (op) {
    926             case JBIG2_COMPOSE_OR:
    927               tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
    928               break;
    929             case JBIG2_COMPOSE_AND:
    930               tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
    931               break;
    932             case JBIG2_COMPOSE_XOR:
    933               tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
    934               break;
    935             case JBIG2_COMPOSE_XNOR:
    936               tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
    937               break;
    938             case JBIG2_COMPOSE_REPLACE:
    939               tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
    940               break;
    941           }
    942           dp[0] = (uint8_t)(tmp >> 24);
    943           dp[1] = (uint8_t)(tmp >> 16);
    944           dp[2] = (uint8_t)(tmp >> 8);
    945           dp[3] = (uint8_t)tmp;
    946           sp += 4;
    947           dp += 4;
    948         }
    949         for (xx = 0; xx < middleDwords; xx++) {
    950           tmp1 = JBIG2_GETDWORD(sp);
    951           tmp2 = JBIG2_GETDWORD(dp);
    952           switch (op) {
    953             case JBIG2_COMPOSE_OR:
    954               tmp = tmp1 | tmp2;
    955               break;
    956             case JBIG2_COMPOSE_AND:
    957               tmp = tmp1 & tmp2;
    958               break;
    959             case JBIG2_COMPOSE_XOR:
    960               tmp = tmp1 ^ tmp2;
    961               break;
    962             case JBIG2_COMPOSE_XNOR:
    963               tmp = ~(tmp1 ^ tmp2);
    964               break;
    965             case JBIG2_COMPOSE_REPLACE:
    966               tmp = tmp1;
    967               break;
    968           }
    969           dp[0] = (uint8_t)(tmp >> 24);
    970           dp[1] = (uint8_t)(tmp >> 16);
    971           dp[2] = (uint8_t)(tmp >> 8);
    972           dp[3] = (uint8_t)tmp;
    973           sp += 4;
    974           dp += 4;
    975         }
    976         if (d2 != 0) {
    977           tmp1 = JBIG2_GETDWORD(sp);
    978           tmp2 = JBIG2_GETDWORD(dp);
    979           switch (op) {
    980             case JBIG2_COMPOSE_OR:
    981               tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
    982               break;
    983             case JBIG2_COMPOSE_AND:
    984               tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
    985               break;
    986             case JBIG2_COMPOSE_XOR:
    987               tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
    988               break;
    989             case JBIG2_COMPOSE_XNOR:
    990               tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
    991               break;
    992             case JBIG2_COMPOSE_REPLACE:
    993               tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
    994               break;
    995           }
    996           dp[0] = (uint8_t)(tmp >> 24);
    997           dp[1] = (uint8_t)(tmp >> 16);
    998           dp[2] = (uint8_t)(tmp >> 8);
    999           dp[3] = (uint8_t)tmp;
   1000         }
   1001         lineSrc += m_nStride;
   1002         lineDst += pDst->m_nStride;
   1003       }
   1004     } else {
   1005       shift1 = d1 - s1;
   1006       shift2 = 32 - shift1;
   1007       middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
   1008       for (yy = yd0; yy < yd1; yy++) {
   1009         sp = lineSrc;
   1010         dp = lineDst;
   1011         if (d1 != 0) {
   1012           tmp1 = JBIG2_GETDWORD(sp) >> shift1;
   1013           tmp2 = JBIG2_GETDWORD(dp);
   1014           switch (op) {
   1015             case JBIG2_COMPOSE_OR:
   1016               tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
   1017               break;
   1018             case JBIG2_COMPOSE_AND:
   1019               tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
   1020               break;
   1021             case JBIG2_COMPOSE_XOR:
   1022               tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
   1023               break;
   1024             case JBIG2_COMPOSE_XNOR:
   1025               tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
   1026               break;
   1027             case JBIG2_COMPOSE_REPLACE:
   1028               tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
   1029               break;
   1030           }
   1031           dp[0] = (uint8_t)(tmp >> 24);
   1032           dp[1] = (uint8_t)(tmp >> 16);
   1033           dp[2] = (uint8_t)(tmp >> 8);
   1034           dp[3] = (uint8_t)tmp;
   1035           dp += 4;
   1036         }
   1037         for (xx = 0; xx < middleDwords; xx++) {
   1038           tmp1 = (JBIG2_GETDWORD(sp) << shift2) |
   1039                  ((JBIG2_GETDWORD(sp + 4)) >> shift1);
   1040           tmp2 = JBIG2_GETDWORD(dp);
   1041           switch (op) {
   1042             case JBIG2_COMPOSE_OR:
   1043               tmp = tmp1 | tmp2;
   1044               break;
   1045             case JBIG2_COMPOSE_AND:
   1046               tmp = tmp1 & tmp2;
   1047               break;
   1048             case JBIG2_COMPOSE_XOR:
   1049               tmp = tmp1 ^ tmp2;
   1050               break;
   1051             case JBIG2_COMPOSE_XNOR:
   1052               tmp = ~(tmp1 ^ tmp2);
   1053               break;
   1054             case JBIG2_COMPOSE_REPLACE:
   1055               tmp = tmp1;
   1056               break;
   1057           }
   1058           dp[0] = (uint8_t)(tmp >> 24);
   1059           dp[1] = (uint8_t)(tmp >> 16);
   1060           dp[2] = (uint8_t)(tmp >> 8);
   1061           dp[3] = (uint8_t)tmp;
   1062           sp += 4;
   1063           dp += 4;
   1064         }
   1065         if (d2 != 0) {
   1066           tmp1 =
   1067               (JBIG2_GETDWORD(sp) << shift2) |
   1068               (((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >>
   1069                shift1);
   1070           tmp2 = JBIG2_GETDWORD(dp);
   1071           switch (op) {
   1072             case JBIG2_COMPOSE_OR:
   1073               tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
   1074               break;
   1075             case JBIG2_COMPOSE_AND:
   1076               tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
   1077               break;
   1078             case JBIG2_COMPOSE_XOR:
   1079               tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
   1080               break;
   1081             case JBIG2_COMPOSE_XNOR:
   1082               tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
   1083               break;
   1084             case JBIG2_COMPOSE_REPLACE:
   1085               tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
   1086               break;
   1087           }
   1088           dp[0] = (uint8_t)(tmp >> 24);
   1089           dp[1] = (uint8_t)(tmp >> 16);
   1090           dp[2] = (uint8_t)(tmp >> 8);
   1091           dp[3] = (uint8_t)tmp;
   1092         }
   1093         lineSrc += m_nStride;
   1094         lineDst += pDst->m_nStride;
   1095       }
   1096     }
   1097   }
   1098   return 1;
   1099 }
   1100