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