1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 21:54:58 +00:00
Commit graph

87 commits

Author SHA1 Message Date
Lucas CHOLLET
9b5050a11c LibGfx/JPEG: Add support for SOF1 images
More precisely, it allows the decoder to try `SOF1` images. There are
still some sub-kind of this kind of JPEG that we don't support. In a
nutshell `SOF1` images allow more Huffman and quantization tables, 12
bits precision and arithmetic encoding. This patch only brings support
for the "more tables" part.

Please note that `SOF2` images are also allowed to have more tables, so
we gave the decoder the ability to handle these in the same time.
2023-05-09 07:00:15 +02:00
Lucas CHOLLET
844e374de1 LibGfx/JPEG: Fix faded 4-channels images 2023-05-08 19:28:51 +02:00
Lucas CHOLLET
e81baa0464 LibGfx/JPEG: Discard the correct number of bytes
This path has never been tested as it requires a non-standard APP
segment. We (un?)fortunately found one, and it exposed a silly bug.
2023-05-08 19:26:17 +02:00
Lucas CHOLLET
677386bfaa LibGfx/JPEG: Use a lookup table to retrieve huffman symbols
Instead of testing all possible code to find the good symbol, we use a
lookup table to directly find the expected symbol. This method is used
by most Huffman decoder (gzip or libjpeg-turbo).

In order to use the correct key when peeking a constant number of bits
from the stream, we generate duplicates in the table. As an example, for
the code 110, all entries with that pattern 110***** will be set to
110's symbol. So, when you read this code plus garbage from following
codes, you still find the correct symbol.
2023-05-07 09:08:56 +02:00
Lucas CHOLLET
9389177e5f LibGfx/JPEG: Make generate_huffman_codes be a method of HuffmanTable
And call it when reading the table definition instead of when starting
to decode the stream.
2023-05-07 09:08:56 +02:00
Lucas CHOLLET
8cba8ed25a LibGfx/JPEG: Rename HuffmanTableSpec => HuffmanTable 2023-05-07 09:08:56 +02:00
Lucas CHOLLET
011fe0d9ba LibGfx/JPEG: Ensure capacity of vector instead of blindly appending 2023-05-07 09:08:56 +02:00
Lucas CHOLLET
f4014f898d LibGfx/JPEG: Use peek_bits in next_symbol
This allows us to read all bits in a single shot instead of one by one.
2023-05-07 09:08:56 +02:00
Lucas CHOLLET
5ec2aa4dcc LibGfx/JPEG: Introduce peek_bits and use it in read_bits
While already providing a performance improvement by removing the loop
in `read_bits`, this method was introduced to optimize `next_symbol`.
2023-05-07 09:08:56 +02:00
Lucas CHOLLET
86ce9cc30f LibGfx/JPEG: Encapsulate operations on HuffmanStream
Advantages of encapsulation are really obvious here:
- Put related code together
- Prevent external functions to modify the object
- Abstract the implementation

No functional changes intended.
2023-05-07 09:08:56 +02:00
Lucas CHOLLET
66108d102e LibGfx/JPEG: Store previous DC values in i16
Forgotten child of cfaa5120.
2023-05-07 09:08:56 +02:00
Lucas CHOLLET
a08b91e63e LibGfx/JPEG: Rename HuffmanStreamState => HuffmanStream 2023-05-07 09:08:56 +02:00
Tom
e7921cfe14 LibGfx: Add first_animated_frame_index method to ImageDecoder
Some image formats such as APNG may not use the first frame for
animations.
2023-05-05 15:20:44 +01:00
Lucas CHOLLET
ddbe65e2f8 LibGfx/JPEG: Factorize chunk size reading 2023-04-25 06:01:39 +02:00
Lucas CHOLLET
105a40f4f6 LibGfx/JPEG: Rename qtable_id => quantization_table_id 2023-04-25 06:01:39 +02:00
Lucas CHOLLET
dd5d2e3505 LibGfx/JPEG: Support up to 4 quantization tables
We used to limit this number to two and name them with their usual
usage. The specification is however broader, and you can find files that
use more tables as in the following link:

20050519/tests/A_2_1-BF-01.htm
2023-04-25 06:01:39 +02:00
Lucas CHOLLET
f46e3e6644 LibGfx/JPEG: Add myself to the copyright header 2023-04-25 06:01:39 +02:00
Lucas CHOLLET
0d3b62cbb7 LibGfx/JPEG: Use more explicit types and add a bunch of const 2023-04-25 06:01:39 +02:00
Nico Weber
cf3835b29b LibGfx/JPEG: Make non-zero-terminated APPn starts non-fatal
Necessary but not sufficient for #18456.
2023-04-21 22:09:31 -04:00
Lucas CHOLLET
cfaa51203f LibGfx/JPEG: Use a smaller type to store coefficients
No need to store them in `i32`, the JPEG norm specifies that they are
not bigger than 16 bits for extended JPEGs. So, in this patch, we
replace `i32` with `i16`. It almost divides memory usage by two :^)
2023-04-06 12:00:08 +01:00
Lucas CHOLLET
6bc30099f2 LibGfx/JPEG: Add YCCK and CMYK to RGB color transformations
It means that we now fully support JPEGs with four components :^).
2023-04-03 17:12:27 +01:00
Lucas CHOLLET
9cbed7b359 LibGfx/JPEG: Support for images with four components
This patch adds support for properly read images with four components,
basically CMYK or YCCK. However, we still lack color spaces
transformations for this type of image. So, it just postpones failure.
2023-04-03 17:12:27 +01:00
Lucas CHOLLET
261d36351d LibGfx/JPEG: Replace C-style array by Array 2023-04-03 17:12:27 +01:00
Lucas CHOLLET
df12e70541 LibGfx/JPEG: Bring IDCT and YCbCr conversion closer to specification
As mentioned in F.2.1.5 - Inverse DCT (IDCT), the decoder needs to
perform a level shift by adding 128. This used to be done in
`ycbcr_to_rgb` after the conversion. Now, we do it in `inverse_dct` in
order to ensure that the task is done unconditionally.

