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