Commit graph

274 commits

Author SHA1 Message Date
Nico Weber
f8362c8abf LibGfx/JPEG2000: Remove an incorrect VERIFY in TagTree construction
...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.)
2024-04-28 01:12:20 +02:00
Timothy Flynn
fecd08ce64 Everywhere: Remove 'clang-format off' comments that are no longer needed 2024-04-24 16:50:01 -04:00
Nico Weber
3568215790 Tests/JPEG2000: Add spec example as test 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.
2024-04-19 12:42:34 -04:00
Nico Weber
ea441fea95 LibGfx: Move QMArithmeticDecoder to its own file
It will be used by the JPEG2000 decoder as well.

Pure code move, no behavior change.
2024-04-19 10:59:11 +02:00
Nico Weber
5ff75ce5fb LibGfx/JBIG2: Rename JBIG2::ArithmeticDecoder to QMArithmeticDecoder
In preparation of moving it to its own file.

No behavior change.
2024-04-19 10:59:11 +02:00
Nico Weber
7296b0fa43 LibGfx/JPEG2000: Implement tag trees
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.
2024-04-16 00:40:16 +02:00
Andreas Kling
217cb01708 LibGfx: Clip out-of-bounds pixel accesses in Painter::draw_rect() 2024-04-14 18:05:48 +02:00
Nico Weber
2d4964b945 LibGfx/JBIG2: Support custom adaptive template pixels in refinement
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
```
2024-04-05 21:32:18 +02:00
Nico Weber
200e36aad3 Tests/JBIG2: Remove test_jbig2_size
It's redundant with test_jbig2_decode nowadays.
2024-04-05 21:32:18 +02:00
Nico Weber
b17a9ad82a Tests/JBIG2: Add test cases for custom adaptive template pixels
I manually wrote a bunch of .ini files and ran this script to
produce the files:

    #!/bin/bash
    set -eu

    J=$HOME/Downloads/T-REC-T.88-201808-I\!\!SOFT-ZST-E/Software
    J=$J/JBIG2_SampleSoftware-A20180829/source/jbig2

    for t in '' template1- template2- template3-; do
      for p in '' '-tpgdon'; do
        i=${t}customat$p
        echo $i.ini
        cat $i.ini
        $J -i Tests/LibGfx/test-inputs/bmp/bitmap -f bmp -o bitmap-$i \
            -F jb2 -ini $i.ini
        cp bitmap-$i.jb2 Tests/LibGfx/test-inputs/jbig2/bitmap-$i.jbig2
      done
    done

The script's output (which shows the .ini file contents) was:

```
% ./make-custom-at.sh
customat.ini
-Gen -Seg 1
-Gen -Param -ATX1 -4
-Gen -Param -ATY1 -5
-Gen -Param -ATX2 6
-Gen -Param -ATY2 -7
-Gen -Param -ATX3 -8
-Gen -Param -ATY3 -9
-Gen -Param -ATX4 10
-Gen -Param -ATY4 -11
ENC Start ===>complete
customat-tpgdon.ini
-Gen -Seg 1
-Gen -Param -ATX1 -4
-Gen -Param -ATY1 -5
-Gen -Param -ATX2 6
-Gen -Param -ATY2 -7
-Gen -Param -ATX3 -8
-Gen -Param -ATY3 -9
-Gen -Param -ATX4 10
-Gen -Param -ATY4 -11
-Gen -Param -TpGDon 1
ENC Start ===>complete
template1-customat.ini
-Gen -Seg 1
-Gen -Param -Template 1
-Gen -Param -ATX1 17
-Gen -Param -ATY1 -2
ENC Start ===>complete
template1-customat-tpgdon.ini
-Gen -Seg 1
-Gen -Param -Template 1
-Gen -Param -ATX1 17
-Gen -Param -ATY1 -2
-Gen -Param -TpGDon 1
ENC Start ===>complete
template2-customat.ini
-Gen -Seg 1
-Gen -Param -Template 2
-Gen -Param -ATX1 17
-Gen -Param -ATY1 -2
ENC Start ===>complete
template2-customat-tpgdon.ini
-Gen -Seg 1
-Gen -Param -Template 2
-Gen -Param -ATX1 17
-Gen -Param -ATY1 -2
-Gen -Param -TpGDon 1
ENC Start ===>complete
template3-customat.ini
-Gen -Seg 1
-Gen -Param -Template 3
-Gen -Param -ATX1 17
-Gen -Param -ATY1 -2
ENC Start ===>complete
template3-customat-tpgdon.ini
-Gen -Seg 1
-Gen -Param -Template 3
-Gen -Param -ATX1 17
-Gen -Param -ATY1 -2
-Gen -Param -TpGDon 1
ENC Start ===>complete
```
2024-04-04 11:44:50 -04:00
Nico Weber
44d3fd0546 Tests/JBIG2: Add tests for transposed non-topleft text reference corners
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.)
2024-04-03 11:40:25 -04:00
Nico Weber
67875ecb6f Tests/JBIG2: Add tests for non-topleft text segment reference corners
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.)
2024-04-03 11:40:25 -04:00
Nico Weber
ce11a34fc6 Tests/LibGfx: Add a jbig2 test for transposed text segments
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.
2024-04-01 14:41:17 +02:00
Nico Weber
ab7da32d25 LibGfx/JPEG2000: Support jpx extended 'colr' boxes
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.
2024-03-30 10:01:07 +01:00
Nico Weber
3f740fc727 Tests/LibGfx: Add some ICC coverage for the JPEG2000 loader 2024-03-30 10:01:07 +01:00
Nico Weber
1570751d64 Tests/LibGfx: Add a jbig2 file using refinement in the symbol segment
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
2024-03-27 11:20:08 -04:00
Nico Weber
9ec5a1591d Tests/JPEG2000: Add a simple JPEG2000 test
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.
2024-03-25 20:35:00 +01:00
Nico Weber
1e31753382 Tests/LibGfx: Add a jbig2 file using refinement in the text segment
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
2024-03-25 15:11:57 -04:00
Nico Weber
b45a4508c7 LibGfx/JBIG2: Implement support for context templates 1, 2, and 3
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.
2024-03-25 14:08:40 +01:00
Nico Weber
e2f02f4df7 Tests/JBIG2: Add test images for non-0 templates
Produced by this shell script:

```sh
S=Tests/LibGfx/test-inputs/bmp/bitmap.bmp
J=$HOME/Downloads/T-REC-T.88-201808-I\!\!SOFT-ZST-E/Software
J=$J/JBIG2_SampleSoftware-A20180829/source/jbig2

