vcl/source/filter/GraphicFormatDetector.cxx | 172 +++++++++++++++++++++++- vcl/source/filter/graphicfilter2.cxx | 199 +--------------------------- 2 files changed, 180 insertions(+), 191 deletions(-)
New commits: commit 6a2fd2d07ed1cb7713776b32ff175b300ee732e9 Author: offtkp <parisop...@gmail.com> AuthorDate: Sat Aug 13 12:02:01 2022 +0300 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Aug 22 18:04:54 2022 +0200 Remove code duplication in GraphicDescriptor for PNG GraphicFormatDetector and GraphicDescriptor have duplicate format detection code so now GraphicDescriptor uses GraphicFormatDetector functions instead to detect the format for PNG files Change-Id: I8ce1c5eee44ff4122f4ecf1094d3d8b18379c6b2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138226 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/source/filter/GraphicFormatDetector.cxx b/vcl/source/filter/GraphicFormatDetector.cxx index 43e403e59936..5b5ccf33d004 100644 --- a/vcl/source/filter/GraphicFormatDetector.cxx +++ b/vcl/source/filter/GraphicFormatDetector.cxx @@ -645,6 +645,102 @@ bool GraphicFormatDetector::checkPNG() if (mnFirstLong == 0x89504e47 && mnSecondLong == 0x0d0a1a0a) { maMetadata.mnFormat = GraphicFileFormat::PNG; + if (mbExtendedInfo) + { + sal_uInt32 nTemp32; + mrStream.Seek(mnStreamPosition + 8); + do + { + sal_uInt8 cByte = 0; + + // IHDR-Chunk + mrStream.SeekRel(8); + + // width + mrStream.ReadUInt32(nTemp32); + if (!mrStream.good()) + break; + maMetadata.maPixSize.setWidth(nTemp32); + + // height + mrStream.ReadUInt32(nTemp32); + if (!mrStream.good()) + break; + maMetadata.maPixSize.setHeight(nTemp32); + + // Bits/Pixel + mrStream.ReadUChar(cByte); + if (!mrStream.good()) + break; + maMetadata.mnBitsPerPixel = cByte; + + // Colour type - check whether it supports alpha values + sal_uInt8 cColType = 0; + mrStream.ReadUChar(cColType); + if (!mrStream.good()) + break; + maMetadata.mbIsAlpha = maMetadata.mbIsTransparent + = (cColType == 4 || cColType == 6); + + // Planes always 1; + // compression always + maMetadata.mnPlanes = 1; + + sal_uInt32 nLen32 = 0; + nTemp32 = 0; + + mrStream.SeekRel(7); + + // read up to the start of the image + mrStream.ReadUInt32(nLen32); + mrStream.ReadUInt32(nTemp32); + while (mrStream.good() && nTemp32 != 0x49444154) + { + if (nTemp32 == 0x70485973) // physical pixel dimensions + { + sal_uLong nXRes; + sal_uLong nYRes; + + // horizontal resolution + nTemp32 = 0; + mrStream.ReadUInt32(nTemp32); + nXRes = nTemp32; + + // vertical resolution + nTemp32 = 0; + mrStream.ReadUInt32(nTemp32); + nYRes = nTemp32; + + // unit + cByte = 0; + mrStream.ReadUChar(cByte); + + if (cByte) + { + if (nXRes) + maMetadata.maLogSize.setWidth( + (maMetadata.maPixSize.Width() * 100000) / nXRes); + + if (nYRes) + maMetadata.maLogSize.setHeight( + (maMetadata.maPixSize.Height() * 100000) / nYRes); + } + + nLen32 -= 9; + } + else if (nTemp32 == 0x74524e53) // transparency + { + maMetadata.mbIsTransparent = true; + maMetadata.mbIsAlpha = (cColType != 0 && cColType != 2); + } + + // skip forward to next chunk + mrStream.SeekRel(4 + nLen32); + mrStream.ReadUInt32(nLen32); + mrStream.ReadUInt32(nTemp32); + } + } while (false); + } return true; } return false; diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx index 0ef05ef1db9d..4327ef5e2f59 100644 --- a/vcl/source/filter/graphicfilter2.cxx +++ b/vcl/source/filter/graphicfilter2.cxx @@ -427,113 +427,12 @@ bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm ) bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo ) { - sal_uInt32 nTemp32 = 0; - bool bRet = false; - sal_Int32 nStmPos = rStm.Tell(); - rStm.SetEndian( SvStreamEndian::BIG ); - rStm.ReadUInt32( nTemp32 ); - - if ( nTemp32 == 0x89504e47 ) - { - rStm.ReadUInt32( nTemp32 ); - if ( nTemp32 == 0x0d0a1a0a ) - { - aMetadata.mnFormat = GraphicFileFormat::PNG; - bRet = true; - - if ( bExtendedInfo ) - { - do { - sal_uInt8 cByte = 0; - - // IHDR-Chunk - rStm.SeekRel( 8 ); - - // width - rStm.ReadUInt32( nTemp32 ); - if (!rStm.good()) - break; - aMetadata.maPixSize.setWidth( nTemp32 ); - - // height - rStm.ReadUInt32( nTemp32 ); - if (!rStm.good()) - break; - aMetadata.maPixSize.setHeight( nTemp32 ); - - // Bits/Pixel - rStm.ReadUChar( cByte ); - if (!rStm.good()) - break; - aMetadata.mnBitsPerPixel = cByte; - - // Colour type - check whether it supports alpha values - sal_uInt8 cColType = 0; - rStm.ReadUChar( cColType ); - if (!rStm.good()) - break; - aMetadata.mbIsAlpha = aMetadata.mbIsTransparent = ( cColType == 4 || cColType == 6 ); - - // Planes always 1; - // compression always - aMetadata.mnPlanes = 1; - - sal_uInt32 nLen32 = 0; - nTemp32 = 0; - - rStm.SeekRel( 7 ); - - // read up to the start of the image - rStm.ReadUInt32( nLen32 ); - rStm.ReadUInt32( nTemp32 ); - while (rStm.good() && nTemp32 != 0x49444154) - { - if ( nTemp32 == 0x70485973 ) // physical pixel dimensions - { - sal_uLong nXRes; - sal_uLong nYRes; - - // horizontal resolution - nTemp32 = 0; - rStm.ReadUInt32( nTemp32 ); - nXRes = nTemp32; - - // vertical resolution - nTemp32 = 0; - rStm.ReadUInt32( nTemp32 ); - nYRes = nTemp32; - - // unit - cByte = 0; - rStm.ReadUChar( cByte ); - - if ( cByte ) - { - if ( nXRes ) - aMetadata.maLogSize.setWidth( (aMetadata.maPixSize.Width() * 100000) / nXRes ); - - if ( nYRes ) - aMetadata.maLogSize.setHeight( (aMetadata.maPixSize.Height() * 100000) / nYRes ); - } - - nLen32 -= 9; - } - else if ( nTemp32 == 0x74524e53 ) // transparency - { - aMetadata.mbIsTransparent = true; - aMetadata.mbIsAlpha = ( cColType != 0 && cColType != 2 ); - } - - // skip forward to next chunk - rStm.SeekRel( 4 + nLen32 ); - rStm.ReadUInt32( nLen32 ); - rStm.ReadUInt32( nTemp32 ); - } - } while (false); - } - } - } + vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo ); + bool bRet = aDetector.detect(); + bRet &= aDetector.checkPNG(); + if ( bRet ) + aMetadata = aDetector.getMetadata(); rStm.Seek( nStmPos ); return bRet; } commit 8d844452df8332edd92e9039e42cdcb1349e7e2c Author: offtkp <parisop...@gmail.com> AuthorDate: Fri Aug 12 23:53:57 2022 +0300 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Aug 22 18:04:40 2022 +0200 Remove code duplication in GraphicDescriptor for BMP GraphicFormatDetector and GraphicDescriptor have duplicate format detection code so now GraphicDescriptor uses GraphicFormatDetector functions instead to detect the format for BMP files Change-Id: I1cf096034a77826e61c36f0a5094976f49814747 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138216 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/source/filter/GraphicFormatDetector.cxx b/vcl/source/filter/GraphicFormatDetector.cxx index 0bd3394bc99d..43e403e59936 100644 --- a/vcl/source/filter/GraphicFormatDetector.cxx +++ b/vcl/source/filter/GraphicFormatDetector.cxx @@ -25,6 +25,7 @@ #include <graphic/DetectorTools.hxx> #include <tools/solar.h> #include <tools/zcodec.hxx> +#include <tools/fract.hxx> #include <filter/WebpReader.hxx> #include <utility> @@ -431,6 +432,7 @@ bool GraphicFormatDetector::checkMET() bool GraphicFormatDetector::checkBMP() { + bool bRet = false; sal_uInt8 nOffset; // We're possibly also able to read an OS/2 bitmap array @@ -452,10 +454,80 @@ bool GraphicFormatDetector::checkBMP() || maFirstBytes[14 + nOffset] == 0x28 || maFirstBytes[14 + nOffset] == 0x0c) { maMetadata.mnFormat = GraphicFileFormat::BMP; - return true; - } - } - return false; + bRet = true; + if (mbExtendedInfo) + { + sal_uInt32 nTemp32; + sal_uInt16 nTemp16; + sal_uInt32 nCompression; + + mrStream.SetEndian(SvStreamEndian::LITTLE); + mrStream.Seek(mnStreamPosition + nOffset + 2); + + // up to first info + mrStream.SeekRel(0x10); + + // Pixel width + mrStream.ReadUInt32(nTemp32); + maMetadata.maPixSize.setWidth(nTemp32); + + // Pixel height + mrStream.ReadUInt32(nTemp32); + maMetadata.maPixSize.setHeight(nTemp32); + + // Planes + mrStream.ReadUInt16(nTemp16); + maMetadata.mnPlanes = nTemp16; + + // BitCount + mrStream.ReadUInt16(nTemp16); + maMetadata.mnBitsPerPixel = nTemp16; + + // Compression + mrStream.ReadUInt32(nTemp32); + nCompression = nTemp32; + + // logical width + mrStream.SeekRel(4); + mrStream.ReadUInt32(nTemp32); + sal_uInt32 nXPelsPerMeter = 0; + if (nTemp32) + { + maMetadata.maLogSize.setWidth((maMetadata.maPixSize.Width() * 100000) + / nTemp32); + nXPelsPerMeter = nTemp32; + } + + // logical height + mrStream.ReadUInt32(nTemp32); + sal_uInt32 nYPelsPerMeter = 0; + if (nTemp32) + { + maMetadata.maLogSize.setHeight((maMetadata.maPixSize.Height() * 100000) + / nTemp32); + nYPelsPerMeter = nTemp32; + } + + // further validation, check for rational values + if ((maMetadata.mnBitsPerPixel > 24) || (nCompression > 3)) + { + maMetadata.mnFormat = GraphicFileFormat::NOT; + bRet = false; + } + + if (bRet && nXPelsPerMeter && nYPelsPerMeter) + { + maMetadata.maPreferredMapMode + = MapMode(MapUnit::MapMM, Point(), Fraction(1000, nXPelsPerMeter), + Fraction(1000, nYPelsPerMeter)); + + maMetadata.maPreferredLogSize + = Size(maMetadata.maPixSize.getWidth(), maMetadata.maPixSize.getHeight()); + } + } + } + } + return bRet; } bool GraphicFormatDetector::checkWMF() diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx index e622901767e8..0ef05ef1db9d 100644 --- a/vcl/source/filter/graphicfilter2.cxx +++ b/vcl/source/filter/graphicfilter2.cxx @@ -121,90 +121,12 @@ void GraphicDescriptor::ImpConstruct() bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, bool bExtendedInfo ) { - sal_uInt16 nTemp16 = 0; - bool bRet = false; sal_Int32 nStmPos = rStm.Tell(); - - rStm.SetEndian( SvStreamEndian::LITTLE ); - rStm.ReadUInt16( nTemp16 ); - - // OS/2-BitmapArray - if ( nTemp16 == 0x4142 ) - { - rStm.SeekRel( 0x0c ); - rStm.ReadUInt16( nTemp16 ); - } - - // Bitmap - if ( nTemp16 == 0x4d42 ) - { - aMetadata.mnFormat = GraphicFileFormat::BMP; - bRet = true; - - if ( bExtendedInfo ) - { - sal_uInt32 nTemp32; - sal_uInt32 nCompression; - - // up to first info - rStm.SeekRel( 0x10 ); - - // Pixel width - rStm.ReadUInt32( nTemp32 ); - aMetadata.maPixSize.setWidth( nTemp32 ); - - // Pixel height - rStm.ReadUInt32( nTemp32 ); - aMetadata.maPixSize.setHeight( nTemp32 ); - - // Planes - rStm.ReadUInt16( nTemp16 ); - aMetadata.mnPlanes = nTemp16; - - // BitCount - rStm.ReadUInt16( nTemp16 ); - aMetadata.mnBitsPerPixel = nTemp16; - - // Compression - rStm.ReadUInt32( nTemp32 ); - nCompression = nTemp32; - - // logical width - rStm.SeekRel( 4 ); - rStm.ReadUInt32( nTemp32 ); - sal_uInt32 nXPelsPerMeter = 0; - if ( nTemp32 ) - { - aMetadata.maLogSize.setWidth( ( aMetadata.maPixSize.Width() * 100000 ) / nTemp32 ); - nXPelsPerMeter = nTemp32; - } - - // logical height - rStm.ReadUInt32( nTemp32 ); - sal_uInt32 nYPelsPerMeter = 0; - if ( nTemp32 ) - { - aMetadata.maLogSize.setHeight( ( aMetadata.maPixSize.Height() * 100000 ) / nTemp32 ); - nYPelsPerMeter = nTemp32; - } - - // further validation, check for rational values - if ( ( aMetadata.mnBitsPerPixel > 24 ) || ( nCompression > 3 ) ) - { - aMetadata.mnFormat = GraphicFileFormat::NOT; - bRet = false; - } - - if (bRet && nXPelsPerMeter && nYPelsPerMeter) - { - aMetadata.maPreferredMapMode - = MapMode(MapUnit::MapMM, Point(), Fraction(1000, nXPelsPerMeter), - Fraction(1000, nYPelsPerMeter)); - - aMetadata.maPreferredLogSize = Size(aMetadata.maPixSize.getWidth(), aMetadata.maPixSize.getHeight()); - } - } - } + vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo ); + bool bRet = aDetector.detect(); + bRet &= aDetector.checkBMP(); + if ( bRet ) + aMetadata = aDetector.getMetadata(); rStm.Seek( nStmPos ); return bRet; }