Break apart CFX_BmpDecompressor::ReadHeader().

Split it into several smaller methods.

Change-Id: I10f518be006f6e19ad569be00cd1184468433f1e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56052
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
index 4bba1b4..32362da 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
@@ -72,218 +72,228 @@
 }
 
 bool CFX_BmpDecompressor::ReadHeader() {
-  if (decode_status_ == DecodeStatus::kHeader) {
-    BmpFileHeader bmp_header;
-    if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_header),
-                  sizeof(BmpFileHeader))) {
-      return false;
-    }
+  if (decode_status_ == DecodeStatus::kHeader && !ReadBmpHeader())
+    return false;
 
-    bmp_header.bfType =
-        FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfType));
-    bmp_header.bfOffBits =
-        FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfOffBits));
-    data_size_ =
-        FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfSize));
-    if (bmp_header.bfType != kBmpSignature) {
-      Error();
-      NOTREACHED();
-    }
-
-    if (!ReadData(reinterpret_cast<uint8_t*>(&img_ifh_size_),
-                  sizeof(img_ifh_size_))) {
-      return false;
-    }
-
-    img_ifh_size_ =
-        FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_));
-    pal_type_ = 0;
-    switch (img_ifh_size_) {
-      case kBmpCoreHeaderSize: {
-        pal_type_ = 1;
-        BmpCoreHeader bmp_core_header;
-        if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_core_header),
-                      sizeof(BmpCoreHeader))) {
-          return false;
-        }
-
-        width_ = FXWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_core_header.bcWidth));
-        height_ = FXWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_core_header.bcHeight));
-        bit_counts_ = FXWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_core_header.bcBitCount));
-        compress_flag_ = kBmpRgb;
-        img_tb_flag_ = false;
-        break;
-      }
-      case kBmpInfoHeaderSize: {
-        BmpInfoHeader bmp_info_header;
-        if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
-                      sizeof(BmpInfoHeader))) {
-          return false;
-        }
-
-        width_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
-        int32_t signed_height = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
-        bit_counts_ = FXWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
-        compress_flag_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
-        color_used_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
-        dpi_x_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)));
-        dpi_y_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)));
-        SetHeight(signed_height);
-        break;
-      }
-      default: {
-        if (img_ifh_size_ <= sizeof(BmpInfoHeader)) {
-          Error();
-          NOTREACHED();
-        }
-
-        FX_SAFE_SIZE_T new_pos = input_buffer_->GetPosition();
-        BmpInfoHeader bmp_info_header;
-        if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
-                      sizeof(bmp_info_header))) {
-          return false;
-        }
-
-        new_pos += img_ifh_size_;
-        if (!new_pos.IsValid()) {
-          Error();
-          NOTREACHED();
-        }
-
-        if (!input_buffer_->Seek(new_pos.ValueOrDie()))
-          return false;
-
-        uint16_t bi_planes;
-        width_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
-        int32_t signed_height = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
-        bit_counts_ = FXWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
-        compress_flag_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
-        color_used_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
-        bi_planes = FXWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes));
-        dpi_x_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter));
-        dpi_y_ = FXDWORD_GET_LSBFIRST(
-            reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter));
-        SetHeight(signed_height);
-        if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0) {
-          Error();
-          NOTREACHED();
-        }
-        break;
-      }
-    }
-
-    if (width_ > kBmpMaxImageDimension || height_ > kBmpMaxImageDimension ||
-        compress_flag_ > kBmpBitfields) {
-      Error();
-      NOTREACHED();
-    }
-
-    switch (bit_counts_) {
-      case 1:
-      case 4:
-      case 8:
-      case 16:
-      case 24: {
-        if (color_used_ > 1U << bit_counts_) {
-          Error();
-          NOTREACHED();
-        }
-        break;
-      }
-      case 32:
-        break;
-      default:
-        Error();
-        NOTREACHED();
-        break;
-    }
-    FX_SAFE_UINT32 stride = CalculatePitch32(bit_counts_, width_);
-    if (!stride.IsValid()) {
-      Error();
-      NOTREACHED();
-    }
-
-    src_row_bytes_ = stride.ValueOrDie();
-    switch (bit_counts_) {
-      case 1:
-      case 4:
-      case 8:
-        stride = CalculatePitch32(8, width_);
-        if (!stride.IsValid()) {
-          Error();
-          NOTREACHED();
-        }
-        out_row_bytes_ = stride.ValueOrDie();
-        components_ = 1;
-        break;
-      case 16:
-      case 24:
-        stride = CalculatePitch32(24, width_);
-        if (!stride.IsValid()) {
-          Error();
-          NOTREACHED();
-        }
-        out_row_bytes_ = stride.ValueOrDie();
-        components_ = 3;
-        break;
-      case 32:
-        out_row_bytes_ = src_row_bytes_;
-        components_ = 4;
-        break;
-    }
-    out_row_buffer_.clear();
-
-    if (out_row_bytes_ <= 0) {
-      Error();
-      NOTREACHED();
-    }
-
-    out_row_buffer_.resize(out_row_bytes_);
-    SaveDecodingStatus(DecodeStatus::kPal);
-  }
   if (decode_status_ != DecodeStatus::kPal)
     return true;
 