for t in template1 template1-tpgdon \
         template2 template2-tpgdon \
         template3 template3-tpgdon; do
  echo $t.ini
  cat $t.ini
  echo
  $J -i "${S%.bmp}" -f bmp -o bitmap-$t -F jb2 -ini $t.ini
  echo
done
```

Producing this output:

```sh
% ./make-templates.sh
template1.ini
-Gen -Seg 1
-Gen -Param -Template 1
-Gen -Param -ATX1 3
-Gen -Param -ATY1 -1

ENC Start ===>complete

template1-tpgdon.ini
-Gen -Seg 1
-Gen -Param -Template 1
-Gen -Param -ATX1 3
-Gen -Param -ATY1 -1
-Gen -Param -TpGDon 1

ENC Start ===>complete

template2.ini
-Gen -Seg 1
-Gen -Param -Template 2
-Gen -Param -TpGDon 1
-Gen -Param -ATX1 2
-Gen -Param -ATY1 -1

ENC Start ===>complete

template2-tpgdon.ini
-Gen -Seg 1
-Gen -Param -Template 2
-Gen -Param -ATX1 2
-Gen -Param -ATY1 -1
-Gen -Param -TpGDon 1

ENC Start ===>complete

template3.ini
-Gen -Seg 1
-Gen -Param -Template 3
-Gen -Param -ATX1 2
-Gen -Param -ATY1 -1

ENC Start ===>complete

template3-tpgdon.ini
-Gen -Seg 1
-Gen -Param -Template 3
-Gen -Param -ATX1 2
-Gen -Param -ATY1 -1
-Gen -Param -TpGDon 1

