When decoding a CMYK image and asked for a normal `frame()`, the decoder
would convert the CMYK bitmap into an RGB bitmap. Calling `cmyk_frame()`
after that point will provoke a null-dereference.
SamplingFactors already has default initializers for its field,
so no need to have an explicit one for the first of the two fields.
No behavior change.
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.
Previously, we handled sampling factors as part of ycbcr_to_rgb().
That meant it worked ok for code paths that used YCbCr ("normal"
jpegs, and the YCC part of YCCK jpegs), but it didn't work for
example for the K channel in YCCK jpegs, nor for CMYK.
By making this a separate pass, it should now work for all cases.
It also makes it easier to support more subsampling arrangements
in the future, and to use something better than nearest neighbor
for upsampling subsampled blocks.
frame() still returns a regular RGB Bitmap (now lazily converted
from internal CMYK data), but JPEGImageDecoderPlugin now also
implements cmyk_frame().
The decoder assumes that k's sampling factor matches y's at the moment.
Better to error out than to silently render something broken.
For ycck, covered by ycck-2111.jpg in the tests.
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.
This is a hack: Ideally we'd have a CMYK Bitmap pixel format,
and we'd convert to rgb at blit time. Then we could also apply color
profiles (which for CMYK images are CMYK-based).
Also, the colors for our CMYK->RGB conversion are off for PDFs,
and we have distinct codepaths for this in Gfx::Color (for paths)
and JPEGs. So when we fix that, we'll have to fix it in two places.
But this doesn't require a lot of code and it's a huge visual
progression, so let's go with it for now.
It is unlikely this is needed anymore, and as pointed out things should
now safely return OOM if the bitmap is too large to allocate.
Also, no recently added decoders respected this limit anyway.
Fixes#20872
The adobe specification doesn't even consider JPEG images with a single
component. So let's not consider the content of the App14 segment for
grayscale images.
The ideal size is the size the user will display the image. Raster
formats should ignore this parameter, but vector formats can use
it to generate a bitmap of the ideal size.
Decoding progressive JPEGs involves a much more complicated logic than
sequential JPEGs. Thanks to template specialization, this patch allow us
to skip the additional cost of progressive images when it's not needed.
It gives a nice 10% improvements on sequential JPEGs :^)
Some of these functions can be called millions of times even for images
of moderate size. Inlining these functions really helps the compiler and
gives performance improvements up to 10%.
Inside each scan, raw data is read with the following rules:
- Each `0x00` that is preceded by `0xFF` should be discarded
- If multiple `0xFF` are following, only consider one.
That, plus the fact that we don't know the size of the scan beforehand
made us put a prepared stream in a vector for an easy, later on, usage.
This patch remove this duplication by realizing these operations in a
stream-friendly way.
This class is similar to some extent to an implementation of `Stream`,
but specialized for JPEG reading.
Technically, it is composed of a `Vector` to bufferize the input and
provides a simple interface to read bytes.
This patch aims for a future better and specialized control over the
input data. The encapsulation already allows us to get rid of the last
`seek` in the decoder, thus the ability to use the decoder with a raw
`Stream`.
As it provides faster `read` routines, this patch already reduces time
spend on reading.
This is done by two distinct things:
- Allowing 12 bits AC and DC coefficients
- Adjusting coefficients in the IDCT
While this patch allows to display them we still don't correctly do
the color transformation and ultimately only truncating coefficients to
8 bits.
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.
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.