-  if (compress_flag_ == kBmpBitfields) {
-    if (bit_counts_ != 16 && bit_counts_ != 32) {
-      Error();
-      NOTREACHED();
-    }
+  if (compress_flag_ == kBmpBitfields)
+    return ReadBmpBitfields();
 
-    uint32_t masks[3];
-    if (!ReadData(reinterpret_cast<uint8_t*>(masks), sizeof(masks)))
+  return ReadBmpPalette();
+}
+
+bool CFX_BmpDecompressor::ReadBmpHeader() {
+  BmpFileHeader bmp_header;
+  if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_header),
+                sizeof(BmpFileHeader))) {
+    return false;
+  }
+
+  bmp_header.bfType =
+      FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfType));
+  bmp_header.bfOffBits =
+      FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfOffBits));
+  data_size_ =
+      FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfSize));
+  if (bmp_header.bfType != kBmpSignature) {
+    Error();
+    NOTREACHED();
+  }
+
+  if (!ReadData(reinterpret_cast<uint8_t*>(&img_ifh_size_),
+                sizeof(img_ifh_size_))) {
+    return false;
+  }
+
+  img_ifh_size_ =
+      FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_));
+  pal_type_ = 0;
+  if (!ReadBmpHeaderIfh())
+    return false;
+
+  if (!ReadBmpHeaderDimensions()) {
+    Error();
+    NOTREACHED();
+  }
+  return true;
+}
+
+bool CFX_BmpDecompressor::ReadBmpHeaderIfh() {
+  if (img_ifh_size_ == kBmpCoreHeaderSize) {
+    pal_type_ = 1;
+    BmpCoreHeader bmp_core_header;
+    if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_core_header),
+                  sizeof(BmpCoreHeader))) {
       return false;
-
-    mask_red_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[0]));
-    mask_green_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[1]));
-    mask_blue_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[2]));
-    if (mask_red_ & mask_green_ || mask_red_ & mask_blue_ ||
-        mask_green_ & mask_blue_) {
-      Error();
-      NOTREACHED();
     }
-    header_offset_ = std::max(header_offset_, 26 + img_ifh_size_);
-    SaveDecodingStatus(DecodeStatus::kDataPre);
+
+    width_ = FXWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_core_header.bcWidth));
+    height_ = FXWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_core_header.bcHeight));
+    bit_counts_ = FXWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_core_header.bcBitCount));
+    compress_flag_ = kBmpRgb;
+    img_tb_flag_ = false;
     return true;
   }
 