ENC Start ===>complete
```

`jbig2` still has the local patch mentioned in #23608 to make it write
correct TPGDON data.
2024-03-25 14:08:40 +01:00
Nico Weber
259a84ddac Tests/JBIG2: Add a test for symbol and text segment decoding 2024-03-23 17:30:15 -04:00
Nico Weber
3454970903 LibGfx/JBIG2: Extract composite_bitbuffer() and add some features
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.
2024-03-23 17:30:15 -04:00
Nico Weber
3a50cadddf Tests/LibGfx: Add a jbig2 file using basic symbol and text segments
I created this file using `jbig2` (see below for details), but as
far as I can tell `jbig2` does not produce spec-compliant files:

1. It always writes to 0s for the run lengths that specify how
   many symbols to export at the end of a symbol segment

2. It doesn't write any referred-to segments for text segments.
   I think it's supposed to write a referred-to segment that
   mentions the symbol segment the text segment refers to (?)

I locally tweaked `jbig2` to fix these two defects (*), so the image
added in this commit is correct as best I can tell. It opens fine
using `image` and `jbig2`'s decode mode, and via
`Meta/jbig2_to_pdf.py` in Firefox and Chrome. Without my tweaks,
the image decodes fine with `jbig2`, but not with any of the other
three. The image (in a pdf) does _not_ decode in Preview.app,
either with or without my local `jbig2` tweaks.

*: 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

    I=Build/lagom/bin/image
    S=Tests/LibGfx/test-inputs/bmp/bitmap.bmp

    $I "$S" --crop 232,70,120,250  -o mouth.bmp
    $I "$S" --crop 135,100,100,100 -o nose.bmp
    $I "$S" --crop 50,108,30,30    -o top_eye.bmp
    $I "$S" --crop 60,265,30,30    -o bottom_eye.bmp

    # I then manually converted those to 1bpp using Photoshop
    # (Image->Mode->Grayscale, then Image->Mode->Bitmap...,
    # File->Save As..., bmp) since `jbig2` gets confused by non-1bpp
    # bmp files and `image` can't write 1bpp files :/
    #
    # (I tried `convert ${in} -monochrome ${in}-1bpp.bmp` via
    # https://cancerberosgx.github.io/magic/playground/index.html
    # first, but that produced bmp files that neither Preview.app nor
    # `jbig2` could handle.)
    #
    # -HeightClass: Number of height classes
    # -WidthClass: Maximum number of symbols in one height class
    # -Simple means no refinement; the number after is the symbol's ID
    # The 3 numbers afer `-ID` are id, y, x. The `-ID` are sorted by x.
    # -RefCorner 1 means "top left".
    #
    # `jbig2` writes symbol and text segments as specified in the ini
    # file, and then only stores the bits of the input image that aren't
    # already set through symbol and text segments.

    cat << EOF > jbig2-symbol.ini
    -sym -Seg 1
    -sym -file -numClass -HeightClass 3 -WidthClass 2
    -sym -file -numSymbol 4
    -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 -Width 30 -Simple 3 bottom_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 -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 -F jb2 -ini jbig2-symbol.ini
2024-03-23 08:18:15 -04:00
Nico Weber
576bc0e55b Tests/LibGfx: Consolidate jbig2 decode tests
Removes some duplication, and makes it easier to add additional tests.
No behavior change.
2024-03-22 11:29:27 +01:00
Nico Weber
4329983cde Tests/LibGfx: Fix a small typo in the jbig2 decode tests
Instead of comparing to a reference bmp file, we accidentally were
comparing the file against itself. Luckily, after fixing this, things
still pass.
2024-03-22 11:29:27 +01:00
Nico Weber
7650e657aa LibGfx/JBIG2: Implement support for TPGDON 2024-03-17 17:38:30 +01:00
Nico Weber
edec2b9baa Tests/LibGfx: Add a test jbig2 file using TPGDON
"TPGD" is short for "Typical Prediction for Generic Direct coding",
and the "ON" bit turns it on. In this mode, before decoding a line,
we decode a single bit first that controls if the current line is
just a copy of the previous line. If so, the line's pixels aren't
encoded, the decoder just copies the previous line.

I created this by running

    jbig2 -i Tests/LibGfx/test-inputs/bmp/bitmap -f bmp \
        -o bitmap -F jb2 -ini tpgdon.ini

where tpgdon.ini contained:

    -Gen -Seg 1
    -Gen -Param -TpGDon 1

See previous commits in this directory for details on the `jbig2` tool.

Sadly, the TPGDON writing path in `jbig2` wasn't implemented yet,
so I had to add this. See the PR that added this commit for my
local diff to `jbig2`.

I'm somewhat confident that my change to `jbig2` (and hence the
image added in this commit) is correct because:

1. `jbig2` succeeds in converting this file to a bmp file,
   while it failed without my patch (the decoding codepath in
   `jbig2` does have TPGDON support)

2. Other pdf viewers display the output of
   `Meta/jbig2_to_pdf.py -o foo.pdf path/to/bitmap-tpgdon.jbig2 399 400`
   the same way we do
2024-03-17 17:38:30 +01:00
Nico Weber
f391c7822d LibGfx/JBIG2: Call decode_immediate_generic_region for lossless regions
It seems to do the right thing already, and nothing in the spec says
not to do this as far as I can tell.

With this, we can finally decode
Tests/LibGfx/test-inputs/jbig2/bitmap.jbig2 and add a test for
decoding simple arithmetic-coded images.
2024-03-16 09:21:42 -04:00
Nico Weber
b0c73d1652 LibGfx/JBIG2: Reject unimplemented combination operators
In practice, everything uses white backgrounds and operators `or`
or `xor` to turn them black, at least for the simple images we're
about to be able to decode.

To make sure we don't forget implementing this for real once needed,
reject other ops, and also reject black backgrounds (because 1 | 0
is 1, not 0 like our overwrite implementation will produce).

This means we have to remove a test, but since this scenario doesn't
seem to happen in practice, that seems ok.
2024-03-16 09:21:42 -04:00
Nico Weber
b8f80501ec LibGfx/JBIG2: Pass Context to get_next_bit() instead of to initialize()
The context can vary for every bit we read.

This does not affect the one use in the test which reuses the same
context for all bits, but it is necessary for future changes.
2024-03-16 09:21:42 -04:00
Nico Weber
df9dd8ec69 LibGfx/JBIG2: Add arithmetic coding decoder
I think the context normally changes for every bit. But this here
is enough to correctly decode the test bitstream in Annex H.2 in
the spec, which seems like a good checkpoint.

The internals of the decoder use spec naming, to make the code
look virtually identical to what's in the spec. (Even so, I managed
to put in several typos that took a while to track down.)
2024-03-14 18:18:15 -06:00
Nico Weber
77850f06dc Tests: Remove logspam from TestPainter 2024-03-14 10:56:13 -04:00
MacDue
4c15c87d0c LibGfx/TinyVG: Fix decoding green channel of graphics RGB565 colors
The division was missed here, so this would produce overly bright greens
(or overflow).
2024-03-12 21:53:23 +00:00
Nico Weber
bdbc21c52d LibGfx/JBIG2: Implement conversion to Gfx::Bitmap and ByteBuffer
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).
2024-03-10 10:10:55 -04:00
Nico Weber
54dcb17062 Tests/LibGfx: Add two more test jbig2 files
I extracted a pure-white jbig2 that has only a PageInformation segment
from a PDF and manually edited the bytes to reduce the bitmap size to
47x23 and to clear all unneded bits (except, in the black version,
the page color bit is set).
2024-03-10 10:10:55 -04:00
Nico Weber
8f4930f2df LibGfx/JBIG2: Scan for the first PageInformation segment and decode it
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.
2024-03-09 16:01:22 +01:00
Nico Weber
bd60d1db7e Tests/LibGfx: Add a simple test jbig2 file
I created this by running

    jbig2 -i Tests/LibGfx/test-inputs/bmp/bitmap -f bmp -o bitmap -F jb2

using the `jbig2` tool whose source code is in the zip file here:
https://www.itu.int/rec/T-REC-T.88-201808-I

(Just `make jbig2` in Software/JBIG2_SampleSoftware-A20180829/source
was enough to build it.)

As far as I can tell (cf `JBIG2_EncMain()` which always writes `1`
to the flags byte in the file header), this tool always writes files
in the sequential organization.
2024-03-09 16:01:22 +01:00
Nico Weber
6607757b08 LibGfx: Make validate_before_create() create a regular bool
This is for validating that a decoder with a weak or nonexistent
sniff() method thinks it can decode an image. This should not be
treated as an error.

No behavior change.
2024-03-08 08:38:31 +01:00
Nico Weber
ab143e9b0e LibGfx/BMP: Clear alpha in palette entries
The semantics of BGRx8888 aren't super clear and it means different
things for different parts of the codebase. In particular, the PNG
writer still writes the x channel to the alpha channel of its output.

In BMPs, the 4th palette byte is usually 0, which means after #21412 we
started writing all .bmp files with <= 8bpp as completely transparent
to PNGs.

This works around that.

(See also #19464 for previous similar workarounds.)

The added `bitmap.bmp` is a 1bpp file I drew in Photoshop and saved
using its "Save as..." saving path.
2024-03-05 21:27:41 +00:00
Lucas CHOLLET
9ec3480207 LibGfx/TIFF: Add support for Group4Fax encoded images
Note that we don't parse the T6 option group yet.

The test case was generated with GIMP.
2024-02-21 13:49:43 +01:00
Lucas CHOLLET
be9ec591e7 LibGfx/CCITT: Add support for Group3 2D
The two test images were created with:
tiffcp ccit3.tiff -c g3:2d ccit3_2d.tiff
tiffcp ccit3.tiff -c g3:2d:fill ccit3_2d_fill.tiff
2024-02-19 01:40:04 +01:00
Tim Ledbetter
3ffa2a39bc Tests: Propagate errors with TRY_OR_FAIL() where possible 2024-02-14 17:46:06 -05:00
Lucas CHOLLET
8e21bbf7bf LibGfx/TIFF: Add support for tiled images
A tile is basically a strip with a user-defined width. With that in
mind, adding support for them is quite straightforward. As a lot the
common code was named after 'strips', to avoid future confusion I
renamed everything that interact with either strips or tiles to a
global term: 'segment'.

Note that tiled images are supposed to always have a 'TileOffsets' tag
instead of 'StripOffset'. However, this doesn't seem to be enforced by
encoders, so we support having either of them indifferently.

The test case was generated with the following Python script:

import pyvips

img = pyvips.Image.new_from_file('deflate.tiff')
img.write_to_file('tiled.tiff',
                  compression=pyvips.ForeignTiffCompression.DEFLATE,
                  tile=True, tile_width=64, tile_height=64)
2024-02-13 10:13:11 +01:00
Lucas CHOLLET
b9afac0a06 LibGfx/CCITT: Consider the UseFillBits option 2024-02-12 14:08:56 +01:00
Nico Weber
69964e10f4 LibGfx+Tests: Improve calculation of restart interval
JPEGs can store a `restart_interval`, which controls how many
minimum coded units (MCUs) apart the stream state resets.
This can be used for error correction, decoding parts of a jpeg
in parallel, etc.

We tried to use

    u32 i = vcursor * context.mblock_meta.hpadded_count + hcursor;
    i % (context.dc_restart_interval *
         context.sampling_factors.vertical *
         context.sampling_factors.horizontal) == 0

to check if we hit a multiple of an MCU.

`hcursor` is the horizontal offset into 8x8 blocks, vcursor the
vertical offset, and hpadded_count stores how many 8x8 blocks
we have per row, padded to a multiple of the sampling factor.

This isn't quite right if hcursor isn't divisible by both
the vertical and horizontal sampling factor. Tweak things so
that they work.

Also rename `i` to `number_of_mcus_decoded_so_far` since that
what it is, at least now.

For the test case, I converted an existing image to a ppm:

    Build/lagom/bin/image -o out.ppm \
        Tests/LibGfx/test-inputs/jpg/12-bit.jpg

Then I resized it to 102x77px in Photoshop and saved it again.
Then I turned it into a jpeg like so:

    path/to/cjpeg \
        -outfile Tests/LibGfx/test-inputs/jpg/odd-restart.jpg \
        -sample 2x2,1x1,1x1 -quality 5 -restart 3B out.ppm

The trick here is to:

a) Pick a size that's not divisible by the data size width (8),
   and that when rounded to a block size (13) still isn't divisible
   by the subsample factor -- done by picking a width of 102.
b) Pick a huffman table that doesn't happen to contain the bit
   pattern for a restart marker, so that reading a restart marker
   from the bitstream as data causes a failure (-quality 5 happens
   to do this)
c) Pick a restart interval where we fail to skip it if our calculation
   is off (-restart 3B)

Together with #22987, fixes #22780.
2024-01-30 14:50:43 +01:00
Nico Weber
6971ba35d5 LibGfx+Tests: Support grayscale jpegs with 2x2 sampling and MCU reset
Non-interleaved files always have an MCU of one data unit.

(A "data unit" is an 8x8 tile of pixels, and an "MCU" is a
"minium coded unit", e.g. 2x2 data units for luminance and
1 data unit each for Cr and Cb for a YCrCb image with
4:2:0 subsampling.)

For the test case, I converted an existing image to a ppm:

    Build/lagom/bin/image -o out.ppm \
        Tests/LibGfx/test-inputs/jpg/12-bit.jpg

Then I converted it to grayscale and saved it as a pgm in Photoshop.
Then I turned it into a weird jpeg like so:

    path/to/cjpeg \
        -outfile Tests/LibGfx/test-inputs/jpg/grayscale_mcu.jpg \
        -sample 2x2 -restart 3 out.pgm

Makes 3 of the 5 jpegs failing to decode at #22780 go.
2024-01-30 05:35:22 +01:00
Nico Weber
c694d4326b Tests: Add a pam cmyk test file
Hand-written in a text editor.

I verified that `convert` converts it to a png that looks like the
rgb test expectations.
2024-01-26 07:36:53 +01:00
Nico Weber
ba8f4e73bf Tests: Add a pam test file
Hand-written in a text editor.

I verified that `convert` converts it to a png that looks like the
test expectations.
2024-01-26 07:36:53 +01:00
Nico Weber
550937f5dd Tests: Add a test cmyk jpeg file with an embedded color profile
I opened Base/res/graphics/buggie.png in Photoshop, converted it
to U.S. Web Coated (SWOP) v2, flattened the image so we don't have
CMYK with alpha, and saved it as a jpeg (with color profile embedded).
2024-01-25 15:53:44 +01:00
Lucas CHOLLET
a17041fe7f LibGfx/TIFF: Add support for CMYK
The test case has been generated with Krita.
2024-01-24 22:16:22 -07:00
Lucas CHOLLET
1faf9bb44f LibGfx/TIFF: Apply the HorizontalDifferencing on the alpha channel
When present, the alpha channel is also affected by the horizontal
differencing predictor.

The test case was generated with GIMP with the following steps:
 - Open an RGB image
 - Add a transparency layer
 - Export as TIFF with the LZW compression scheme
2024-01-22 20:10:48 -07:00
Lucas CHOLLET
c2c7365494 LibGfx/TIFF: Accept images with a single strip and no RowsPerStrip tag
This tag is required by the specification, but some encoders (at least
Krita) don't write it for images with a single strip.

The test file was generated by opening deflate.tiff in Krita and saving
it with the DEFLATE compression.
2024-01-19 14:13:44 +01:00
Lucas CHOLLET
75d87ccf5f LibGfx/TIFF+CCITT: Start to decode CCITT Group 3 images
We currently only support 1D Group 3, but that's a start.

The test case was generated with GIMP (it happens to be 1D by chance).
2024-01-18 14:00:56 +01:00
Lucas CHOLLET
edffdc35a9 LibGfx/TIFF+CCITT: Clarify naming of compression type 2
Type 2 <=> One-dimensional Group3, customized for TIFF
Type 3 <=> Two-dimensional Group3, uses the original 1D internally
Type 4 <=> Two-dimensional Group4

So let's clarify that this is not Group3 1D but the TIFF variant, which
is called `CCITTRLE` in libtiff. So let's stick with this name to avoid
confusion.
2024-01-18 14:00:56 +01:00
Nicolas Ramz
534eeb6c4b LibGfx/ILBMLoader: Properly display images with a bitplane mask
Images with a display mask ("stencil" as it's called in DPaint) add
an extra bitplane which acts as a mask. For now, at least skip it
properly. Later we should render masked pixels as transparent, but
this requires some refactoring.
2024-01-18 13:59:17 +01:00
Lucas CHOLLET
015c47da51 Tests/LibGfx: Use TRY_OR_FAIL more in TestImageDecoder 2024-01-15 23:16:57 -07:00
Nico Weber
3616d14c80 LibGfx/JPEG: Allow decoding more subsampling factors
We now allow all subsampling factors where the subsampling factors
of follow-on components evenly decode the ones of the first component.

In practice, this allows YCCK 2111, CMYK 2112, and CMYK 2111.
2024-01-15 11:20:11 -07:00
Nicolas Ramz
a1255cb6c9 LibGfx/ILBMLoader: Don't decode bits once full row has been decoded
We were potentially decoding more bits than needed: this could
trash the next lines if decoder didn't zero the extra bits.
2024-01-14 20:41:25 +01:00
Nico Weber
1b4f9bdbdb Tests: Add a png in Display P3 that shows up as solid color in sRGB
I created a 16-bpp RGB file in Display P3 in photoshop, filled it
with (0, 255, 0), and then drew something on it with (100, 255, 0).

(Since it's a 16-bpp image, 255 ix stored as 0xffff and 100 is stored
as 65535 * 100 / 255 == 0x6464 in the file.)

I verified that Edit->Convert to Profile...->sRGB resulted in an
image filled with (0, 255, 0) in that color space (due to gamut
clipping).

Similar to these:
* https://webkit.org/blog-files/color-gamut/Webkit-logo-P3.png
* https://www.dropbox.com/s/tgarynpj65ouafd/insta-logo.png?dl=1

...but in green instead of in red, and hand-drawn by me so no license
concerns.
2024-01-12 16:20:46 -07:00
Nico Weber
7fb32b6682 LibGfx: Fix off-by-some in Painter::draw_scaled_bitmap_with_transform()
Before this, drawing a 1x1 bitmap scaled up to MxN would only fill
M/2 x N/2 pixel, due to source_point going outside (0, 0).
2024-01-10 09:38:13 +01:00
Nicolas Ramz
fc5b6e4dda LiGfx/ILBMLoader: Don't throw if malformed bitplane can be decoded
Some apps seem to generate malformed images that are accepted
by most readers. We now only throw if malformed data would lead to
a write outside the chunky buffer.
2024-01-08 07:21:27 -07:00
Lucas CHOLLET
335097e446 LibGfx/TIFF: Modify the image according to the Orientation tag
Let's use the already existing logic (ExifOrientedBitmap) to modify the
bitmap to honor the orientation tag.
2024-01-08 00:07:44 +01:00
Lucas CHOLLET
402de2985d LibGfx/ICO: Do not try to decode a mask if we already reached EOF
When using the BMP encoding, ICO images are expected to contain a 1-bit
mask for transparency. Regardless an alpha channel is already included
in the image, the mask is always required. As stated here[1], the
mask is used to provide shadow around the image.

Unfortunately, it seems that some encoder do not include that second
transparency mask. So let's read that mask only if some data is still
remaining after decoding the image.

The test case has been generated by truncating the 64 last bytes
(originally dedicated to the mask) from the `serenity.ico` file and
changing the declared size of the image in the ICO header. The size
value is stored at the offset 0x0E in the file and I changed the value
from 0x0468 to 0x0428.

[1]: https://devblogs.microsoft.com/oldnewthing/20101021-00/?p=12483
2024-01-07 12:32:02 -05:00
Lucas CHOLLET
9c54c13744 Tests/LibGfx: Move the ICO test file to the ico directory
And add more tests on the image than just "we are able to decode it".
2024-01-07 12:32:02 -05:00
Lucas CHOLLET
75fc51bb67 Tests/LibGfx: Fix a typo 2024-01-07 10:22:59 +01:00
Andreas Kling
182a2b0c3a LibGfx/GIF: Only parse global color table if header flag is set
This fixes an issue where GIF images without a global color table would
have the first segment incorrectly interpreted as color table data.

Makes many more screenshots appear on https://virtuallyfun.com/ :^)
2024-01-05 13:20:00 +01:00
Lucas CHOLLET
b8cbc282f3 LibGfx/TIFF: Don't stop decoding when failing to decode a tag
TIFF files are made in a way that make them easily extendable and over
the years people have made sure to exploit that. In other words, it's
easy to find images with non-standard tags. Instead of returning an
error for that, let's skip them.

Note that we need to make sure to realign the reading head in the file.

The test case was originally a 10x10 checkerboard image with required
tags, and also the `DocumentName` tag. Then, I modified this tag in a
hexadecimal editor and replaced its id with 30 000 (0x3075 as a LE u16)
and the type with the same value as well. This is AFAIK, never used as
a custom TIFF tag, so this should remain an invalid tag id and type.
2024-01-04 14:27:16 +01:00
Lucas CHOLLET
73c8b4865e LibGfx/TIFF: Add AdobeDeflate compression support
This new compression is quite popular and uses a basic Zlib compression
to compress strips. Note that this is not part of the original TIFF
specification but in the Technical Notes from 2002:
https://web.archive.org/web/20160305055905/http://partners.adobe.com/public/developer/en/tiff/TIFFphotoshop.pdf

The test case was generated with GIMP.
2023-12-29 20:12:07 +01:00
Nico Weber
a2bd19fdac LibGfx/JPEG: Make ycck jpegs with just cc subsampled decode correctly
We currently assume that the K (black) channel uses the same sampling
as the Y channel already, so this already works as long as we don't
error out on it.
2023-12-29 09:45:31 -05:00
Nico Weber
4236798244 Tests/LibGfx: Add automated tests for ycck jpegs
Only one of the three test cases pass at the moment.
2023-12-29 09:45:31 -05:00
Nico Weber
e735ee5251 Tests/LibGfx: Add YCCK jpeg test files
Obtained by running:

    convert rgb_components.jpg -colorspace cmyk \
        -sampling-factor 1 ycck-1111.jpg
    convert rgb_components.jpg -colorspace cmyk \
        -sampling-factor 2 ycck-2111.jpg
    convert rgb_components.jpg -colorspace cmyk ycck-2112.jpg

where rgb_components.jpg is the file in Tests/LibGfx/test-inputs/jpg.

(I used the web version of `convert` at
https://cancerberosgx.github.io/magic/playground/index.html)

While this does indeed produce a cmyk jpg (using the YCCK encoding
internally), it uses the mathematical rgb->cmyk conversion and does
not embed an cmyk color space in the output jpg.

Normally, cmyk images are for printing and hence converting them
from cmyk to rgb using a color profile like SWOP leads to better
results. So if a cmyk image does not contain color space information,
applications might use something like SWOP instead of the simple
math transform to convert to RGB. Programs doing that will show
these images as fairly muted (and would arguably be correct doing
so).

Hence, tests using these images shouldn't check their RGB values.
Ideally, we'd add a way to get the raw cmyk data from a cmyk jpeg,
and then tests could test color values against that.

The -1111 image uses no subsampling, meaning each channel's sampling
factor is 1.

The -2111 image uses subsampling for the non-Y channels, meaning the
sampling factors are 2 for Y and 1 each for YYK.

The -2112 image uses subsampling for the two C channels, meaning the
sampling factors are 2 for Y and K and 1 each for YY.

We correctly render the -1111 variant (using e.g.
`Build/lagom/bin/image -o out.png .../ycck-1111.jpg).

