summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2024-03-23 20:59:24 +0900
committerTomaž Vajngerl <quikee@gmail.com>2024-04-01 08:08:39 +0200
commitd8ece6a5f56f012ecf1766cc3f68c85706e3b6cb (patch)
treec6a94f491474d189864302cbca8fd1a637a8639a /vcl
parent350c590620226c4d5b94aa01d3853e15af3cebb0 (diff)
vcl: remove partial XPM image loading
This removes the code that handles the IO_PENDING and the graphic "context" handling from XPM image format. Partial loading of images complicates the image filter life cycle a lot (many exceptions) and is not really needed so much today as this was needed in the past. In most cases we load the whole image in one pass anyway. Even loading from the network should be fast enough to not cause issues for the user. Most image filters don't even implement this like PNG and nobody noticed for many years that this is not supported. To handle IO_PENDING case it is probably better to load the bitstream into memory and then load the whole image after that in one pass. This can also be implemented all inside (Imp)Graphic in a very straight forward way. Change-Id: Icdc4f042b38936e3d9f11d7026fd8525a6f46943 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165210 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/filter/ixpm/xpmread.cxx213
1 files changed, 93 insertions, 120 deletions
diff --git a/vcl/source/filter/ixpm/xpmread.cxx b/vcl/source/filter/ixpm/xpmread.cxx
index eca9b50287bd..1ad06483a712 100644
--- a/vcl/source/filter/ixpm/xpmread.cxx
+++ b/vcl/source/filter/ixpm/xpmread.cxx
@@ -52,8 +52,7 @@ namespace {
enum ReadState
{
XPMREAD_OK,
- XPMREAD_ERROR,
- XPMREAD_NEED_MORE
+ XPMREAD_ERROR
};
}
@@ -112,7 +111,7 @@ private:
public:
explicit XPMReader(SvStream& rStream);
- ReadState ReadXPM(Graphic& rGraphic);
+ ReadState ReadXPM(BitmapEx& rBitmapEx);
};
}
@@ -123,136 +122,122 @@ XPMReader::XPMReader(SvStream& rStream)
{
}
-ReadState XPMReader::ReadXPM(Graphic& rGraphic)
+ReadState XPMReader::ReadXPM(BitmapEx& rBitmapEx)
{
- ReadState eReadState;
- sal_uInt8 cDummy;
+ if (!mrStream.good())
+ return XPMREAD_ERROR;
- // check if we can real ALL
- mrStream.Seek( STREAM_SEEK_TO_END );
- mrStream.ReadUChar( cDummy );
+ ReadState eReadState = XPMREAD_ERROR;
- // if we could not read all
- // return and wait for new data
- if (mrStream.GetError() != ERRCODE_IO_PENDING)
+ mrStream.Seek( mnLastPos );
+ mbStatus = true;
+
+ if ( mbStatus )
{
- mrStream.Seek( mnLastPos );
- mbStatus = true;
+ mpStringBuf = new sal_uInt8 [ XPMSTRINGBUF ];
+ mpTempBuf = new sal_uInt8 [ XPMTEMPBUFSIZE ];
+ mbStatus = ImplGetString();
if ( mbStatus )
{
- mpStringBuf = new sal_uInt8 [ XPMSTRINGBUF ];
- mpTempBuf = new sal_uInt8 [ XPMTEMPBUFSIZE ];
+ mnIdentifier = XPMVALUES; // fetch Bitmap information
+ mnWidth = ImplGetULONG( 0 );
+ mnHeight = ImplGetULONG( 1 );
+ mnColors = ImplGetULONG( 2 );
+ mnCpp = ImplGetULONG( 3 );
+ }
+ if ( mnColors > ( SAL_MAX_UINT32 / ( 4 + mnCpp ) ) )
+ mbStatus = false;
+ if ( ( mnWidth * mnCpp ) >= XPMSTRINGBUF )
+ mbStatus = false;
+ //xpms are a minimum of one character (one byte) per pixel, so if the file isn't
+ //even that long, it's not all there
+ if (mrStream.remainingSize() + mnTempAvail < static_cast<sal_uInt64>(mnWidth) * mnHeight)
+ mbStatus = false;
+ if ( mbStatus && mnWidth && mnHeight && mnColors && mnCpp )
+ {
+ mnIdentifier = XPMCOLORS;
- mbStatus = ImplGetString();
- if ( mbStatus )
+ for (sal_uLong i = 0; i < mnColors; ++i)
{
- mnIdentifier = XPMVALUES; // fetch Bitmap information
- mnWidth = ImplGetULONG( 0 );
- mnHeight = ImplGetULONG( 1 );
- mnColors = ImplGetULONG( 2 );
- mnCpp = ImplGetULONG( 3 );
+ if (!ImplGetColor())
+ {
+ mbStatus = false;
+ break;
+ }
}
- if ( mnColors > ( SAL_MAX_UINT32 / ( 4 + mnCpp ) ) )
- mbStatus = false;
- if ( ( mnWidth * mnCpp ) >= XPMSTRINGBUF )
- mbStatus = false;
- //xpms are a minimum of one character (one byte) per pixel, so if the file isn't
- //even that long, it's not all there
- if (mrStream.remainingSize() + mnTempAvail < static_cast<sal_uInt64>(mnWidth) * mnHeight)
- mbStatus = false;
- if ( mbStatus && mnWidth && mnHeight && mnColors && mnCpp )
+
+ if ( mbStatus )
{
- mnIdentifier = XPMCOLORS;
+ // create a 24bit graphic when more as 256 colours present
+ auto ePixelFormat = vcl::PixelFormat::INVALID;
+ if ( mnColors > 256 )
+ ePixelFormat = vcl::PixelFormat::N24_BPP;
+ else
+ ePixelFormat = vcl::PixelFormat::N8_BPP;
- for (sal_uLong i = 0; i < mnColors; ++i)
+ maBitmap = Bitmap(Size(mnWidth, mnHeight), ePixelFormat);
+ mpWriterAccess = maBitmap;
+
+ // mbTransparent is TRUE if at least one colour is transparent
+ if ( mbTransparent )
{
- if (!ImplGetColor())
- {
+ maMaskBitmap = Bitmap(Size(mnWidth, mnHeight), vcl::PixelFormat::N8_BPP, &Bitmap::GetGreyPalette(256));
+ mpMaskWriterAccess = maMaskBitmap;
+ if (!mpMaskWriterAccess)
mbStatus = false;
- break;
- }
}
-
- if ( mbStatus )
+ if (mpWriterAccess && mbStatus)
{
- // create a 24bit graphic when more as 256 colours present
- auto ePixelFormat = vcl::PixelFormat::INVALID;
- if ( mnColors > 256 )
- ePixelFormat = vcl::PixelFormat::N24_BPP;
- else
- ePixelFormat = vcl::PixelFormat::N8_BPP;
-
- maBitmap = Bitmap(Size(mnWidth, mnHeight), ePixelFormat);
- mpWriterAccess = maBitmap;
-
- // mbTransparent is TRUE if at least one colour is transparent
- if ( mbTransparent )
- {
- maMaskBitmap = Bitmap(Size(mnWidth, mnHeight), vcl::PixelFormat::N8_BPP, &Bitmap::GetGreyPalette(256));
- mpMaskWriterAccess = maMaskBitmap;
- if (!mpMaskWriterAccess)
- mbStatus = false;
- }
- if (mpWriterAccess && mbStatus)
- {
- if (mnColors <= 256) // palette is only needed by using less than 257
- { // colors
- sal_uInt8 i = 0;
- for (auto& elem : maColMap)
- {
- mpWriterAccess->SetPaletteColor(i, Color(elem.second[1], elem.second[2], elem.second[3]));
- //reuse map entry, overwrite color with palette index
- elem.second[1] = i;
- i++;
- }
+ if (mnColors <= 256) // palette is only needed by using less than 257
+ { // colors
+ sal_uInt8 i = 0;
+ for (auto& elem : maColMap)
+ {
+ mpWriterAccess->SetPaletteColor(i, Color(elem.second[1], elem.second[2], elem.second[3]));
+ //reuse map entry, overwrite color with palette index
+ elem.second[1] = i;
+ i++;
}
+ }
- // now we get the bitmap data
- mnIdentifier = XPMPIXELS;
- for (tools::Long i = 0; i < mnHeight; ++i)
+ // now we get the bitmap data
+ mnIdentifier = XPMPIXELS;
+ for (tools::Long i = 0; i < mnHeight; ++i)
+ {
+ if ( !ImplGetScanLine( i ) )
{
- if ( !ImplGetScanLine( i ) )
- {
- mbStatus = false;
- break;
- }
+ mbStatus = false;
+ break;
}
- mnIdentifier = XPMEXTENSIONS;
}
+ mnIdentifier = XPMEXTENSIONS;
}
}
+ }
- delete[] mpStringBuf;
- delete[] mpTempBuf;
+ delete[] mpStringBuf;
+ delete[] mpTempBuf;
- }
- if( mbStatus )
+ }
+ if( mbStatus )
+ {
+ mpWriterAccess.reset();
+ if (mpMaskWriterAccess)
{
- mpWriterAccess.reset();
- if (mpMaskWriterAccess)
- {
- mpMaskWriterAccess.reset();
- rGraphic = Graphic(BitmapEx(maBitmap, maMaskBitmap));
- }
- else
- {
- rGraphic = BitmapEx(maBitmap);
- }
- eReadState = XPMREAD_OK;
+ mpMaskWriterAccess.reset();
+ rBitmapEx = BitmapEx(maBitmap, maMaskBitmap);
}
else
{
- mpMaskWriterAccess.reset();
- mpWriterAccess.reset();
-
- eReadState = XPMREAD_ERROR;
+ rBitmapEx = BitmapEx(maBitmap);
}
+ eReadState = XPMREAD_OK;
}
else
{
- mrStream.ResetError();
- eReadState = XPMREAD_NEED_MORE;
+ mpMaskWriterAccess.reset();
+ mpWriterAccess.reset();
}
return eReadState;
}
@@ -650,29 +635,17 @@ bool XPMReader::ImplGetString()
}
-VCL_DLLPUBLIC bool ImportXPM( SvStream& rStm, Graphic& rGraphic )
+VCL_DLLPUBLIC bool ImportXPM(SvStream& rStream, Graphic& rGraphic)
{
- std::shared_ptr<GraphicReader> pContext = rGraphic.GetReaderContext();
- rGraphic.SetReaderContext(nullptr);
- XPMReader* pXPMReader = dynamic_cast<XPMReader*>( pContext.get() );
- if (!pXPMReader)
- {
- pContext = std::make_shared<XPMReader>( rStm );
- pXPMReader = static_cast<XPMReader*>( pContext.get() );
- }
+ XPMReader aXPMReader(rStream);
- bool bRet = true;
+ BitmapEx aBitmapEx;
+ ReadState eReadState = aXPMReader.ReadXPM(aBitmapEx);
- ReadState eReadState = pXPMReader->ReadXPM( rGraphic );
-
- if( eReadState == XPMREAD_ERROR )
- {
- bRet = false;
- }
- else if( eReadState == XPMREAD_NEED_MORE )
- rGraphic.SetReaderContext( pContext );
-
- return bRet;
+ if (eReadState == XPMREAD_ERROR)
+ return false;
+ rGraphic = Graphic(aBitmapEx);
+ return true;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */