Issue 60272 - Extreme slowness when opening HTML file whose image uses the data URI scheme
Summary: Extreme slowness when opening HTML file whose image uses the data URI scheme
Status: CONFIRMED
Alias: None
Product: Writer
Classification: Application
Component: open-import (show other issues)
Version: OOo 2.0
Hardware: All All
: P3 Trivial (vote)
Target Milestone: ---
Assignee: AOO issues mailing list
QA Contact:
URL:
Keywords: performance
: 121320 (view as issue list)
Depends on:
Blocks:
 
Reported: 2006-01-09 16:07 UTC by encolpe
Modified: 2023-01-04 04:58 UTC (History)
4 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: 4.2.0-dev
Developer Difficulty: ---


Attachments
HTML file with base64 image (68.53 KB, text/html)
2006-01-09 16:29 UTC, encolpe
no flags Details

Note You need to log in before you can comment on or make changes to this issue.
Description encolpe 2006-01-09 16:07:58 UTC
An HTML file with an base64 image make all the OOo windows freeze and the
processus take all the CPU.
This file works with Mozilla/firefox, MSWord, IE6 and HTML editor.
Comment 1 encolpe 2006-01-09 16:29:28 UTC
Created attachment 33061 [details]
HTML file with base64 image
Comment 2 michael.ruess 2006-01-09 16:39:27 UTC
Reassigned to ES.
Comment 3 eric.savary 2006-02-08 15:24:09 UTC
ES->Hbrinkm: no regression.. Please have a look.
Comment 4 pmike 2006-04-13 06:29:30 UTC
Confimed on OO.o 2.0.2, Windows XP
Comment 5 Marcus 2017-05-20 11:22:29 UTC
Reset assigne to the default "issues@openoffice.apache.org".
Comment 6 damjan 2023-01-03 11:09:02 UTC
Still an issue in latest Git.

OpenOffice doesn't actually hang, if you wait long enough, the document will load. Even then, scrolling is unbearably slow, taking almost a minute to update the screen, and only improves when the image scrolls out of view. But why is it so slow?

Here is the top of a stack trace taken while the document was loading and CPU usage was at 100%, with C++ templates trimmed for brevity:

---snip---
#0  0x0000000802910d5e in std::__1::__compressed_pair_elem<std::__1::__unordered_map_equal<>::__get() (this=0x80aab38b0)
    at /usr/include/c++/v1/__memory/compressed_pair.h:103
#1  0x0000000802910b6e in std::__1::__hash_table<>::find<int>(int const&)
    (this=0x80aab3890, __k=@0x7fffffffaf08: 48) at /usr/include/c++/v1/__hash_table:2403
#2  0x0000000802910a25 in std::__1::unordered_map<>::find(int const&)
    (this=0x80aab38b0, __k=<error reading variable: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/v1/unordered_map:1355
#3  0x000000080290f85d in FtFontInfo::GetGlyphIndex(unsigned int) const (this=0x80a278d90, cChar=cChar@entry=48) at source/glyphs/gcach_ftyp.hxx:128
#4  0x000000080290cc0f in FreetypeServerFont::GetRawGlyphIndex(unsigned int) const (this=0x80fa29990, aChar=48) at source/glyphs/gcach_ftyp.cxx:1217
#5  0x000000080290d026 in FreetypeServerFont::GetGlyphIndex(unsigned int) const (this=0x80aab38b0, aChar=4294967295) at source/glyphs/gcach_ftyp.cxx:1290
#6  0x0000000802919184 in ServerFontLayoutEngine::operator()(ServerFontLayout&, ImplLayoutArgs&) (this=<optimized out>, rLayout=..., rArgs=...) at source/glyphs/gcach_layout.cxx:119
#7  0x0000000802a9f842 in OutputDevice::ImplLayout(String const&, unsigned short, unsigned short, Point const&, long, int const*, bool) const (this=this@entry=0x80fa95118, rOrigStr=..., nMinIndex=<optimized out>, nLen=<optimized out>, 
    nLen@entry=18077, rLogicalPos=..., nLogicalWidth=nLogicalWidth@entry=0, pDXArray=0x0, bFilter=<optimized out>) at source/gdi/outdev3.cxx:6055
