Commit Graph

665 Commits

Author SHA1 Message Date
Nico Weber
51fc51d0b5 LibGfx/WebPWriter: Use one-element huffman tree for opaque images
That way, we can write 0 instead of 8 bits for every alpha byte.
Reduces the size of sunset-retro.png when saved as a webp file
from 3 MiB to 2.25 MiB, without affecting encode speed.

Once we use CanonicalCodes we'll get this for free for all channels,
but opaque images are common enough that it feels worth it to do this
before then.
2024-05-07 11:13:01 -04:00
Nico Weber
7d93f7fc99 LibGfx/WebPWriter: Correctly fill in alpha_is_used hint 2024-05-07 11:13:01 -04:00
Nico Weber
0e2e7cd1be LibGfx/WebPWriter: Rename alpha_hint to alpha_is_used_hint
No behavior change.
2024-05-07 11:13:01 -04:00
Nico Weber
5b335d51e1 LibGfx/WebPWriter: Implement ICC color profile data writing
Most of this code (VP8X chunk writing) will be used for writing
animated webp files too.
2024-05-07 11:11:41 -04:00
Nico Weber
c174adc6b1 LibGfx/WebPLossless: Remove a useless non-spec comment
There's already a spec comment saying the same thing a few lines
further down, just move that up.

No behavior change.
2024-05-07 11:10:06 -04:00
Nico Weber
7b3cc2e055 LibGfx/WebPLossless: Add spec ref about color indexing modifying width
No behavior change. This got clarified here:
https://chromium-review.googlesource.com/c/webm/libwebp/+/4688320
2024-05-07 11:10:06 -04:00
Nico Weber
26b3e31f2e LibGfx/WebPLossless: Make width_bits reading look more like in the spec
No behavior change.
2024-05-07 11:10:06 -04:00
Nico Weber
c1b289c144 LibGfx/WebPLossless: Add spec note about combining predicted values
No behavior change. This got clarified in the spec in
https://chromium-review.googlesource.com/c/webm/libwebp/+/4638649
2024-05-07 11:10:06 -04:00
Nico Weber
3662eea0ac LibGfx/WebPLossless: Update spec comments for reading max_symbol
This used to be misleading in the spec, but that was fixed in
https://chromium-review.googlesource.com/c/webm/libwebp/+/4674031

Update the comments to match.

Also, a check we already had got added to the spec in
https://chromium-review.googlesource.com/c/webm/libwebp/+/4674032
so add a citation for that.

No behavior change.
2024-05-07 11:10:06 -04:00
Nico Weber
a511f5507c LibGfx/WebPLossless: Add spec comment about transform order
This used to not be mentioned in the spec, but it got added
based on our feedback:
https://chromium-review.googlesource.com/c/webm/libwebp/+/4637757
2024-05-07 11:10:06 -04:00
Nico Weber
e69a0fa7d3 LibGfx/WebPLossless: Add a spec comment
No behavior change. Makes things flow better with the comment I'm
about to add in the next commit.
2024-05-07 11:10:06 -04:00
Nico Weber
5897e9bd29 LibGfx/WebPLossless: Move around a spec comment
That way, we don't need a comment that wasn't from the spec.
No behavior change.
2024-05-07 11:10:06 -04:00
Nico Weber
076a8e5d0b LibGfx/WebPLossless: Remove "AMENDED" in spec comments
No behavior change. This corresponds to this spec change:
https://chromium-review.googlesource.com/c/webm/libwebp/+/4567695
2024-05-07 11:10:06 -04:00
Nico Weber
05bb657b8b LibGfx/WebPLossless: Replace num_code_lengths check with VERIFY
No behavior change. This corresponds to this spec change:
https://chromium-review.googlesource.com/c/webm/libwebp/+/4779444
2024-05-07 11:10:06 -04:00
Lucas CHOLLET
3c138b9580 LibGfx/TIFF: Support bilevel images missing baseline tags
Bilevel images are not required to have a BitsPerSample or a
SamplesPerPixel tag.
2024-05-06 17:33:25 +02:00
Lucas CHOLLET
eb142b1d28 LibGfx/TIFF: Put code to check for bilevel images in its own function 2024-05-06 17:33:25 +02:00
Lucas CHOLLET
8fb9c72c56 LibGfx/TIFF: Manually check for the presence of two baseline tags
Namely: BitsPerSample and SamplesPerPixel.
2024-05-06 17:33:25 +02:00
Nico Weber
d0a2cf2dce LibGfx/WebPWriter: Implement basic lossless webp writing
This doesn't use any transforms yet (in particular not the predictor
transform), and doesn't do anything else that actually compresses the
data.

It also give all 256 values code length 8 unconditionally. This means
the huffman trees are not data-dependent at all and provide no
compression. It also means we can just write out the image data
unmodified.

So the output is fairly large. But it _is_ a valid lossless webp file.

Possible follow-ups, to improve compression later:
1. Use actual byte distributions to create huffman trees, to get
   huffman compression.
2. If the distribution has just 1 element, write a simple code length
   code (that way, images that have alpha 0xff everywhere need to store
   no data for alpha).
3. Add backref support, to get full deflate(ish) compression of pixels.
4. Add predictor transform.
5. Consider writing different sets of prefix codes for every 16x16 tile
   (by writing a meta prefix code image).

