Fix -Wnon-virtual-dtor compiler warnings.
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_Image.cpp
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 = 0, ys0  = 0, xs1  = 0, ys1   = 0, xd0    = 0, yd0          = 0, xd1      = 0, 
780              yd1 = 0, xx   = 0, yy   = 0, w     = 0, h      = 0, middleDwords = 0, lineLeft = 0;
781
782     FX_DWORD s1  = 0, d1   = 0, d2   = 0, shift = 0, shift1 = 0, shift2       = 0, 
783              tmp = 0, tmp1 = 0, tmp2 = 0, maskL = 0, maskR  = 0, maskM        = 0;
784
785     FX_BYTE *lineSrc = NULL, *lineDst = NULL, *sp = NULL, *dp = NULL;
786
787     if (!m_pData) {
788         return FALSE;
789     }
790     if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) {
791         return FALSE;
792     }
793     if(y < 0) {
794         ys0 = -y;
795     }
796     if(y + m_nHeight > pDst->m_nHeight) {
797         ys1 = pDst->m_nHeight - y;
798     } else {
799         ys1 = m_nHeight;
800     }
801     if(x < 0) {
802         xs0 = -x;
803     }
804     if(x + m_nWidth > pDst->m_nWidth) {
805         xs1 = pDst->m_nWidth - x;
806     } else {
807         xs1 = m_nWidth;
808     }
809     if((ys0 >= ys1) || (xs0 >= xs1)) {
810         return 0;
811     }
812     w = xs1 - xs0;
813     h = ys1 - ys0;
814     if(y >= 0) {
815         yd0 = y;
816     } 
817     if(x >= 0) {
818         xd0 = x;
819     }
820     xd1 = xd0 + w;
821     yd1 = yd0 + h;
822     d1 = xd0 & 31;
823     d2 = xd1 & 31;
824     s1 = xs0 & 31;
825     maskL = 0xffffffff >> d1;
826     maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
827     maskM = maskL & maskR;
828     lineSrc = m_pData + ys0 * m_nStride + ((xs0 >> 5) << 2);
829     lineLeft = m_nStride - ((xs0 >> 5) << 2);
830     lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
831     if((xd0 & ~31) == ((xd1 - 1) & ~31)) {
832         if((xs0 & ~31) == ((xs1 - 1) & ~31)) {
833             if(s1 > d1) {
834                 shift = s1 - d1;
835                 for(yy = yd0; yy < yd1; yy++) {
836                     tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
837                     tmp2 = JBIG2_GETDWORD(lineDst);
838                     switch(op) {
839                         case JBIG2_COMPOSE_OR:
840                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
841                             break;
842                         case JBIG2_COMPOSE_AND:
843                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
844                             break;
845                         case JBIG2_COMPOSE_XOR:
846                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
847                             break;
848                         case JBIG2_COMPOSE_XNOR:
849                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
850                             break;
851                         case JBIG2_COMPOSE_REPLACE:
852                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
853                             break;
854                     }
855                     lineDst[0] = (FX_BYTE)(tmp >> 24);
856                     lineDst[1] = (FX_BYTE)(tmp >> 16);
857                     lineDst[2] = (FX_BYTE)(tmp >> 8);
858                     lineDst[3] = (FX_BYTE)tmp;
859                     lineSrc += m_nStride;
860                     lineDst += pDst->m_nStride;
861                 }
862             } else {
863                 shift = d1 - s1;
864                 for(yy = yd0; yy < yd1; yy++) {
865                     tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
866                     tmp2 = JBIG2_GETDWORD(lineDst);
867                     switch(op) {
868                         case JBIG2_COMPOSE_OR:
869                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
870                             break;
871                         case JBIG2_COMPOSE_AND:
872                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
873                             break;
874                         case JBIG2_COMPOSE_XOR:
875                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
876                             break;
877                         case JBIG2_COMPOSE_XNOR:
878                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
879                             break;
880                         case JBIG2_COMPOSE_REPLACE:
881                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
882                             break;
883                     }
884                     lineDst[0] = (FX_BYTE)(tmp >> 24);
885                     lineDst[1] = (FX_BYTE)(tmp >> 16);
886                     lineDst[2] = (FX_BYTE)(tmp >> 8);
887                     lineDst[3] = (FX_BYTE)tmp;
888                     lineSrc += m_nStride;
889                     lineDst += pDst->m_nStride;
890                 }
891             }
892         } else {
893             shift1 = s1 - d1;
894             shift2 = 32 - shift1;
895             for(yy = yd0; yy < yd1; yy++) {
896                 tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) | (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
897                 tmp2 = JBIG2_GETDWORD(lineDst);
898                 switch(op) {
899                     case JBIG2_COMPOSE_OR:
900                         tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
901                         break;
902                     case JBIG2_COMPOSE_AND:
903                         tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
904                         break;
905                     case JBIG2_COMPOSE_XOR:
906                         tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
907                         break;
908                     case JBIG2_COMPOSE_XNOR:
909                         tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
910                         break;
911                     case JBIG2_COMPOSE_REPLACE:
912                         tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
913                         break;
914                 }
915                 lineDst[0] = (FX_BYTE)(tmp >> 24);
916                 lineDst[1] = (FX_BYTE)(tmp >> 16);
917                 lineDst[2] = (FX_BYTE)(tmp >> 8);
918                 lineDst[3] = (FX_BYTE)tmp;
919                 lineSrc += m_nStride;
920                 lineDst += pDst->m_nStride;
921             }
922         }
923     } else {
924         if(s1 > d1) {
925             shift1 = s1 - d1;
926             shift2 = 32 - shift1;
927             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
928             for(yy = yd0; yy < yd1; yy++) {
929                 sp = lineSrc;
930                 dp = lineDst;
931                 if(d1 != 0) {
932                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
933                     tmp2 = JBIG2_GETDWORD(dp);
934                     switch(op) {
935                         case JBIG2_COMPOSE_OR:
936                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
937                             break;
938                         case JBIG2_COMPOSE_AND:
939                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
940                             break;
941                         case JBIG2_COMPOSE_XOR:
942                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
943                             break;
944                         case JBIG2_COMPOSE_XNOR:
945                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
946                             break;
947                         case JBIG2_COMPOSE_REPLACE:
948                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
949                             break;
950                     }
951                     dp[0] = (FX_BYTE)(tmp >> 24);
952                     dp[1] = (FX_BYTE)(tmp >> 16);
953                     dp[2] = (FX_BYTE)(tmp >> 8);
954                     dp[3] = (FX_BYTE)tmp;
955                     sp += 4;
956                     dp += 4;
957                 }
958                 for(xx = 0; xx < middleDwords; xx++) {
959                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
960                     tmp2 = JBIG2_GETDWORD(dp);
961                     switch(op) {
962                         case JBIG2_COMPOSE_OR:
963                             tmp = tmp1 | tmp2;
964                             break;
965                         case JBIG2_COMPOSE_AND:
966                             tmp = tmp1 & tmp2;
967                             break;
968                         case JBIG2_COMPOSE_XOR:
969                             tmp = tmp1 ^ tmp2;
970                             break;
971                         case JBIG2_COMPOSE_XNOR:
972                             tmp = ~(tmp1 ^ tmp2);
973                             break;
974                         case JBIG2_COMPOSE_REPLACE:
975                             tmp = tmp1;
976                             break;
977                     }
978                     dp[0] = (FX_BYTE)(tmp >> 24);
979                     dp[1] = (FX_BYTE)(tmp >> 16);
980                     dp[2] = (FX_BYTE)(tmp >> 8);
981                     dp[3] = (FX_BYTE)tmp;
982                     sp += 4;
983                     dp += 4;
984                 }
985                 if(d2 != 0) {
986                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (
987                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift2);
988                     tmp2 = JBIG2_GETDWORD(dp);
989                     switch(op) {
990                         case JBIG2_COMPOSE_OR:
991                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
992                             break;
993                         case JBIG2_COMPOSE_AND:
994                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
995                             break;
996                         case JBIG2_COMPOSE_XOR:
997                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
998                             break;
999                         case JBIG2_COMPOSE_XNOR:
1000                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
1001                             break;
1002                         case JBIG2_COMPOSE_REPLACE:
1003                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
1004                             break;
1005                     }
1006                     dp[0] = (FX_BYTE)(tmp >> 24);
1007                     dp[1] = (FX_BYTE)(tmp >> 16);
1008                     dp[2] = (FX_BYTE)(tmp >> 8);
1009                     dp[3] = (FX_BYTE)tmp;
1010                 }
1011                 lineSrc += m_nStride;
1012                 lineDst += pDst->m_nStride;
1013             }
1014         } else if(s1 == d1) {
1015             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
1016             for(yy = yd0; yy < yd1; yy++) {
1017                 sp = lineSrc;
1018                 dp = lineDst;
1019                 if(d1 != 0) {
1020                     tmp1 = JBIG2_GETDWORD(sp);
1021                     tmp2 = JBIG2_GETDWORD(dp);
1022                     switch(op) {
1023                         case JBIG2_COMPOSE_OR:
1024                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
1025                             break;
1026                         case JBIG2_COMPOSE_AND:
1027                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
1028                             break;
1029                         case JBIG2_COMPOSE_XOR:
1030                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
1031                             break;
1032                         case JBIG2_COMPOSE_XNOR:
1033                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
1034                             break;
1035                         case JBIG2_COMPOSE_REPLACE:
1036                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
1037                             break;
1038                     }
1039                     dp[0] = (FX_BYTE)(tmp >> 24);
1040                     dp[1] = (FX_BYTE)(tmp >> 16);
1041                     dp[2] = (FX_BYTE)(tmp >> 8);
1042                     dp[3] = (FX_BYTE)tmp;
1043                     sp += 4;
1044                     dp += 4;
1045                 }
1046                 for(xx = 0; xx < middleDwords; xx++) {
1047                     tmp1 = JBIG2_GETDWORD(sp);
1048                     tmp2 = JBIG2_GETDWORD(dp);
1049                     switch(op) {
1050                         case JBIG2_COMPOSE_OR:
1051                             tmp = tmp1 | tmp2;
1052                             break;
1053                         case JBIG2_COMPOSE_AND:
1054                             tmp = tmp1 & tmp2;
1055                             break;
1056                         case JBIG2_COMPOSE_XOR:
1057                             tmp = tmp1 ^ tmp2;
1058                             break;
1059                         case JBIG2_COMPOSE_XNOR:
1060                             tmp = ~(tmp1 ^ tmp2);
1061                             break;
1062                         case JBIG2_COMPOSE_REPLACE:
1063                             tmp = tmp1;
1064                             break;
1065                     }
1066                     dp[0] = (FX_BYTE)(tmp >> 24);
1067                     dp[1] = (FX_BYTE)(tmp >> 16);
1068                     dp[2] = (FX_BYTE)(tmp >> 8);
1069                     dp[3] = (FX_BYTE)tmp;
1070                     sp += 4;
1071                     dp += 4;
1072                 }
1073                 if(d2 != 0) {
1074                     tmp1 = JBIG2_GETDWORD(sp);
1075                     tmp2 = JBIG2_GETDWORD(dp);
1076                     switch(op) {
1077                         case JBIG2_COMPOSE_OR:
1078                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
1079                             break;
1080                         case JBIG2_COMPOSE_AND:
1081                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
1082                             break;
1083                         case JBIG2_COMPOSE_XOR:
1084                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
1085                             break;
1086                         case JBIG2_COMPOSE_XNOR:
1087                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
1088                             break;
1089                         case JBIG2_COMPOSE_REPLACE:
1090                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
1091                             break;
1092                     }
1093                     dp[0] = (FX_BYTE)(tmp >> 24);
1094                     dp[1] = (FX_BYTE)(tmp >> 16);
1095                     dp[2] = (FX_BYTE)(tmp >> 8);
1096                     dp[3] = (FX_BYTE)tmp;
1097                 }
1098                 lineSrc += m_nStride;
1099                 lineDst += pDst->m_nStride;
1100             }
1101         } else {
1102             shift1 = d1 - s1;
1103             shift2 = 32 - shift1;
1104             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
1105             for(yy = yd0; yy < yd1; yy++) {
1106                 sp = lineSrc;
1107                 dp = lineDst;
1108                 if(d1 != 0) {
1109                     tmp1 = JBIG2_GETDWORD(sp) >> shift1;
1110                     tmp2 = JBIG2_GETDWORD(dp);
1111                     switch(op) {
1112                         case JBIG2_COMPOSE_OR:
1113                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
1114                             break;
1115                         case JBIG2_COMPOSE_AND:
1116                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
1117                             break;
1118                         case JBIG2_COMPOSE_XOR:
1119                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
1120                             break;
1121                         case JBIG2_COMPOSE_XNOR:
1122                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
1123                             break;
1124                         case JBIG2_COMPOSE_REPLACE:
1125                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
1126                             break;
1127                     }
1128                     dp[0] = (FX_BYTE)(tmp >> 24);
1129                     dp[1] = (FX_BYTE)(tmp >> 16);
1130                     dp[2] = (FX_BYTE)(tmp >> 8);
1131                     dp[3] = (FX_BYTE)tmp;
1132                     dp += 4;
1133                 }
1134                 for(xx = 0; xx < middleDwords; xx++) {
1135                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ((JBIG2_GETDWORD(sp + 4)) >> shift1);
1136                     tmp2 = JBIG2_GETDWORD(dp);
1137                     switch(op) {
1138                         case JBIG2_COMPOSE_OR:
1139                             tmp = tmp1 | tmp2;
1140                             break;
1141                         case JBIG2_COMPOSE_AND:
1142                             tmp = tmp1 & tmp2;
1143                             break;
1144                         case JBIG2_COMPOSE_XOR:
1145                             tmp = tmp1 ^ tmp2;
1146                             break;
1147                         case JBIG2_COMPOSE_XNOR:
1148                             tmp = ~(tmp1 ^ tmp2);
1149                             break;
1150                         case JBIG2_COMPOSE_REPLACE:
1151                             tmp = tmp1;
1152                             break;
1153                     }
1154                     dp[0] = (FX_BYTE)(tmp >> 24);
1155                     dp[1] = (FX_BYTE)(tmp >> 16);
1156                     dp[2] = (FX_BYTE)(tmp >> 8);
1157                     dp[3] = (FX_BYTE)tmp;
1158                     sp += 4;
1159                     dp += 4;
1160                 }
1161                 if(d2 != 0) {
1162                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | (
1163                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift1);
1164                     tmp2 = JBIG2_GETDWORD(dp);
1165                     switch(op) {
1166                         case JBIG2_COMPOSE_OR:
1167                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
1168                             break;
1169                         case JBIG2_COMPOSE_AND:
1170                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
1171                             break;
1172                         case JBIG2_COMPOSE_XOR:
1173                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
1174                             break;
1175                         case JBIG2_COMPOSE_XNOR:
1176                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
1177                             break;
1178                         case JBIG2_COMPOSE_REPLACE:
1179                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
1180                             break;
1181                     }
1182                     dp[0] = (FX_BYTE)(tmp >> 24);
1183                     dp[1] = (FX_BYTE)(tmp >> 16);
1184                     dp[2] = (FX_BYTE)(tmp >> 8);
1185                     dp[3] = (FX_BYTE)tmp;
1186                 }
1187                 lineSrc += m_nStride;
1188                 lineDst += pDst->m_nStride;
1189             }
1190         }
1191     }
1192     return 1;
1193 }
1194 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image *pDst, FX_INT32 x, FX_INT32 y, JBig2ComposeOp op, const FX_RECT* pSrcRect)
1195 {
1196     FX_INT32 xs0, ys0, xs1, ys1, xd0, yd0, xd1, yd1, xx, yy, w, h, middleDwords, lineLeft;
1197     FX_DWORD s1, d1, d2, shift, shift1, shift2, tmp, tmp1, tmp2, maskL, maskR, maskM;
1198     FX_BYTE *lineSrc, *lineDst, *sp, *dp;
1199     FX_INT32 sw, sh;
1200     if (!m_pData) {
1201         return FALSE;
1202     }
1203     if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576) {
1204         return FALSE;
1205     }
1206     sw = pSrcRect->Width();
1207     sh = pSrcRect->Height();
1208     if(y < 0) {
1209         ys0 = -y;
1210     } else {
1211         ys0 = 0;
1212     }
1213     if(y + sh > pDst->m_nHeight) {
1214         ys1 = pDst->m_nHeight - y;
1215     } else {
1216         ys1 = sh;
1217     }
1218     if(x < 0) {
1219         xs0 = -x;
1220     } else {
1221         xs0 = 0;
1222     }
1223     if(x + sw > pDst->m_nWidth) {
1224         xs1 = pDst->m_nWidth - x;
1225     } else {
1226         xs1 = sw;
1227     }
1228     if((ys0 >= ys1) || (xs0 >= xs1)) {
1229         return 0;
1230     }
1231     w = xs1 - xs0;
1232     h = ys1 - ys0;
1233     if(y < 0) {
1234         yd0 = 0;
1235     } else {
1236         yd0 = y;
1237     }
1238     if(x < 0) {
1239         xd0 = 0;
1240     } else {
1241         xd0 = x;
1242     }
1243     xd1 = xd0 + w;
1244     yd1 = yd0 + h;
1245     d1 = xd0 & 31;
1246     d2 = xd1 & 31;
1247     s1 = xs0 & 31;
1248     maskL = 0xffffffff >> d1;
1249     maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
1250     maskM = maskL & maskR;
1251     lineSrc = m_pData + (pSrcRect->top + ys0) * m_nStride + (((xs0 + pSrcRect->left) >> 5) << 2);
1252     lineLeft = m_nStride - ((xs0 >> 5) << 2);
1253     lineDst = pDst->m_pData + yd0 * pDst->m_nStride + ((xd0 >> 5) << 2);
1254     if((xd0 & ~31) == ((xd1 - 1) & ~31)) {
1255         if((xs0 & ~31) == ((xs1 - 1) & ~31)) {
1256             if(s1 > d1) {
1257                 shift = s1 - d1;
1258                 for(yy = yd0; yy < yd1; yy++) {
1259                     tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
1260                     tmp2 = JBIG2_GETDWORD(lineDst);
1261                     switch(op) {
1262                         case JBIG2_COMPOSE_OR:
1263                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
1264                             break;
1265                         case JBIG2_COMPOSE_AND:
1266                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
1267                             break;
1268                         case JBIG2_COMPOSE_XOR:
1269                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
1270                             break;
1271                         case JBIG2_COMPOSE_XNOR:
1272                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
1273                             break;
1274                         case JBIG2_COMPOSE_REPLACE:
1275                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
1276                             break;
1277                     }
1278                     lineDst[0] = (FX_BYTE)(tmp >> 24);
1279                     lineDst[1] = (FX_BYTE)(tmp >> 16);
1280                     lineDst[2] = (FX_BYTE)(tmp >> 8);
1281                     lineDst[3] = (FX_BYTE)tmp;
1282                     lineSrc += m_nStride;
1283                     lineDst += pDst->m_nStride;
1284                 }
1285             } else {
1286                 shift = d1 - s1;
1287                 for(yy = yd0; yy < yd1; yy++) {
1288                     tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
1289                     tmp2 = JBIG2_GETDWORD(lineDst);
1290                     switch(op) {
1291                         case JBIG2_COMPOSE_OR:
1292                             tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
1293                             break;
1294                         case JBIG2_COMPOSE_AND:
1295                             tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
1296                             break;
1297                         case JBIG2_COMPOSE_XOR:
1298                             tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
1299                             break;
1300                         case JBIG2_COMPOSE_XNOR:
1301                             tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
1302                             break;
1303                         case JBIG2_COMPOSE_REPLACE:
1304                             tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
1305                             break;
1306                     }
1307                     lineDst[0] = (FX_BYTE)(tmp >> 24);
1308                     lineDst[1] = (FX_BYTE)(tmp >> 16);
1309                     lineDst[2] = (FX_BYTE)(tmp >> 8);
1310                     lineDst[3] = (FX_BYTE)tmp;
1311                     lineSrc += m_nStride;
1312                     lineDst += pDst->m_nStride;
1313                 }
1314             }
1315         } else {
1316             shift1 = s1 - d1;
1317             shift2 = 32 - shift1;
1318             for(yy = yd0; yy < yd1; yy++) {
1319                 tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) | (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
1320                 tmp2 = JBIG2_GETDWORD(lineDst);
1321                 switch(op) {
1322                     case JBIG2_COMPOSE_OR:
1323                         tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
1324                         break;
1325                     case JBIG2_COMPOSE_AND:
1326                         tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
1327                         break;
1328                     case JBIG2_COMPOSE_XOR:
1329                         tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
1330                         break;
1331                     case JBIG2_COMPOSE_XNOR:
1332                         tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
1333                         break;
1334                     case JBIG2_COMPOSE_REPLACE:
1335                         tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
1336                         break;
1337                 }
1338                 lineDst[0] = (FX_BYTE)(tmp >> 24);
1339                 lineDst[1] = (FX_BYTE)(tmp >> 16);
1340                 lineDst[2] = (FX_BYTE)(tmp >> 8);
1341                 lineDst[3] = (FX_BYTE)tmp;
1342                 lineSrc += m_nStride;
1343                 lineDst += pDst->m_nStride;
1344             }
1345         }
1346     } else {
1347         if(s1 > d1) {
1348             shift1 = s1 - d1;
1349             shift2 = 32 - shift1;
1350             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
1351             for(yy = yd0; yy < yd1; yy++) {
1352                 sp = lineSrc;
1353                 dp = lineDst;
1354                 if(d1 != 0) {
1355                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
1356                     tmp2 = JBIG2_GETDWORD(dp);
1357                     switch(op) {
1358                         case JBIG2_COMPOSE_OR:
1359                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
1360                             break;
1361                         case JBIG2_COMPOSE_AND:
1362                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
1363                             break;
1364                         case JBIG2_COMPOSE_XOR:
1365                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
1366                             break;
1367                         case JBIG2_COMPOSE_XNOR:
1368                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
1369                             break;
1370                         case JBIG2_COMPOSE_REPLACE:
1371                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
1372                             break;
1373                     }
1374                     dp[0] = (FX_BYTE)(tmp >> 24);
1375                     dp[1] = (FX_BYTE)(tmp >> 16);
1376                     dp[2] = (FX_BYTE)(tmp >> 8);
1377                     dp[3] = (FX_BYTE)tmp;
1378                     sp += 4;
1379                     dp += 4;
1380                 }
1381                 for(xx = 0; xx < middleDwords; xx++) {
1382                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (JBIG2_GETDWORD(sp + 4) >> shift2);
1383                     tmp2 = JBIG2_GETDWORD(dp);
1384                     switch(op) {
1385                         case JBIG2_COMPOSE_OR:
1386                             tmp = tmp1 | tmp2;
1387                             break;
1388                         case JBIG2_COMPOSE_AND:
1389                             tmp = tmp1 & tmp2;
1390                             break;
1391                         case JBIG2_COMPOSE_XOR:
1392                             tmp = tmp1 ^ tmp2;
1393                             break;
1394                         case JBIG2_COMPOSE_XNOR:
1395                             tmp = ~(tmp1 ^ tmp2);
1396                             break;
1397                         case JBIG2_COMPOSE_REPLACE:
1398                             tmp = tmp1;
1399                             break;
1400                     }
1401                     dp[0] = (FX_BYTE)(tmp >> 24);
1402                     dp[1] = (FX_BYTE)(tmp >> 16);
1403                     dp[2] = (FX_BYTE)(tmp >> 8);
1404                     dp[3] = (FX_BYTE)tmp;
1405                     sp += 4;
1406                     dp += 4;
1407                 }
1408                 if(d2 != 0) {
1409                     tmp1 = (JBIG2_GETDWORD(sp) << shift1) | (
1410                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift2);
1411                     tmp2 = JBIG2_GETDWORD(dp);
1412                     switch(op) {
1413                         case JBIG2_COMPOSE_OR:
1414                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
1415                             break;
1416                         case JBIG2_COMPOSE_AND:
1417                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
1418                             break;
1419                         case JBIG2_COMPOSE_XOR:
1420                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
1421                             break;
1422                         case JBIG2_COMPOSE_XNOR:
1423                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
1424                             break;
1425                         case JBIG2_COMPOSE_REPLACE:
1426                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
1427                             break;
1428                     }
1429                     dp[0] = (FX_BYTE)(tmp >> 24);
1430                     dp[1] = (FX_BYTE)(tmp >> 16);
1431                     dp[2] = (FX_BYTE)(tmp >> 8);
1432                     dp[3] = (FX_BYTE)tmp;
1433                 }
1434                 lineSrc += m_nStride;
1435                 lineDst += pDst->m_nStride;
1436             }
1437         } else if(s1 == d1) {
1438             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
1439             for(yy = yd0; yy < yd1; yy++) {
1440                 sp = lineSrc;
1441                 dp = lineDst;
1442                 if(d1 != 0) {
1443                     tmp1 = JBIG2_GETDWORD(sp);
1444                     tmp2 = JBIG2_GETDWORD(dp);
1445                     switch(op) {
1446                         case JBIG2_COMPOSE_OR:
1447                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
1448                             break;
1449                         case JBIG2_COMPOSE_AND:
1450                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
1451                             break;
1452                         case JBIG2_COMPOSE_XOR:
1453                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
1454                             break;
1455                         case JBIG2_COMPOSE_XNOR:
1456                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
1457                             break;
1458                         case JBIG2_COMPOSE_REPLACE:
1459                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
1460                             break;
1461                     }
1462                     dp[0] = (FX_BYTE)(tmp >> 24);
1463                     dp[1] = (FX_BYTE)(tmp >> 16);
1464                     dp[2] = (FX_BYTE)(tmp >> 8);
1465                     dp[3] = (FX_BYTE)tmp;
1466                     sp += 4;
1467                     dp += 4;
1468                 }
1469                 for(xx = 0; xx < middleDwords; xx++) {
1470                     tmp1 = JBIG2_GETDWORD(sp);
1471                     tmp2 = JBIG2_GETDWORD(dp);
1472                     switch(op) {
1473                         case JBIG2_COMPOSE_OR:
1474                             tmp = tmp1 | tmp2;
1475                             break;
1476                         case JBIG2_COMPOSE_AND:
1477                             tmp = tmp1 & tmp2;
1478                             break;
1479                         case JBIG2_COMPOSE_XOR:
1480                             tmp = tmp1 ^ tmp2;
1481                             break;
1482                         case JBIG2_COMPOSE_XNOR:
1483                             tmp = ~(tmp1 ^ tmp2);
1484                             break;
1485                         case JBIG2_COMPOSE_REPLACE:
1486                             tmp = tmp1;
1487                             break;
1488                     }
1489                     dp[0] = (FX_BYTE)(tmp >> 24);
1490                     dp[1] = (FX_BYTE)(tmp >> 16);
1491                     dp[2] = (FX_BYTE)(tmp >> 8);
1492                     dp[3] = (FX_BYTE)tmp;
1493                     sp += 4;
1494                     dp += 4;
1495                 }
1496                 if(d2 != 0) {
1497                     tmp1 = JBIG2_GETDWORD(sp);
1498                     tmp2 = JBIG2_GETDWORD(dp);
1499                     switch(op) {
1500                         case JBIG2_COMPOSE_OR:
1501                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
1502                             break;
1503                         case JBIG2_COMPOSE_AND:
1504                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
1505                             break;
1506                         case JBIG2_COMPOSE_XOR:
1507                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
1508                             break;
1509                         case JBIG2_COMPOSE_XNOR:
1510                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
1511                             break;
1512                         case JBIG2_COMPOSE_REPLACE:
1513                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
1514                             break;
1515                     }
1516                     dp[0] = (FX_BYTE)(tmp >> 24);
1517                     dp[1] = (FX_BYTE)(tmp >> 16);
1518                     dp[2] = (FX_BYTE)(tmp >> 8);
1519                     dp[3] = (FX_BYTE)tmp;
1520                 }
1521                 lineSrc += m_nStride;
1522                 lineDst += pDst->m_nStride;
1523             }
1524         } else {
1525             shift1 = d1 - s1;
1526             shift2 = 32 - shift1;
1527             middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
1528             for(yy = yd0; yy < yd1; yy++) {
1529                 sp = lineSrc;
1530                 dp = lineDst;
1531                 if(d1 != 0) {
1532                     tmp1 = JBIG2_GETDWORD(sp) >> shift1;
1533                     tmp2 = JBIG2_GETDWORD(dp);
1534                     switch(op) {
1535                         case JBIG2_COMPOSE_OR:
1536                             tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
1537                             break;
1538                         case JBIG2_COMPOSE_AND:
1539                             tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
1540                             break;
1541                         case JBIG2_COMPOSE_XOR:
1542                             tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
1543                             break;
1544                         case JBIG2_COMPOSE_XNOR:
1545                             tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
1546                             break;
1547                         case JBIG2_COMPOSE_REPLACE:
1548                             tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
1549                             break;
1550                     }
1551                     dp[0] = (FX_BYTE)(tmp >> 24);
1552                     dp[1] = (FX_BYTE)(tmp >> 16);
1553                     dp[2] = (FX_BYTE)(tmp >> 8);
1554                     dp[3] = (FX_BYTE)tmp;
1555                     dp += 4;
1556                 }
1557                 for(xx = 0; xx < middleDwords; xx++) {
1558                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | ((JBIG2_GETDWORD(sp + 4)) >> shift1);
1559                     tmp2 = JBIG2_GETDWORD(dp);
1560                     switch(op) {
1561                         case JBIG2_COMPOSE_OR:
1562                             tmp = tmp1 | tmp2;
1563                             break;
1564                         case JBIG2_COMPOSE_AND:
1565                             tmp = tmp1 & tmp2;
1566                             break;
1567                         case JBIG2_COMPOSE_XOR:
1568                             tmp = tmp1 ^ tmp2;
1569                             break;
1570                         case JBIG2_COMPOSE_XNOR:
1571                             tmp = ~(tmp1 ^ tmp2);
1572                             break;
1573                         case JBIG2_COMPOSE_REPLACE:
1574                             tmp = tmp1;
1575                             break;
1576                     }
1577                     dp[0] = (FX_BYTE)(tmp >> 24);
1578                     dp[1] = (FX_BYTE)(tmp >> 16);
1579                     dp[2] = (FX_BYTE)(tmp >> 8);
1580                     dp[3] = (FX_BYTE)tmp;
1581                     sp += 4;
1582                     dp += 4;
1583                 }
1584                 if(d2 != 0) {
1585                     tmp1 = (JBIG2_GETDWORD(sp) << shift2) | (
1586                                ((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >> shift1);
1587                     tmp2 = JBIG2_GETDWORD(dp);
1588                     switch(op) {
1589                         case JBIG2_COMPOSE_OR:
1590                             tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
1591                             break;
1592                         case JBIG2_COMPOSE_AND:
1593                             tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
1594                             break;
1595                         case JBIG2_COMPOSE_XOR:
1596                             tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
1597                             break;
1598                         case JBIG2_COMPOSE_XNOR:
1599                             tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
1600                             break;
1601                         case JBIG2_COMPOSE_REPLACE:
1602                             tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
1603                             break;
1604                     }
1605                     dp[0] = (FX_BYTE)(tmp >> 24);
1606                     dp[1] = (FX_BYTE)(tmp >> 16);
1607                     dp[2] = (FX_BYTE)(tmp >> 8);
1608                     dp[3] = (FX_BYTE)tmp;
1609                 }
1610                 lineSrc += m_nStride;
1611                 lineDst += pDst->m_nStride;
1612             }
1613         }
1614     }
1615     return 1;
1616 }