diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-05-08 16:52:00 +0200 |
---|---|---|
committer | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2018-06-18 13:34:30 -0400 |
commit | bc559eecccf08b3cb7fd328f49ea81aba32a6d71 (patch) | |
tree | de0741b1c767c12620e9ca53e5f6fff54ae6dadc | |
parent | d4333b1108a5ea734e31732175785edced83a951 (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.hxx | 2 | ||||
-rw-r--r-- | include/vcl/graph.hxx | 2 | ||||
-rw-r--r-- | include/vcl/graphicfilter.hxx | 6 | ||||
-rw-r--r-- | vcl/inc/impgraph.hxx | 2 | ||||
-rw-r--r-- | vcl/source/filter/graphicfilter.cxx | 13 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/JpegReader.cxx | 47 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/JpegReader.hxx | 13 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/jpeg.cxx | 6 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/jpeg.h | 5 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/jpeg.hxx | 3 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/jpegc.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/bitmapex.cxx | 5 | ||||
-rw-r--r-- | vcl/source/gdi/graph.cxx | 5 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 5 | ||||
-rw-r--r-- | vcl/workben/fftester.cxx | 2 |
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); } |