summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-05-08 16:52:00 +0200
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-06-18 13:34:30 -0400
commitbc559eecccf08b3cb7fd328f49ea81aba32a6d71 (patch)
treede0741b1c767c12620e9ca53e5f6fff54ae6dadc
parentd4333b1108a5ea734e31732175785edced83a951 (diff)
vcl: split jpeg import into two parts
Split the import into two: 1) Just create the bitmap, this part is not thread-safe (e.g. OpenGLContext::makeCurrent() is called when OpenGL is enabled). 2) Import the image into an existing bitmap. The point is that the second part takes much more time than the first, and in the future that part may be executed on a thread, while without such a split the whole ImportJPEG() can't do that. For now GraphicFilter::ImportGraphic() simply invokes the two parts after each other, so no real functional changes yet. Reviewed-on: https://gerrit.libreoffice.org/37397 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit e8a05109d91bb9e82fcec5204514766f4bdbbee8) Change-Id: Iee742a2cd3c581aeaf1a1ed9f55cd543955a85e0
-rw-r--r--include/vcl/bitmapex.hxx2
-rw-r--r--include/vcl/graph.hxx2
-rw-r--r--include/vcl/graphicfilter.hxx6
-rw-r--r--vcl/inc/impgraph.hxx2
-rw-r--r--vcl/source/filter/graphicfilter.cxx13
-rw-r--r--vcl/source/filter/jpeg/JpegReader.cxx47
-rw-r--r--vcl/source/filter/jpeg/JpegReader.hxx13
-rw-r--r--vcl/source/filter/jpeg/jpeg.cxx6
-rw-r--r--vcl/source/filter/jpeg/jpeg.h5
-rw-r--r--vcl/source/filter/jpeg/jpeg.hxx3
-rw-r--r--vcl/source/filter/jpeg/jpegc.cxx4
-rw-r--r--vcl/source/gdi/bitmapex.cxx5
-rw-r--r--vcl/source/gdi/graph.cxx5
-rw-r--r--vcl/source/gdi/impgraph.cxx5
-rw-r--r--vcl/workben/fftester.cxx2
15 files changed, 85 insertions, 35 deletions
diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx
index 3d6a04eefc1e..ab68620fd76f 100644
--- a/include/vcl/bitmapex.hxx
+++ b/include/vcl/bitmapex.hxx
@@ -72,6 +72,8 @@ public:
TransparentType GetTransparentType() const { return eTransparent; }
Bitmap GetBitmap( const Color* pTransReplaceColor = nullptr ) const;
+ /// Gives direct access to the contained bitmap.
+ const Bitmap& GetBitmapRef() const;
Bitmap GetMask() const;
bool IsAlpha() const;
diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx
index 7aec891e05ff..1676b883c4d6 100644
--- a/include/vcl/graph.hxx
+++ b/include/vcl/graph.hxx
@@ -148,6 +148,8 @@ public:
// before.
Bitmap GetBitmap(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const;
BitmapEx GetBitmapEx(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const;
+ /// Gives direct access to the contained BitmapEx.
+ const BitmapEx& GetBitmapExRef() const;
Animation GetAnimation() const;
const GDIMetaFile& GetGDIMetaFile() const;
diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx
index c0bbb3d62a77..8b8a7cef3008 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -56,10 +56,14 @@ enum class GraphicFilterImportFlags
DontSetLogsizeForJpeg = 0x002,
ForPreview = 0x004,
AllowPartialStreamRead = 0x010,
+ /// Only create a bitmap, do not read pixel data.
+ OnlyCreateBitmap = 0x020,
+ /// Read pixel data into an existing bitmap.
+ UseExistingBitmap = 0x040,
};
namespace o3tl
{
- template<> struct typed_flags<GraphicFilterImportFlags> : is_typed_flags<GraphicFilterImportFlags, 0x0017> {};
+ template<> struct typed_flags<GraphicFilterImportFlags> : is_typed_flags<GraphicFilterImportFlags, 0x0077> {};
}
#define IMP_BMP "SVBMP"
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index bba9b9708d1e..10d04183f2b1 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -118,6 +118,8 @@ private:
Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const;
BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const;
+ /// Gives direct access to the contained BitmapEx.
+ const BitmapEx& ImplGetBitmapExRef() const;
Animation ImplGetAnimation() const;
const GDIMetaFile& ImplGetGDIMetaFile() const;
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index 8b57c8085b26..4a84f683bef7 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -1501,10 +1501,19 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPat
if( !( nImportFlags & GraphicFilterImportFlags::DontSetLogsizeForJpeg ) )
nImportFlags |= GraphicFilterImportFlags::SetLogsizeForJpeg;
- if( !ImportJPEG( rIStream, rGraphic, nImportFlags ) )
+ sal_uInt64 nPosition = rIStream.Tell();
+ if( !ImportJPEG( rIStream, rGraphic, nImportFlags | GraphicFilterImportFlags::OnlyCreateBitmap, nullptr ) )
nStatus = GRFILTER_FILTERERROR;
else
- eLinkType = GfxLinkType::NativeJpg;
+ {
+ Bitmap& rBitmap = const_cast<Bitmap&>(rGraphic.GetBitmapExRef().GetBitmapRef());
+ Bitmap::ScopedWriteAccess pWriteAccess(rBitmap);
+ rIStream.Seek(nPosition);
+ if( !ImportJPEG( rIStream, rGraphic, nImportFlags | GraphicFilterImportFlags::UseExistingBitmap, &pWriteAccess ) )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ eLinkType = GfxLinkType::NativeJpg;
+ }
}
else if( aFilterName.equalsIgnoreAsciiCase( IMP_SVG ) )
{
diff --git a/vcl/source/filter/jpeg/JpegReader.cxx b/vcl/source/filter/jpeg/JpegReader.cxx
index 9f8510a4f4b1..9f7185f23f36 100644
--- a/vcl/source/filter/jpeg/JpegReader.cxx
+++ b/vcl/source/filter/jpeg/JpegReader.cxx
@@ -169,14 +169,19 @@ void jpeg_svstream_src (j_decompress_ptr cinfo, void* input)
source->pub.next_input_byte = nullptr; /* until buffer loaded */
}
-JPEGReader::JPEGReader( SvStream& rStream, bool bSetLogSize ) :
+JPEGReader::JPEGReader( SvStream& rStream, GraphicFilterImportFlags nImportFlags ) :
mrStream ( rStream ),
mnLastPos ( rStream.Tell() ),
mnLastLines ( 0 ),
- mbSetLogSize ( bSetLogSize )
+ mbSetLogSize ( nImportFlags & GraphicFilterImportFlags::SetLogsizeForJpeg )
{
maUpperName = "SVIJPEG";
- mnFormerPos = mnLastPos;
+
+ if (!(nImportFlags & GraphicFilterImportFlags::UseExistingBitmap))
+ {
+ mpBitmap.reset(new Bitmap());
+ mpIncompleteAlpha.reset(new Bitmap());
+ }
}
JPEGReader::~JPEGReader()
@@ -194,7 +199,7 @@ bool JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam)
Size aSize(rParam.nWidth, rParam.nHeight);
bool bGray = rParam.bGray;
- maBitmap = Bitmap();
+ mpBitmap.reset(new Bitmap());
sal_uInt64 nSize = aSize.Width() * aSize.Height();
@@ -211,11 +216,11 @@ bool JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam)
aGrayPal[ n ] = BitmapColor( cGray, cGray, cGray );
}
- maBitmap = Bitmap(aSize, 8, &aGrayPal);
+ mpBitmap.reset(new Bitmap(aSize, 8, &aGrayPal));
}
else
{
- maBitmap = Bitmap(aSize, 24);
+ mpBitmap.reset(new Bitmap(aSize, 24));
}
if (mbSetLogSize)
@@ -230,8 +235,8 @@ bool JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam)
MapMode aMapMode( nUnit == 1 ? MapUnit::MapInch : MapUnit::MapCM, aEmptyPoint, aFractX, aFractY );
Size aPrefSize = OutputDevice::LogicToLogic( aSize, aMapMode, MapUnit::Map100thMM );
- maBitmap.SetPrefSize(aPrefSize);
- maBitmap.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
+ mpBitmap->SetPrefSize(aPrefSize);
+ mpBitmap->SetPrefMapMode(MapMode(MapUnit::Map100thMM));
}
}
@@ -241,12 +246,12 @@ bool JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam)
Graphic JPEGReader::CreateIntermediateGraphic(long nLines)
{
Graphic aGraphic;
- const Size aSizePixel(maBitmap.GetSizePixel());
+ const Size aSizePixel(mpBitmap->GetSizePixel());
if (!mnLastLines)
{
- maIncompleteAlpha = Bitmap(aSizePixel, 1);
- maIncompleteAlpha.Erase(Color(COL_WHITE));
+ mpIncompleteAlpha.reset(new Bitmap(aSizePixel, 1));
+ mpIncompleteAlpha->Erase(Color(COL_WHITE));
}
if (nLines && (nLines < aSizePixel.Height()))
@@ -256,21 +261,21 @@ Graphic JPEGReader::CreateIntermediateGraphic(long nLines)
if (nNewLines > 0)
{
{
- Bitmap::ScopedWriteAccess pAccess(maIncompleteAlpha);
+ Bitmap::ScopedWriteAccess pAccess(*mpIncompleteAlpha);
pAccess->SetFillColor(Color(COL_BLACK));
pAccess->FillRect(Rectangle(Point(0, mnLastLines), Size(pAccess->Width(), nNewLines)));
}
- aGraphic = BitmapEx(maBitmap, maIncompleteAlpha);
+ aGraphic = BitmapEx(*mpBitmap, *mpIncompleteAlpha);
}
else
{
- aGraphic = maBitmap;
+ aGraphic = *mpBitmap;
}
}
else
{
- aGraphic = maBitmap;
+ aGraphic = *mpBitmap;
}
mnLastLines = nLines;
@@ -278,10 +283,9 @@ Graphic JPEGReader::CreateIntermediateGraphic(long nLines)
return aGraphic;
}
-ReadState JPEGReader::Read( Graphic& rGraphic )
+ReadState JPEGReader::Read( Graphic& rGraphic, GraphicFilterImportFlags nImportFlags, Bitmap::ScopedWriteAccess* ppAccess )
{
long nEndPosition;
- long nLines;
ReadState eReadState;
bool bRet = false;
sal_uInt8 cDummy;
@@ -307,9 +311,11 @@ ReadState JPEGReader::Read( Graphic& rGraphic )
mrStream.Seek( mnLastPos );
// read the (partial) image
- ReadJPEG( this, &mrStream, &nLines, GetPreviewSize() );
+ long nLines;
+ ReadJPEG( this, &mrStream, &nLines, GetPreviewSize(), nImportFlags, ppAccess );
- if (!maBitmap.IsEmpty())
+ auto bUseExistingBitmap = static_cast<bool>(nImportFlags & GraphicFilterImportFlags::UseExistingBitmap);
+ if (bUseExistingBitmap || !mpBitmap->IsEmpty())
{
if( mrStream.GetError() == ERRCODE_IO_PENDING )
{
@@ -317,7 +323,8 @@ ReadState JPEGReader::Read( Graphic& rGraphic )
}
else
{
- rGraphic = maBitmap;
+ if (!bUseExistingBitmap)
+ rGraphic = *mpBitmap;
}
bRet = true;
diff --git a/vcl/source/filter/jpeg/JpegReader.hxx b/vcl/source/filter/jpeg/JpegReader.hxx
index bb020f449f19..e45a4421867c 100644
--- a/vcl/source/filter/jpeg/JpegReader.hxx
+++ b/vcl/source/filter/jpeg/JpegReader.hxx
@@ -21,10 +21,13 @@
#define INCLUDED_VCL_SOURCE_FILTER_JPEG_JPEGREADER_HXX
#include <vcl/graph.hxx>
+#include <vcl/bitmap.hxx>
#include <vcl/fltcall.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
+enum class GraphicFilterImportFlags;
+
enum ReadState
{
JPEGREAD_OK,
@@ -46,8 +49,8 @@ struct JPEGCreateBitmapParam
class JPEGReader : public GraphicReader
{
SvStream& mrStream;
- Bitmap maBitmap;
- Bitmap maIncompleteAlpha;
+ std::unique_ptr<Bitmap> mpBitmap;
+ std::unique_ptr<Bitmap> mpIncompleteAlpha;
long mnLastPos;
long mnFormerPos;
@@ -57,14 +60,14 @@ class JPEGReader : public GraphicReader
Graphic CreateIntermediateGraphic(long nLines);
public:
- JPEGReader( SvStream& rStream, bool bSetLogSize );
+ JPEGReader( SvStream& rStream, GraphicFilterImportFlags nImportFlags );
virtual ~JPEGReader() override;
- ReadState Read(Graphic& rGraphic);
+ ReadState Read(Graphic& rGraphic, GraphicFilterImportFlags nImportFlags, Bitmap::ScopedWriteAccess* ppAccess);
bool CreateBitmap(JPEGCreateBitmapParam& param);
- Bitmap& GetBitmap() { return maBitmap; }
+ Bitmap& GetBitmap() { return *mpBitmap; }
};
#endif // INCLUDED_VCL_SOURCE_FILTER_JPEG_JPEGREADER_HXX
diff --git a/vcl/source/filter/jpeg/jpeg.cxx b/vcl/source/filter/jpeg/jpeg.cxx
index f1cb2eb2ed65..5b067153dc30 100644
--- a/vcl/source/filter/jpeg/jpeg.cxx
+++ b/vcl/source/filter/jpeg/jpeg.cxx
@@ -25,7 +25,7 @@
#include <vcl/FilterConfigItem.hxx>
#include <vcl/graphicfilter.hxx>
-VCL_DLLPUBLIC bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, GraphicFilterImportFlags nImportFlags )
+VCL_DLLPUBLIC bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, GraphicFilterImportFlags nImportFlags, Bitmap::ScopedWriteAccess* ppAccess )
{
bool bReturn = true;
@@ -34,7 +34,7 @@ VCL_DLLPUBLIC bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, Graphi
JPEGReader* pJPEGReader = dynamic_cast<JPEGReader*>( pContext.get() );
if (!pJPEGReader)
{
- pContext = std::make_shared<JPEGReader>( rInputStream, bool( nImportFlags & GraphicFilterImportFlags::SetLogsizeForJpeg ) );
+ pContext = std::make_shared<JPEGReader>( rInputStream, nImportFlags );
pJPEGReader = static_cast<JPEGReader*>( pContext.get() );
}
@@ -47,7 +47,7 @@ VCL_DLLPUBLIC bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, Graphi
pJPEGReader->DisablePreviewMode();
}
- ReadState eReadState = pJPEGReader->Read( rGraphic );
+ ReadState eReadState = pJPEGReader->Read( rGraphic, nImportFlags, ppAccess );
if( eReadState == JPEGREAD_ERROR )
{
diff --git a/vcl/source/filter/jpeg/jpeg.h b/vcl/source/filter/jpeg/jpeg.h
index 08caa474226c..4d542c5c7110 100644
--- a/vcl/source/filter/jpeg/jpeg.h
+++ b/vcl/source/filter/jpeg/jpeg.h
@@ -25,6 +25,8 @@
#include <com/sun/star/uno/Reference.hxx>
#include <sal/types.h>
#include <basegfx/vector/b2dsize.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/graphicfilter.hxx>
#include <jpeglib.h>
@@ -45,7 +47,8 @@ bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream,
css::uno::Reference<css::task::XStatusIndicator> const & status);
void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines,
- Size const & previewSize );
+ Size const & previewSize, GraphicFilterImportFlags nImportFlags,
+ Bitmap::ScopedWriteAccess* ppAccess );
long Transform( void* pInputStream, void* pOutputStream, long nAngle );
diff --git a/vcl/source/filter/jpeg/jpeg.hxx b/vcl/source/filter/jpeg/jpeg.hxx
index f8f900ace03d..776e7d60042f 100644
--- a/vcl/source/filter/jpeg/jpeg.hxx
+++ b/vcl/source/filter/jpeg/jpeg.hxx
@@ -23,11 +23,12 @@
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
#include <vcl/fltcall.hxx>
+#include <vcl/bitmap.hxx>
#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
-VCL_DLLPUBLIC bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, GraphicFilterImportFlags nImportFlags );
+VCL_DLLPUBLIC bool ImportJPEG( SvStream& rInputStream, Graphic& rGraphic, GraphicFilterImportFlags nImportFlags, Bitmap::ScopedWriteAccess* ppAccess );
bool ExportJPEG(SvStream& rOutputStream,
const Graphic& rGraphic,
diff --git a/vcl/source/filter/jpeg/jpegc.cxx b/vcl/source/filter/jpeg/jpegc.cxx
index 3353fe9c247a..06c36a821f5c 100644
--- a/vcl/source/filter/jpeg/jpegc.cxx
+++ b/vcl/source/filter/jpeg/jpegc.cxx
@@ -37,6 +37,7 @@ extern "C" {
#include <JpegWriter.hxx>
#include <memory>
#include <vcl/bitmapaccess.hxx>
+#include <vcl/graphicfilter.hxx>
#ifdef _MSC_VER
#pragma warning(push, 1) /* disable to __declspec(align()) aligned warning */
@@ -67,7 +68,8 @@ extern "C" void outputMessage (j_common_ptr cinfo)
}
void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines,
- Size const & previewSize )
+ Size const & previewSize, GraphicFilterImportFlags nImportFlags,
+ Bitmap::ScopedWriteAccess* ppAccess )
{
jpeg_decompress_struct cinfo;
ErrorManagerStruct jerr;
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index e1dbdd9ad3cb..cc47fb748ae4 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -249,6 +249,11 @@ bool BitmapEx::IsAlpha() const
return( IsTransparent() && bAlpha );
}
+const Bitmap& BitmapEx::GetBitmapRef() const
+{
+ return aBitmap;
+}
+
Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const
{
Bitmap aRetBmp( aBitmap );
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index 74aaacc6c421..d22a29779d8b 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -354,6 +354,11 @@ const GDIMetaFile& Graphic::GetGDIMetaFile() const
return mxImpGraphic->ImplGetGDIMetaFile();
}
+const BitmapEx& Graphic::GetBitmapExRef() const
+{
+ return mxImpGraphic->ImplGetBitmapExRef();
+}
+
uno::Reference< graphic::XGraphic > Graphic::GetXGraphic() const
{
uno::Reference< graphic::XGraphic > xRet;
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index e0215eb9ab26..64b5bab9ac75 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -648,6 +648,11 @@ Animation ImpGraphic::ImplGetAnimation() const
return aAnimation;
}
+const BitmapEx& ImpGraphic::ImplGetBitmapExRef() const
+{
+ return maEx;
+}
+
const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const
{
ensureAvailable();
diff --git a/vcl/workben/fftester.cxx b/vcl/workben/fftester.cxx
index 45d10f928e86..7ea02538cd3d 100644
--- a/vcl/workben/fftester.cxx
+++ b/vcl/workben/fftester.cxx
@@ -114,7 +114,7 @@ try_again:
{
Graphic aGraphic;
SvFileStream aFileStream(out, StreamMode::READ);
- ret = (int) ImportJPEG(aFileStream, aGraphic, GraphicFilterImportFlags::NONE);
+ ret = (int) ImportJPEG(aFileStream, aGraphic, GraphicFilterImportFlags::NONE, nullptr);
BitmapEx aTarget = aGraphic.GetBitmapEx();
aTarget.Convert(BmpConversion::N24Bit);
}