In the previous fix, we were still drawing IDAT data to the reference
frame even when no fcTL was present. This would cause rendering issues
when subsequent frames use APNG_BLEND_OP_OVER blending mode, as they
would composite over the incorrect reference frame. This commit adds a
simple check to properly skip any frame without an fcTL chunk.
We now properly handle OS/2 format BMPs that use 3 bytes per color
entry instead of 4. While OS/2 2.x officially specified 4 bytes per
color, some tools still produce files with 3-byte entries. We can
identify such files by checking the available color table space.
This extends ICO loader to support Windows cursor files. There is no
point in creating a separate loader for this, as the ICO format is
very similar to the CUR format. The only differences are bytes used to
identify the file and a presence of a hotspot in the CUR header.
Color masks should only be used when the compression type is either
BITFIELDS or ALPHABITFIELDS. They were always read before and produced
corrupted images when there was random data in the mask fields.
Other browsers don't think that BMP files with more than 1024 colors are
invalid. They clamp the palette instead, and now we do the same. This
allows us to load more BMPs.
Before this change, IDAT data was mistakenly always included in the
animation. Now we only include frames with explicit fcTL chunks.
As per the PNG spec (third edition):
"The static image may be included as the first frame of the animation
by the presence of a single fcTL chunk before IDAT. Otherwise, the
static image is not part of the animation."
We also fall back to the IDAT data when APNG has acTL but no fcTL
chunks. Test image is 062.png from fDAT-inherits-cICP.html from WPT.
GIF loader was completely failing when encountering errors with
frame descriptors or individual frames, even when some frames were
successfully loaded. Now we attempt to decode at least some frames
and fail only when no frames can be decoded at all.
Fixes wpt/png/exif-chunk.html.
At some point there should probably be some mechanism to handle this
outside of the individual decoder plugins. The TIFF decoder seems to
have its own version of this, and as far as I can tell, the JPEG decoder
doesn't handle this at all, even though that's probably the most common
use case for Exif orientations. :^)
It currently doesn't support animated image.
Note that Gfx::Bitmap has no support for get_pixel when the format is
RGBA8888. This is why it has been removed from the tests.
This matches libwebp (see ZeroFillCanvas() call in
libwebp/src/demux/anim_decode.c:355 and ZeroFillFrameRect() call
in line 435, but in WebPAnimDecoderGetNext()) and makes files
written e.g. by asesprite look correct -- even though the old
behavior is also spec-compliant and arguably makes more sense.
Now nothing looks at the background color stored in the file.
See PR for an example image where it makes a visible difference.
Cherry-picked from serenityos master
276a904d20ffe260b5544a9ace9841d083e0243
Bilevel images are not required to have a BitsPerSample or a
SamplesPerPixel tag, while this is unusual these images are still valid.
The test case has been generated by first making a copy of
ccitt3_1d_fill.tiff and then, using `tiffset` to remove both tags:
tiffset -u 258 ccitt3_no_tags.tiff
tiffset -u 277 ccitt3_no_tags.tiff
...and add a test case that shows why it's incorrect.
If one dimension is 2^n + 1 and the other side is just 1, then the
topmost node will have 2^n x 1 and 1 x 1 children. The first child will
have n levels of children. The 1 x 1 child could end immediately, or it
could require that it also has n levels of (all 1 x 1) children. The
spec isn't clear on which of the two alternatives should happen. We
currently have n levels of 1 x 1 blocks.
This test case shows that a VERIFY we had was incorrect, so remove it.
The alternative implementation is to keep the VERIFY and to add a
if (x_count == 1 && y_count == 1)
level = 0;
to the top of TagTreeNode::create(). Then we don't have multiple levels
of 1 x 1 nodes, and we need to read fewer bits.
The images in the spec suggest that all nodes should have the same
number of levels, so go with that interpretation for now. Once we can
actually decode images, we'll hopefully see which of the two
interpretations is correct.
(The removed VERIFY() is hit when decoding
Tests/LibGfx/test-inputs/jpeg2000/buggie-gray.jpf in a local branch that
has some image decoding implemented. That file contains a packet with
1x3 code-blocks, which hits this case.)
This tests reading JPEG2000 codestreams that aren't embedded in
the ISOBMFF wrapper. It's also useful for debugging bitstream
internals, since the spec lists expected output for many internal
intermediate results.
A tag tree is a data structure used for deserializing JPEG2000
packet headers.
We don't use them for anything yet, except from tests.
The implementation feels a bit awkward to me, but we can always polish
it later.
The spec thankfully includes two concrete examples. The code is
correct enough to pass those -- I added them as test.
The implementation is very similar to #23831.
I created the test exactly like in #23713, except that I replaced the
last four lines in the ini file with:
```
-txt -Param -rATX1 10
-txt -Param -rATY1 -1
-txt -Param -rATX2 4
-txt -Param -rATY2 15
```
This needed the same `jbig2` changes as for the non-transposed ones,
and the changes to it mentioned on #23780.
I used the same .ini files as for the non-transposed ones, except
that I added `-txt -Param -Transposed 1` as last line to each of them.
All three new files display fine in Chrome.
They all look busted in Firefox.
I think this is likey a bug in pdf.js that I'll report upstream.
(Reportedly they look fine in Acrobat on Android.)
This already worked fine. Now it's tested.
I did have to teach `jbig2` to correctly generate test files for this.
See the PR adding these tests for local changes.
I used the script from #23659 to create these images, but I replaced
these lines:
```
-txt -Param -numInst 4
-ID 2 108 50 -ID 3 265 60 -ID 1 100 135 -ID 0 70 232
-txt -Param -RefCorner 2
```
For `bottomleft`, I replaced them with:
```
-txt -Param -numInst 4
-ID 2 137 50 -ID 3 294 60 -ID 1 199 135 -ID 0 319 232
-txt -Param -RefCorner 0
```
For `bottomright`, I replaced them with:
```
-txt -Param -numInst 4
-ID 2 108 50 -ID 3 265 60 -ID 1 100 135 -ID 0 70 232
-txt -Param -RefCorner 2
```
For `topright`, I replaced them with:
```
-txt -Param -numInst 4
-ID 2 108 79 -ID 3 265 89 -ID 1 100 234 -ID 0 70 351
-txt -Param -RefCorner 3
```
All three new files display fine in Chrome.
The bottomleft one displays fine in Firefox, while the other two
look compressed in X. I think this is a bug in pdf.js that I'll
report upstream.
(Reportedly they look fine in Acrobat on Android.)
See the PR adding this test for local changes to `jbig2`.
I used the shell script mentioned in #23659, except I added the line
`-txt -Param -Transposed 1` at the very end of the .ini file.
As with all the symbol test cases, after running
Meta/jbig2_to_pdf.py -o foo.pdf foo.jb2 399 400
the file opens up ok in Chrome and Firefox (but not Safari), so
maybe it's not completely broken.
The T.800 spec says there should only be one 'colr' box, but the
extended jpx file format spec in T.801 annex M allows having multiple.
Method 2 is a basic ICC profile, while method 3 (jpx-only) allows full
ICC profiles. Support that.
For the test, I opened buggie.png in Photoshop, converted it to
grayscale, and saved it as a JPEG2000, with "JP2 Compatible" checked
and "Include Transparency" unchecked. I also unchecked "Include
Metadata", and "Lossless". I left "Fast Mode" checked and the quality
at the default 50.
This adds a test for the code added in #23710.
I created this file using `jbig2` (see below for details), but as
usual it required a bunch of changes to it to make it actually produce
spec-compliant output. See the PR adding this image for my local diff.
I created the test image file by running this shell script with
`jbig2` tweaked as described above:
#!/bin/bash
set -eu
S=Tests/LibGfx/test-inputs/bmp/bitmap.bmp
# See make-symbol-jbig.sh (the script in #23659) for the general
# setup and some comments. See also make-symbol-textrefine.sh (in
# #23713).
#
# `-Ref` takes 5 arguments:
# 1. The symbol ID of this symbol (like after a `-Simple`)
# 2. A bmp file that the base symbol gets refined to
# 3. The ID of the base symbol
# 4. dx, dy
cat << EOF > jbig2-symbol-symbolrefine.ini
-sym -Seg 1
-sym -file -numClass -HeightClass 3 -WidthClass 1
-sym -file -numSymbol 3
-sym -file -Height 250
-sym -file -Width 120 -Simple 0 mouth-1bpp.bmp
-sym -file -EndOfHeightClass
-sym -file -Height 100
-sym -file -Width 100 -Simple 1 nose-1bpp.bmp
-sym -file -EndOfHeightClass
-sym -file -Height 30
-sym -file -Width 30 -Simple 2 top_eye-1bpp.bmp
-sym -file -EndOfHeightClass
-sym -Param -Huff_DH 0
-sym -Param -Huff_DW 0
-sym -Seg 2
-sym -file -numClass -HeightClass 1 -WidthClass 1
-sym -file -numSymbol 1
-sym -file -Height 30
-sym -file -Width 30 -Ref 3 bottom_eye-1bpp.bmp 2 0 0
-sym -file -EndOfHeightClass
-sym -Param -Huff_DH 0
-sym -Param -Huff_DW 0
-sym -Param -RefTemplate 1
-txt -Seg 3
-txt -Param -numInst 4
-ID 2 108 50 -ID 3 265 60 -ID 1 100 135 -ID 0 70 232
-txt -Param -RefCorner 1
-txt -Param -Xlocation 0
-txt -Param -Ylocation 0
-txt -Param -W 399
-txt -Param -H 400
EOF
J=$HOME/Downloads/T-REC-T.88-201808-I\!\!SOFT-ZST-E/Software
J=$J/JBIG2_SampleSoftware-A20180829/source/jbig2
$J -i "${S%.bmp}" -f bmp -o symbol-symbolrefine -F jb2 \
-ini jbig2-symbol-symbolrefine.ini
We can't decode any actual image data yet, but it shows that we can
read the basics of the container format. (...as long as there's an
Annex I container around the data, not just an Annex A codestream.
All files I've found so far have the container.)
I drew the thes input in Acorn.app and used "Save as..." to save it as
JPEG2000. It's an RGBA image.
This adds a test for the code added in #23696.
I created this file using `jbig2` (see below for details), but as
usual it required a bunch of changes to it to make it actually produce
spec-compliant output. See the PR adding this image for my local diff.
I created the test image file by running this shell script with
`jbig2` tweaked as described above:
#!/bin/bash
set -eu
S=Tests/LibGfx/test-inputs/bmp/bitmap.bmp
# See make-symbol-jbig.sh (the script in #23659) for the general
# setup and some comments. Note that the symbol section here only
# has 3 symbols, instead of 4 over there.
#
# `-RefID` takes 6 arguments:
# 1. The symbol ID of the base symbol (like after an `-ID`)
# 2. A bmp file that the base symbol gets refined to
# 3. y, x (like after an `-ID`)
# 4. dx, dy (note swapped order to previous item)
#
# We also explicitly set refinement adaptive pixels, because the
# default adaptive refinement pixels aren't the nominal pixels from
# the spec.
cat << EOF > jbig2-symbol-textrefine.ini
-sym -Seg 1
-sym -file -numClass -HeightClass 3 -WidthClass 1
-sym -file -numSymbol 3
-sym -file -Height 250
-sym -file -Width 120 -Simple 0 mouth-1bpp.bmp
-sym -file -EndOfHeightClass
-sym -file -Height 100
-sym -file -Width 100 -Simple 1 nose-1bpp.bmp
-sym -file -EndOfHeightClass
-sym -file -Height 30
-sym -file -Width 30 -Simple 2 top_eye-1bpp.bmp
-sym -file -EndOfHeightClass
-sym -Param -Huff_DH 0
-sym -Param -Huff_DW 0
-txt -Seg 2
-txt -Param -numInst 4
-ID 2 108 50 -RefID 2 bottom_eye-1bpp.bmp 265 60 0 0
-ID 1 100 135 -ID 0 70 232
-txt -Param -RefCorner 1
-txt -Param -Xlocation 0
-txt -Param -Ylocation 0
-txt -Param -W 399
-txt -Param -H 400
-txt -Param -rATX1 -1
-txt -Param -rATY1 -1
-txt -Param -rATX2 -1
-txt -Param -rATY2 -1
EOF
J=$HOME/Downloads/T-REC-T.88-201808-I\!\!SOFT-ZST-E/Software
J=$J/JBIG2_SampleSoftware-A20180829/source/jbig2
$J -i "${S%.bmp}" -f bmp -o symbol-textrefine -F jb2 -ini \
jbig2-symbol-textrefine.ini
Template 2 is needed by some symbols in 0000372.pdf page 11 and
0000857.pdf pages 1-4. Implement the others too while here. (The
mentioned pages in those two PDFs also use the "end of stripe" segment,
so they still don't render yet.
We still don't support EXTTEMPLATE.
This extracts the bitbuffer combining code we had into a new function
composite_bitbuffer() and adds the following features:
* Real support for combination operators (which also lets us allow black
as background color again, even if that's never used in practice)
* Clipping support (not used here yet, but will be needed elsewhere
soon)
We're going to need this for text segment handling.
No behavior change.