Consequences of this are that we are no longer required to explicitly
do it for RGB images and also, the `ycbcr_to_rgb` function is exactly
like the specification.
2023-04-03 17:12:27 +01:00
Lucas CHOLLET
f42d850211 LibGfx/JPEG: Don't reject SOF2 image with successive approximations
It means full SOF2 JPEG support, yay!
2023-04-03 17:06:21 +01:00
Lucas CHOLLET
fbad9a70fc LibGfx/JPEG: Support refinement scans
These scans are only present in progressive JPEGs and contains bits to
increase the precision of values acquired in previous scans.
2023-04-03 17:06:21 +01:00
Lucas CHOLLET
8806e66f66 LibGfx/JPEG: Handle ZRL as a special case
When reading the stream, interpreted as a normal value 0xF0 means skip
15 values and assign the 16th to 0. On the other hand, the marker ZRL
- which has the value 0xF0, means skip 16 values. For baseline JPEGs,
ZRL doesn't need to be interpreted differently as writing the 16th value
has no consequence. This is no longer the case with refining scans.
That's why this patch implement correctly ZRL.
2023-04-03 17:06:21 +01:00
Lucas CHOLLET
731c876ff7 LibGfx/JPEG: Change the loop over AC coefficients
We used to skip over zero coefficient by modifying the loop counter. It
is unfortunately impossible to perform this with SOF2 images as only
coefficients with a zero-history should be skipped.
This induces no behavior change for the user of the function.
2023-04-03 17:06:21 +01:00
Lucas CHOLLET
902d0ab58e LibGfx/JPEG: Still iterate over AC coefficients of a EOB targeted block
This commit is nonsense for anything else than SOF2 images with spectral
approximation. For this particular case, skips like EOB or ZRL only
apply to coefficients with a zero-history. This commit prepares the code
to handle this behavior.
2023-04-03 17:06:21 +01:00
Lucas CHOLLET
ef98b06dff LibGfx/JPEG: Split spectral_approximation
This `u8` is actually two values of 4 bits. Let's store them separately
to avoid confusion.
2023-04-03 17:06:21 +01:00
Lucas CHOLLET
cb0c8634d4 LibGfx/JPEG: Use a basic Stream instead of a SeekableStream
Only one use `seek` remains, as it is a bit more complex to remove.
2023-04-03 09:19:15 -04:00
Lucas CHOLLET
dc9e783608 LibGfx/JPEG: Remove the ensure_bounds_okay function
This function has probably been added when we weren't as good with error
propagations as we are now. We can safely remove it and let future
calls to `read` fail if the file is corrupted.

This can be tested with the following bytes (already used in 9191829a):
ffd8ffc000000800080ef701101200ffda00030100
2023-04-03 09:19:15 -04:00
Lucas CHOLLET
3f9c5af553 LibGfx/JPEG: More support for scans with a single component
Introduced in 2c98eff, support for non-interleaved scans was not working
for frames with a number of MCU per line or column that is odd. Indeed,
the decoder assumed that they have scans that include a fabricated MCU
like scans with multiple components.

This patch makes the decoder handle images with a number of MCU per line
or column that is odd. To do so, as in the current decoder state we do
not know if components are interleaved at allocation time, we skip over
falsely-created macroblocks when filling them. As stated in 2c98eff,
this is probably not a good solution and a whole refactor will be
welcome.

It also comes with a test that open a square image with a side of 600px,
meaning 75 MCUs.
2023-03-25 21:31:21 +01:00
Lucas CHOLLET
b820f9ffbd LibGfx/JPEG: Rename mb_index to macroblock_index 2023-03-25 21:31:21 +01:00
Lucas CHOLLET
3d7888f309 LibGfx/JPEG: Log components present in a scan 2023-03-25 21:31:21 +01:00
Lucas CHOLLET
f66de973ff LibGfx/JPEG: Replace a FIXME with some explanations
Calling the `ycbcr_to_rgb` function still looks unsuitable for this
usage, but it does the job correctly.
2023-03-22 08:57:51 +01:00
Lucas CHOLLET
496b7ffb2b LibGfx: Move all image loaders and writers to a subdirectory 2023-03-21 22:39:25 +01:00
Renamed from Userland/Libraries/LibGfx/JPEGLoader.cpp (Browse further)