sw/qa/extras/htmlexport/data/paint-ole-bitmap-format.odt |binary
 sw/qa/extras/htmlexport/htmlexport.cxx                   |   33 +++++++++++++++
 sw/source/filter/html/htmlreqifreader.cxx                |    6 ++
 3 files changed, 39 insertions(+)

New commits:
commit b33fe3f5435745daf04758675750033468ac6b3c
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Aug 30 15:00:19 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Aug 31 15:40:12 2022 +0200

    sw reqif/xhtml export: fix invalid pixel formats of graphics exported as OLE
    
    When exporting a Writer document to reqif-xhtml in ExportImagesAsOLE
    mode with something like:
    
            soffice.bin --convert-to 'xhtml:HTML 
(StarWriter):{"XhtmlNs":{"type":"string","value":"reqif-xhtml"},"ExportImagesAsOLE":{"type":"boolean","value":"true"}}'
 test.odt
    
    images are exported as ms paint ole objects instead of plain images.
    
    This happens in WrapGraphicInRtf(), using GraphicConverter::Export()
    where we just specify we want a BMP output. This usually works, but not
    when the bitmap format is something exotic where we try to keep that
    format in BMP, but ms paint can't handle it. When this happens, we get
    an RPC_E_SERVERFAULT error from OleRun() in OleComponent::RunObject(),
    which doesn't say much, except that ms paint failed to read the byte
    array we handed out.
    
    Fix the problem by ensuring that if a graphic is exported as OLE data,
    then it always has the 24bit pixel format.
    
    Interestingly a 8bit BMP can be opened in ms paint manually, but not
    when embedding it as OLE object.
    
    (cherry picked from commit 13219c632b7ec154ba882a715cf890b54f10b146)
    
    Change-Id: I2285bf67c4528cde208ae9fba42ece56822f5403

diff --git a/sw/qa/extras/htmlexport/data/paint-ole-bitmap-format.odt 
b/sw/qa/extras/htmlexport/data/paint-ole-bitmap-format.odt
new file mode 100644
index 000000000000..d83b89459773
Binary files /dev/null and 
b/sw/qa/extras/htmlexport/data/paint-ole-bitmap-format.odt differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 9d2aed175a66..442feecaa145 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -41,6 +41,7 @@
 #include <vcl/graphicfilter.hxx>
 #include <vcl/dibtools.hxx>
 #include <editeng/brushitem.hxx>
+#include <vcl/dibtools.hxx>
 
 #include <itabenum.hxx>
 
@@ -1266,6 +1267,38 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqifOle1Paint)
     CPPUNIT_ASSERT_EQUAL(OString("PBrush"), aClassName);
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PaintBitmapFormat)
+{
+    // Given a document with a 8bpp bitmap:
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"paint-ole-bitmap-format.odt";
+    mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", {});
+
+    // When exporting to reqif-xhtml with ExportImagesAsOLE enabled:
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValue> aStoreProperties = {
+        comphelper::makePropertyValue("FilterName", OUString("HTML 
(StarWriter)")),
+        comphelper::makePropertyValue("FilterOptions", 
OUString("xhtmlns=reqif-xhtml")),
+        comphelper::makePropertyValue("ExportImagesAsOLE", true),
+    };
+    xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
+
+    // Then make sure the resulting bitmap is 24bpp:
+    OUString aRtfUrl = GetOlePath();
+    SvMemoryStream aOle1;
+    ParseOle1FromRtfUrl(aRtfUrl, aOle1);
+    OLE1Reader aOle1Reader(aOle1);
+    Bitmap aBitmap;
+    SvMemoryStream aMemory;
+    aMemory.WriteBytes(aOle1Reader.m_aNativeData.data(), 
aOle1Reader.m_aNativeData.size());
+    aMemory.Seek(0);
+    CPPUNIT_ASSERT(ReadDIB(aBitmap, aMemory, true));
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 24
+    // - Actual  : 8
+    // i.e. it was not a pixel format ms paint could handle in OLE mode.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(24), aBitmap.GetBitCount());
+}
+
 CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testMultiParaListItem)
 {
     // Create a document with 3 list items: A, B&C and D.
diff --git a/sw/source/filter/html/htmlreqifreader.cxx 
b/sw/source/filter/html/htmlreqifreader.cxx
index a091183b9f69..894b78d99d20 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -550,6 +550,12 @@ bool WrapGraphicInRtf(const Graphic& rGraphic, const 
SwFrameFormat& rFormat, SvS
     BitmapEx aBitmapEx = rGraphic.GetBitmapEx();
     Bitmap aBitmap = 
aBitmapEx.GetBitmap(/*aTransparentReplaceColor=*/COL_WHITE);
 
+    if (aBitmap.GetBitCount() != 24)
+    {
+        // More exotic pixel formats cause trouble for ms paint.
+        aBitmap.Convert(BmpConversion::N24Bit);
+    }
+
     if (GraphicConverter::Export(aNativeData, BitmapEx(aBitmap), 
ConvertDataFormat::BMP)
         != ERRCODE_NONE)
     {

Reply via email to