Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
JBig2_Image.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
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 "core/fxcodec/jbig2/JBig2_Image.h"
8
9#include <limits.h>
10#include <stddef.h>
11
12#include <algorithm>
13#include <memory>
14
15#include "core/fxcrt/check.h"
16#include "core/fxcrt/compiler_specific.h"
17#include "core/fxcrt/fx_2d_size.h"
18#include "core/fxcrt/fx_coordinates.h"
19#include "core/fxcrt/fx_memcpy_wrappers.h"
20#include "core/fxcrt/fx_memory.h"
21#include "core/fxcrt/fx_safe_types.h"
22
23#define JBIG2_GETDWORD(buf)
24 ((static_cast<uint32_t>((buf)[0]) << 24) |
25 (static_cast<uint32_t>((buf)[1]) << 16) |
26 (static_cast<uint32_t>((buf)[2]) << 8) |
27 (static_cast<uint32_t>((buf)[3]) << 0))
28
29#define JBIG2_PUTDWORD(buf, val)
30 ((buf)[0] = static_cast<uint8_t>((val) >> 24),
31 (buf)[1] = static_cast<uint8_t>((val) >> 16),
32 (buf)[2] = static_cast<uint8_t>((val) >> 8),
33 (buf)[3] = static_cast<uint8_t>((val) >> 0))
34
35namespace {
36
37const int kMaxImagePixels = INT_MAX - 31;
38const int kMaxImageBytes = kMaxImagePixels / 8;
39
40int BitIndexToByte(int index) {
41 return index / 8;
42}
43
44int BitIndexToAlignedByte(int index) {
45 return index / 32 * 4;
46}
47
48} // namespace
49
50CJBig2_Image::CJBig2_Image(int32_t w, int32_t h) {
51 if (w <= 0 || h <= 0 || w > kMaxImagePixels)
52 return;
53
54 int32_t stride_pixels = FxAlignToBoundary<32>(w);
55 if (h > kMaxImagePixels / stride_pixels)
56 return;
57
58 m_nWidth = w;
59 m_nHeight = h;
60 m_nStride = stride_pixels / 8;
61 m_pData.Reset(std::unique_ptr<uint8_t, FxFreeDeleter>(
62 FX_Alloc2D(uint8_t, m_nStride, m_nHeight)));
63}
64
66 int32_t h,
67 int32_t stride,
68 pdfium::span<uint8_t> pBuf) {
69 if (w < 0 || h < 0)
70 return;
71
72 // Stride must be word-aligned.
73 if (stride < 0 || stride > kMaxImageBytes || stride % 4 != 0)
74 return;
75
76 int32_t stride_pixels = 8 * stride;
77 if (stride_pixels < w || h > kMaxImagePixels / stride_pixels)
78 return;
79
80 m_nWidth = w;
81 m_nHeight = h;
82 m_nStride = stride;
83 m_pData.Reset(pBuf.data());
84}
85
87 : m_nWidth(other.m_nWidth),
88 m_nHeight(other.m_nHeight),
89 m_nStride(other.m_nStride) {
90 if (other.m_pData) {
91 m_pData.Reset(std::unique_ptr<uint8_t, FxFreeDeleter>(
92 FX_Alloc2D(uint8_t, m_nStride, m_nHeight)));
93 UNSAFE_TODO(FXSYS_memcpy(data(), other.data(), m_nStride * m_nHeight));
94 }
95}
96
97CJBig2_Image::~CJBig2_Image() = default;
98
99// static
100bool CJBig2_Image::IsValidImageSize(int32_t w, int32_t h) {
101 return w > 0 && w <= kJBig2MaxImageSize && h > 0 && h <= kJBig2MaxImageSize;
102}
103
104int CJBig2_Image::GetPixel(int32_t x, int32_t y) const {
105 if (!m_pData)
106 return 0;
107
108 if (x < 0 || x >= m_nWidth)
109 return 0;
110
111 const uint8_t* pLine = GetLine(y);
112 if (!pLine)
113 return 0;
114
115 int32_t m = BitIndexToByte(x);
116 int32_t n = x & 7;
117 return UNSAFE_TODO((pLine[m] >> (7 - n)) & 1);
118}
119
120void CJBig2_Image::SetPixel(int32_t x, int32_t y, int v) {
121 if (!m_pData)
122 return;
123
124 if (x < 0 || x >= m_nWidth)
125 return;
126
127 uint8_t* pLine = GetLine(y);
128 if (!pLine)
129 return;
130
131 int32_t m = BitIndexToByte(x);
132 int32_t n = 1 << (7 - (x & 7));
133 if (v) {
134 UNSAFE_TODO(pLine[m]) |= n;
135 } else {
136 UNSAFE_TODO(pLine[m]) &= ~n;
137 }
138}
139
140void CJBig2_Image::CopyLine(int32_t hTo, int32_t hFrom) {
141 if (!m_pData)
142 return;
143
144 uint8_t* pDst = GetLine(hTo);
145 if (!pDst)
146 return;
147
148 const uint8_t* pSrc = GetLine(hFrom);
150 if (!pSrc) {
151 FXSYS_memset(pDst, 0, m_nStride);
152 return;
153 }
154 FXSYS_memcpy(pDst, pSrc, m_nStride);
155 });
156}
157
158void CJBig2_Image::Fill(bool v) {
159 if (!m_pData)
160 return;
161
163 FXSYS_memset(data(), v ? 0xff : 0, Fx2DSizeOrDie(m_nStride, m_nHeight)));
164}
165
167 int32_t x,
168 int32_t y,
169 JBig2ComposeOp op) {
170 return m_pData &&
171 ComposeToInternal(pDst, x, y, op, FX_RECT(0, 0, m_nWidth, m_nHeight));
172}
173
175 int32_t x,
176 int32_t y,
177 const FX_RECT& rtSrc,
178 JBig2ComposeOp op) {
179 return m_pData && ComposeToInternal(pDst, x, y, op, rtSrc);
180}
181
182bool CJBig2_Image::ComposeFrom(int32_t x,
183 int32_t y,
184 CJBig2_Image* pSrc,
185 JBig2ComposeOp op) {
186 return m_pData && pSrc->ComposeTo(this, x, y, op);
187}
188
190 int32_t y,
191 CJBig2_Image* pSrc,
192 const FX_RECT& rtSrc,
193 JBig2ComposeOp op) {
194 return m_pData && pSrc->ComposeToWithRect(this, x, y, rtSrc, op);
195}
196
198 int32_t y,
199 int32_t w,
200 int32_t h) {
201 auto pImage = std::make_unique<CJBig2_Image>(w, h);
202 if (!pImage->data() || !m_pData)
203 return pImage;
204
205 if (x < 0 || x >= m_nWidth || y < 0 || y >= m_nHeight)
206 return pImage;
207
208 // Fast case when byte-aligned, normal slow case otherwise.
209 if ((x & 7) == 0)
210 SubImageFast(x, y, w, h, pImage.get());
211 else
212 SubImageSlow(x, y, w, h, pImage.get());
213
214 return pImage;
215}
216
217void CJBig2_Image::SubImageFast(int32_t x,
218 int32_t y,
219 int32_t w,
220 int32_t h,
221 CJBig2_Image* pImage) {
222 int32_t m = BitIndexToByte(x);
223 int32_t bytes_to_copy = std::min(pImage->m_nStride, m_nStride - m);
224 int32_t lines_to_copy = std::min(pImage->m_nHeight, m_nHeight - y);
225 for (int32_t j = 0; j < lines_to_copy; j++) {
227 bytes_to_copy));
228 }
229}
230
231void CJBig2_Image::SubImageSlow(int32_t x,
232 int32_t y,
233 int32_t w,
234 int32_t h,
235 CJBig2_Image* pImage) {
236 int32_t m = BitIndexToAlignedByte(x);
237 int32_t n = x & 31;
238 int32_t bytes_to_copy = std::min(pImage->m_nStride, m_nStride - m);
239 int32_t lines_to_copy = std::min(pImage->m_nHeight, m_nHeight - y);
241 for (int32_t j = 0; j < lines_to_copy; j++) {
242 const uint8_t* pLineSrc = GetLineUnsafe(y + j);
243 uint8_t* pLineDst = pImage->GetLineUnsafe(j);
244 const uint8_t* pSrc = pLineSrc + m;
245 const uint8_t* pSrcEnd = pLineSrc + m_nStride;
246 uint8_t* pDstEnd = pLineDst + bytes_to_copy;
247 for (uint8_t* pDst = pLineDst; pDst < pDstEnd; pSrc += 4, pDst += 4) {
248 uint32_t wTmp = JBIG2_GETDWORD(pSrc) << n;
249 if (pSrc + 4 < pSrcEnd) {
250 wTmp |= (JBIG2_GETDWORD(pSrc + 4) >> (32 - n));
251 }
252 JBIG2_PUTDWORD(pDst, wTmp);
253 }
254 }
255 });
256}
257
258void CJBig2_Image::Expand(int32_t h, bool v) {
259 if (!m_pData || h <= m_nHeight || h > kMaxImageBytes / m_nStride)
260 return;
261
262 // Won't die unless kMaxImageBytes were to be increased someday.
263 const size_t current_size = Fx2DSizeOrDie(m_nHeight, m_nStride);
264 const size_t desired_size = Fx2DSizeOrDie(h, m_nStride);
265
266 if (m_pData.IsOwned()) {
267 m_pData.Reset(std::unique_ptr<uint8_t, FxFreeDeleter>(FX_Realloc(
268 uint8_t, m_pData.ReleaseAndClear().release(), desired_size)));
269 } else {
270 uint8_t* pExternalBuffer = data();
271 m_pData.Reset(std::unique_ptr<uint8_t, FxFreeDeleter>(
272 FX_Alloc(uint8_t, desired_size)));
273 UNSAFE_TODO(FXSYS_memcpy(data(), pExternalBuffer, current_size));
274 }
275 UNSAFE_TODO(FXSYS_memset(data() + current_size, v ? 0xff : 0,
276 desired_size - current_size));
277 m_nHeight = h;
278}
279
280bool CJBig2_Image::ComposeToInternal(CJBig2_Image* pDst,
281 int32_t x,
282 int32_t y,
284 const FX_RECT& rtSrc) {
285 DCHECK(m_pData);
286
287 // TODO(weili): Check whether the range check is correct. Should x>=1048576?
288 if (x < -1048576 || x > 1048576 || y < -1048576 || y > 1048576)
289 return false;
290
291 int32_t sw = rtSrc.Width();
292 int32_t sh = rtSrc.Height();
293
294 int32_t xs0 = x < 0 ? -x : 0;
295 int32_t xs1;
296 FX_SAFE_INT32 iChecked = pDst->m_nWidth;
297 iChecked -= x;
298 if (iChecked.IsValid() && sw > iChecked.ValueOrDie())
299 xs1 = iChecked.ValueOrDie();
300 else
301 xs1 = sw;
302
303 int32_t ys0 = y < 0 ? -y : 0;
304 int32_t ys1;
305 iChecked = pDst->m_nHeight;
306 iChecked -= y;
307 if (iChecked.IsValid() && sh > iChecked.ValueOrDie())
308 ys1 = iChecked.ValueOrDie();
309 else
310 ys1 = sh;
311
312 if (ys0 >= ys1 || xs0 >= xs1)
313 return false;
314
315 int32_t xd0 = std::max(x, 0);
316 int32_t yd0 = std::max(y, 0);
317 int32_t w = xs1 - xs0;
318 int32_t h = ys1 - ys0;
319 int32_t xd1 = xd0 + w;
320 int32_t yd1 = yd0 + h;
321 uint32_t d1 = xd0 & 31;
322 uint32_t d2 = xd1 & 31;
323 uint32_t s1 = xs0 & 31;
324 uint32_t maskL = 0xffffffff >> d1;
325 uint32_t maskR = 0xffffffff << ((32 - (xd1 & 31)) % 32);
326 uint32_t maskM = maskL & maskR;
328 const uint8_t* lineSrc = GetLineUnsafe(rtSrc.top + ys0) +
329 BitIndexToAlignedByte(xs0 + rtSrc.left);
330 const uint8_t* lineSrcEnd = data() + Fx2DSizeOrDie(m_nHeight, m_nStride);
331 int32_t lineLeft = m_nStride - BitIndexToAlignedByte(xs0);
332 uint8_t* lineDst = pDst->GetLineUnsafe(yd0) + BitIndexToAlignedByte(xd0);
333 if ((xd0 & ~31) == ((xd1 - 1) & ~31)) {
334 if ((xs0 & ~31) == ((xs1 - 1) & ~31)) {
335 if (s1 > d1) {
336 uint32_t shift = s1 - d1;
337 for (int32_t yy = yd0; yy < yd1; yy++) {
338 if (lineSrc >= lineSrcEnd) {
339 return false;
340 }
341 uint32_t tmp1 = JBIG2_GETDWORD(lineSrc) << shift;
342 uint32_t tmp2 = JBIG2_GETDWORD(lineDst);
343 uint32_t tmp = 0;
344 switch (op) {
345 case JBIG2_COMPOSE_OR:
346 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
347 break;
349 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
350 break;
352 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
353 break;
355 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
356 break;
358 tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
359 break;
360 }
361 JBIG2_PUTDWORD(lineDst, tmp);
362 lineSrc += m_nStride;
363 lineDst += pDst->m_nStride;
364 }
365 } else {
366 uint32_t shift = d1 - s1;
367 for (int32_t yy = yd0; yy < yd1; yy++) {
368 if (lineSrc >= lineSrcEnd) {
369 return false;
370 }
371 uint32_t tmp1 = JBIG2_GETDWORD(lineSrc) >> shift;
372 uint32_t tmp2 = JBIG2_GETDWORD(lineDst);
373 uint32_t tmp = 0;
374 switch (op) {
375 case JBIG2_COMPOSE_OR:
376 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
377 break;
379 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
380 break;
382 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
383 break;
385 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
386 break;
388 tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
389 break;
390 }
391 JBIG2_PUTDWORD(lineDst, tmp);
392 lineSrc += m_nStride;
393 lineDst += pDst->m_nStride;
394 }
395 }
396 } else {
397 uint32_t shift1 = s1 - d1;
398 uint32_t shift2 = 32 - shift1;
399 for (int32_t yy = yd0; yy < yd1; yy++) {
400 if (lineSrc >= lineSrcEnd)
401 return false;
402 uint32_t tmp1 = (JBIG2_GETDWORD(lineSrc) << shift1) |
403 (JBIG2_GETDWORD(lineSrc + 4) >> shift2);
404 uint32_t tmp2 = JBIG2_GETDWORD(lineDst);
405 uint32_t tmp = 0;
406 switch (op) {
407 case JBIG2_COMPOSE_OR:
408 tmp = (tmp2 & ~maskM) | ((tmp1 | tmp2) & maskM);
409 break;
411 tmp = (tmp2 & ~maskM) | ((tmp1 & tmp2) & maskM);
412 break;
414 tmp = (tmp2 & ~maskM) | ((tmp1 ^ tmp2) & maskM);
415 break;
417 tmp = (tmp2 & ~maskM) | ((~(tmp1 ^ tmp2)) & maskM);
418 break;
420 tmp = (tmp2 & ~maskM) | (tmp1 & maskM);
421 break;
422 }
423 JBIG2_PUTDWORD(lineDst, tmp);
424 lineSrc += m_nStride;
425 lineDst += pDst->m_nStride;
426 }
427 }
428 } else {
429 if (s1 > d1) {
430 uint32_t shift1 = s1 - d1;
431 uint32_t shift2 = 32 - shift1;
432 int32_t middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
433 for (int32_t yy = yd0; yy < yd1; yy++) {
434 if (lineSrc >= lineSrcEnd) {
435 return false;
436 }
437 const uint8_t* sp = lineSrc;
438 uint8_t* dp = lineDst;
439 if (d1 != 0) {
440 uint32_t tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
441 (JBIG2_GETDWORD(sp + 4) >> shift2);
442 uint32_t tmp2 = JBIG2_GETDWORD(dp);
443 uint32_t tmp = 0;
444 switch (op) {
445 case JBIG2_COMPOSE_OR:
446 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
447 break;
449 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
450 break;
452 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
453 break;
455 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
456 break;
458 tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
459 break;
460 }
461 JBIG2_PUTDWORD(dp, tmp);
462 sp += 4;
463 dp += 4;
464 }
465 for (int32_t xx = 0; xx < middleDwords; xx++) {
466 uint32_t tmp1 = (JBIG2_GETDWORD(sp) << shift1) |
467 (JBIG2_GETDWORD(sp + 4) >> shift2);
468 uint32_t tmp2 = JBIG2_GETDWORD(dp);
469 uint32_t tmp = 0;
470 switch (op) {
471 case JBIG2_COMPOSE_OR:
472 tmp = tmp1 | tmp2;
473 break;
475 tmp = tmp1 & tmp2;
476 break;
478 tmp = tmp1 ^ tmp2;
479 break;
481 tmp = ~(tmp1 ^ tmp2);
482 break;
484 tmp = tmp1;
485 break;
486 }
487 JBIG2_PUTDWORD(dp, tmp);
488 sp += 4;
489 dp += 4;
490 }
491 if (d2 != 0) {
492 uint32_t tmp1 =
493 (JBIG2_GETDWORD(sp) << shift1) |
494 (((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >>
495 shift2);
496 uint32_t tmp2 = JBIG2_GETDWORD(dp);
497 uint32_t tmp = 0;
498 switch (op) {
499 case JBIG2_COMPOSE_OR:
500 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
501 break;
503 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
504 break;
506 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
507 break;
509 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
510 break;
512 tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
513 break;
514 }
515 JBIG2_PUTDWORD(dp, tmp);
516 }
517 lineSrc += m_nStride;
518 lineDst += pDst->m_nStride;
519 }
520 } else if (s1 == d1) {
521 int32_t middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
522 for (int32_t yy = yd0; yy < yd1; yy++) {
523 if (lineSrc >= lineSrcEnd) {
524 return false;
525 }
526 const uint8_t* sp = lineSrc;
527 uint8_t* dp = lineDst;
528 if (d1 != 0) {
529 uint32_t tmp1 = JBIG2_GETDWORD(sp);
530 uint32_t tmp2 = JBIG2_GETDWORD(dp);
531 uint32_t tmp = 0;
532 switch (op) {
533 case JBIG2_COMPOSE_OR:
534 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
535 break;
537 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
538 break;
540 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
541 break;
543 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
544 break;
546 tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
547 break;
548 }
549 JBIG2_PUTDWORD(dp, tmp);
550 sp += 4;
551 dp += 4;
552 }
553 for (int32_t xx = 0; xx < middleDwords; xx++) {
554 uint32_t tmp1 = JBIG2_GETDWORD(sp);
555 uint32_t tmp2 = JBIG2_GETDWORD(dp);
556 uint32_t tmp = 0;
557 switch (op) {
558 case JBIG2_COMPOSE_OR:
559 tmp = tmp1 | tmp2;
560 break;
562 tmp = tmp1 & tmp2;
563 break;
565 tmp = tmp1 ^ tmp2;
566 break;
568 tmp = ~(tmp1 ^ tmp2);
569 break;
571 tmp = tmp1;
572 break;
573 }
574 JBIG2_PUTDWORD(dp, tmp);
575 sp += 4;
576 dp += 4;
577 }
578 if (d2 != 0) {
579 uint32_t tmp1 = JBIG2_GETDWORD(sp);
580 uint32_t tmp2 = JBIG2_GETDWORD(dp);
581 uint32_t tmp = 0;
582 switch (op) {
583 case JBIG2_COMPOSE_OR:
584 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
585 break;
587 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
588 break;
590 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
591 break;
593 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
594 break;
596 tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
597 break;
598 }
599 JBIG2_PUTDWORD(dp, tmp);
600 }
601 lineSrc += m_nStride;
602 lineDst += pDst->m_nStride;
603 }
604 } else {
605 uint32_t shift1 = d1 - s1;
606 uint32_t shift2 = 32 - shift1;
607 int32_t middleDwords = (xd1 >> 5) - ((xd0 + 31) >> 5);
608 for (int32_t yy = yd0; yy < yd1; yy++) {
609 if (lineSrc >= lineSrcEnd) {
610 return false;
611 }
612 const uint8_t* sp = lineSrc;
613 uint8_t* dp = lineDst;
614 if (d1 != 0) {
615 uint32_t tmp1 = JBIG2_GETDWORD(sp) >> shift1;
616 uint32_t tmp2 = JBIG2_GETDWORD(dp);
617 uint32_t tmp = 0;
618 switch (op) {
619 case JBIG2_COMPOSE_OR:
620 tmp = (tmp2 & ~maskL) | ((tmp1 | tmp2) & maskL);
621 break;
623 tmp = (tmp2 & ~maskL) | ((tmp1 & tmp2) & maskL);
624 break;
626 tmp = (tmp2 & ~maskL) | ((tmp1 ^ tmp2) & maskL);
627 break;
629 tmp = (tmp2 & ~maskL) | ((~(tmp1 ^ tmp2)) & maskL);
630 break;
632 tmp = (tmp2 & ~maskL) | (tmp1 & maskL);
633 break;
634 }
635 JBIG2_PUTDWORD(dp, tmp);
636 dp += 4;
637 }
638 for (int32_t xx = 0; xx < middleDwords; xx++) {
639 uint32_t tmp1 = (JBIG2_GETDWORD(sp) << shift2) |
640 ((JBIG2_GETDWORD(sp + 4)) >> shift1);
641 uint32_t tmp2 = JBIG2_GETDWORD(dp);
642 uint32_t tmp = 0;
643 switch (op) {
644 case JBIG2_COMPOSE_OR:
645 tmp = tmp1 | tmp2;
646 break;
648 tmp = tmp1 & tmp2;
649 break;
651 tmp = tmp1 ^ tmp2;
652 break;
654 tmp = ~(tmp1 ^ tmp2);
655 break;
657 tmp = tmp1;
658 break;
659 }
660 JBIG2_PUTDWORD(dp, tmp);
661 sp += 4;
662 dp += 4;
663 }
664 if (d2 != 0) {
665 uint32_t tmp1 =
666 (JBIG2_GETDWORD(sp) << shift2) |
667 (((sp + 4) < lineSrc + lineLeft ? JBIG2_GETDWORD(sp + 4) : 0) >>
668 shift1);
669 uint32_t tmp2 = JBIG2_GETDWORD(dp);
670 uint32_t tmp = 0;
671 switch (op) {
672 case JBIG2_COMPOSE_OR:
673 tmp = (tmp2 & ~maskR) | ((tmp1 | tmp2) & maskR);
674 break;
676 tmp = (tmp2 & ~maskR) | ((tmp1 & tmp2) & maskR);
677 break;
679 tmp = (tmp2 & ~maskR) | ((tmp1 ^ tmp2) & maskR);
680 break;
682 tmp = (tmp2 & ~maskR) | ((~(tmp1 ^ tmp2)) & maskR);
683 break;
685 tmp = (tmp2 & ~maskR) | (tmp1 & maskR);
686 break;
687 }
688 JBIG2_PUTDWORD(dp, tmp);
689 }
690 lineSrc += m_nStride;
691 lineDst += pDst->m_nStride;
692 }
693 }
694 }
695 });
696 return true;
697}
constexpr int32_t kJBig2MaxImageSize
#define JBIG2_PUTDWORD(buf, val)
#define JBIG2_GETDWORD(buf)
JBig2ComposeOp
Definition JBig2_Image.h:22
@ JBIG2_COMPOSE_REPLACE
Definition JBig2_Image.h:27
@ JBIG2_COMPOSE_AND
Definition JBig2_Image.h:24
@ JBIG2_COMPOSE_XOR
Definition JBig2_Image.h:25
@ JBIG2_COMPOSE_OR
Definition JBig2_Image.h:23
@ JBIG2_COMPOSE_XNOR
Definition JBig2_Image.h:26
#define DCHECK
Definition check.h:33
CJBig2_Image(int32_t w, int32_t h, int32_t stride, pdfium::span< uint8_t > pBuf)
bool ComposeFrom(int32_t x, int32_t y, CJBig2_Image *pSrc, JBig2ComposeOp op)
void SetPixel(int32_t x, int32_t y, int v)
std::unique_ptr< CJBig2_Image > SubImage(int32_t x, int32_t y, int32_t w, int32_t h)
CJBig2_Image(int32_t w, int32_t h)
uint8_t * GetLine(int32_t y) const
Definition JBig2_Image.h:56
void CopyLine(int32_t hTo, int32_t hFrom)
CJBig2_Image(const CJBig2_Image &other)
bool ComposeToWithRect(CJBig2_Image *pDst, int32_t x, int32_t y, const FX_RECT &rtSrc, JBig2ComposeOp op)
uint8_t * data() const
Definition JBig2_Image.h:46
static bool IsValidImageSize(int32_t w, int32_t h)
int GetPixel(int32_t x, int32_t y) const
bool ComposeTo(CJBig2_Image *pDst, int32_t x, int32_t y, JBig2ComposeOp op)
UNSAFE_BUFFER_USAGE uint8_t * GetLineUnsafe(int32_t y) const
Definition JBig2_Image.h:52
void Fill(bool v)
void Expand(int32_t h, bool v)
bool ComposeFromWithRect(int32_t x, int32_t y, CJBig2_Image *pSrc, const FX_RECT &rtSrc, JBig2ComposeOp op)
#define UNSAFE_TODO(...)
UNSAFE_BUFFER_USAGE void * FXSYS_memset(void *ptr1, int val, size_t len)
UNSAFE_BUFFER_USAGE void * FXSYS_memcpy(void *ptr1, const void *ptr2, size_t len)
pdfium::CheckedNumeric< int32_t > FX_SAFE_INT32
int Height() const
int Width() const
int32_t top
int32_t left