De-duplicate some code between ProgressiveDecoder and CStretchEngine.
The more complex code in CStretchEngine reduces[1] to the simplified
code in ProgressiveDecoder when the arguments are passed as indicated.
1. a bounded max size is now enforced.
Change-Id: I269459d384df23af63b502deef779c4c8e9d3f0e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/82133
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/progressive_decoder.cpp b/core/fxcodec/progressive_decoder.cpp
index 8d4e9d5..899e92a 100644
--- a/core/fxcodec/progressive_decoder.cpp
+++ b/core/fxcodec/progressive_decoder.cpp
@@ -64,79 +64,6 @@
} // namespace
-ProgressiveDecoder::WeightTable::WeightTable() = default;
-
-ProgressiveDecoder::WeightTable::~WeightTable() = default;
-
-void ProgressiveDecoder::WeightTable::CalculateWeights(int dest_len,
- int src_len) {
- CHECK_GE(dest_len, 0);
- double scale = static_cast<double>(src_len) / dest_len;
- const size_t weight_count = static_cast<size_t>(ceil(fabs(scale))) + 1;
- m_ItemSize = PixelWeight::TotalBytesForWeightCount(weight_count);
- FX_SAFE_SIZE_T safe_size = m_ItemSize;
- safe_size *= dest_len;
- m_pWeightTables.resize(safe_size.ValueOrDie());
- m_DestMin = 0;
- if (fabs(scale) < 1.0) {
- for (int dest_pixel = 0; dest_pixel < dest_len; dest_pixel++) {
- PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
- double src_pos = dest_pixel * scale + scale / 2;
- pixel_weights.m_SrcStart = (int)floor((float)src_pos - 1.0f / 2);
- pixel_weights.m_SrcEnd = (int)floor((float)src_pos + 1.0f / 2);
- pixel_weights.m_SrcStart = std::max(pixel_weights.m_SrcStart, 0);
- pixel_weights.m_SrcEnd = std::min(pixel_weights.m_SrcEnd, src_len - 1);
- if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
- pixel_weights.m_Weights[0] = 65536;
- } else {
- pixel_weights.m_Weights[1] = FXSYS_roundf(
- (float)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);
- pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
- }
- }
- return;
- }
- for (int dest_pixel = 0; dest_pixel < dest_len; dest_pixel++) {
- PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
- double src_start = dest_pixel * scale;
- double src_end = src_start + scale;
- int start_i;
- int end_i;
- if (src_start < src_end) {
- start_i = (int)floor((float)src_start);
- end_i = (int)ceil((float)src_end);
- } else {
- start_i = (int)floor((float)src_end);
- end_i = (int)ceil((float)src_start);
- }
- start_i = std::max(start_i, 0);
- end_i = std::min(end_i, src_len - 1);
- if (start_i > end_i) {
- pixel_weights.m_SrcStart = start_i;
- pixel_weights.m_SrcEnd = start_i;
- continue;
- }
- pixel_weights.m_SrcStart = start_i;
- pixel_weights.m_SrcEnd = end_i;
- for (int j = start_i; j <= end_i; j++) {
- double dest_start = ((float)j) / scale;
- double dest_end = ((float)(j + 1)) / scale;
- if (dest_start > dest_end) {
- std::swap(dest_start, dest_end);
- }
- double area_start = std::max(dest_start, static_cast<double>(dest_pixel));
- double area_end = std::min(dest_end, static_cast<double>(dest_pixel + 1));
- double weight = area_start >= area_end ? 0.0 : area_end - area_start;
- if (weight == 0 && j == end_i) {
- pixel_weights.m_SrcEnd--;
- break;
- }
- pixel_weights.m_Weights[j - start_i] =
- FXSYS_roundf((float)(weight * 65536));
- }
- }
-}
-
ProgressiveDecoder::HorzTable::HorzTable() = default;
ProgressiveDecoder::HorzTable::~HorzTable() = default;
@@ -792,7 +719,10 @@
GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
m_ScanlineSize = FxAlignToBoundary<4>(m_SrcWidth * m_SrcComponents);
m_pDecodeBuf.reset(FX_Alloc(uint8_t, m_ScanlineSize));
- m_WeightHorz.CalculateWeights(m_sizeX, m_clipBox.Width());
+ FXDIB_ResampleOptions options;
+ options.bInterpolateBilinear = true;
+ m_WeightHorz.CalculateWeights(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
+ m_clipBox.Width(), options);
m_WeightVert.CalculateWeights(m_sizeY, m_clipBox.Height());
m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
return m_status;
@@ -864,7 +794,10 @@
GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
int scanline_size = FxAlignToBoundary<4>(m_SrcWidth);
m_pDecodeBuf.reset(FX_Alloc(uint8_t, scanline_size));
- m_WeightHorz.CalculateWeights(m_sizeX, m_clipBox.Width());
+ FXDIB_ResampleOptions options;
+ options.bInterpolateBilinear = true;
+ m_WeightHorz.CalculateWeights(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
+ m_clipBox.Width(), options);
m_WeightVert.CalculateWeights(m_sizeY, m_clipBox.Height());
m_FrameCur = 0;
m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
@@ -1056,7 +989,10 @@
int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
scanline_size = FxAlignToBoundary<4>(scanline_size * m_SrcComponents);
m_pDecodeBuf.reset(FX_Alloc(uint8_t, scanline_size));
- m_WeightHorz.CalculateWeights(m_sizeX, m_clipBox.Width());
+ FXDIB_ResampleOptions options;
+ options.bInterpolateBilinear = true;
+ m_WeightHorz.CalculateWeights(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
+ m_clipBox.Width(), options);
m_WeightVert.CalculateWeights(m_sizeY, m_clipBox.Height());
switch (m_SrcComponents) {
case 1:
diff --git a/core/fxcodec/progressive_decoder.h b/core/fxcodec/progressive_decoder.h
index 1f25302..d8b4b78 100644
--- a/core/fxcodec/progressive_decoder.h
+++ b/core/fxcodec/progressive_decoder.h
@@ -17,6 +17,7 @@
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/retain_ptr.h"
+#include "core/fxge/dib/cstretchengine.h"
#include "core/fxge/dib/fx_dib.h"
#ifdef PDF_ENABLE_XFA_BMP
@@ -120,21 +121,7 @@
#endif // PDF_ENABLE_XFA_BMP
private:
- class WeightTable {
- public:
- WeightTable();
- ~WeightTable();
-
- void CalculateWeights(int dest_len, int src_len);
- PixelWeight* GetPixelWeight(int pixel) {
- return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() +
- (pixel - m_DestMin) * m_ItemSize);
- }
-
- int m_DestMin;
- int m_ItemSize;
- std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_pWeightTables;
- };
+ using WeightTable = CStretchEngine::CWeightTable;
class HorzTable {
public:
diff --git a/core/fxge/dib/cstretchengine.h b/core/fxge/dib/cstretchengine.h
index 79fc60b..600212f 100644
--- a/core/fxge/dib/cstretchengine.h
+++ b/core/fxge/dib/cstretchengine.h
@@ -40,7 +40,6 @@
return m_ResampleOptions;
}
- private:
class CWeightTable {
public:
CWeightTable();
@@ -69,6 +68,7 @@
std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_WeightTables;
};
+ private:
enum class State : uint8_t { kInitial, kHorizontal, kVertical };
enum class TransformMethod : uint8_t {