Do we even want to error early here? This isn't exactly fatal to reading
the image it is a only nuisance. It becomes crucial only when we are at
the point of reading all the tiles themselves.
I didn't realize we support this in a slightly weird manner where the
tag is completely ignored and zune-jpeg performs the upsampling as
indicated in the JPEG stream. This is a recurring problem with the
compression scheme and tags in TIFF. In the end, decoder can only handle
the data as indicated by the JPEG steam and while the specification
requires the tags to be consistent with the underlying data, sometimes
they are not. The useful fallback is of course to ignore the tag.
Ignoring the tag of course buts us in a weird spot for zero-copy
decoding since the buffer indication to the caller will be incorrect.
For now, maybe the best way of treating subsampling is to upsample all
the cases when we add support.
In particular we avoid mistaking the absence of this tag for an absence
of subsampling. The specification instead requires it to mean half the
samples in both directions—a mode that we do not support yet. Instead of
returning erroneous samples or an error in the data stream (which would
appear too short) we return an error when asked to layout the read
buffer for these images.
By adding the type interpretation to `BufferLayoutPreference` (simply
computed from the same fields that are trivial to fetch in
`ReadoutLayout` with the rest) we can allocate an appropriate
`DecoderResult` without any `Decoder` instance. We still want a Limits
instance though. This lets a caller read _typed_ data from the `_bytes`
methods which perform less allocations. It also lets them read multiple
planes in a more convenient interface. See, `read_image` will keep its
planar treatment bug for a little bit so you don't accidentally break
during an upgrade.
This also implies less code is being monomorphized, just a bonus.
This is well-defined even if we add sub-sampling support later on. We
can adjust the layout type accordingly with factors per each plane. Note
that the layout, in theory, does not depend on the index of the unit if
we describe all planes for a multi-planar layout. The specification
requires that the subsampling factors divide the tile sizes. However we
have to handle non-planar images here and this leaves us open to other
potential parameters.
We currently have one type in decoder/image.rs and another in
decoder/mod.rs which each contributes part of the computation for laying
out the output buffer. Confusingly though they rely on shared
implementation details such as determining the number of channels that
are written and their bit depth. We should have one shared method and
resulting struct instead.
These samples are normal bits in the encoded (e.g. compressed) stream of
each tile or row of the image. However, when considering the photometric
interpretation of an image these samples should be discarded. They are
only relevant for multiband.
For the most part we previously rejected these images due to a mismatch
between sample count and the color as indicated by the interpretation.
Only, for alpha we never really verified if the extra channel is indeed
alpha or something unrelated. We don't have a perfect solution as
GeoTiff motivates us having a MultiBand pseudo-color output
configuration that has no related photometric interpretation and borrows
the usual gray tone instead. We can only really distinguish this from a
gray-alpha image through looking at the values of the ExtraSamples
vector. Then again we do not yet support GrayAlpha anyways.
As a simplification for the discarding process we only support full-byte
extra samples and require all samples to be the same bit-depth, not only
those which we return. This is blessed by Tiff's recommendations for
baseline decoding as well as libtiff.
This was found through the fax4 decoding that is always bilevel.
No longer silently ignore an unknown color type when a photometric
interpretation requires an inversion. DICOM requires that WhiteIsZero
and BlackIsZero are only used for samples-per-pixel=1 but we do not
strictly enforce that early. Previously for the result Multiband color
we just ignored the tag which is also not right.
Prepares extensibility for the eventual case of supporting multi-planar
image layouts that are to be written into a multi-planar buffer as
indicated by the caller in some way (possibly not via read_*_bytes but a
method taking a wrapper around the output buffer instead). Through the
struct we can later add an indicator that can be used by the caller to
decide between methods of fetching the pixel data as appropriate.
Having the value reader itself take care of the bigtiff and limit
semantics is a little cleaner, with the TagReader being responsible
for the interface of grabbing specific types of IFD values.
This allows us to recombine the reader and other file data in a Decoder
with any IFD, whether that of an image or an extension IFD as indicated
by an IFD pointer such as Exif and GPS.