summaryrefslogtreecommitdiffstats
path: root/emfio
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2021-06-05 19:30:46 +0200
committerBartosz Kosiorek <gang65@poczta.onet.pl>2021-06-05 20:20:24 +0200
commit33d2cf7008de79106b5da4bba0241aa14d81d88f (patch)
treecccfea3a55086a0fcb9a0c089d7cbfc72ca5dfc7 /emfio
parentPotentially uninitialized local variable 'aEvpMd' used (diff)
downloadcore-33d2cf7008de79106b5da4bba0241aa14d81d88f.tar.gz
core-33d2cf7008de79106b5da4bba0241aa14d81d88f.zip
WMF Change the sign of read fields in BITBLT and DIB records
Additionally the names of variables were improved, and additional checks were added for unsupported cases Change-Id: Id84ef1218c5c2a40c8d01f2d40857d892badbb9f Change-Id: I1b8571d0a627827bc1e67c2bfc6c1932d58c5233 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116744 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Diffstat (limited to 'emfio')
-rw-r--r--emfio/inc/wmfreader.hxx2
-rw-r--r--emfio/qa/cppunit/emf/EmfImportTest.cxx34
-rw-r--r--emfio/qa/cppunit/wmf/data/TestStretchDIB.wmfbin0 -> 612 bytes
-rw-r--r--emfio/source/reader/wmfreader.cxx115
4 files changed, 103 insertions, 48 deletions
diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx
index 9e1059d63760..279f3e4caeee 100644
--- a/emfio/inc/wmfreader.hxx
+++ b/emfio/inc/wmfreader.hxx
@@ -55,7 +55,7 @@ namespace emfio
bool ReadHeader();
// reads parameters of the record with the functionnumber nFunction.
- void ReadRecordParams(sal_uInt16 nFunction);
+ void ReadRecordParams(sal_uInt32 nRecordSize, sal_uInt16 nFunction);
Point ReadPoint(); // reads and converts a point (first X then Y)
Point ReadYX(); // reads and converts a point (first Y then X)
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 1613fe943e6f..2ad512d0bac1 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -65,6 +65,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest:
void TestExtTextOutOpaqueAndClipWMF();
void TestPaletteWMF();
void TestRoundrectWMF();
+ void TestStretchDIBWMF();
void TestPolylinetoCloseStroke();
void TestPolyLineWidth();
void TestRoundRect();
@@ -98,6 +99,7 @@ public:
CPPUNIT_TEST(TestExtTextOutOpaqueAndClipWMF);
CPPUNIT_TEST(TestPaletteWMF);
CPPUNIT_TEST(TestRoundrectWMF);
+ CPPUNIT_TEST(TestStretchDIBWMF);
CPPUNIT_TEST(TestPolylinetoCloseStroke);
CPPUNIT_TEST(TestPolyLineWidth);
CPPUNIT_TEST(TestRoundRect);
@@ -685,6 +687,38 @@ void Test::TestRoundrectWMF()
"width", "143");
}
+void Test::TestStretchDIBWMF()
+{
+ // WMF records: STRETCHDIB
+ Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/wmf/data/TestStretchDIB.wmf");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "xy11", "12065");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "xy12", "0");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "xy13", "3598");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "xy21", "0");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "xy22", "12065");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "xy23", "3598");
+
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "height", "10");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "width", "10");
+#if !defined(MACOSX) // TODO DIB display needs to be fixed for macOS
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap",
+ "checksum", "275245357");
+#endif
+}
+
void Test::TestPolyLineWidth()
{
// EMF import with records: CREATEPEN, ROUNDRECT.
diff --git a/emfio/qa/cppunit/wmf/data/TestStretchDIB.wmf b/emfio/qa/cppunit/wmf/data/TestStretchDIB.wmf
new file mode 100644
index 000000000000..c828debbc26e
--- /dev/null
+++ b/emfio/qa/cppunit/wmf/data/TestStretchDIB.wmf
Binary files differ
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index b3998e2e811b..7cd98315adef 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -279,7 +279,7 @@ namespace emfio
return Size( nW, nH );
}
- void WmfReader::ReadRecordParams( sal_uInt16 nFunc )
+ void WmfReader::ReadRecordParams( sal_uInt32 nRecordSize, sal_uInt16 nFunc )
{
SAL_INFO("emfio", "\t" << record_type_name(nFunc));
switch( nFunc )
@@ -803,7 +803,7 @@ namespace emfio
case W_META_BITBLT:
{
- // 0-3 : nWinROP #93454#
+ // 0-3 : nRasterOperation #93454#
// 4-5 : y offset of source bitmap
// 6-7 : x offset of source bitmap
// 8-9 : used height of source bitmap
@@ -817,16 +817,23 @@ namespace emfio
// 24 : planes
// 25 : bitcount
- sal_Int32 nWinROP = 0;
- sal_uInt16 nSx = 0, nSy = 0, nSxe = 0, nSye = 0, nDontKnow = 0, nWidth = 0, nHeight = 0, nBytesPerScan = 0;
+ sal_uInt32 nRasterOperation = 0;
+ sal_uInt16 nYSrc = 0, nXSrc = 0, nSye = 0, nSxe = 0, nBitmapType = 0, nWidth = 0, nHeight = 0, nBytesPerScan = 0;
sal_uInt8 nPlanes, nBitCount;
- mpInputStream->ReadInt32( nWinROP )
- .ReadUInt16( nSy ).ReadUInt16( nSx ).ReadUInt16( nSye ).ReadUInt16( nSxe );
- Point aPoint( ReadYX() );
- mpInputStream->ReadUInt16( nDontKnow ).ReadUInt16( nWidth ).ReadUInt16( nHeight ).ReadUInt16( nBytesPerScan ).ReadUChar( nPlanes ).ReadUChar( nBitCount );
+ mpInputStream->ReadUInt32( nRasterOperation );
+ SAL_WARN("emfio", "\t\t Raster operation: 0x" << std::hex << nRasterOperation << std::dec);
+ if ( nRecordSize == ( ( static_cast< sal_uInt32 >( nFunc ) >> 8 ) + 3 ) )
+ {
+ SAL_WARN("emfio", "\t\t TODO The Bitmap record detected without Bitmap. This case in not supported. Please fill a bug.");
+ break;
+ }
+ mpInputStream->ReadUInt16( nYSrc ).ReadUInt16( nXSrc ).ReadUInt16( nSye ).ReadUInt16( nSxe );
+ Point aPoint( ReadYX() ); // The upper-left corner of the destination rectangle.
+ mpInputStream->ReadUInt16( nBitmapType ).ReadUInt16( nWidth ).ReadUInt16( nHeight ).ReadUInt16( nBytesPerScan ).ReadUChar( nPlanes ).ReadUChar( nBitCount );
- bool bOk = nWidth && nHeight && nPlanes == 1 && nBitCount == 1 && nBytesPerScan != 0;
+ SAL_INFO("emfio", "\t\t Bitmap type:" << nBitmapType << " Width:" << nWidth << " Height:" << nHeight << " WidthBytes:" << nBytesPerScan);
+ bool bOk = nWidth && nHeight && nBytesPerScan > 0 && nPlanes == 1 && nBitCount == 1;
if (bOk)
{
// must be enough data to fulfil the request
@@ -859,63 +866,73 @@ namespace emfio
}
BitmapEx aBitmap = vcl::bitmap::CreateFromData(std::move(aBmp));
if ( nSye && nSxe &&
- ( nSx + nSxe <= nWidth ) &&
- ( nSy + nSye <= nHeight ) )
+ ( nXSrc + nSxe <= nWidth ) &&
+ ( nYSrc + nSye <= nHeight ) )
{
- tools::Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
+ tools::Rectangle aCropRect( Point( nXSrc, nYSrc ), Size( nSxe, nSye ) );
aBitmap.Crop( aCropRect );
}
tools::Rectangle aDestRect( aPoint, Size( nSxe, nSye ) );
- maBmpSaveList.emplace_back(new BSaveStruct(aBitmap, aDestRect, nWinROP));
+ maBmpSaveList.emplace_back(new BSaveStruct(aBitmap, aDestRect, nRasterOperation));
}
}
break;
- case W_META_STRETCHBLT:
case W_META_DIBBITBLT:
case W_META_DIBSTRETCHBLT:
+ case W_META_STRETCHBLT:
case W_META_STRETCHDIB:
{
- sal_Int32 nWinROP = 0;
- sal_uInt16 nSx = 0, nSy = 0, nSxe = 0, nSye = 0, nUsage = 0;
+ sal_uInt32 nRasterOperation = 0;
+ sal_Int16 nYSrc = 0, nXSrc = 0, nSrcHeight = 0, nSrcWidth = 0;
+ sal_uInt16 nColorUsage = 0;
Bitmap aBmp;
- mpInputStream->ReadInt32( nWinROP );
+ mpInputStream->ReadUInt32( nRasterOperation );
+ SAL_WARN("emfio", "\t\t Raster operation: 0x" << std::hex << nRasterOperation << std::dec);
+ if ( nRecordSize == ( ( static_cast< sal_uInt32 >( nFunc ) >> 8 ) + 3 ) )
+ {
+ SAL_WARN("emfio", "\t\t TODO The Bitmap record detected without Bitmap. This case in not supported. Please fill a bug.");
+ break;
+ }
if( nFunc == W_META_STRETCHDIB )
- mpInputStream->ReadUInt16( nUsage );
+ mpInputStream->ReadUInt16( nColorUsage );
- // nSye and nSxe is the number of pixels that has to been used
+ // nSrcHeight and nSrcWidth is the number of pixels that has to been used
// If they are set to zero, it is as indicator not to scale the bitmap later
+ if( nFunc == W_META_DIBSTRETCHBLT ||
+ nFunc == W_META_STRETCHBLT ||
+ nFunc == W_META_STRETCHDIB )
+ mpInputStream->ReadInt16( nSrcHeight ).ReadInt16( nSrcWidth );
- if( nFunc == W_META_STRETCHDIB || nFunc == W_META_STRETCHBLT || nFunc == W_META_DIBSTRETCHBLT )
- mpInputStream->ReadUInt16( nSye ).ReadUInt16( nSxe );
-
- // nSy and nx is the offset of the first pixel
- mpInputStream->ReadUInt16( nSy ).ReadUInt16( nSx );
+ // nYSrc and nXSrc is the offset of the first pixel
+ mpInputStream->ReadInt16( nYSrc ).ReadInt16( nXSrc );
- if( nFunc == W_META_STRETCHDIB || nFunc == W_META_DIBBITBLT || nFunc == W_META_DIBSTRETCHBLT )
+ if( nFunc == W_META_DIBBITBLT ||
+ nFunc == W_META_DIBSTRETCHBLT ||
+ nFunc == W_META_STRETCHDIB )
{
- if ( nWinROP == PATCOPY )
- mpInputStream->ReadUInt16( nUsage ); // i don't know anything of this parameter, so it's called nUsage
+ if ( nRasterOperation == PATCOPY )
+ mpInputStream->ReadUInt16( nColorUsage ); // i don't know anything of this parameter, so it's called nUsage
// DrawRect( Rectangle( ReadYX(), aDestSize ), false );
Size aDestSize( ReadYXExt() );
if ( aDestSize.Width() && aDestSize.Height() ) // #92623# do not try to read buggy bitmaps
{
tools::Rectangle aDestRect( ReadYX(), aDestSize );
- if ( nWinROP != PATCOPY )
+ if ( nRasterOperation != PATCOPY )
ReadDIB(aBmp, *mpInputStream, false);
// test if it is sensible to crop
- if ( nSye && nSxe &&
- ( nSx + nSxe <= aBmp.GetSizePixel().Width() ) &&
- ( nSy + nSye <= aBmp.GetSizePixel().Height() ) )
+ if ( nSrcHeight && nSrcWidth &&
+ ( nXSrc + nSrcWidth <= aBmp.GetSizePixel().Width() ) &&
+ ( nYSrc + nSrcHeight <= aBmp.GetSizePixel().Height() ) )
{
- tools::Rectangle aCropRect( Point( nSx, nSy ), Size( nSxe, nSye ) );
+ tools::Rectangle aCropRect( Point( nXSrc, nYSrc ), Size( nSrcWidth, nSrcHeight ) );
aBmp.Crop( aCropRect );
}
- maBmpSaveList.emplace_back(new BSaveStruct(aBmp, aDestRect, nWinROP));
+ maBmpSaveList.emplace_back(new BSaveStruct(aBmp, aDestRect, nRasterOperation));
}
}
}
@@ -1574,7 +1591,7 @@ namespace emfio
}
if ( !mnSkipActions)
- ReadRecordParams( nFunction );
+ ReadRecordParams( mnRecSize, nFunction );
else
mnSkipActions--;
@@ -1888,32 +1905,36 @@ namespace emfio
}
break;
case W_META_BITBLT:
- case W_META_STRETCHBLT:
case W_META_DIBBITBLT:
case W_META_DIBSTRETCHBLT:
+ case W_META_STRETCHBLT:
case W_META_STRETCHDIB:
{
- sal_Int32 nWinROP;
- sal_uInt16 nSx, nSy, nUsage;
- pStm->ReadInt32( nWinROP );
+ sal_uInt32 nRasterOperation;
+ sal_Int16 nYSrc, nXSrc;
+ sal_uInt16 nColorUsage;
+ pStm->ReadUInt32( nRasterOperation );
if( nFunction == W_META_STRETCHDIB )
- pStm->ReadUInt16( nUsage );
+ pStm->ReadUInt16( nColorUsage );
// nSye and nSxe is the number of pixels that has to been used
- if( nFunction == W_META_STRETCHDIB || nFunction == W_META_STRETCHBLT || nFunction == W_META_DIBSTRETCHBLT )
+ if( nFunction == W_META_DIBSTRETCHBLT ||
+ nFunction == W_META_STRETCHBLT ||
+ nFunction == W_META_STRETCHDIB )
{
- sal_uInt16 nSxe, nSye;
- pStm->ReadUInt16( nSye ).ReadUInt16( nSxe );
+ sal_Int16 nSrcHeight, nSrcWidth;
+ pStm->ReadInt16( nSrcHeight ).ReadInt16( nSrcWidth );
}
- // nSy and nx is the offset of the first pixel
- pStm->ReadUInt16( nSy ).ReadUInt16( nSx );
+ // nYSrc and nXSrc is the offset of the first pixel
+ pStm->ReadInt16( nYSrc ).ReadInt16( nXSrc );
- if( nFunction == W_META_STRETCHDIB || nFunction == W_META_DIBBITBLT || nFunction == W_META_DIBSTRETCHBLT )
+ if( nFunction == W_META_DIBBITBLT ||
+ nFunction == W_META_DIBSTRETCHBLT )
{
- if ( nWinROP == PATCOPY )
- pStm->ReadUInt16( nUsage ); // i don't know anything of this parameter, so it's called nUsage
+ if ( nRasterOperation == PATCOPY )
+ pStm->ReadUInt16( nColorUsage ); // i don't know anything of this parameter, so it's called nUsage
// DrawRect( Rectangle( ReadYX(), aDestSize ), false );
Size aDestSize( ReadYXExt() );