Use more spans inside flatemodule.cpp
- Switch from DataVector to FixedSizeDataVector when appropriate.
- Use spancpy() in more spans.
- Reduce scope of buffer guessing calculation in FlateUncompress().
- Switch FlateOutput() to take a span and return a bool.
Change-Id: Ifaade43fd73eaf1c9782a0e69fe09bff748f8b76
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119135
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fxcodec/flate/flatemodule.cpp b/core/fxcodec/flate/flatemodule.cpp
index 4e632be..1fc8d7d 100644
--- a/core/fxcodec/flate/flatemodule.cpp
+++ b/core/fxcodec/flate/flatemodule.cpp
@@ -95,20 +95,15 @@
context->avail_in = static_cast<uint32_t>(src_buf.size());
}
-uint32_t FlateOutput(z_stream* context,
- unsigned char* dest_buf,
- uint32_t dest_size) {
- context->next_out = dest_buf;
- context->avail_out = dest_size;
+bool FlateOutput(z_stream* context, pdfium::span<uint8_t> dest_span) {
+ context->next_out = dest_span.data();
+ context->avail_out = pdfium::checked_cast<uint32_t>(dest_span.size());
uint32_t pre_pos = FlateGetPossiblyTruncatedTotalOut(context);
- int ret = inflate(static_cast<z_stream*>(context), Z_SYNC_FLUSH);
+ bool ret = inflate(static_cast<z_stream*>(context), Z_SYNC_FLUSH) == Z_OK;
uint32_t post_pos = FlateGetPossiblyTruncatedTotalOut(context);
- DCHECK(post_pos >= pre_pos);
-
- uint32_t written = post_pos - pre_pos;
- if (written < dest_size)
- FXSYS_memset(dest_buf + written, '\0', dest_size - written);
+ CHECK_GE(post_pos, pre_pos);
+ fxcrt::spanclr(dest_span.subspan(post_pos - pre_pos));
return ret;
}
@@ -498,6 +493,14 @@
return true;
}
+uint32_t EstimateFlateUncompressBufferSize(uint32_t orig_size,
+ size_t src_size) {
+ constexpr uint32_t kMaxInitialAllocSize = 10000000;
+ uint32_t guess_size =
+ orig_size ? orig_size : pdfium::checked_cast<uint32_t>(src_size * 2);
+ return std::min(guess_size, kMaxInitialAllocSize);
+}
+
DataAndBytesConsumed FlateUncompress(pdfium::span<const uint8_t> src_buf,
uint32_t orig_size) {
std::unique_ptr<z_stream, FlateDeleter> context(FlateInit());
@@ -507,24 +510,20 @@
FlateInput(context.get(), src_buf);
- const uint32_t kMaxInitialAllocSize = 10000000;
- uint32_t guess_size =
- orig_size ? orig_size
- : pdfium::checked_cast<uint32_t>(src_buf.size() * 2);
- guess_size = std::min(guess_size, kMaxInitialAllocSize);
-
- uint32_t buf_size = guess_size;
+ const uint32_t buf_size =
+ EstimateFlateUncompressBufferSize(orig_size, src_buf.size());
uint32_t last_buf_size = buf_size;
std::unique_ptr<uint8_t, FxFreeDeleter> guess_buf(
- FX_Alloc(uint8_t, guess_size + 1));
- guess_buf.get()[guess_size] = '\0';
+ FX_Alloc(uint8_t, buf_size + 1));
+ guess_buf.get()[buf_size] = '\0';
std::vector<std::unique_ptr<uint8_t, FxFreeDeleter>> result_tmp_bufs;
{
std::unique_ptr<uint8_t, FxFreeDeleter> cur_buf = std::move(guess_buf);
while (true) {
- uint32_t ret = FlateOutput(context.get(), cur_buf.get(), buf_size);
+ bool ret = FlateOutput(context.get(),
+ pdfium::make_span(cur_buf.get(), buf_size));
uint32_t avail_buf_size = FlateGetAvailOut(context.get());
- if (ret != Z_OK || avail_buf_size != 0) {
+ if (!ret || avail_buf_size != 0) {
last_buf_size = buf_size - avail_buf_size;
result_tmp_bufs.push_back(std::move(cur_buf));
break;
@@ -589,7 +588,7 @@
protected:
std::unique_ptr<z_stream, FlateDeleter> m_pFlate;
const pdfium::raw_span<const uint8_t> m_SrcBuf;
- DataVector<uint8_t> m_Scanline;
+ FixedSizeDataVector<uint8_t> m_Scanline;
};
FlateScanlineDecoder::FlateScanlineDecoder(pdfium::span<const uint8_t> src_span,
@@ -605,7 +604,7 @@
bpc,
fxge::CalculatePitch8OrDie(bpc, nComps, width)),
m_SrcBuf(src_span),
- m_Scanline(m_Pitch) {}
+ m_Scanline(FixedSizeDataVector<uint8_t>::Zeroed(m_Pitch)) {}
FlateScanlineDecoder::~FlateScanlineDecoder() {
// Span in superclass can't outlive our buffer.
@@ -622,7 +621,7 @@
}
pdfium::span<uint8_t> FlateScanlineDecoder::GetNextLine() {
- FlateOutput(m_pFlate.get(), m_Scanline.data(), m_Pitch);
+ FlateOutput(m_pFlate.get(), m_Scanline);
return m_Scanline;
}
@@ -657,9 +656,9 @@
int m_Columns = 0;
uint32_t m_PredictPitch = 0;
size_t m_LeftOver = 0;
- DataVector<uint8_t> m_LastLine;
- DataVector<uint8_t> m_PredictBuffer;
- DataVector<uint8_t> m_PredictRaw;
+ FixedSizeDataVector<uint8_t> m_LastLine;
+ FixedSizeDataVector<uint8_t> m_PredictBuffer;
+ FixedSizeDataVector<uint8_t> m_PredictRaw;
};
FlatePredictorScanlineDecoder::FlatePredictorScanlineDecoder(
@@ -685,9 +684,9 @@
m_Columns = Columns;
m_PredictPitch =
fxge::CalculatePitch8OrDie(m_BitsPerComponent, m_Colors, m_Columns);
- m_LastLine.resize(m_PredictPitch);
- m_PredictBuffer.resize(m_PredictPitch);
- m_PredictRaw.resize(m_PredictPitch + 1);
+ m_LastLine = FixedSizeDataVector<uint8_t>::Zeroed(m_PredictPitch);
+ m_PredictBuffer = FixedSizeDataVector<uint8_t>::Zeroed(m_PredictPitch);
+ m_PredictRaw = FixedSizeDataVector<uint8_t>::Zeroed(m_PredictPitch + 1);
}
FlatePredictorScanlineDecoder::~FlatePredictorScanlineDecoder() {
@@ -717,16 +716,16 @@
const uint32_t row_size =
fxge::CalculatePitch8OrDie(m_BitsPerComponent, m_Colors, m_Columns);
const uint32_t bytes_per_pixel = (m_BitsPerComponent * m_Colors + 7) / 8;
- FlateOutput(m_pFlate.get(), m_PredictRaw.data(), m_PredictPitch + 1);
+ FlateOutput(m_pFlate.get(), m_PredictRaw);
PNG_PredictLine(m_Scanline, m_PredictRaw, m_LastLine, row_size,
bytes_per_pixel);
- FXSYS_memcpy(m_LastLine.data(), m_Scanline.data(), m_PredictPitch);
+ fxcrt::spancpy(m_LastLine.span(), m_Scanline.first(m_PredictPitch));
break;
}
case PredictorType::kFlate: {
- FlateOutput(m_pFlate.get(), m_Scanline.data(), m_Pitch);
- TIFF_PredictLine(pdfium::make_span(m_Scanline).first(m_PredictPitch),
- m_bpc, m_nComps, m_OutputWidth);
+ FlateOutput(m_pFlate.get(), m_Scanline);
+ TIFF_PredictLine(m_Scanline.first(m_PredictPitch), m_bpc, m_nComps,
+ m_OutputWidth);
break;
}
case PredictorType::kNone: {
@@ -739,8 +738,9 @@
size_t bytes_to_go = m_Pitch;
size_t read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver;
if (read_leftover) {
- FXSYS_memcpy(m_Scanline.data(),
- &m_PredictBuffer[m_PredictPitch - m_LeftOver], read_leftover);
+ fxcrt::spancpy(
+ m_Scanline.span(),
+ m_PredictBuffer.subspan(m_PredictPitch - m_LeftOver, read_leftover));
m_LeftOver -= read_leftover;
bytes_to_go -= read_leftover;
}
@@ -750,14 +750,14 @@
while (bytes_to_go) {
switch (m_Predictor) {
case PredictorType::kPng: {
- FlateOutput(m_pFlate.get(), m_PredictRaw.data(), m_PredictPitch + 1);
+ FlateOutput(m_pFlate.get(), m_PredictRaw);
PNG_PredictLine(m_PredictBuffer, m_PredictRaw, m_LastLine, row_size,
bytes_per_pixel);
- FXSYS_memcpy(m_LastLine.data(), m_PredictBuffer.data(), m_PredictPitch);
+ fxcrt::spancpy(m_LastLine.span(), m_PredictBuffer.span());
break;
}
case PredictorType::kFlate: {
- FlateOutput(m_pFlate.get(), m_PredictBuffer.data(), m_PredictPitch);
+ FlateOutput(m_pFlate.get(), m_PredictBuffer);
TIFF_PredictLine(m_PredictBuffer, m_BitsPerComponent, m_Colors,
m_Columns);
break;
@@ -768,8 +768,8 @@
}
size_t read_bytes =
m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch;
- fxcrt::spancpy(pdfium::make_span(m_Scanline).subspan(m_Pitch - bytes_to_go),
- pdfium::make_span(m_PredictBuffer).first(read_bytes));
+ fxcrt::spancpy(m_Scanline.subspan(m_Pitch - bytes_to_go),
+ m_PredictBuffer.first(read_bytes));
m_LeftOver += m_PredictPitch - read_bytes;
bytes_to_go -= read_bytes;
}