summaryrefslogtreecommitdiff
path: root/core/fxcodec
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcodec')
-rw-r--r--core/fxcodec/codec/ccodec_progressivedecoder.cpp67
-rw-r--r--core/fxcodec/codec/ccodec_progressivedecoder.h3
-rw-r--r--core/fxcodec/codec/cfx_codec_memory.cpp27
-rw-r--r--core/fxcodec/codec/cfx_codec_memory.h22
-rw-r--r--core/fxcodec/gif/cfx_gifcontext_unittest.cpp45
5 files changed, 74 insertions, 90 deletions
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.cpp b/core/fxcodec/codec/ccodec_progressivedecoder.cpp
index 07665c1d4a..9d375cbcf1 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder.cpp
+++ b/core/fxcodec/codec/ccodec_progressivedecoder.cpp
@@ -718,10 +718,7 @@ bool CCodec_ProgressiveDecoder::BmpDetectImageTypeInBuffer(
std::unique_ptr<CodecModuleIface::Context> pBmpContext =
pBmpModule->Start(this);
- pBmpModule->Input(pBmpContext.get(),
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
- nullptr);
+ pBmpModule->Input(pBmpContext.get(), m_pCodecMemory, nullptr);
std::vector<uint32_t> palette;
int32_t readResult = pBmpModule->ReadHeader(
@@ -866,10 +863,7 @@ bool CCodec_ProgressiveDecoder::GifDetectImageTypeInBuffer(
return false;
}
m_pGifContext = pGifModule->Start(this);
- pGifModule->Input(m_pGifContext.get(),
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
- nullptr);
+ pGifModule->Input(m_pGifContext.get(), m_pCodecMemory, nullptr);
m_SrcComponents = 1;
CFX_GifDecodeStatus readResult = pGifModule->ReadHeader(
m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
@@ -1052,10 +1046,8 @@ bool CCodec_ProgressiveDecoder::JpegDetectImageTypeInBuffer(
m_status = FXCODEC_STATUS_ERR_MEMORY;
return false;
}
- pJpegModule->Input(m_pJpegContext.get(),
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
- nullptr);
+ pJpegModule->Input(m_pJpegContext.get(), m_pCodecMemory, nullptr);
+
// Setting jump marker before calling ReadHeader, since a longjmp to
// the marker indicates a fatal error.
if (setjmp(*pJpegModule->GetJumpMark(m_pJpegContext.get())) == -1) {
@@ -1264,12 +1256,7 @@ bool CCodec_ProgressiveDecoder::PngDetectImageTypeInBuffer(
m_status = FXCODEC_STATUS_ERR_MEMORY;
return false;
}
- bool bResult =
- pPngModule->Input(m_pPngContext.get(),
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
- pAttribute);
- while (bResult) {
+ while (pPngModule->Input(m_pPngContext.get(), m_pCodecMemory, pAttribute)) {
uint32_t remain_size = static_cast<uint32_t>(m_pFile->GetSize()) - m_offSet;
uint32_t input_size =
remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
@@ -1278,21 +1265,16 @@ bool CCodec_ProgressiveDecoder::PngDetectImageTypeInBuffer(
m_status = FXCODEC_STATUS_ERR_FORMAT;
return false;
}
- if (m_pSrcBuf && input_size > m_SrcSize) {
- m_pSrcBuf.reset(FX_Alloc(uint8_t, input_size));
+ if (m_pCodecMemory && input_size > m_SrcSize) {
+ m_pCodecMemory = pdfium::MakeRetain<CFX_CodecMemory>(input_size);
m_SrcSize = input_size;
}
- bResult = m_pFile->ReadBlock(m_pSrcBuf.get(), m_offSet, input_size);
- if (!bResult) {
+ if (!m_pFile->ReadBlock(m_pCodecMemory->GetBuffer(), m_offSet,
+ input_size)) {
m_status = FXCODEC_STATUS_ERR_READ;
return false;
}
m_offSet += input_size;
- bResult =
- pPngModule->Input(m_pPngContext.get(),
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), input_size)),
- pAttribute);
}
m_pPngContext.reset();
if (m_SrcPassNumber == 0) {
@@ -1367,11 +1349,12 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::PngContinueDecode() {
m_status = FXCODEC_STATUS_DECODE_FINISH;
return m_status;
}
- if (m_pSrcBuf && input_size > m_SrcSize) {
- m_pSrcBuf.reset(FX_Alloc(uint8_t, input_size));
+ if (m_pCodecMemory && input_size > m_SrcSize) {
+ m_pCodecMemory = pdfium::MakeRetain<CFX_CodecMemory>(input_size);
m_SrcSize = input_size;
}
- bool bResult = m_pFile->ReadBlock(m_pSrcBuf.get(), m_offSet, input_size);
+ bool bResult =
+ m_pFile->ReadBlock(m_pCodecMemory->GetBuffer(), m_offSet, input_size);
if (!bResult) {
m_pDeviceBitmap = nullptr;
m_pFile = nullptr;
@@ -1379,11 +1362,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::PngContinueDecode() {
return m_status;
}
m_offSet += input_size;
- bResult =
- pPngModule->Input(m_pPngContext.get(),
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), input_size)),
- nullptr);
+ bResult = pPngModule->Input(m_pPngContext.get(), m_pCodecMemory, nullptr);
if (!bResult) {
m_pDeviceBitmap = nullptr;
m_pFile = nullptr;
@@ -1570,10 +1549,9 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
size_t size = std::min<size_t>(m_pFile->GetSize(), FXCODEC_BLOCK_SIZE);
m_SrcSize = static_cast<uint32_t>(size);
- m_pSrcBuf.reset(FX_Alloc(uint8_t, m_SrcSize));
-
+ m_pCodecMemory = pdfium::MakeRetain<CFX_CodecMemory>(m_SrcSize);
m_offSet = 0;
- if (!m_pFile->ReadBlock(m_pSrcBuf.get(), m_offSet, m_SrcSize)) {
+ if (!m_pFile->ReadBlock(m_pCodecMemory->GetBuffer(), m_offSet, m_SrcSize)) {
m_status = FXCODEC_STATUS_ERR_READ;
return false;
}
@@ -1629,31 +1607,26 @@ bool CCodec_ProgressiveDecoder::ReadMoreData(
dwBytesToFetchFromFile =
std::min<uint32_t>(dwBytesToFetchFromFile, FXCODEC_BLOCK_SIZE);
uint32_t dwNewSize = m_SrcSize + dwBytesToFetchFromFile;
- uint8_t* pNewBuf = FX_TryRealloc(uint8_t, m_pSrcBuf.release(), dwNewSize);
- if (!pNewBuf) {
+ if (!m_pCodecMemory->TryResize(dwNewSize)) {
err_status = FXCODEC_STATUS_ERR_MEMORY;
return false;
}
m_SrcSize = dwNewSize;
- m_pSrcBuf.reset(pNewBuf);
} else {
uint32_t dwConsumed = m_SrcSize - dwUnconsumed;
- memmove(m_pSrcBuf.get(), m_pSrcBuf.get() + dwConsumed, dwUnconsumed);
+ m_pCodecMemory->Consume(dwConsumed);
dwBytesToFetchFromFile = std::min(dwBytesToFetchFromFile, dwConsumed);
m_SrcSize = dwBytesToFetchFromFile + dwUnconsumed;
}
// Append new data past the bytes not yet processed by the codec.
- if (!m_pFile->ReadBlock(m_pSrcBuf.get() + dwUnconsumed, m_offSet,
+ if (!m_pFile->ReadBlock(m_pCodecMemory->GetBuffer() + dwUnconsumed, m_offSet,
dwBytesToFetchFromFile)) {
err_status = FXCODEC_STATUS_ERR_READ;
return false;
}
m_offSet += dwBytesToFetchFromFile;
- return pModule->Input(pContext,
- pdfium::MakeRetain<CFX_CodecMemory>(
- pdfium::make_span(m_pSrcBuf.get(), m_SrcSize)),
- nullptr);
+ return pModule->Input(pContext, m_pCodecMemory, nullptr);
}
FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h
index 9821c67f4f..d0419f8268 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder.h
+++ b/core/fxcodec/codec/ccodec_progressivedecoder.h
@@ -251,8 +251,7 @@ class CCodec_ProgressiveDecoder :
RetainPtr<IFX_SeekableReadStream> m_pFile;
RetainPtr<CFX_DIBitmap> m_pDeviceBitmap;
UnownedPtr<CCodec_ModuleMgr> m_pCodecMgr;
- // |m_pSrcBuf| must outlive |m_pGifContext|.
- std::unique_ptr<uint8_t, FxFreeDeleter> m_pSrcBuf;
+ RetainPtr<CFX_CodecMemory> m_pCodecMemory;
std::unique_ptr<uint8_t, FxFreeDeleter> m_pDecodeBuf;
std::unique_ptr<FX_ARGB, FxFreeDeleter> m_pSrcPalette;
std::unique_ptr<CodecModuleIface::Context> m_pJpegContext;
diff --git a/core/fxcodec/codec/cfx_codec_memory.cpp b/core/fxcodec/codec/cfx_codec_memory.cpp
index b8cf97b098..640db12415 100644
--- a/core/fxcodec/codec/cfx_codec_memory.cpp
+++ b/core/fxcodec/codec/cfx_codec_memory.cpp
@@ -6,13 +6,13 @@
#include <algorithm>
-CFX_CodecMemory::CFX_CodecMemory(pdfium::span<uint8_t> buffer)
- : buffer_(buffer) {}
+CFX_CodecMemory::CFX_CodecMemory(size_t buffer_size)
+ : buffer_(FX_Alloc(uint8_t, buffer_size)), size_(buffer_size) {}
CFX_CodecMemory::~CFX_CodecMemory() = default;
bool CFX_CodecMemory::Seek(size_t pos) {
- if (pos > buffer_.size())
+ if (pos > size_)
return false;
pos_ = pos;
@@ -23,8 +23,25 @@ size_t CFX_CodecMemory::ReadBlock(void* buffer, size_t size) {
if (!buffer || !size || IsEOF())
return 0;
- size_t bytes_to_read = std::min(size, buffer_.size() - pos_);
- memcpy(buffer, &buffer_[pos_], bytes_to_read);
+ size_t bytes_to_read = std::min(size, size_ - pos_);
+ memcpy(buffer, buffer_.get() + pos_, bytes_to_read);
pos_ += bytes_to_read;
return bytes_to_read;
}
+
+bool CFX_CodecMemory::TryResize(size_t new_buffer_size) {
+ uint8_t* pOldBuf = buffer_.release();
+ uint8_t* pNewBuf = FX_TryRealloc(uint8_t, pOldBuf, new_buffer_size);
+ if (!pNewBuf) {
+ buffer_.reset(pOldBuf);
+ return false;
+ }
+ buffer_.reset(pNewBuf);
+ size_ = new_buffer_size;
+ return true;
+}
+
+void CFX_CodecMemory::Consume(size_t consumed) {
+ size_t unconsumed = size_ - consumed;
+ memmove(buffer_.get(), buffer_.get() + consumed, unconsumed);
+}
diff --git a/core/fxcodec/codec/cfx_codec_memory.h b/core/fxcodec/codec/cfx_codec_memory.h
index 0d11d41de8..fa26e240ec 100644
--- a/core/fxcodec/codec/cfx_codec_memory.h
+++ b/core/fxcodec/codec/cfx_codec_memory.h
@@ -5,6 +5,9 @@
#ifndef CORE_FXCODEC_CODEC_CFX_CODEC_MEMORY_H_
#define CORE_FXCODEC_CODEC_CFX_CODEC_MEMORY_H_
+#include <memory>
+
+#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/retain_ptr.h"
#include "third_party/base/span.h"
@@ -13,21 +16,28 @@ class CFX_CodecMemory final : public Retainable {
template <typename T, typename... Args>
friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
- pdfium::span<uint8_t> GetSpan() { return buffer_; }
- uint8_t* GetBuffer() { return buffer_.data(); }
- size_t GetSize() const { return buffer_.size(); }
+ pdfium::span<uint8_t> GetSpan() { return {buffer_.get(), size_}; }
+ uint8_t* GetBuffer() { return buffer_.get(); }
+ size_t GetSize() const { return size_; }
size_t GetPosition() const { return pos_; }
- bool IsEOF() const { return pos_ >= buffer_.size(); }
+ bool IsEOF() const { return pos_ >= size_; }
size_t ReadBlock(void* buffer, size_t size);
// Sets the cursor position to |pos| if possible.
bool Seek(size_t pos);
+ // Try to change the size of the buffer, keep the old one on failure.
+ bool TryResize(size_t new_buffer_size);
+
+ // Schlep the bytes down the buffer.
+ void Consume(size_t consumed);
+
private:
- explicit CFX_CodecMemory(pdfium::span<uint8_t> buffer);
+ explicit CFX_CodecMemory(size_t buffer_size);
~CFX_CodecMemory() override;
- pdfium::span<uint8_t> const buffer_;
+ std::unique_ptr<uint8_t, FxFreeDeleter> buffer_;
+ size_t size_ = 0;
size_t pos_ = 0;
};
diff --git a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
index 24b8acd769..9b081a4183 100644
--- a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp
@@ -4,6 +4,8 @@
#include "core/fxcodec/gif/cfx_gifcontext.h"
+#include <utility>
+
#include "testing/gtest/include/gtest/gtest.h"
class CFX_GifContextForTest final : public CFX_GifContext {
@@ -19,49 +21,33 @@ class CFX_GifContextForTest final : public CFX_GifContext {
CFX_CodecMemory* InputBuffer() const { return input_buffer_.Get(); }
void SetTestInputBuffer(pdfium::span<uint8_t> input) {
- SetInputBuffer(pdfium::MakeRetain<CFX_CodecMemory>(input));
+ auto pMemory = pdfium::MakeRetain<CFX_CodecMemory>(input.size());
+ memcpy(pMemory->GetBuffer(), input.data(), input.size());
+ SetInputBuffer(std::move(pMemory));
}
};
TEST(CFX_GifContext, SetInputBuffer) {
uint8_t buffer[] = {0x00, 0x01, 0x02};
- {
- // Context must not outlive its buffers.
- CFX_GifContextForTest context(nullptr, nullptr);
-
- context.SetTestInputBuffer({nullptr, 0});
- EXPECT_EQ(nullptr, context.InputBuffer()->GetBuffer());
- EXPECT_EQ(0u, context.InputBuffer()->GetSize());
- EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
-
- context.SetTestInputBuffer({nullptr, 100});
- EXPECT_EQ(nullptr, context.InputBuffer()->GetBuffer());
- EXPECT_EQ(100u, context.InputBuffer()->GetSize());
- EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
+ CFX_GifContextForTest context(nullptr, nullptr);
- context.SetTestInputBuffer({buffer, 0});
- EXPECT_EQ(buffer, context.InputBuffer()->GetBuffer());
- EXPECT_EQ(0u, context.InputBuffer()->GetSize());
- EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
+ context.SetTestInputBuffer({nullptr, 0});
+ EXPECT_EQ(0u, context.InputBuffer()->GetSize());
+ EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
- context.SetTestInputBuffer({buffer, 3});
- EXPECT_EQ(buffer, context.InputBuffer()->GetBuffer());
- EXPECT_EQ(3u, context.InputBuffer()->GetSize());
- EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
+ context.SetTestInputBuffer({buffer, 0});
+ EXPECT_EQ(0u, context.InputBuffer()->GetSize());
+ EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
- context.SetTestInputBuffer({buffer, 100});
- EXPECT_EQ(buffer, context.InputBuffer()->GetBuffer());
- EXPECT_EQ(100u, context.InputBuffer()->GetSize());
- EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
- }
+ context.SetTestInputBuffer({buffer, 3});
+ EXPECT_EQ(3u, context.InputBuffer()->GetSize());
+ EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
}
TEST(CFX_GifContext, ReadAllOrNone) {
std::vector<uint8_t> dest_buffer;
uint8_t src_buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09};
- {
- // Context must not outlive its buffers.
CFX_GifContextForTest context(nullptr, nullptr);
context.SetTestInputBuffer({nullptr, 0});
@@ -94,7 +80,6 @@ TEST(CFX_GifContext, ReadAllOrNone) {
EXPECT_TRUE(context.ReadAllOrNone(dest_buffer.data(), 1));
EXPECT_EQ(src_buffer[i], dest_buffer[0]);
}
- }
}
TEST(CFX_GifContext, ReadGifSignature) {