From d801c9c9caddf3941f6844fab58b19261d7d3cad Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Mon, 13 Aug 2018 20:36:16 +0000 Subject: Implement CFX_CodecMemory. This class is much simpler than CFX_MemoryStream and does only what CFX_BmpDecompressor and CFX_GifContext needs. Swap out CFX_MemoryStream and remove CFX_MemoryStream::Seek(). BUG=pdfium:263 Change-Id: Ifd8ce4d2b6c9fedd6ec842d46f54fc8e654fbca7 Reviewed-on: https://pdfium-review.googlesource.com/39880 Commit-Queue: Lei Zhang Reviewed-by: Ryan Harrison --- BUILD.gn | 6 +++ core/fxcodec/bmp/cfx_bmpdecompressor.cpp | 4 +- core/fxcodec/bmp/cfx_bmpdecompressor.h | 4 +- core/fxcodec/codec/cfx_codec_memory.cpp | 30 +++++++++++++ core/fxcodec/codec/cfx_codec_memory.h | 33 ++++++++++++++ core/fxcodec/gif/cfx_gifcontext.cpp | 3 +- core/fxcodec/gif/cfx_gifcontext.h | 5 ++- core/fxcodec/gif/cfx_gifcontext_unittest.cpp | 66 +++++++++++++--------------- core/fxcrt/cfx_memorystream.cpp | 8 ---- core/fxcrt/cfx_memorystream.h | 3 -- 10 files changed, 107 insertions(+), 55 deletions(-) create mode 100644 core/fxcodec/codec/cfx_codec_memory.cpp create mode 100644 core/fxcodec/codec/cfx_codec_memory.h diff --git a/BUILD.gn b/BUILD.gn index c3576b49b4..4fbb2932ad 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -824,6 +824,12 @@ jumbo_static_library("fxcodec") { ] deps += [ "third_party:fx_tiff" ] } + if (pdf_enable_xfa_bmp || pdf_enable_xfa_gif) { + sources += [ + "core/fxcodec/codec/cfx_codec_memory.cpp", + "core/fxcodec/codec/cfx_codec_memory.h", + ] + } } } diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp index c56d17d15d..739853aa13 100644 --- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp +++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp @@ -10,6 +10,7 @@ #include #include "core/fxcodec/bmp/cfx_bmpcontext.h" +#include "core/fxcrt/fx_safe_types.h" #include "core/fxcrt/fx_system.h" #include "third_party/base/logging.h" #include "third_party/base/numerics/safe_math.h" @@ -659,8 +660,7 @@ void CFX_BmpDecompressor::SaveDecodingStatus(int32_t status) { } void CFX_BmpDecompressor::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) { - input_buffer_ = - pdfium::MakeRetain(src_buf, src_size, false); + input_buffer_ = pdfium::MakeRetain(src_buf, src_size); } FX_FILESIZE CFX_BmpDecompressor::GetAvailInput(uint8_t** avail_buf) { diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.h b/core/fxcodec/bmp/cfx_bmpdecompressor.h index 2f1585e649..519297881a 100644 --- a/core/fxcodec/bmp/cfx_bmpdecompressor.h +++ b/core/fxcodec/bmp/cfx_bmpdecompressor.h @@ -14,7 +14,7 @@ #include #include -#include "core/fxcrt/cfx_memorystream.h" +#include "core/fxcodec/codec/cfx_codec_memory.h" class CFX_BmpContext; @@ -69,7 +69,7 @@ class CFX_BmpDecompressor { bool ValidateFlag() const; void SetHeight(int32_t signed_height); - RetainPtr input_buffer_; + RetainPtr input_buffer_; }; #endif // CORE_FXCODEC_BMP_CFX_BMPDECOMPRESSOR_H_ diff --git a/core/fxcodec/codec/cfx_codec_memory.cpp b/core/fxcodec/codec/cfx_codec_memory.cpp new file mode 100644 index 0000000000..8eac02c9ee --- /dev/null +++ b/core/fxcodec/codec/cfx_codec_memory.cpp @@ -0,0 +1,30 @@ +// Copyright 2018 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fxcodec/codec/cfx_codec_memory.h" + +#include + +CFX_CodecMemory::CFX_CodecMemory(uint8_t* buffer, size_t size) + : buffer_(buffer), size_(size) {} + +CFX_CodecMemory::~CFX_CodecMemory() = default; + +bool CFX_CodecMemory::Seek(size_t pos) { + if (pos > size_) + return false; + + pos_ = pos; + return true; +} + +size_t CFX_CodecMemory::ReadBlock(void* buffer, size_t size) { + if (!buffer || !size || IsEOF()) + return 0; + + size_t bytes_to_read = std::min(size, size_ - pos_); + memcpy(buffer, &buffer_[pos_], bytes_to_read); + pos_ += bytes_to_read; + return bytes_to_read; +} diff --git a/core/fxcodec/codec/cfx_codec_memory.h b/core/fxcodec/codec/cfx_codec_memory.h new file mode 100644 index 0000000000..6eee72a32d --- /dev/null +++ b/core/fxcodec/codec/cfx_codec_memory.h @@ -0,0 +1,33 @@ +// Copyright 2018 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CORE_FXCODEC_CODEC_CFX_CODEC_MEMORY_H_ +#define CORE_FXCODEC_CODEC_CFX_CODEC_MEMORY_H_ + +#include "core/fxcrt/retain_ptr.h" + +class CFX_CodecMemory : public Retainable { + public: + template + friend RetainPtr pdfium::MakeRetain(Args&&... args); + + uint8_t* GetBuffer() { return buffer_; } + size_t GetSize() const { return size_; } + size_t GetPosition() const { return pos_; } + 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); + + private: + CFX_CodecMemory(uint8_t* buffer, size_t size); + ~CFX_CodecMemory() override; + + uint8_t* const buffer_; + const size_t size_; + size_t pos_ = 0; +}; + +#endif // CORE_FXCODEC_CODEC_CFX_CODEC_MEMORY_H_ diff --git a/core/fxcodec/gif/cfx_gifcontext.cpp b/core/fxcodec/gif/cfx_gifcontext.cpp index 44c2c654f0..4083072fbe 100644 --- a/core/fxcodec/gif/cfx_gifcontext.cpp +++ b/core/fxcodec/gif/cfx_gifcontext.cpp @@ -343,8 +343,7 @@ CFX_GifDecodeStatus CFX_GifContext::LoadFrame(int32_t frame_num) { } void CFX_GifContext::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) { - input_buffer_ = - pdfium::MakeRetain(src_buf, src_size, false); + input_buffer_ = pdfium::MakeRetain(src_buf, src_size); } uint32_t CFX_GifContext::GetAvailInput(uint8_t** avail_buf) const { diff --git a/core/fxcodec/gif/cfx_gifcontext.h b/core/fxcodec/gif/cfx_gifcontext.h index d9bcf4950d..f96cf058b2 100644 --- a/core/fxcodec/gif/cfx_gifcontext.h +++ b/core/fxcodec/gif/cfx_gifcontext.h @@ -11,9 +11,9 @@ #include #include "core/fxcodec/codec/ccodec_gifmodule.h" +#include "core/fxcodec/codec/cfx_codec_memory.h" #include "core/fxcodec/gif/cfx_gif.h" #include "core/fxcodec/gif/cfx_lzwdecompressor.h" -#include "core/fxcrt/cfx_memorystream.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/unowned_ptr.h" @@ -66,7 +66,8 @@ class CFX_GifContext : public CCodec_GifModule::Context { bool ReadData(uint8_t* dest, uint32_t size); CFX_GifDecodeStatus ReadGifSignature(); CFX_GifDecodeStatus ReadLogicalScreenDescriptor(); - RetainPtr input_buffer_; + + RetainPtr input_buffer_; private: void SaveDecodingStatus(int32_t status); diff --git a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp index 20aa6913d0..d6cfa1fd0d 100644 --- a/core/fxcodec/gif/cfx_gifcontext_unittest.cpp +++ b/core/fxcodec/gif/cfx_gifcontext_unittest.cpp @@ -18,7 +18,7 @@ class CFX_GifContextForTest : public CFX_GifContext { using CFX_GifContext::ReadGifSignature; using CFX_GifContext::ReadLogicalScreenDescriptor; - CFX_MemoryStream* InputBuffer() const { return input_buffer_.Get(); } + CFX_CodecMemory* InputBuffer() const { return input_buffer_.Get(); } }; TEST(CFX_GifContext, SetInputBuffer) { @@ -26,29 +26,29 @@ TEST(CFX_GifContext, SetInputBuffer) { context.SetInputBuffer(nullptr, 0); EXPECT_EQ(nullptr, context.InputBuffer()->GetBuffer()); - EXPECT_EQ(0, context.InputBuffer()->GetSize()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(0u, context.InputBuffer()->GetSize()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); context.SetInputBuffer(nullptr, 100); EXPECT_EQ(nullptr, context.InputBuffer()->GetBuffer()); - EXPECT_EQ(100, context.InputBuffer()->GetSize()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(100u, context.InputBuffer()->GetSize()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); uint8_t buffer[] = {0x00, 0x01, 0x02}; context.SetInputBuffer(buffer, 0); EXPECT_EQ(buffer, context.InputBuffer()->GetBuffer()); - EXPECT_EQ(0, context.InputBuffer()->GetSize()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(0u, context.InputBuffer()->GetSize()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); context.SetInputBuffer(buffer, 3); EXPECT_EQ(buffer, context.InputBuffer()->GetBuffer()); - EXPECT_EQ(3, context.InputBuffer()->GetSize()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(3u, context.InputBuffer()->GetSize()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); context.SetInputBuffer(buffer, 100); EXPECT_EQ(buffer, context.InputBuffer()->GetBuffer()); - EXPECT_EQ(100, context.InputBuffer()->GetSize()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(100u, context.InputBuffer()->GetSize()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); } TEST(CFX_GifContext, ReadData) { @@ -70,7 +70,7 @@ TEST(CFX_GifContext, ReadData) { context.SetInputBuffer(src_buffer, 1); EXPECT_FALSE(context.ReadData(dest_buffer.data(), sizeof(src_buffer))); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); EXPECT_FALSE(context.ReadData(nullptr, sizeof(src_buffer))); EXPECT_FALSE(context.ReadData(nullptr, 1)); EXPECT_TRUE(context.ReadData(dest_buffer.data(), 1)); @@ -96,48 +96,48 @@ TEST(CFX_GifContext, ReadGifSignature) { uint8_t data[1]; context.SetInputBuffer(data, 0); EXPECT_EQ(CFX_GifDecodeStatus::Unfinished, context.ReadGifSignature()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); } // Make sure testing the entire signature { uint8_t data[] = {'G', 'I', 'F'}; context.SetInputBuffer(data, sizeof(data)); EXPECT_EQ(CFX_GifDecodeStatus::Unfinished, context.ReadGifSignature()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); } { uint8_t data[] = {'N', 'O', 'T', 'G', 'I', 'F'}; context.SetInputBuffer(data, sizeof(data)); EXPECT_EQ(CFX_GifDecodeStatus::Error, context.ReadGifSignature()); - EXPECT_EQ(6, context.InputBuffer()->GetPosition()); + EXPECT_EQ(6u, context.InputBuffer()->GetPosition()); } // Make sure not matching GIF8*a { uint8_t data[] = {'G', 'I', 'F', '8', '0', 'a'}; context.SetInputBuffer(data, sizeof(data)); EXPECT_EQ(CFX_GifDecodeStatus::Error, context.ReadGifSignature()); - EXPECT_EQ(6, context.InputBuffer()->GetPosition()); + EXPECT_EQ(6u, context.InputBuffer()->GetPosition()); } // Make sure not matching GIF**a { uint8_t data[] = {'G', 'I', 'F', '9', '2', 'a'}; context.SetInputBuffer(data, sizeof(data)); EXPECT_EQ(CFX_GifDecodeStatus::Error, context.ReadGifSignature()); - EXPECT_EQ(6, context.InputBuffer()->GetPosition()); + EXPECT_EQ(6u, context.InputBuffer()->GetPosition()); } // One valid signature { uint8_t data[] = {'G', 'I', 'F', '8', '7', 'a'}; context.SetInputBuffer(data, sizeof(data)); EXPECT_EQ(CFX_GifDecodeStatus::Success, context.ReadGifSignature()); - EXPECT_EQ(6, context.InputBuffer()->GetPosition()); + EXPECT_EQ(6u, context.InputBuffer()->GetPosition()); } // The other valid signature { uint8_t data[] = {'G', 'I', 'F', '8', '9', 'a'}; context.SetInputBuffer(data, sizeof(data)); EXPECT_EQ(CFX_GifDecodeStatus::Success, context.ReadGifSignature()); - EXPECT_EQ(6, context.InputBuffer()->GetPosition()); + EXPECT_EQ(6u, context.InputBuffer()->GetPosition()); } } @@ -190,7 +190,7 @@ TEST(CFX_GifContext, ReadLocalScreenDescriptor) { EXPECT_EQ(CFX_GifDecodeStatus::Unfinished, context.ReadLogicalScreenDescriptor()); - EXPECT_EQ(0, context.InputBuffer()->GetPosition()); + EXPECT_EQ(0u, context.InputBuffer()->GetPosition()); } // LSD with global palette { @@ -204,8 +204,7 @@ TEST(CFX_GifContext, ReadLocalScreenDescriptor) { EXPECT_EQ(CFX_GifDecodeStatus::Success, context.ReadLogicalScreenDescriptor()); - EXPECT_EQ(sizeof(data), - static_cast(context.InputBuffer()->GetPosition())); + EXPECT_EQ(sizeof(data), context.InputBuffer()->GetPosition()); EXPECT_EQ(0x000A, context.width_); EXPECT_EQ(0x0F00, context.height_); EXPECT_EQ(1u, context.bc_index_); @@ -214,8 +213,8 @@ TEST(CFX_GifContext, ReadLocalScreenDescriptor) { EXPECT_EQ(1u, context.global_pal_exp_); EXPECT_EQ(1, context.global_sort_flag_); EXPECT_EQ(2, context.global_color_resolution_); - EXPECT_TRUE(0 == memcmp(data.palette, context.global_palette_.data(), - sizeof(data.palette))); + EXPECT_EQ(0, memcmp(data.palette, context.global_palette_.data(), + sizeof(data.palette))); } } @@ -232,8 +231,7 @@ TEST(CFX_GifContext, ReadHeader) { EXPECT_EQ(CFX_GifDecodeStatus::Error, context.ReadHeader()); - EXPECT_EQ(sizeof(data.signature), - static_cast(context.InputBuffer()->GetPosition())); + EXPECT_EQ(sizeof(data.signature), context.InputBuffer()->GetPosition()); } // Short after signature { @@ -243,8 +241,7 @@ TEST(CFX_GifContext, ReadHeader) { EXPECT_EQ(CFX_GifDecodeStatus::Unfinished, context.ReadHeader()); - EXPECT_EQ(sizeof(signature), - static_cast(context.InputBuffer()->GetPosition())); + EXPECT_EQ(sizeof(signature), context.InputBuffer()->GetPosition()); } // Success without global palette { @@ -257,8 +254,7 @@ TEST(CFX_GifContext, ReadHeader) { EXPECT_EQ(CFX_GifDecodeStatus::Success, context.ReadHeader()); - EXPECT_EQ(sizeof(data), - static_cast(context.InputBuffer()->GetPosition())); + EXPECT_EQ(sizeof(data), context.InputBuffer()->GetPosition()); EXPECT_EQ(0x000A, context.width_); EXPECT_EQ(0x0F00, context.height_); EXPECT_EQ(0u, context.bc_index_); // bc_index_ is 0 if no global palette @@ -275,8 +271,7 @@ TEST(CFX_GifContext, ReadHeader) { EXPECT_EQ(CFX_GifDecodeStatus::Unfinished, context.ReadHeader()); - EXPECT_EQ(sizeof(data.signature), - static_cast(context.InputBuffer()->GetPosition())); + EXPECT_EQ(sizeof(data.signature), context.InputBuffer()->GetPosition()); } // Success with global palette { @@ -291,8 +286,7 @@ TEST(CFX_GifContext, ReadHeader) { EXPECT_EQ(CFX_GifDecodeStatus::Success, context.ReadHeader()); - EXPECT_EQ(sizeof(data), - static_cast(context.InputBuffer()->GetPosition())); + EXPECT_EQ(sizeof(data), context.InputBuffer()->GetPosition()); EXPECT_EQ(0x000A, context.width_); EXPECT_EQ(0x0F00, context.height_); EXPECT_EQ(1u, context.bc_index_); @@ -300,7 +294,7 @@ TEST(CFX_GifContext, ReadHeader) { EXPECT_EQ(1u, context.global_pal_exp_); EXPECT_EQ(1, context.global_sort_flag_); EXPECT_EQ(2, context.global_color_resolution_); - EXPECT_TRUE(0 == memcmp(data.palette, context.global_palette_.data(), - sizeof(data.palette))); + EXPECT_EQ(0, memcmp(data.palette, context.global_palette_.data(), + sizeof(data.palette))); } } diff --git a/core/fxcrt/cfx_memorystream.cpp b/core/fxcrt/cfx_memorystream.cpp index 8073d375da..15cde78f42 100644 --- a/core/fxcrt/cfx_memorystream.cpp +++ b/core/fxcrt/cfx_memorystream.cpp @@ -146,14 +146,6 @@ bool CFX_MemoryStream::WriteBlock(const void* buffer, return true; } -bool CFX_MemoryStream::Seek(size_t pos) { - if (pos > m_nCurSize) - return false; - - m_nCurPos = pos; - return true; -} - bool CFX_MemoryStream::ExpandBlocks(size_t size) { m_nCurSize = std::max(m_nCurSize, size); if (size <= m_nTotalSize) diff --git a/core/fxcrt/cfx_memorystream.h b/core/fxcrt/cfx_memorystream.h index 3726b897c4..cd89c629fc 100644 --- a/core/fxcrt/cfx_memorystream.h +++ b/core/fxcrt/cfx_memorystream.h @@ -26,9 +26,6 @@ class CFX_MemoryStream : public IFX_SeekableStream { bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override; bool Flush() override; - // Sets the cursor position to |pos| if possible - bool Seek(size_t pos); - uint8_t* GetBuffer() { return !m_Blocks.empty() ? m_Blocks.front() : nullptr; } -- cgit v1.2.3