(It might be nice to make the follow-ups optional, so that this can also
be used as a webp example file generator.)
2024-05-06 17:32:19 +02:00
Nico Weber
d04f9cf3c8 LibGfx+image: Add scaffolding for writing webp files 2024-05-06 17:32:19 +02:00
Nico Weber
dd020a108a LibGfx/WebP: Rename two variables to be a bit clearer
No behavior change.
2024-05-04 13:46:53 +02:00
Sergey Bugaev
51707a4dbd LibGfx: Explicitly cast literals to size_t in JBIG2Loader
width is size_t, so 8 should be that too, not unsigned long long.
2024-05-02 07:46:53 -06:00
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
Nico Weber
b364a58753 LibGfx/JPEG2000: Read COC marker segments, both in main and tile headers
Not yet used for anything.
2024-04-25 09:00:46 -04:00
Nico Weber
8eb3d436e6 LibGfx/JPEG2000: Extract CodingStyleParameters
This is the data shared between COD and COC marker segments.

No behavior change.
2024-04-25 09:00:46 -04:00
Nico Weber
3735f2cbed LibGfx/JPEG2000: Read COD on tile headers too
I haven't seen this in the wild yet, but it is allowed per spec
and easy to do.
2024-04-25 09:00:46 -04:00
Nico Weber
0c935f8f42 LibGfx/JPEG2000: Support reading raw jpeg2000 codestreams
Most JPEG2000 files put the codestream in an ISOBMFF box structure
(which is useful for including metadata that's bigger than the
~65k marker segment data limit, such as large ICC profiles), but
some files just store the codestream directly, for example
https://sembiance.com/fileFormatSamples/image/jpeg2000/balloon.j2c

See https://www.iana.org/assignments/media-types/image/j2c for the
mime type.

The main motivation is to be able to use the test data in J.10 in
the spec as a test case.
2024-04-19 12:42:34 -04:00
Nico Weber
5695acf328 LibGfx/JPEG2000: Add comment mentioning J.10 2024-04-19 12:42:34 -04:00
Nico Weber
1a232ba2a6 LibGfx/JPEG2000: Check SIZ marker (w, h) against JP2 header (w, h) 2024-04-19 12:42:34 -04:00
Dan Klishch
5ed7cd6e32 Everywhere: Use east const in more places
These changes are compatible with clang-format 16 and will be mandatory
when we eventually bump clang-format version. So, since there are no
real downsides, let's commit them now.
2024-04-19 06:31:19 -04:00
Nico Weber
ca3a62a6bb LibGfx: Add a comment to QMArithmeticDecoder.h 2024-04-19 10:59:11 +02: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
Nico Weber
69fa1d1b6e LibGfx/WebP: Remove a bounds check that is never hit
No behavior change.
2024-04-15 15:53:52 +02:00
Nico Weber
04c6af7dfd LibGfx/WebP: Add two spec comments 2024-04-15 15:53:52 +02:00
Nico Weber
f9fa41cadf LibGfx/JPEG2000: Use streams instead of manual offsets
No behavior change for valid images. More cryptic errors for invalid
images, but on the flipside quite a bit less code.
2024-04-10 10:51:04 -04:00
Nico Weber
2c9c996130 LibGfx/JPEG2000: Fix off-by-one in reading comment data 😬
For text, we always ended up with a leading \0 byte (on little-endian),
which prints as nothing. Since that's the only thing we do with this
data, no actual behavior change.
2024-04-10 10:51:04 -04:00
Nico Weber
b2d7c405cd LibGfx/JPEG2000: Remove needless "AK::" qualifiers 2024-04-10 10:51:04 -04:00
Nico Weber
f91d8472ee LibGfx/JPEG2000: Make unimplemented markers in tile-part header fatal 2024-04-09 15:52:00 -04:00
Nico Weber
dbe179f0d5 LibGfx/JPEG2000: Decode tile-part QCD and QCC marker segment data 2024-04-09 15:52:00 -04:00
Nico Weber
8ba7c23165 LibGfx/JPEG2000: Decode QCC marker segment data
I haven't seen any images that set this in the main header, but
Tests/LibGfx/test-inputs/jpeg2000/buggie-gray.jpf sets it in a tile-part
header.
2024-04-09 15:52:00 -04:00
Nico Weber
072457edd8 LibGfx/JPEG2000: Decode tile-part COM marker segment data
We don't do anything with this (except log the contents if
JPEG2000_DEBUG is 1).
2024-04-09 15:52:00 -04:00
Nico Weber
38be93c9a1 LibGfx/JPEG2000: Store some tile and tile part data on context 2024-04-09 15:52:00 -04:00
Nico Weber
0df01dea4a LibGfx/JPEG2000: Add two spec comments 2024-04-09 15:52:00 -04:00
Nico Weber
7b7ef7dcc7 LibGfx/JPEG2000: Allow COD, COC, QCD, QCC, RGN only in first tile-part
(The FIXME was incomplete, it didn't mention RGN also only being valid
in a tile's first tile-part header.)
2024-04-09 15:52:00 -04:00
Nico Weber
1df5c01bfb LibGfx/JPEG2000: Make unimplemented markers in main header fatal
We now implement decoding enough marker segments that we can do this.
2024-04-09 15:52:00 -04:00
Nico Weber
b9677be8a7 LibGfx/JPEG2000: Decode COM marker segment data
We don't do anything with this (except log the contents if
JPEG2000_DEBUG is 1).

The motivation is that we now decode all marker segments that are
used in all JPEG2000 files I've seen so far, allowing us to make
remaining unknown marker types fatal.
2024-04-09 15:52:00 -04:00
Nico Weber
e05791f5dd LibGfx/JPEG2000: Decode QCD marker segment data
We now decode all required main header marker segments :^)
2024-04-09 15:52:00 -04:00
Nico Weber
99c1c685fc LibGfx/JPEG2000: Decode COD marker segment data 2024-04-09 15:52:00 -04:00
Nico Weber
d8811a83c9 LibGfx/JPEG2000: Decode SIZ marker segment data 2024-04-09 15:52:00 -04:00