If the "MMR" bit is set, the generic region decoding procedure just
uses ITU-T T.6 (2D CCITT), which we already have an implementation of.
In practice, this is used almost never in .jbig2 files and in none of
the PDFs I have.
The two files that do use MMR are:
1.) JBIG2_ConformanceData-A20180829/F01_200_TT9.jb2
2) 042_3.jb2 from the ghostpdl tests
The first uses an immediate _lossless_ generic region, which we don't
implement yet (but I think it should just forward to the normal
immediate generic region code? Not in this commit, though). The second
uses a regular immediate generic region, and we can decode it now:
Build/lagom/bin/image -o out.png \
path/to/ghostpdl/tests/jbig2/042_3.jb2
While IMO, the change makes sense on its own as flattening this function
will just duplicate the code from `draw_glyph()` with no benefits, this
is not what motivated this patch.
When compiling with debug information and ASAN, GCC 13.2 would issue
this warning:
Userland/Libraries/LibGfx/Painter.cpp: In member function ‘void Gfx::Pai
nter::draw_glyph(Gfx::FloatPoint, u32, Gfx::Color)’:
Userland/Libraries/LibGfx/Painter.cpp:1354:14: note: variable tracking s
ize limit exceeded with ‘-fvar-tracking-assignments’, retrying without
1354 | FLATTEN void Painter::draw_glyph(FloatPoint point, u32 code_poin
t, Color color)
| ^~~~~~~
From what I've read online, this is caused by some limit on the number
of symbols in the compiler's internal data structures. People at Google
have fixed this warning by splitting functions:
https://codereview.chromium.org/1164893003
While getting us rid of the warning, it also drastically improves
compilation time. Going from 1min27 to 59s on my machine.
Performance handles the document origin time correctly, and prevents
these times from being unusually large. Also initialize the
DocumentTimeline time in the constructor, since these can be created
from JS.
With this, `image` can convert any jbig2 file, as long as it's
black (or white), and LibPDF can draw jbig2 files (again, as long
as they only contain a single color stored in just a
PageInformation segment).
Also make scan_for_page_size() not early return, so that it has the
same behavior as the main decoding look. (Multiple page information
segments for a single page are likely invalid and don't happen in
practice, so this is mostly an academic change.)
Add a BitBuffer class to store the bit image data, and introduce a
Page struct for storing data associated with a page. We currently
only handle a single page, but a) this makes it easier to decode
multiple pages in the future if we want b) it makes the code easier
to understand.
7.4.8.2 Page bitmap height:
"In some cases, this value may not be known at the time that the page
information segment is written. In this case, this field must contain
0xFFFFFFFF, and the actual page height may be communicated later, once
it is known."
Sounds like the spec guarantees that that's the number of the first
page.
(In practice, all but one of all jbig2 files I've found contain just
page 1. PDFs almost always contain just page 1, and very rarely a
page 0 for globally shared parameters.)
If the provided ID is smaller than the corner clipping vector, we would
shrink the vector to match. This causes a crash when we have nested
PaintContext instances (as these IDs are allocated by PaintContext),
each of which perform radius painting.
This is seen on https://www.strava.com/login when it loads a reCAPTCHA.
The outer div has a border radius, which contains the reCAPTCHA in an
iframe. That iframe contains an SVG which also has a border radius.
Now, if an element belongs to a shadow tree, we use only the style
sheets from the corresponding shadow root during style computation,
instead of using all available style sheets as was the case
previously.
The only exception is the user agent style sheets, which are still
taken into account for all elements.
Tests/LibWeb/Layout/input/input-element-with-display-inline.html
is affected because style of document no longer affects shadow tree
of input element, like it is supposed to be.
Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
Doing that will allow us to get a list of style sheets for each shadow
root from StyleComputer without having to traverse the entire tree in
upcoming changes.
If a style element belongs to a shadow tree, its CSSStyleSheet is now
added to the corresponding ShadowRoot instead of the document.
Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
This patch also makes FlexFormattingContext::calculate_static_position
use computed values for margins and borders, since this function may be
called before the box's state has been finalized.
This allows `file` to correctly print the dimensions of a .jbig2 file,
and it allows us to write a test that covers much of all the code
written so far.
Several ramifications:
* /JBIG2Globals is an indirect reference, which means we now need
a Document for unfiltering. (Technically, other decode parameters
can also be indirect objects and we should use the Document to
resolve() those too, but in practice it only seems to be needed
for /JBIG2Globals.)
* Since /JBIG2Globals are so rare, we just parse once for each
image that use them, and decode_embedded() now receives a
Vector<ReadonlyBytes> with all sections of sequences of
segments.
* Internally, decode_segment_headers() is now called several times
for embedded JBIG2s with multiple such sections (e.g. PDFs with
/JBIG2Globals).
* That means `data` is now no longer part of JBIG2LoadingContext
and things get slightly reshuffled due to this.
This completes the LibPDF part of JBIG2 support. Once LibGfx
implements actual decoding of JBIG2s, things should start to
Just Work in PDFs.
They're in different places for Sequential/Embedded (right after
the header) and RandomAccess (which has all headers first, followed
by all data bits next).
We don't do anything with the data yet, but now everything's in
place to actually process segment data.
Except for /JBIG2Globals, which we bail out on for now. In my 1000
files, 13 use JBIG2, and of those, 2 use JBIG2Globals (0000372.pdf e.g.
page 11 and 0000857.pdf e.g. page 1), and only one (the latter) of the
two uses the same JBIG2Globals stream for more than a single image.
JBIG2ImageDecoderPlugin cannot decode the data yet, so no behavior
change, but with `#define JBIG2_DEBUG 1` at the top of that file,
it now prints segment header info for PDFs containing JBIG2 data :^)
With `#define JBIG2_DEBUG 1` at the top of the file:
% Build/lagom/bin/image --no-output \
.../JBIG2_ConformanceData-A20180829/F01_200_TT10.jb2
JBIG2LoadingContext: Organization: 0 (Sequential)
JBIG2LoadingContext: Number of pages: 1
Segment number: 0
Segment type: 48
Referred to segment count: 0
Segment page association: 1
Segment data length: 19
Segment number: 1
Segment type: 39
Referred to segment count: 0
Segment page association: 1
Segment data length: 12666
Segment number: 2
Segment type: 49
Referred to segment count: 0
Segment page association: 1
Segment data length: 0
Runtime error: JBIG2ImageDecoderPlugin: Draw the rest of the owl
With `#define JBIG2_DEBUG 1` at the top of the file:
% Build/lagom/bin/image --no-output \
.../JBIG2_ConformanceData-A20180829/F01_200_TT10.jb2
JBIG2LoadingContext: Organization: 0 (Sequential)
JBIG2LoadingContext: Number of pages: 1
Segment number: 0
Segment type: 48
Referred to segment count: 0
Segment page association: 1
Segment data length: 19
Runtime error: JBIG2ImageDecoderPlugin: Draw the rest of the owl
This is closer to what the spec instructs us to do, and matches how
associations are maintained in the timelines. Also note that the removed
destructor logic is not necessary since we visit the associated
animations anyways.
We create labels in the Browser from text on web documents, which may
use carriage returns. LibGfx will split lines on CR already, but LibGUI
would not consider CRs when computing the height of the containing
widget. The result was text that would not fit in the label's box.