47 RetainPtr<
const CPDF_Stream> pStream(pObj->AsStream());
51 RetainPtr<
const CPDF_Dictionary> pDict = pStream->GetDict();
52 RetainPtr<
const CPDF_Array> pSize = pDict->GetArrayFor(
"Size");
53 if (!pSize || pSize->IsEmpty())
56 m_nBitsPerSample = pDict->GetIntegerFor(
"BitsPerSample");
57 if (!IsValidBitsPerSample(m_nBitsPerSample))
60 FX_SAFE_UINT32 nTotalSampleBits = m_nBitsPerSample;
62 RetainPtr<
const CPDF_Array> pEncode = pDict->GetArrayFor(
"Encode");
63 m_EncodeInfo.resize(m_nInputs);
64 for (uint32_t i = 0; i <
m_nInputs; i++) {
65 int size = pSize->GetIntegerAt(i);
69 m_EncodeInfo[i].sizes = size;
70 nTotalSampleBits *= m_EncodeInfo[i].sizes;
72 m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
73 m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
75 m_EncodeInfo[i].encode_min = 0;
76 m_EncodeInfo[i].encode_max =
77 m_EncodeInfo[i].sizes == 1 ? 1 : m_EncodeInfo[i].sizes - 1;
80 FX_SAFE_UINT32 nTotalSampleBytes = (nTotalSampleBits + 7) / 8;
81 if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0)
84 m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample);
85 m_pSampleStream = pdfium::MakeRetain<CPDF_StreamAcc>(std::move(pStream));
86 m_pSampleStream->LoadAllDataFiltered();
87 if (nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize())
90 RetainPtr<
const CPDF_Array> pDecode = pDict->GetArrayFor(
"Decode");
91 m_DecodeInfo.resize(m_nOutputs);
94 m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
95 m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
97 m_DecodeInfo[i].decode_min = m_Ranges[i * 2];
98 m_DecodeInfo[i].decode_max = m_Ranges[i * 2 + 1];
104bool CPDF_SampledFunc::
v_Call(pdfium::span<
const float> inputs,
105 pdfium::span<
float> results)
const {
107 absl::InlinedVector<
float, 16, FxAllocAllocator<
float>> encoded_input_buf(
109 absl::InlinedVector<uint32_t, 32, FxAllocAllocator<uint32_t>> int_buf(
111 float* encoded_input = encoded_input_buf.data();
112 uint32_t* index = int_buf.data();
114 for (uint32_t i = 0; i <
m_nInputs; i++) {
118 blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes;
120 Interpolate(inputs[i], m_Domains[i * 2], m_Domains[i * 2 + 1],
121 m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max);
122 index[i] = std::clamp(
static_cast<uint32_t>(encoded_input[i]), 0U,
123 m_EncodeInfo[i].sizes - 1);
124 pos += index[i] * blocksize[i];
126 FX_SAFE_INT32 bits_to_output = m_nOutputs;
127 bits_to_output *= m_nBitsPerSample;
128 if (!bits_to_output.IsValid())
133 FX_SAFE_INT32 bitpos = pos;
134 bitpos *= bits_to_output.ValueOrDie();
135 bits_to_skip = bitpos.ValueOrDefault(-1);
136 if (bits_to_skip < 0)
139 FX_SAFE_INT32 range_check = bitpos;
140 range_check += bits_to_output.ValueOrDie();
141 if (!range_check.IsValid())
145 pdfium::span<
const uint8_t> pSampleData = m_pSampleStream->GetSpan();
146 if (pSampleData.empty())
150 bitstream.SkipBits(bits_to_skip);
152 uint32_t sample = bitstream
.GetBits(m_nBitsPerSample
);
153 float encoded = sample;
154 for (uint32_t j = 0; j <
m_nInputs; ++j) {
155 if (index[j] == m_EncodeInfo[j].sizes - 1) {
157 encoded = encoded_input[j] * sample;
159 FX_SAFE_INT32 bitpos2 = blocksize[j];
163 bitpos2 *= m_nBitsPerSample;
164 int bits_to_skip2 = bitpos2.ValueOrDefault(-1);
165 if (bits_to_skip2 < 0)
169 bitstream2.SkipBits(bits_to_skip2);
171 static_cast<
float>(bitstream2
.GetBits(m_nBitsPerSample
));
172 encoded += (encoded_input[j] - index[j]) * (sample2 - sample);
176 Interpolate(encoded, 0, m_SampleMax, m_DecodeInfo[i].decode_min,
177 m_DecodeInfo[i].decode_max);