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
16static_assert(sizeof(BmpFileHeader) == 14,
17              "BmpFileHeader should have a size of 14");
18
19namespace {
20
21const size_t kBmpCoreHeaderSize = 12;
22const size_t kBmpInfoHeaderSize = 40;
23
24uint8_t HalfRoundUp(uint8_t value) {
25  uint16_t value16 = value;
26  return static_cast<uint8_t>((value16 + 1) / 2);
27}
28
29}  // namespace
30
31BMPDecompressor::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
60BMPDecompressor::~BMPDecompressor() {}
61
62void BMPDecompressor::Error() {
63  longjmp(jmpbuf, 1);
64}
65
66void 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
72bool BMPDecompressor::GetDataPosition(uint32_t rcd_pos) {
73  auto* p = reinterpret_cast<CBmpContext*>(context_ptr);
74  return p->m_pDelegate->BmpInputImagePositionBuf(rcd_pos);
75}
76
77int32_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
294bool 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
306int32_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
334bool BMPDecompressor::ValidateColorIndex(uint8_t val) {
335  if (val >= pal_num) {
336    Error();
337    NOTREACHED();
338  }
339  return true;
340}
341
342int32_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
411int32_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
512int32_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
629uint8_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
638void 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
645void 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
651uint32_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
660void 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