We render the -2111 variant, but it looks pretty broken.

We refuse to decode the -2112 variant. This is #21259.

Manual tests for now, but having these in tree will make it easier
to write unit tests later, once things work better.
2023-12-29 08:17:10 +00:00
Lucas CHOLLET
67522fab2e LibGfx/TIFF: Add support for RGBPalette images
TIFF images with the PhotometricInterpretation tag set to RGBPalette are
based on indexed colors instead of explicitly describing the color for
each pixel. Let's add support for them.

The test case was generated with GIMP using the Indexed image mode after
adding an alpha layer. Not all decoders are able to open this image, but
GIMP can.
2023-12-23 20:41:48 +01:00
Lucas CHOLLET
2cfca633ca LibGfx/TIFF: Add support for images with UnassociatedAlpha
UnassociatedAlpha is the one used by GIMP when generating TIFF images
with transparency. Support is added for Grayscale and RGB images as it's
the two that we support right now but managing transparency should be
really straightforward for other types as well.
2023-12-22 08:08:47 +00:00
Nicolas Ramz
6ccdb1dc72 LibGfx/ILBMLoader: Add support for 24bit files 2023-12-21 09:19:30 +00:00
Lucas CHOLLET
64912d4d02 LibGfx/TIFF: Add support for images with CCITT3 1D compression
This compression (tag Compression=2) is not very popular on its own, but
a base to implement CCITT3 2D and CCITT4 compressions.

