diff options
-rw-r--r-- | core/fxcodec/codec/ccodec_tiffmodule.cpp | 102 |
1 files changed, 55 insertions, 47 deletions
diff --git a/core/fxcodec/codec/ccodec_tiffmodule.cpp b/core/fxcodec/codec/ccodec_tiffmodule.cpp index b5287ae9e4..1a7a51af80 100644 --- a/core/fxcodec/codec/ccodec_tiffmodule.cpp +++ b/core/fxcodec/codec/ccodec_tiffmodule.cpp @@ -7,6 +7,7 @@ #include "core/fxcodec/codec/ccodec_tiffmodule.h" #include <limits> +#include <memory> #include "core/fxcodec/codec/codec_int.h" #include "core/fxcodec/fx_codec.h" @@ -20,12 +21,21 @@ extern "C" { #include "third_party/libtiff/tiffiop.h" -} +} // extern C + +namespace { + +// For use with std::unique_ptr<TIFF>. +struct TiffDeleter { + inline void operator()(TIFF* context) { TIFFClose(context); } +}; + +} // namespace class CTiffContext : public CCodec_TiffModule::Context { public: - CTiffContext(); - ~CTiffContext() override; + CTiffContext() = default; + ~CTiffContext() override = default; bool InitDecoder(const RetainPtr<IFX_SeekableReadStream>& file_ptr); bool LoadFrameInfo(int32_t frame, @@ -60,8 +70,8 @@ class CTiffContext : public CCodec_TiffModule::Context { uint16_t spp); RetainPtr<IFX_SeekableReadStream> m_io_in; - uint32_t m_offset; - TIFF* m_tif_ctx; + uint32_t m_offset = 0; + std::unique_ptr<TIFF, TiffDeleter> m_tif_ctx; }; void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) { @@ -220,18 +230,10 @@ void TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) { } // namespace -CTiffContext::CTiffContext() - : m_io_in(nullptr), m_offset(0), m_tif_ctx(nullptr) {} - -CTiffContext::~CTiffContext() { - if (m_tif_ctx) - TIFFClose(m_tif_ctx); -} - bool CTiffContext::InitDecoder( const RetainPtr<IFX_SeekableReadStream>& file_ptr) { m_io_in = file_ptr; - m_tif_ctx = tiff_open(this, "r"); + m_tif_ctx.reset(tiff_open(this, "r")); return !!m_tif_ctx; } @@ -241,7 +243,7 @@ bool CTiffContext::LoadFrameInfo(int32_t frame, int32_t* comps, int32_t* bpc, CFX_DIBAttribute* pAttribute) { - if (!TIFFSetDirectory(m_tif_ctx, (uint16)frame)) + if (!TIFFSetDirectory(m_tif_ctx.get(), (uint16)frame)) return false; uint32_t tif_width = 0; @@ -249,32 +251,36 @@ bool CTiffContext::LoadFrameInfo(int32_t frame, uint16_t tif_comps = 0; uint16_t tif_bpc = 0; uint32_t tif_rps = 0; - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &tif_width); - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &tif_height); - TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &tif_comps); - TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc); - TIFFGetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_IMAGEWIDTH, &tif_width); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_IMAGELENGTH, &tif_height); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_SAMPLESPERPIXEL, &tif_comps); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_BITSPERSAMPLE, &tif_bpc); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_ROWSPERSTRIP, &tif_rps); if (pAttribute) { pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH; - if (TIFFGetField(m_tif_ctx, TIFFTAG_RESOLUTIONUNIT, + if (TIFFGetField(m_tif_ctx.get(), TIFFTAG_RESOLUTIONUNIT, &pAttribute->m_wDPIUnit)) { pAttribute->m_wDPIUnit--; } - Tiff_Exif_GetInfo<uint16_t>(m_tif_ctx, TIFFTAG_ORIENTATION, pAttribute); - if (Tiff_Exif_GetInfo<float>(m_tif_ctx, TIFFTAG_XRESOLUTION, pAttribute)) { + Tiff_Exif_GetInfo<uint16_t>(m_tif_ctx.get(), TIFFTAG_ORIENTATION, + pAttribute); + if (Tiff_Exif_GetInfo<float>(m_tif_ctx.get(), TIFFTAG_XRESOLUTION, + pAttribute)) { void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION]; float fDpi = val ? *reinterpret_cast<float*>(val) : 0; pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f); } - if (Tiff_Exif_GetInfo<float>(m_tif_ctx, TIFFTAG_YRESOLUTION, pAttribute)) { + if (Tiff_Exif_GetInfo<float>(m_tif_ctx.get(), TIFFTAG_YRESOLUTION, + pAttribute)) { void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION]; float fDpi = val ? *reinterpret_cast<float*>(val) : 0; pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f); } - Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute); - Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MAKE, pAttribute); - Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MODEL, pAttribute); + Tiff_Exif_GetStringInfo(m_tif_ctx.get(), TIFFTAG_IMAGEDESCRIPTION, + pAttribute); + Tiff_Exif_GetStringInfo(m_tif_ctx.get(), TIFFTAG_MAKE, pAttribute); + Tiff_Exif_GetStringInfo(m_tif_ctx.get(), TIFFTAG_MODEL, pAttribute); } pdfium::base::CheckedNumeric<int32_t> checked_width = tif_width; pdfium::base::CheckedNumeric<int32_t> checked_height = tif_height; @@ -287,17 +293,17 @@ bool CTiffContext::LoadFrameInfo(int32_t frame, *bpc = tif_bpc; if (tif_rps > tif_height) { tif_rps = tif_height; - TIFFSetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps); + TIFFSetField(m_tif_ctx.get(), TIFFTAG_ROWSPERSTRIP, tif_rps); } return true; } bool CTiffContext::IsSupport(const RetainPtr<CFX_DIBitmap>& pDIBitmap) const { - if (TIFFIsTiled(m_tif_ctx)) + if (TIFFIsTiled(m_tif_ctx.get())) return false; uint16_t photometric = 0; - if (!TIFFGetField(m_tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) + if (!TIFFGetField(m_tif_ctx.get(), TIFFTAG_PHOTOMETRIC, &photometric)) return false; switch (pDIBitmap->GetBPP()) { @@ -316,7 +322,8 @@ bool CTiffContext::IsSupport(const RetainPtr<CFX_DIBitmap>& pDIBitmap) const { return false; } uint16_t planarconfig = 0; - if (!TIFFGetFieldDefaulted(m_tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) + if (!TIFFGetFieldDefaulted(m_tif_ctx.get(), TIFFTAG_PLANARCONFIG, + &planarconfig)) return false; return planarconfig != PLANARCONFIG_SEPARATE; @@ -327,7 +334,8 @@ void CTiffContext::SetPalette(const RetainPtr<CFX_DIBitmap>& pDIBitmap, uint16_t* red_orig = nullptr; uint16_t* green_orig = nullptr; uint16_t* blue_orig = nullptr; - TIFFGetField(m_tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_COLORMAP, &red_orig, &green_orig, + &blue_orig); for (int32_t i = (1L << bps) - 1; i >= 0; i--) { #define CVT(x) ((uint16_t)((x) >> 8)) red_orig[i] = CVT(red_orig[i]); @@ -356,16 +364,16 @@ bool CTiffContext::Decode1bppRGB(const RetainPtr<CFX_DIBitmap>& pDIBitmap, return false; } SetPalette(pDIBitmap, bps); - int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); + int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx.get()); uint8_t* buf = (uint8_t*)_TIFFmalloc(size); if (!buf) { - TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); + TIFFError(TIFFFileName(m_tif_ctx.get()), "No space for scanline buffer"); return false; } uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); uint32_t pitch = pDIBitmap->GetPitch(); for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(m_tif_ctx, buf, row, 0); + TIFFReadScanline(m_tif_ctx.get(), buf, row, 0); for (int32_t j = 0; j < size; j++) { bitMapbuffer[row * pitch + j] = buf[j]; } @@ -384,16 +392,16 @@ bool CTiffContext::Decode8bppRGB(const RetainPtr<CFX_DIBitmap>& pDIBitmap, return false; } SetPalette(pDIBitmap, bps); - int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); + int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx.get()); uint8_t* buf = (uint8_t*)_TIFFmalloc(size); if (!buf) { - TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); + TIFFError(TIFFFileName(m_tif_ctx.get()), "No space for scanline buffer"); return false; } uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); uint32_t pitch = pDIBitmap->GetPitch(); for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(m_tif_ctx, buf, row, 0); + TIFFReadScanline(m_tif_ctx.get(), buf, row, 0); for (int32_t j = 0; j < size; j++) { switch (bps) { case 4: @@ -418,16 +426,16 @@ bool CTiffContext::Decode24bppRGB(const RetainPtr<CFX_DIBitmap>& pDIBitmap, if (pDIBitmap->GetBPP() != 24 || !IsSupport(pDIBitmap)) return false; - int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx); + int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx.get()); uint8_t* buf = (uint8_t*)_TIFFmalloc(size); if (!buf) { - TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer"); + TIFFError(TIFFFileName(m_tif_ctx.get()), "No space for scanline buffer"); return false; } uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer(); uint32_t pitch = pDIBitmap->GetPitch(); for (int32_t row = 0; row < height; row++) { - TIFFReadScanline(m_tif_ctx, buf, row, 0); + TIFFReadScanline(m_tif_ctx.get(), buf, row, 0); for (int32_t j = 0; j < size - 2; j += 3) { bitMapbuffer[row * pitch + j + 0] = buf[j + 2]; bitMapbuffer[row * pitch + j + 1] = buf[j + 1]; @@ -443,15 +451,15 @@ bool CTiffContext::Decode(const RetainPtr<CFX_DIBitmap>& pDIBitmap) { uint32_t img_height = pDIBitmap->GetHeight(); uint32_t width = 0; uint32_t height = 0; - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &height); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_IMAGELENGTH, &height); if (img_width != width || img_height != height) return false; if (pDIBitmap->GetBPP() == 32) { uint16_t rotation = ORIENTATION_TOPLEFT; - TIFFGetField(m_tif_ctx, TIFFTAG_ORIENTATION, &rotation); - if (TIFFReadRGBAImageOriented(m_tif_ctx, img_width, img_height, + TIFFGetField(m_tif_ctx.get(), TIFFTAG_ORIENTATION, &rotation); + if (TIFFReadRGBAImageOriented(m_tif_ctx.get(), img_width, img_height, (uint32*)pDIBitmap->GetBuffer(), rotation, 1)) { for (uint32_t row = 0; row < img_height; row++) { @@ -463,8 +471,8 @@ bool CTiffContext::Decode(const RetainPtr<CFX_DIBitmap>& pDIBitmap) { } uint16_t spp = 0; uint16_t bps = 0; - TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp); - TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetField(m_tif_ctx.get(), TIFFTAG_BITSPERSAMPLE, &bps); FX_SAFE_UINT32 safe_bpp = bps; safe_bpp *= spp; if (!safe_bpp.IsValid()) |