#8  0x0000000802aa45dd in OutputDevice::GetTextArray(String const&, int*, unsigned short, unsigned short) const (this=this@entry=0x80fa95118, rStr=..., pDXAry=pDXAry@entry=0x0, nIndex=<optimized out>, nLen=18077)
    at source/gdi/outdev3.cxx:5725
#9  0x0000000802aa44c7 in OutputDevice::GetTextWidth(String const&, unsigned short, unsigned short) const (this=0x80fa95118, rStr=..., nIndex=18, nLen=18077) at source/gdi/outdev3.cxx:5653
#10 0x0000000802a63f9f in ImplDrawDefault(OutputDevice*, String const*, Font*, Bitmap const*, BitmapEx const*, Point const&, Size const&)
    (pOutDev=0x80fa95118, pText=0x7fffffffb520, pFont=<optimized out>, pBitmap=pBitmap@entry=0x0, pBitmapEx=<optimized out>, rDestPt=<optimized out>, rDestSize=...) at source/gdi/graph.cxx:165
#11 0x0000000802a64180 in Graphic::DrawEx(OutputDevice*, String const&, Font&, BitmapEx const&, Point const&, Size const&) (pOutDev=0x80aab38b0, rText=..., rFont=..., rBitmap=..., rDestPt=..., rDestSz=<optimized out>)
    at source/gdi/graph.cxx:584
#12 0x000000080ebc0926 in lcl_PaintReplacement(SwRect const&, String const&, ViewShell const&, SwNoTxtFrm const*, unsigned char) (rRect=..., rText=..., rSh=..., pFrm=pFrm@entry=0x80a022110, bDefect=<optimized out>, 
    bDefect@entry=0 '\000') at source/core/doc/notxtfrm.cxx:147
#13 0x000000080ebc1519 in SwNoTxtFrm::PaintPicture(OutputDevice*, SwRect const&) const (this=this@entry=0x80a022110, pOut=pOut@entry=0x80fa95118, rGrfArea=...) at source/core/doc/notxtfrm.cxx:960
---snip---


In frame 13, SwNoTxtFrm::PaintPicture(), we reach this section of code, which deals with failure and tries to paint the replacement text:

---snip---
            else if ( ( rGrfObj.GetType() == GRAPHIC_DEFAULT ||
                        rGrfObj.GetType() == GRAPHIC_NONE ) &&
                      pGrfNd->IsLinkedFile() &&
                      pGrfNd->IsAsyncRetrieveInputStreamPossible() )
            // <--
            {
                Size aTmpSz;
                ::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj();
                if( !pGrfObj ||
                    !pGrfObj->IsDataComplete() ||
                    !(aTmpSz = pGrfNd->GetTwipSize()).Width() ||
                    !aTmpSz.Height() || !pGrfNd->GetAutoFmtLvl() )
                {
                    // --> OD 2006-12-22 #i73788#
                    pGrfNd->TriggerAsyncRetrieveInputStream();
                    // <--
                }
                String aTxt( pGrfNd->GetTitle() );
                if ( !aTxt.Len() )
                    GetRealURL( *pGrfNd, aTxt );
                ::lcl_PaintReplacement( aAlignedGrfArea, aTxt, *pShell, this, sal_False );
                bContinue = sal_False;
            }
---snip---

Frame 12's lcl_PaintReplacement() is then called and paints the replacement text. Note from the code how the text painted is the URL, because there is no title. The URL is however 25806 characters long, and painting that many characters is what massively slows down OpenOffice. The slowness is at the top of the stack, in frames 0-5, which are in the Freetype library.

So the solution for this bug would be:
* Add support for the data URI scheme (https://en.wikipedia.org/wiki/Data_URI_scheme).
* When image URLs can't be loaded, and the replacement text is extremely long such as here, do something to reduce the amount of work Freetype has to do, eg. clip the text that doesn't fit, or limit the maximum length that is painted.
Comment 7 damjan 2023-01-04 04:58:55 UTC
*** Issue 121320 has been marked as a duplicate of this issue. ***