As the format has no real benefits, it is quite hard to find an app that
accepts tho encode that for you. So I used the following program that
calls `libtiff` directly:
```cpp
#include <vector>
#include <cstdlib>
#include <iostream>

#include <tiffio.h>

// An array containing 0 and 1 of length width * height.
extern std::vector<uint8_t> array;
int main() {
    // From: https://stackoverflow.com/a/34257789

    TIFF *image = TIFFOpen("input.tif", "w");
    int const width = 400;
    int const height = 300;
    TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width);
    TIFFSetField(image, TIFFTAG_IMAGELENGTH, height);
    TIFFSetField(image, TIFFTAG_PHOTOMETRIC, 0);
    TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_CCITTRLE);

    TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 1);
    TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1);

    std::vector<uint8_t> scan_line(width / 8 + 8, 0);
    int count = 0;
    for (int i = 0; i < height; i++) {
        std::fill(scan_line.begin(), scan_line.end(), 0);
        for (int x = 0; x < width; ++x) {
            uint8_t eight_pixels = scan_line.at(x / 8);
            eight_pixels = eight_pixels << 1;
            eight_pixels |= !array.at(i * width + x);
            scan_line.at(x / 8) = eight_pixels;
        }
        int bytes = int(width / 8.0 + 0.5);
        if (TIFFWriteScanline(image, scan_line.data(), i, bytes) != 1)
            std::cerr << "Something went wrong\n";
    }

    TIFFClose(image);
}
```
2023-12-19 21:01:24 +01:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).