+  if (img_ifh_size_ == kBmpInfoHeaderSize) {
+    BmpInfoHeader bmp_info_header;
+    if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
+                  sizeof(BmpInfoHeader))) {
+      return false;
+    }
+
+    width_ = FXDWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
+    int32_t signed_height = FXDWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
+    bit_counts_ = FXWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
+    compress_flag_ = FXDWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
+    color_used_ = FXDWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
+    dpi_x_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)));
+    dpi_y_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
+        reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)));
+    SetHeight(signed_height);
+    return true;
+  }
+
+  if (img_ifh_size_ <= sizeof(BmpInfoHeader)) {
+    Error();
+    NOTREACHED();
+  }
+
+  FX_SAFE_SIZE_T new_pos = input_buffer_->GetPosition();
+  BmpInfoHeader bmp_info_header;
+  if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
+                sizeof(bmp_info_header))) {
+    return false;
+  }
+
+  new_pos += img_ifh_size_;
+  if (!new_pos.IsValid()) {
+    Error();
+    NOTREACHED();
+  }
+
+  if (!input_buffer_->Seek(new_pos.ValueOrDie()))
+    return false;
+
+  uint16_t bi_planes;
+  width_ = FXDWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
+  int32_t signed_height = FXDWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
+  bit_counts_ = FXWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
+  compress_flag_ = FXDWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
+  color_used_ = FXDWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
+  bi_planes = FXWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes));
+  dpi_x_ = FXDWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter));
+  dpi_y_ = FXDWORD_GET_LSBFIRST(
+      reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter));
+  SetHeight(signed_height);
+  if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0) {
+    Error();
+    NOTREACHED();
+  }
+  return true;
+}
+
+bool CFX_BmpDecompressor::ReadBmpHeaderDimensions() {
+  if (width_ > kBmpMaxImageDimension || height_ > kBmpMaxImageDimension ||
+      compress_flag_ > kBmpBitfields) {
+    return false;
+  }
+
+  switch (bit_counts_) {
+    case 1:
+    case 4:
+    case 8:
+    case 16:
+    case 24: {
+      if (color_used_ > 1U << bit_counts_)
+        return false;
+      break;
+    }
+    case 32:
+      break;
+    default:
+      return false;
+  }
+  FX_SAFE_UINT32 stride = CalculatePitch32(bit_counts_, width_);
+  if (!stride.IsValid())
+    return false;
+
+  src_row_bytes_ = stride.ValueOrDie();
+  switch (bit_counts_) {
+    case 1:
+    case 4:
+    case 8:
+      stride = CalculatePitch32(8, width_);
+      if (!stride.IsValid())
+        return false;
+      out_row_bytes_ = stride.ValueOrDie();
+      components_ = 1;
+      break;
+    case 16:
+    case 24:
+      stride = CalculatePitch32(24, width_);
+      if (!stride.IsValid())
+        return false;
+      out_row_bytes_ = stride.ValueOrDie();
+      components_ = 3;
+      break;
+    case 32:
+      out_row_bytes_ = src_row_bytes_;
+      components_ = 4;
+      break;
+  }
+  out_row_buffer_.clear();
+
+  if (out_row_bytes_ <= 0)
+    return false;
+
+  out_row_buffer_.resize(out_row_bytes_);
+  SaveDecodingStatus(DecodeStatus::kPal);
+  return true;
+}
+
+bool CFX_BmpDecompressor::ReadBmpBitfields() {
+  if (bit_counts_ != 16 && bit_counts_ != 32) {
+    Error();
+    NOTREACHED();
+  }
+
+  uint32_t masks[3];
+  if (!ReadData(reinterpret_cast<uint8_t*>(masks), sizeof(masks)))
+    return false;
+
+  mask_red_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[0]));
+  mask_green_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[1]));
+  mask_blue_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[2]));
+  if (mask_red_ & mask_green_ || mask_red_ & mask_blue_ ||
+      mask_green_ & mask_blue_) {
+    Error();
+    NOTREACHED();
+  }
+  header_offset_ = std::max(header_offset_, 26 + img_ifh_size_);
+  SaveDecodingStatus(DecodeStatus::kDataPre);
+  return true;
+}
+
+bool CFX_BmpDecompressor::ReadBmpPalette() {
   if (bit_counts_ == 16) {
     mask_red_ = 0x7C00;
     mask_green_ = 0x03E0;
@@ -297,9 +307,8 @@
     uint32_t src_pal_size = pal_num_ * (pal_type_ ? 3 : 4);
     std::vector<uint8_t> src_pal(src_pal_size);
     uint8_t* src_pal_data = src_pal.data();
-    if (!ReadData(src_pal_data, src_pal_size)) {
+    if (!ReadData(src_pal_data, src_pal_size))
       return false;
-    }
 
     palette_.resize(pal_num_);
     int32_t src_pal_index = 0;
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.h b/core/fxcodec/bmp/cfx_bmpdecompressor.h
index 223ab63..eb987b2 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.h
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.h
@@ -48,6 +48,11 @@
     kTail,
   };
 
+  bool ReadBmpHeader();
+  bool ReadBmpHeaderIfh();
+  bool ReadBmpHeaderDimensions();
+  bool ReadBmpBitfields();
+  bool ReadBmpPalette();
   bool GetDataPosition(uint32_t cur_pos);
   void ReadNextScanline();
   int32_t DecodeRGB();