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 "core/fxcodec/lbmp/fx_bmp.h"
8
9 #include <algorithm>
10 #include <limits>
11
12 #include "core/fxcrt/fx_system.h"
13 #include "third_party/base/logging.h"
14 #include "third_party/base/ptr_util.h"
15
16 static_assert(sizeof(BmpFileHeader) == 14,
17 "BmpFileHeader should have a size of 14");
18
19 namespace {
20
21 const size_t kBmpCoreHeaderSize = 12;
22 const size_t kBmpInfoHeaderSize = 40;
23
HalfRoundUp(uint8_t value)24 uint8_t HalfRoundUp(uint8_t value) {
25 uint16_t value16 = value;
26 return static_cast<uint8_t>((value16 + 1) / 2);
27 }
28
29 } // namespace
30
BMPDecompressor()31 BMPDecompressor::BMPDecompressor()
32 : context_ptr(nullptr),
33 next_in(nullptr),
34 header_offset(0),
35 width(0),
36 height(0),
37 compress_flag(0),
38 components(0),
39 src_row_bytes(0),
40 out_row_bytes(0),
41 bitCounts(0),
42 color_used(0),
43 imgTB_flag(false),
44 pal_num(0),
45 pal_type(0),
46 data_size(0),
47 img_data_offset(0),
48 img_ifh_size(0),
49 row_num(0),
50 col_num(0),
51 dpi_x(0),
52 dpi_y(0),
53 mask_red(0),
54 mask_green(0),
55 mask_blue(0),
56 avail_in(0),
57 skip_size(0),
58 decode_status(BMP_D_STATUS_HEADER) {}
59
~BMPDecompressor()60 BMPDecompressor::~BMPDecompressor() {}
61
Error()62 void BMPDecompressor::Error() {
63 longjmp(jmpbuf, 1);
64 }
65
ReadScanline(uint32_t row_num,const std::vector<uint8_t> & row_buf)66 void BMPDecompressor::ReadScanline(uint32_t row_num,
67 const std::vector<uint8_t>& row_buf) {
68 auto* p = reinterpret_cast<CBmpContext*>(context_ptr);
69 p->m_pDelegate->BmpReadScanline(row_num, row_buf);
70 }
71
GetDataPosition(uint32_t rcd_pos)72 bool BMPDecompressor::GetDataPosition(uint32_t rcd_pos) {
73 auto* p = reinterpret_cast<CBmpContext*>(context_ptr);
74 return p->m_pDelegate->BmpInputImagePositionBuf(rcd_pos);
75 }
76
ReadHeader()77 int32_t BMPDecompressor::ReadHeader() {
78 uint32_t skip_size_org = skip_size;
79 if (decode_status == BMP_D_STATUS_HEADER) {
80 BmpFileHeader* pBmp_header = nullptr;
81 if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_header),
82 sizeof(BmpFileHeader))) {
83 return 2;
84 }
85
86 pBmp_header->bfType =
87 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&pBmp_header->bfType));
88 pBmp_header->bfOffBits = FXDWORD_GET_LSBFIRST(
89 reinterpret_cast<uint8_t*>(&pBmp_header->bfOffBits));
90 data_size =
91 FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&pBmp_header->bfSize));
92 if (pBmp_header->bfType != BMP_SIGNATURE) {
93 Error();
94 NOTREACHED();
95 }
96 if (avail_in < sizeof(uint32_t)) {
97 skip_size = skip_size_org;
98 return 2;
99 }
100 img_ifh_size =
101 FXDWORD_GET_LSBFIRST(static_cast<uint8_t*>(next_in + skip_size));
102 pal_type = 0;
103 static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize,
104 "BmpCoreHeader has wrong size");
105 static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize,
106 "BmpInfoHeader has wrong size");
107 switch (img_ifh_size) {
108 case kBmpCoreHeaderSize: {
109 pal_type = 1;
110 BmpCoreHeader* pBmp_core_header = nullptr;
111 if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_core_header),
112 img_ifh_size)) {
113 skip_size = skip_size_org;
114 return 2;
115 }
116 width = FXWORD_GET_LSBFIRST(
117 reinterpret_cast<uint8_t*>(&pBmp_core_header->bcWidth));
118 height = FXWORD_GET_LSBFIRST(
119 reinterpret_cast<uint8_t*>(&pBmp_core_header->bcHeight));
120 bitCounts = FXWORD_GET_LSBFIRST(
121 reinterpret_cast<uint8_t*>(&pBmp_core_header->bcBitCount));
122 compress_flag = BMP_RGB;
123 imgTB_flag = false;
124 } break;
125 case kBmpInfoHeaderSize: {
126 BmpInfoHeader* pBmp_info_header = nullptr;
127 if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_info_header),
128 img_ifh_size)) {
129 skip_size = skip_size_org;
130 return 2;
131 }
132 width = FXDWORD_GET_LSBFIRST(
133 reinterpret_cast<uint8_t*>(&pBmp_info_header->biWidth));
134 int32_t signed_height = FXDWORD_GET_LSBFIRST(
135 reinterpret_cast<uint8_t*>(&pBmp_info_header->biHeight));
136 bitCounts = FXWORD_GET_LSBFIRST(
137 reinterpret_cast<uint8_t*>(&pBmp_info_header->biBitCount));
138 compress_flag = FXDWORD_GET_LSBFIRST(
139 reinterpret_cast<uint8_t*>(&pBmp_info_header->biCompression));
140 color_used = FXDWORD_GET_LSBFIRST(
141 reinterpret_cast<uint8_t*>(&pBmp_info_header->biClrUsed));
142 dpi_x = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
143 reinterpret_cast<uint8_t*>(&pBmp_info_header->biXPelsPerMeter)));
144 dpi_y = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
145 reinterpret_cast<uint8_t*>(&pBmp_info_header->biYPelsPerMeter)));
146 SetHeight(signed_height);
147 } break;
148 default: {
149 if (img_ifh_size >
150 std::min(kBmpInfoHeaderSize, sizeof(BmpInfoHeader))) {
151 BmpInfoHeader* pBmp_info_header = nullptr;
152 if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_info_header),
153 img_ifh_size)) {
154 skip_size = skip_size_org;
155 return 2;
156 }
157 uint16_t biPlanes;
158 width = FXDWORD_GET_LSBFIRST(
159 reinterpret_cast<uint8_t*>(&pBmp_info_header->biWidth));
160 int32_t signed_height = FXDWORD_GET_LSBFIRST(
161 reinterpret_cast<uint8_t*>(&pBmp_info_header->biHeight));
162 bitCounts = FXWORD_GET_LSBFIRST(
163 reinterpret_cast<uint8_t*>(&pBmp_info_header->biBitCount));
164 compress_flag = FXDWORD_GET_LSBFIRST(
165 reinterpret_cast<uint8_t*>(&pBmp_info_header->biCompression));
166 color_used = FXDWORD_GET_LSBFIRST(
167 reinterpret_cast<uint8_t*>(&pBmp_info_header->biClrUsed));
168 biPlanes = FXWORD_GET_LSBFIRST(
169 reinterpret_cast<uint8_t*>(&pBmp_info_header->biPlanes));
170 dpi_x = FXDWORD_GET_LSBFIRST(
171 reinterpret_cast<uint8_t*>(&pBmp_info_header->biXPelsPerMeter));
172 dpi_y = FXDWORD_GET_LSBFIRST(
173 reinterpret_cast<uint8_t*>(&pBmp_info_header->biYPelsPerMeter));
174 SetHeight(signed_height);
175 if (compress_flag == BMP_RGB && biPlanes == 1 && color_used == 0)
176 break;
177 }
178 Error();
179 NOTREACHED();
180 }
181 }
182 if (width > BMP_MAX_WIDTH || compress_flag > BMP_BITFIELDS) {
183 Error();
184 NOTREACHED();
185 }
186 switch (bitCounts) {
187 case 1:
188 case 4:
189 case 8:
190 case 16:
191 case 24: {
192 if (color_used > 1U << bitCounts) {
193 Error();
194 NOTREACHED();
195 }
196 }
197 case 32:
198 break;
199 default:
200 Error();
201 NOTREACHED();
202 }
203 src_row_bytes = BMP_WIDTHBYTES(width, bitCounts);
204 switch (bitCounts) {
205 case 1:
206 case 4:
207 case 8:
208 out_row_bytes = BMP_WIDTHBYTES(width, 8);
209 components = 1;
210 break;
211 case 16:
212 case 24:
213 out_row_bytes = BMP_WIDTHBYTES(width, 24);
214 components = 3;
215 break;
216 case 32:
217 out_row_bytes = src_row_bytes;
218 components = 4;
219 break;
220 }
221 out_row_buffer.clear();
222
223 if (out_row_bytes <= 0) {
224 Error();
225 NOTREACHED();
226 }
227
228 out_row_buffer.resize(out_row_bytes);
229 SaveDecodingStatus(BMP_D_STATUS_PAL);
230 }
231 if (decode_status == BMP_D_STATUS_PAL) {
232 skip_size_org = skip_size;
233 if (compress_flag == BMP_BITFIELDS) {
234 if (bitCounts != 16 && bitCounts != 32) {
235 Error();
236 NOTREACHED();
237 }
238 uint32_t* mask;
239 if (ReadData(reinterpret_cast<uint8_t**>(&mask), 3 * sizeof(uint32_t)) ==
240 nullptr) {
241 skip_size = skip_size_org;
242 return 2;
243 }
244 mask_red = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&mask[0]));
245 mask_green = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&mask[1]));
246 mask_blue = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&mask[2]));
247 if (mask_red & mask_green || mask_red & mask_blue ||
248 mask_green & mask_blue) {
249 Error();
250 NOTREACHED();
251 }
252 header_offset = std::max(header_offset, 26 + img_ifh_size);
253 SaveDecodingStatus(BMP_D_STATUS_DATA_PRE);
254 return 1;
255 } else if (bitCounts == 16) {
256 mask_red = 0x7C00;
257 mask_green = 0x03E0;
258 mask_blue = 0x001F;
259 }
260 pal_num = 0;
261 if (bitCounts < 16) {
262 pal_num = 1 << bitCounts;
263 if (color_used != 0)
264 pal_num = color_used;
265 uint8_t* src_pal_ptr = nullptr;
266 uint32_t src_pal_size = pal_num * (pal_type ? 3 : 4);
267 if (ReadData(&src_pal_ptr, src_pal_size) == nullptr) {
268 skip_size = skip_size_org;
269 return 2;
270 }
271 palette.resize(pal_num);
272 int32_t src_pal_index = 0;
273 if (pal_type == BMP_PAL_OLD) {
274 while (src_pal_index < pal_num) {
275 palette[src_pal_index++] = BMP_PAL_ENCODE(
276 0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]);
277 src_pal_ptr += 3;
278 }
279 } else {
280 while (src_pal_index < pal_num) {
281 palette[src_pal_index++] = BMP_PAL_ENCODE(
282 src_pal_ptr[3], src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]);
283 src_pal_ptr += 4;
284 }
285 }
286 }
287 header_offset = std::max(header_offset,
288 14 + img_ifh_size + pal_num * (pal_type ? 3 : 4));
289 SaveDecodingStatus(BMP_D_STATUS_DATA_PRE);
290 }
291 return 1;
292 }
293
ValidateFlag() const294 bool BMPDecompressor::ValidateFlag() const {
295 switch (compress_flag) {
296 case BMP_RGB:
297 case BMP_BITFIELDS:
298 case BMP_RLE8:
299 case BMP_RLE4:
300 return true;
301 default:
302 return false;
303 }
304 }
305
DecodeImage()306 int32_t BMPDecompressor::DecodeImage() {
307 if (decode_status == BMP_D_STATUS_DATA_PRE) {
308 avail_in = 0;
309 if (!GetDataPosition(header_offset)) {
310 decode_status = BMP_D_STATUS_TAIL;
311 Error();
312 NOTREACHED();
313 }
314 row_num = 0;
315 SaveDecodingStatus(BMP_D_STATUS_DATA);
316 }
317 if (decode_status != BMP_D_STATUS_DATA || !ValidateFlag()) {
318 Error();
319 NOTREACHED();
320 }
321 switch (compress_flag) {
322 case BMP_RGB:
323 case BMP_BITFIELDS:
324 return DecodeRGB();
325 case BMP_RLE8:
326 return DecodeRLE8();
327 case BMP_RLE4:
328 return DecodeRLE4();
329 default:
330 return 0;
331 }
332 }
333
ValidateColorIndex(uint8_t val)334 bool BMPDecompressor::ValidateColorIndex(uint8_t val) {
335 if (val >= pal_num) {
336 Error();
337 NOTREACHED();
338 }
339 return true;
340 }
341
DecodeRGB()342 int32_t BMPDecompressor::DecodeRGB() {
343 uint8_t* des_buf = nullptr;
344 while (row_num < height) {
345 size_t idx = 0;
346 if (!ReadData(&des_buf, src_row_bytes))
347 return 2;
348
349 SaveDecodingStatus(BMP_D_STATUS_DATA);
350 switch (bitCounts) {
351 case 1: {
352 for (uint32_t col = 0; col < width; ++col)
353 out_row_buffer[idx++] =
354 des_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00;
355 } break;
356 case 4: {
357 for (uint32_t col = 0; col < width; ++col) {
358 out_row_buffer[idx++] = (col & 0x01)
359 ? (des_buf[col >> 1] & 0x0F)
360 : ((des_buf[col >> 1] & 0xF0) >> 4);
361 }
362 } break;
363 case 16: {
364 uint16_t* buf = (uint16_t*)des_buf;
365 uint8_t blue_bits = 0;
366 uint8_t green_bits = 0;
367 uint8_t red_bits = 0;
368 for (int32_t i = 0; i < 16; i++) {
369 if ((mask_blue >> i) & 0x01)
370 blue_bits++;
371 if ((mask_green >> i) & 0x01)
372 green_bits++;
373 if ((mask_red >> i) & 0x01)
374 red_bits++;
375 }
376 green_bits += blue_bits;
377 red_bits += green_bits;
378 if (blue_bits > 8 || green_bits < 8 || red_bits < 8)
379 return 2;
380 blue_bits = 8 - blue_bits;
381 green_bits -= 8;
382 red_bits -= 8;
383 for (uint32_t col = 0; col < width; ++col) {
384 *buf = FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(buf));
385 out_row_buffer[idx++] =
386 static_cast<uint8_t>((*buf & mask_blue) << blue_bits);
387 out_row_buffer[idx++] =
388 static_cast<uint8_t>((*buf & mask_green) >> green_bits);
389 out_row_buffer[idx++] =
390 static_cast<uint8_t>((*buf++ & mask_red) >> red_bits);
391 }
392 } break;
393 case 8:
394 case 24:
395 case 32:
396 std::copy(des_buf, des_buf + src_row_bytes, out_row_buffer.begin());
397 idx += src_row_bytes;
398 break;
399 }
400 for (uint8_t byte : out_row_buffer) {
401 if (!ValidateColorIndex(byte))
402 return 0;
403 }
404 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
405 out_row_buffer);
406 }
407 SaveDecodingStatus(BMP_D_STATUS_TAIL);
408 return 1;
409 }
410
DecodeRLE8()411 int32_t BMPDecompressor::DecodeRLE8() {
412 uint8_t* first_byte_ptr = nullptr;
413 uint8_t* second_byte_ptr = nullptr;
414 col_num = 0;
415 while (true) {
416 uint32_t skip_size_org = skip_size;
417 if (!ReadData(&first_byte_ptr, 1))
418 return 2;
419
420 switch (*first_byte_ptr) {
421 case RLE_MARKER: {
422 if (!ReadData(&first_byte_ptr, 1)) {
423 skip_size = skip_size_org;
424 return 2;
425 }
426 switch (*first_byte_ptr) {
427 case RLE_EOL: {
428 if (row_num >= height) {
429 SaveDecodingStatus(BMP_D_STATUS_TAIL);
430 Error();
431 NOTREACHED();
432 }
433 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
434 out_row_buffer);
435 col_num = 0;
436 std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
437 SaveDecodingStatus(BMP_D_STATUS_DATA);
438 continue;
439 }
440 case RLE_EOI: {
441 if (row_num < height) {
442 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
443 out_row_buffer);
444 }
445 SaveDecodingStatus(BMP_D_STATUS_TAIL);
446 return 1;
447 }
448 case RLE_DELTA: {
449 uint8_t* delta_ptr;
450 if (!ReadData(&delta_ptr, 2)) {
451 skip_size = skip_size_org;
452 return 2;
453 }
454 col_num += delta_ptr[0];
455 size_t bmp_row_num_next = row_num + delta_ptr[1];
456 if (col_num >= out_row_bytes || bmp_row_num_next >= height) {
457 Error();
458 NOTREACHED();
459 }
460 while (row_num < bmp_row_num_next) {
461 std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
462 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
463 out_row_buffer);
464 }
465 } break;
466 default: {
467 int32_t avail_size = out_row_bytes - col_num;
468 if (!avail_size ||
469 static_cast<int32_t>(*first_byte_ptr) > avail_size) {
470 Error();
471 NOTREACHED();
472 }
473 if (!ReadData(&second_byte_ptr, *first_byte_ptr & 1
474 ? *first_byte_ptr + 1
475 : *first_byte_ptr)) {
476 skip_size = skip_size_org;
477 return 2;
478 }
479 std::copy(second_byte_ptr, second_byte_ptr + *first_byte_ptr,
480 out_row_buffer.begin() + col_num);
481 for (size_t i = col_num; i < col_num + *first_byte_ptr; ++i) {
482 if (!ValidateColorIndex(out_row_buffer[i]))
483 return 0;
484 }
485 col_num += *first_byte_ptr;
486 }
487 }
488 } break;
489 default: {
490 int32_t avail_size = out_row_bytes - col_num;
491 if (!avail_size || static_cast<int32_t>(*first_byte_ptr) > avail_size) {
492 Error();
493 NOTREACHED();
494 }
495 if (!ReadData(&second_byte_ptr, 1)) {
496 skip_size = skip_size_org;
497 return 2;
498 }
499 std::fill(out_row_buffer.begin() + col_num,
500 out_row_buffer.begin() + col_num + *first_byte_ptr,
501 *second_byte_ptr);
502 if (!ValidateColorIndex(out_row_buffer[col_num]))
503 return 0;
504 col_num += *first_byte_ptr;
505 }
506 }
507 }
508 Error();
509 NOTREACHED();
510 }
511
DecodeRLE4()512 int32_t BMPDecompressor::DecodeRLE4() {
513 uint8_t* first_byte_ptr = nullptr;
514 uint8_t* second_byte_ptr = nullptr;
515 col_num = 0;
516 while (true) {
517 uint32_t skip_size_org = skip_size;
518 if (!ReadData(&first_byte_ptr, 1))
519 return 2;
520
521 switch (*first_byte_ptr) {
522 case RLE_MARKER: {
523 if (!ReadData(&first_byte_ptr, 1)) {
524 skip_size = skip_size_org;
525 return 2;
526 }
527 switch (*first_byte_ptr) {
528 case RLE_EOL: {
529 if (row_num >= height) {
530 SaveDecodingStatus(BMP_D_STATUS_TAIL);
531 Error();
532 NOTREACHED();
533 }
534 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
535 out_row_buffer);
536 col_num = 0;
537 std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
538 SaveDecodingStatus(BMP_D_STATUS_DATA);
539 continue;
540 }
541 case RLE_EOI: {
542 if (row_num < height) {
543 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
544 out_row_buffer);
545 }
546 SaveDecodingStatus(BMP_D_STATUS_TAIL);
547 return 1;
548 }
549 case RLE_DELTA: {
550 uint8_t* delta_ptr;
551 if (!ReadData(&delta_ptr, 2)) {
552 skip_size = skip_size_org;
553 return 2;
554 }
555 col_num += delta_ptr[0];
556 size_t bmp_row_num_next = row_num + delta_ptr[1];
557 if (col_num >= out_row_bytes || bmp_row_num_next >= height) {
558 Error();
559 NOTREACHED();
560 }
561 while (row_num < bmp_row_num_next) {
562 std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0);
563 ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++),
564 out_row_buffer);
565 }
566 } break;
567 default: {
568 int32_t avail_size = out_row_bytes - col_num;
569 if (!avail_size) {
570 Error();
571 NOTREACHED();
572 }
573 uint8_t size = HalfRoundUp(*first_byte_ptr);
574 if (static_cast<int32_t>(*first_byte_ptr) > avail_size) {
575 if (size + (col_num >> 1) > src_row_bytes) {
576 Error();
577 NOTREACHED();
578 }
579 *first_byte_ptr = avail_size - 1;
580 }
581 if (!ReadData(&second_byte_ptr, size & 1 ? size + 1 : size)) {
582 skip_size = skip_size_org;
583 return 2;
584 }
585 for (uint8_t i = 0; i < *first_byte_ptr; i++) {
586 uint8_t color = (i & 0x01) ? (*second_byte_ptr++ & 0x0F)
587 : (*second_byte_ptr & 0xF0) >> 4;
588 if (!ValidateColorIndex(color))
589 return 0;
590
591 out_row_buffer[col_num++] = color;
592 }
593 }
594 }
595 } break;
596 default: {
597 int32_t avail_size = out_row_bytes - col_num;
598 if (!avail_size) {
599 Error();
600 NOTREACHED();
601 }
602 if (static_cast<int32_t>(*first_byte_ptr) > avail_size) {
603 uint8_t size = HalfRoundUp(*first_byte_ptr);
604 if (size + (col_num >> 1) > src_row_bytes) {
605 Error();
606 NOTREACHED();
607 }
608 *first_byte_ptr = avail_size - 1;
609 }
610 if (!ReadData(&second_byte_ptr, 1)) {
611 skip_size = skip_size_org;
612 return 2;
613 }
614 for (uint8_t i = 0; i < *first_byte_ptr; i++) {
615 uint8_t second_byte = *second_byte_ptr;
616 second_byte =
617 i & 0x01 ? (second_byte & 0x0F) : (second_byte & 0xF0) >> 4;
618 if (!ValidateColorIndex(second_byte))
619 return 0;
620 out_row_buffer[col_num++] = second_byte;
621 }
622 }
623 }
624 }
625 Error();
626 NOTREACHED();
627 }
628
ReadData(uint8_t ** des_buf,uint32_t data_size)629 uint8_t* BMPDecompressor::ReadData(uint8_t** des_buf, uint32_t data_size) {
630 if (avail_in < skip_size + data_size)
631 return nullptr;
632
633 *des_buf = next_in + skip_size;
634 skip_size += data_size;
635 return *des_buf;
636 }
637
SaveDecodingStatus(int32_t status)638 void BMPDecompressor::SaveDecodingStatus(int32_t status) {
639 decode_status = status;
640 next_in += skip_size;
641 avail_in -= skip_size;
642 skip_size = 0;
643 }
644
SetInputBuffer(uint8_t * src_buf,uint32_t src_size)645 void BMPDecompressor::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) {
646 next_in = src_buf;
647 avail_in = src_size;
648 skip_size = 0;
649 }
650
GetAvailInput(uint8_t ** avail_buf)651 uint32_t BMPDecompressor::GetAvailInput(uint8_t** avail_buf) {
652 if (avail_buf) {
653 *avail_buf = nullptr;
654 if (avail_in > 0)
655 *avail_buf = next_in;
656 }
657 return avail_in;
658 }
659
SetHeight(int32_t signed_height)660 void BMPDecompressor::SetHeight(int32_t signed_height) {
661 if (signed_height >= 0) {
662 height = signed_height;
663 return;
664 }
665 if (signed_height == std::numeric_limits<int>::min()) {
666 Error();
667 NOTREACHED();
668 }
669 height = -signed_height;
670 imgTB_flag = true;
671 }
672