This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
2023-12-17 18:25:10 +03:30
Nicolas Ramz
cd6c7f3fc4 LibGfx/ILBMLoader: Add support for PC DeluxePaint files 2023-12-13 10:39:13 +00:00
Lucas CHOLLET
234d084876 LibGfx/TIFF: Add support for bit-depth up to 32 bits per sample
This makes us support every "minisblack" and "rgb-contig" images from
the depth folder of libtiff's test suite:
https://libtiff.gitlab.io/libtiff/images.html
2023-12-09 21:47:33 +01:00
Lucas CHOLLET
25993cd93b Tests: Use TRY_OR_FAIL instead of MUST in TestImageDecoder.cpp
No need to panic the executable on a test failure.
2023-12-09 19:05:45 +01:00
Nicolas Ramz
8d68f94282 LibGfx/ILBMLoader: Add HAM6/HAM8 support 2023-12-07 10:08:29 -07:00
Lucas CHOLLET
da134f6867 LibGfx/TIFF: Add support for grayscale images
Images with a single sample per pixel should be interpreted as
grayscale.
2023-12-07 08:17:46 +00:00
Nico Weber
b2a1130556 LibGfx/ICC: Implement conversion between different connection spaces
If one profile uses PCSXYZ and the other PCSLAB as connection space,
we now do the necessary XYZ/LAB conversion.

