diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2021-02-15 10:23:27 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2021-02-17 05:54:36 +0100 |
commit | 68012eaaab9968f6ccfdfc018bcc5befa36a7a2f (patch) | |
tree | 4e8bb8efdcca069906f0d1c9d87cc8cc2daf6d8b /vcl | |
parent | d338dc277d7dbe381d669728e30a1c2606a4814a (diff) |
Move PCD reader from filter module into VCL
Change-Id: Icd23d1343f5231c09dd8197943ca472f4b573bfc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111018
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/CppunitTest_vcl_filters_test.mk | 1 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/inc/filter/PcdReader.hxx | 28 | ||||
-rw-r--r-- | vcl/qa/cppunit/graphicfilter/data/pcd/fail/.gitignore | 0 | ||||
-rw-r--r-- | vcl/qa/cppunit/graphicfilter/data/pcd/indeterminate/.gitignore | 1 | ||||
-rw-r--r-- | vcl/qa/cppunit/graphicfilter/data/pcd/pass/.gitignore | 0 | ||||
-rw-r--r-- | vcl/qa/cppunit/graphicfilter/data/pcd/pass/blank-square.pcd | bin | 0 -> 788480 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/graphicfilter/filters-pcd-test.cxx | 61 | ||||
-rw-r--r-- | vcl/source/filter/FilterConfigCache.cxx | 7 | ||||
-rw-r--r-- | vcl/source/filter/graphicfilter.cxx | 44 | ||||
-rw-r--r-- | vcl/source/filter/ipcd/ipcd.cxx | 363 | ||||
-rw-r--r-- | vcl/workben/fftester.cxx | 12 | ||||
-rw-r--r-- | vcl/workben/pcdfuzzer.cxx | 5 |
13 files changed, 487 insertions, 36 deletions
diff --git a/vcl/CppunitTest_vcl_filters_test.mk b/vcl/CppunitTest_vcl_filters_test.mk index a62e3b109927..8ebc4c7c1ae0 100644 --- a/vcl/CppunitTest_vcl_filters_test.mk +++ b/vcl/CppunitTest_vcl_filters_test.mk @@ -12,6 +12,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,vcl_filters_test)) $(eval $(call gb_CppunitTest_add_exception_objects,vcl_filters_test, \ vcl/qa/cppunit/graphicfilter/filters-eps-test \ vcl/qa/cppunit/graphicfilter/filters-met-test \ + vcl/qa/cppunit/graphicfilter/filters-pcd-test \ vcl/qa/cppunit/graphicfilter/filters-pcx-test \ vcl/qa/cppunit/graphicfilter/filters-pict-test \ vcl/qa/cppunit/graphicfilter/filters-psd-test \ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 578d55eb46ee..42b3b86f3ef1 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -440,6 +440,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/igif/decode \ vcl/source/filter/igif/gifread \ vcl/source/filter/imet/ios2met \ + vcl/source/filter/ipcd/ipcd \ vcl/source/filter/ipcx/ipcx \ vcl/source/filter/ipict/ipict \ vcl/source/filter/ipsd/ipsd \ diff --git a/vcl/inc/filter/PcdReader.hxx b/vcl/inc/filter/PcdReader.hxx new file mode 100644 index 000000000000..216a14b89040 --- /dev/null +++ b/vcl/inc/filter/PcdReader.hxx @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <vcl/graph.hxx> +#include <vcl/FilterConfigItem.hxx> + +VCL_DLLPUBLIC bool ImportPcdGraphic(SvStream& rStream, Graphic& rGraphic, + FilterConfigItem* pFilterConfigItem); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qa/cppunit/graphicfilter/data/pcd/fail/.gitignore b/vcl/qa/cppunit/graphicfilter/data/pcd/fail/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/data/pcd/fail/.gitignore diff --git a/vcl/qa/cppunit/graphicfilter/data/pcd/indeterminate/.gitignore b/vcl/qa/cppunit/graphicfilter/data/pcd/indeterminate/.gitignore new file mode 100644 index 000000000000..23ad7d155635 --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/data/pcd/indeterminate/.gitignore @@ -0,0 +1 @@ +*.pcd-* diff --git a/vcl/qa/cppunit/graphicfilter/data/pcd/pass/.gitignore b/vcl/qa/cppunit/graphicfilter/data/pcd/pass/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/data/pcd/pass/.gitignore diff --git a/vcl/qa/cppunit/graphicfilter/data/pcd/pass/blank-square.pcd b/vcl/qa/cppunit/graphicfilter/data/pcd/pass/blank-square.pcd Binary files differnew file mode 100644 index 000000000000..a626b5f2309b --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/data/pcd/pass/blank-square.pcd diff --git a/vcl/qa/cppunit/graphicfilter/filters-pcd-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-pcd-test.cxx new file mode 100644 index 000000000000..bd100c8f2090 --- /dev/null +++ b/vcl/qa/cppunit/graphicfilter/filters-pcd-test.cxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <unotest/filters-test.hxx> +#include <test/bootstrapfixture.hxx> +#include <vcl/FilterConfigItem.hxx> +#include <tools/stream.hxx> +#include <vcl/graph.hxx> +#include <filter/PcdReader.hxx> + +using namespace css; + +/* Implementation of Filters test */ + +class PcdFilterTest + : public test::FiltersTest + , public test::BootstrapFixture +{ +public: + PcdFilterTest() : BootstrapFixture(true, false) {} + + virtual bool load(const OUString &, + const OUString &rURL, const OUString &, + SfxFilterFlags, SotClipboardFormatId, unsigned int) override; + + /** + * Ensure CVEs remain unbroken + */ + void testCVEs(); + + CPPUNIT_TEST_SUITE(PcdFilterTest); + CPPUNIT_TEST(testCVEs); + CPPUNIT_TEST_SUITE_END(); +}; + +bool PcdFilterTest::load(const OUString &, + const OUString &rURL, const OUString &, + SfxFilterFlags, SotClipboardFormatId, unsigned int) +{ + SvFileStream aFileStream(rURL, StreamMode::READ); + Graphic aGraphic; + return ImportPcdGraphic(aFileStream, aGraphic, nullptr); +} + +void PcdFilterTest::testCVEs() +{ +#ifndef DISABLE_CVE_TESTS + testDir(OUString(), + m_directories.getURLFromSrc(u"/vcl/qa/cppunit/graphicfilter/data/pcd/")); +#endif +} + +CPPUNIT_TEST_SUITE_REGISTRATION(PcdFilterTest); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/filter/FilterConfigCache.cxx b/vcl/source/filter/FilterConfigCache.cxx index e3752a24a7c6..9e5a1a236955 100644 --- a/vcl/source/filter/FilterConfigCache.cxx +++ b/vcl/source/filter/FilterConfigCache.cxx @@ -43,7 +43,8 @@ const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameLi { IMP_BMP, IMP_GIF, IMP_PNG, IMP_JPEG, IMP_XBM, IMP_XPM, EXP_BMP, EXP_JPEG, EXP_PNG, IMP_MOV, IMP_TIFF, EXP_TIFF, - IMP_TGA, IMP_PICT, IMP_MET, IMP_RAS, IMP_PCX, IMP_PSD, nullptr + IMP_TGA, IMP_PICT, IMP_MET, IMP_RAS, IMP_PCX, IMP_PSD, + IMP_PCD, nullptr }; const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList[] = @@ -55,7 +56,7 @@ const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameL const char* FilterConfigCache::FilterConfigCacheEntry::ExternalPixelFilterNameList[] = { - "egi", "icd", "ipb", "epb", "epg", + "egi", "ipb", "epb", "epg", "epp", nullptr }; @@ -234,7 +235,7 @@ const char* FilterConfigCache::InternalFilterListForSvxLight[] = "png","1","SVIPNG", "png","2","SVEPNG", "pct","1","SVPICT", - "pcd","1","icd", + "pcd","1","SVPCD", "psd","1","SVPSD", "pcx","1","SVPCX", "pbm","1","ipb", diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index c7eefd4ddf73..3e10e33debbf 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -57,6 +57,7 @@ #include <filter/EpsReader.hxx> #include <filter/EpsWriter.hxx> #include <filter/PsdReader.hxx> +#include <filter/PcdReader.hxx> #include <osl/module.hxx> #include <com/sun/star/uno/Reference.h> #include <com/sun/star/awt/Size.hpp> @@ -647,7 +648,6 @@ ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const OUString& rPathname, const #ifdef DISABLE_DYNLOADING -extern "C" bool icdGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem ); extern "C" bool idxGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem ); extern "C" bool ipbGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem ); @@ -658,16 +658,12 @@ PFilterCall ImpFilterLibCacheEntry::GetImportFunction() if( !mpfnImport ) { #ifndef DISABLE_DYNLOADING - if (maFormatName == "icd") - mpfnImport = reinterpret_cast<PFilterCall>(maLibrary.getFunctionSymbol("icdGraphicImport")); - else if (maFormatName == "idx") + if (maFormatName == "idx") mpfnImport = reinterpret_cast<PFilterCall>(maLibrary.getFunctionSymbol("idxGraphicImport")); else if (maFormatName == "ipb") mpfnImport = reinterpret_cast<PFilterCall>(maLibrary.getFunctionSymbol("ipbGraphicImport")); #else - if (maFormatName == "icd") - mpfnImport = icdGraphicImport; - else if (maFormatName == "idx") + if (maFormatName == "idx") mpfnImport = idxGraphicImport; else if (maFormatName == "ipb") mpfnImport = ipbGraphicImport; @@ -1399,7 +1395,7 @@ void GraphicFilter::preload() sal_Int32 nTokenCount = comphelper::string::getTokenCount(aFilterPath, ';'); ImpFilterLibCache& rCache = Cache::get(); static const std::initializer_list<std::u16string_view> aFilterNames = { - u"icd", u"idx", u"ipb", u"ipd" + u"idx", u"ipb", u"ipd" }; // Load library for each filter. @@ -1745,6 +1741,21 @@ ErrCode GraphicFilter::readPSD(SvStream & rStream, Graphic & rGraphic) return ERRCODE_GRFILTER_FILTERERROR; } +ErrCode GraphicFilter::readPCD(SvStream & rStream, Graphic & rGraphic) +{ + std::unique_ptr<FilterConfigItem> pFilterConfigItem; + if (!utl::ConfigManager::IsFuzzing()) + { + OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" ); + pFilterConfigItem = std::make_unique<FilterConfigItem>(aFilterConfigPath); + } + + if (ImportPcdGraphic(rStream, rGraphic, pFilterConfigItem.get())) + return ERRCODE_NONE; + else + return ERRCODE_GRFILTER_FILTERERROR; +} + ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, const css::uno::Sequence< css::beans::PropertyValue >* /*pFilterData*/, @@ -1886,6 +1897,10 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, { nStatus = readPSD(rIStream, rGraphic); } + else if (aFilterName.equalsIgnoreAsciiCase(IMP_PCD)) + { + nStatus = readPCD(rIStream, rGraphic); + } else nStatus = ERRCODE_GRFILTER_FILTERERROR; } @@ -1913,18 +1928,7 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, nStatus = ERRCODE_GRFILTER_FILTERERROR; else { - std::unique_ptr<FilterConfigItem> pFilterConfigItem; - OUString aShortName; - if( nFormat != GRFILTER_FORMAT_DONTKNOW ) - { - aShortName = GetImportFormatShortName( nFormat ).toAsciiUpperCase(); - if (aShortName == "PCD" && !utl::ConfigManager::IsFuzzing()) - { - OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" ); - pFilterConfigItem = std::make_unique<FilterConfigItem>( aFilterConfigPath ); - } - } - if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem.get() ) ) + if( !(*pFunc)( rIStream, rGraphic, nullptr ) ) nStatus = ERRCODE_GRFILTER_FORMATERROR; } } diff --git a/vcl/source/filter/ipcd/ipcd.cxx b/vcl/source/filter/ipcd/ipcd.cxx new file mode 100644 index 000000000000..5072e2ab4354 --- /dev/null +++ b/vcl/source/filter/ipcd/ipcd.cxx @@ -0,0 +1,363 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <vcl/graph.hxx> +#include <vcl/BitmapTools.hxx> +#include <vcl/FilterConfigItem.hxx> +#include <tools/stream.hxx> +#include <filter/PcdReader.hxx> + +//============================ PCDReader ================================== + +namespace { + +// these resolutions are contained in a PCD file: +enum PCDResolution { + PCDRES_BASE16, // 192 x 128 + PCDRES_BASE4, // 384 x 256 + PCDRES_BASE, // 768 x 512 + // the following ones are compressed + // and CANNOT be read by us + PCDRES_4BASE, // 1536 x 1024 + PCDRES_16BASE // 3072 x 3072 +}; + +class PCDReader { + +private: + + bool bStatus; + + SvStream &m_rPCD; + std::unique_ptr<vcl::bitmap::RawBitmap> mpBitmap; + + sal_uInt8 nOrientation; // orientation of the picture within the PCD file: + // 0 - spire point up + // 1 - spire points to the right + // 2 - spire points down + // 3 - spire points to the left + + PCDResolution eResolution; // which resolution we want + + sal_uInt32 nWidth; // width of the PCD picture + sal_uInt32 nHeight; // height of the PCD picture + sal_uInt32 nImagePos; // position of the picture within the PCD file + + // temporary lLue-Green-Red-Bitmap + sal_uInt32 nBMPWidth; + sal_uInt32 nBMPHeight; + + void CheckPCDImagePacFile(); + // checks whether it's a Photo-CD file with 'Image Pac' + + void ReadOrientation(); + // reads the orientation and sets nOrientation + + void ReadImage(); + +public: + + explicit PCDReader(SvStream &rStream) + : bStatus(false) + , m_rPCD(rStream) + , nOrientation(0) + , eResolution(PCDRES_BASE16) + , nWidth(0) + , nHeight(0) + , nImagePos(0) + , nBMPWidth(0) + , nBMPHeight(0) + { + } + + bool ReadPCD( Graphic & rGraphic, FilterConfigItem* pConfigItem ); +}; + +} + +//=================== Methods of PCDReader ============================== + +bool PCDReader::ReadPCD( Graphic & rGraphic, FilterConfigItem* pConfigItem ) +{ + bStatus = true; + + // is it a PCD file with a picture? ( sets bStatus == sal_False, if that's not the case): + CheckPCDImagePacFile(); + + // read orientation of the picture: + ReadOrientation(); + + // which resolution do we want?: + eResolution = PCDRES_BASE; + if ( pConfigItem ) + { + sal_Int32 nResolution = pConfigItem->ReadInt32( "Resolution", 2 ); + if ( nResolution == 1 ) + eResolution = PCDRES_BASE4; + else if ( nResolution == 0 ) + eResolution = PCDRES_BASE16; + } + // determine size and position (position within the PCD file) of the picture: + switch (eResolution) + { + case PCDRES_BASE16 : + nWidth = 192; + nHeight = 128; + nImagePos = 8192; + break; + + case PCDRES_BASE4 : + nWidth = 384; + nHeight = 256; + nImagePos = 47104; + break; + + case PCDRES_BASE : + nWidth = 768; + nHeight = 512; + nImagePos = 196608; + break; + + default: + bStatus = false; + } + if ( bStatus ) + { + if ( ( nOrientation & 0x01 ) == 0 ) + { + nBMPWidth = nWidth; + nBMPHeight = nHeight; + } + else + { + nBMPWidth = nHeight; + nBMPHeight = nWidth; + } + mpBitmap.reset(new vcl::bitmap::RawBitmap( Size( nBMPWidth, nBMPHeight ), 24 )); + + ReadImage(); + + rGraphic = vcl::bitmap::CreateFromData(std::move(*mpBitmap)); + } + return bStatus; +} + + +void PCDReader::CheckPCDImagePacFile() +{ + char Buf[ 8 ]; + + m_rPCD.Seek( 2048 ); + m_rPCD.ReadBytes(Buf, 7); + Buf[ 7 ] = 0; + if (OString(Buf) != "PCD_IPI") + bStatus = false; +} + + +void PCDReader::ReadOrientation() +{ + if ( !bStatus ) + return; + m_rPCD.Seek( 194635 ); + m_rPCD.ReadUChar( nOrientation ); + nOrientation &= 0x03; +} + + +void PCDReader::ReadImage() +{ + sal_uInt32 nx,ny,nW2,nH2,nYPair,ndy,nXPair; + tools::Long nL,nCb,nCr,nRed,nGreen,nBlue; + sal_uInt8 * pt; + sal_uInt8 * pL0; // luminance for each pixel of the 1st row of the current pair of rows + sal_uInt8 * pL1; // luminance for each pixel of the 2nd row of the current pair of rows + sal_uInt8 * pCb; // blue chrominance for each 2x2 pixel of the current pair of rows + sal_uInt8 * pCr; // red chrominance for each 2x2 pixel of the current pair of rows + sal_uInt8 * pL0N, * pL1N, * pCbN, * pCrN; // like above, but for the next pair of rows + + if ( !bStatus ) + return; + + nW2=nWidth>>1; + nH2=nHeight>>1; + + pL0 =static_cast<sal_uInt8*>(std::malloc( nWidth )); + pL1 =static_cast<sal_uInt8*>(std::malloc( nWidth )); + pCb =static_cast<sal_uInt8*>(std::malloc( nW2+1 )); + pCr =static_cast<sal_uInt8*>(std::malloc( nW2+1 )); + pL0N=static_cast<sal_uInt8*>(std::malloc( nWidth )); + pL1N=static_cast<sal_uInt8*>(std::malloc( nWidth )); + pCbN=static_cast<sal_uInt8*>(std::malloc( nW2+1 )); + pCrN=static_cast<sal_uInt8*>(std::malloc( nW2+1 )); + + if ( pL0 == nullptr || pL1 == nullptr || pCb == nullptr || pCr == nullptr || + pL0N == nullptr || pL1N == nullptr || pCbN == nullptr || pCrN == nullptr) + { + std::free(static_cast<void*>(pL0) ); + std::free(static_cast<void*>(pL1) ); + std::free(static_cast<void*>(pCb) ); + std::free(static_cast<void*>(pCr) ); + std::free(static_cast<void*>(pL0N)); + std::free(static_cast<void*>(pL1N)); + std::free(static_cast<void*>(pCbN)); + std::free(static_cast<void*>(pCrN)); + bStatus = false; + return; + } + + m_rPCD.Seek( nImagePos ); + + // next pair of rows := first pair of rows: + m_rPCD.ReadBytes( pL0N, nWidth ); + m_rPCD.ReadBytes( pL1N, nWidth ); + m_rPCD.ReadBytes( pCbN, nW2 ); + m_rPCD.ReadBytes( pCrN, nW2 ); + pCbN[ nW2 ] = pCbN[ nW2 - 1 ]; + pCrN[ nW2 ] = pCrN[ nW2 - 1 ]; + + for ( nYPair = 0; nYPair < nH2; nYPair++ ) + { + // current pair of rows := next pair of rows: + pt=pL0; pL0=pL0N; pL0N=pt; + pt=pL1; pL1=pL1N; pL1N=pt; + pt=pCb; pCb=pCbN; pCbN=pt; + pt=pCr; pCr=pCrN; pCrN=pt; + + // get the next pair of rows: + if ( nYPair < nH2 - 1 ) + { + m_rPCD.ReadBytes( pL0N, nWidth ); + m_rPCD.ReadBytes( pL1N, nWidth ); + m_rPCD.ReadBytes( pCbN, nW2 ); + m_rPCD.ReadBytes( pCrN, nW2 ); + pCbN[nW2]=pCbN[ nW2 - 1 ]; + pCrN[nW2]=pCrN[ nW2 - 1 ]; + } + else + { + for ( nXPair = 0; nXPair < nW2; nXPair++ ) + { + pCbN[ nXPair ] = pCb[ nXPair ]; + pCrN[ nXPair ] = pCr[ nXPair ]; + } + } + + // loop through both rows of the pair of rows: + for ( ndy = 0; ndy < 2; ndy++ ) + { + ny = ( nYPair << 1 ) + ndy; + + // loop through X: + for ( nx = 0; nx < nWidth; nx++ ) + { + // get/calculate nL,nCb,nCr for the pixel nx,ny: + nXPair = nx >> 1; + if ( ndy == 0 ) + { + nL = static_cast<tools::Long>(pL0[ nx ]); + if (( nx & 1 ) == 0 ) + { + nCb = static_cast<tools::Long>(pCb[ nXPair ]); + nCr = static_cast<tools::Long>(pCr[ nXPair ]); + } + else + { + nCb = ( static_cast<tools::Long>(pCb[ nXPair ]) + static_cast<tools::Long>(pCb[ nXPair + 1 ]) ) >> 1; + nCr = ( static_cast<tools::Long>(pCr[ nXPair ]) + static_cast<tools::Long>(pCr[ nXPair + 1 ]) ) >> 1; + } + } + else { + nL = pL1[ nx ]; + if ( ( nx & 1 ) == 0 ) + { + nCb = ( static_cast<tools::Long>(pCb[ nXPair ]) + static_cast<tools::Long>(pCbN[ nXPair ]) ) >> 1; + nCr = ( static_cast<tools::Long>(pCr[ nXPair ]) + static_cast<tools::Long>(pCrN[ nXPair ]) ) >> 1; + } + else + { + nCb = ( static_cast<tools::Long>(pCb[ nXPair ]) + static_cast<tools::Long>(pCb[ nXPair + 1 ]) + + static_cast<tools::Long>(pCbN[ nXPair ]) + static_cast<tools::Long>(pCbN[ nXPair + 1 ]) ) >> 2; + nCr = ( static_cast<tools::Long>(pCr[ nXPair ]) + static_cast<tools::Long>(pCr[ nXPair + 1]) + + static_cast<tools::Long>(pCrN[ nXPair ]) + static_cast<tools::Long>(pCrN[ nXPair + 1 ]) ) >> 2; + } + } + // conversion of nL,nCb,nCr in nRed,nGreen,nBlue: + nL *= 89024; + nCb -= 156; + nCr -= 137; + nRed = ( nL + nCr * 119374 + 0x8000 ) >> 16; + if ( nRed < 0 ) + nRed = 0; + if ( nRed > 255) + nRed = 255; + nGreen = ( nL - nCb * 28198 - nCr * 60761 + 0x8000 ) >> 16; + if ( nGreen < 0 ) + nGreen = 0; + if ( nGreen > 255 ) + nGreen = 255; + nBlue = ( nL + nCb * 145352 + 0x8000 ) >> 16; + if ( nBlue < 0 ) + nBlue = 0; + if ( nBlue > 255 ) + nBlue = 255; + + // register color value in pBMPMap: + if ( nOrientation < 2 ) + { + if ( nOrientation == 0 ) + mpBitmap->SetPixel( ny, nx, Color( static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue) ) ); + else + mpBitmap->SetPixel( nWidth - 1 - nx, ny, Color( static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue) ) ); + } + else + { + if ( nOrientation == 2 ) + mpBitmap->SetPixel( nHeight - 1 - ny, ( nWidth - 1 - nx ), Color( static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue) ) ); + else + mpBitmap->SetPixel( nx, ( nHeight - 1 - ny ), Color( static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue) ) ); + } + } + } + + if ( m_rPCD.GetError() ) + bStatus = false; + if ( !bStatus ) + break; + } + std::free(static_cast<void*>(pL0) ); + std::free(static_cast<void*>(pL1) ); + std::free(static_cast<void*>(pCb) ); + std::free(static_cast<void*>(pCr) ); + std::free(static_cast<void*>(pL0N)); + std::free(static_cast<void*>(pL1N)); + std::free(static_cast<void*>(pCbN)); + std::free(static_cast<void*>(pCrN)); +} + +//================== GraphicImport - the exported Function ================ + +bool ImportPcdGraphic(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pConfigItem) +{ + PCDReader aPCDReader(rStream); + return aPCDReader.ReadPCD(rGraphic, pConfigItem); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/workben/fftester.cxx b/vcl/workben/fftester.cxx index fe030475e3f8..02dc6d90eb21 100644 --- a/vcl/workben/fftester.cxx +++ b/vcl/workben/fftester.cxx @@ -50,6 +50,7 @@ #include <filter/PcxReader.hxx> #include <filter/EpsReader.hxx> #include <filter/PsdReader.hxx> +#include <filter/PcdReader.hxx> #include <osl/file.hxx> #include <osl/module.hxx> #include <tools/stream.hxx> @@ -166,18 +167,9 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) #ifndef DISABLE_DYNLOADING else if (strcmp(argv[2], "pcd") == 0) { - static PFilterCall pfnImport(nullptr); - if (!pfnImport) - { - osl::Module aLibrary; - aLibrary.loadRelative(&thisModule, "libgielo.so"); - pfnImport = reinterpret_cast<PFilterCall>( - aLibrary.getFunctionSymbol("icdGraphicImport")); - aLibrary.release(); - } Graphic aGraphic; SvFileStream aFileStream(out, StreamMode::READ); - ret = static_cast<int>((*pfnImport)(aFileStream, aGraphic, nullptr)); + ret = static_cast<int>(ImportPcdGraphic(aFileStream, aGraphic, nullptr)); } else if (strcmp(argv[2], "dxf") == 0) { diff --git a/vcl/workben/pcdfuzzer.cxx b/vcl/workben/pcdfuzzer.cxx index ccd0367535be..86df131da1cc 100644 --- a/vcl/workben/pcdfuzzer.cxx +++ b/vcl/workben/pcdfuzzer.cxx @@ -10,6 +10,7 @@ #include <tools/stream.hxx> #include <vcl/FilterConfigItem.hxx> #include "commonfuzzer.hxx" +#include <filter/PcdReader.hxx> #include <config_features.h> #include <osl/detail/component-mapping.h> @@ -39,8 +40,6 @@ extern "C" void* lo_get_custom_widget_func(const char*) return nullptr; } -extern "C" bool icdGraphicImport(SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem); - extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { TypicalFuzzerInitialize(argc, argv); @@ -51,7 +50,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { SvMemoryStream aStream(const_cast<uint8_t*>(data), size, StreamMode::READ); Graphic aGraphic; - (void)icdGraphicImport(aStream, aGraphic, nullptr); + (void)ImportPcdGraphic(aStream, aGraphic, nullptr); return 0; } |