summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2021-02-15 10:23:27 +0900
committerTomaž Vajngerl <quikee@gmail.com>2021-02-17 05:54:36 +0100
commit68012eaaab9968f6ccfdfc018bcc5befa36a7a2f (patch)
tree4e8bb8efdcca069906f0d1c9d87cc8cc2daf6d8b /vcl
parentd338dc277d7dbe381d669728e30a1c2606a4814a (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.mk1
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/inc/filter/PcdReader.hxx28
-rw-r--r--vcl/qa/cppunit/graphicfilter/data/pcd/fail/.gitignore0
-rw-r--r--vcl/qa/cppunit/graphicfilter/data/pcd/indeterminate/.gitignore1
-rw-r--r--vcl/qa/cppunit/graphicfilter/data/pcd/pass/.gitignore0
-rw-r--r--vcl/qa/cppunit/graphicfilter/data/pcd/pass/blank-square.pcdbin0 -> 788480 bytes
-rw-r--r--vcl/qa/cppunit/graphicfilter/filters-pcd-test.cxx61
-rw-r--r--vcl/source/filter/FilterConfigCache.cxx7
-rw-r--r--vcl/source/filter/graphicfilter.cxx44
-rw-r--r--vcl/source/filter/ipcd/ipcd.cxx363
-rw-r--r--vcl/workben/fftester.cxx12
-rw-r--r--vcl/workben/pcdfuzzer.cxx5
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
new file mode 100644
index 000000000000..a626b5f2309b
--- /dev/null
+++ b/vcl/qa/cppunit/graphicfilter/data/pcd/pass/blank-square.pcd
Binary files differ
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;
}