With this and the previous commits, we can now convert from profiles
that use PCSLAB with mAB, such as stress.jpeg from
https://littlecms.com/blog/2020/09/09/browser-check/ :

    % Build/lagom/icc --name sRGB --reencode-to serenity-sRGB.icc
    % Build/lagom/bin/image -o out.png \
        --convert-to-color-profile serenity-sRGB.icc \
        ~/src/jpegfiles/stress.jpeg
2023-12-04 08:02:36 +00:00
Tim Ledbetter
aa54007943 LibGfx/TinyVG: Avoid OOM if header contains a bogus color table size
This change limits the amount of memory that is initially allocated for
the color table. This prevents an OOM condition if the file contains an
incorrect color table size.
2023-12-02 10:47:39 +01:00
Lucas CHOLLET
4994609af0 LibGfx/TIFF: Add support for the ICCProfile tag 2023-12-02 10:36:02 +01:00
Lucas CHOLLET
272be6b20a LibGfx/TIFF: Add support for LZW compression 2023-11-12 13:56:27 +01:00
Tim Ledbetter
c1d7a51391 LibGfx/ICC: Avoid buffer overrun when creating TextDescriptionTagData
We now validate that the offsets used cannot overflow, preventing
possible buffer overruns.
2023-11-08 09:37:30 +01:00
Tim Ledbetter
f56ae8c0e9 LibGfx/ILBM: Ensure CMAP chunk size matches expected value
The color map should be 3 bytes per pixel and should contain
`2^nPlanes` pixels. We now return an error if the color map isn't the
size we expect.
2023-11-08 09:36:01 +01:00
Tim Ledbetter
ae6c39e501 LibGfx/ILBM: Ensure decompressed body chunk data is the correct length 2023-11-08 09:36:01 +01:00
Tim Ledbetter
39f7f1e84c Tests: Use more representative test cases for ILBM regression tests
Previously, the regression tests for OSS-Fuzz issues 62033 and 63296
used test case files directly from OSS-Fuzz. These files are invalid
in multiple ways because they have been generated by a fuzzer. This
commit replaces these files with ones that only expose the issue being
tested.
2023-11-08 09:36:01 +01:00
Lucas CHOLLET
81794df280 LibGfx/TIFF: Add support for images with PackBits compression 2023-11-08 09:28:36 +01:00
Lucas CHOLLET
ed8d82f3de Tests/LibGfx: Move the tiff image to its own folder 2023-11-08 09:28:36 +01:00
Lucas CHOLLET
404093a42e Tests/LibGfx: Add a test for the TIFF decoder 2023-11-06 12:29:30 -07:00
Tim Ledbetter
438e9e146c LibGfx/JPEG: Refill reservoir if necessary when discarding bits
This condition was hit 157 times out of the 109,233 JPEG images in the
Govdocs1 corpus. This change allows all of these
images to load correctly.
2023-11-05 09:01:15 +01:00
MacDue
50d33f79fa LibGfx: Allow extracting paths from fonts and add Gfx::Path::text()
This updates fonts so rather than rastering directly to a bitmap, you
can extract paths for glyphs. This is then used to implement a
Gfx::Path::text("some text", font) API, that if given a vector font
appends the path of the text to your Gfx::Path. This then allows
arbitrary manipulation of the text (rotation, skewing, etc), paving the
way for Word Art in Serenity.
2023-11-05 02:46:46 +01:00
Andrew Kaster
1567332e34 Userland+Tests: Remove uses of direct file loading for BitmapFont
Route them through Core::Resource APIs instead.
2023-10-29 13:12:28 -06:00
Tim Ledbetter
1a4df4ffe7 LibGfx/ICC: Avoid overflow when constructing NamedColor2TagData 2023-10-26 10:59:22 +02:00
Tim Ledbetter
52f78d07b8 LibGfx/WOFF2: Ensure numTables is within expected range
An error is now returned if `numTables` is zero or greater than 4096.
While this isn't explicitly mentioned in the specification, subsequent
calculations will be incorrect if the value falls outside this range.
2023-10-26 08:39:26 +02:00
Tim Ledbetter
2311e28d63 LibGfx/BMPLoader: Mitigate potential overflows when decoding bitmap DIB 2023-10-25 05:52:29 +02:00
Tim Ledbetter
e9be1bcd09 LibGfx/WOFF2: Reject fonts with a compressed size larger than 10MiB
This prevents a potential OOM condition when the header is malformed.
2023-10-24 13:45:01 +02:00
Tim Ledbetter
af633523af LibGfx/WOFF2: Tolerate incorrect totalSfntSize in WOFF2 header
The specification says that this value is for reference only, so we
should be able to load a file where this value is incorrect.
2023-10-24 13:45:01 +02:00