-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: image: decoding options #27830
Comments
/cc @nigeltao |
The overall goal seems OK. Some rambling thoughts, major and minor: I'd suggest forking For example, the API proposal still doesn't let us see the intermediate stages when decoding a progressive JPEG, when the compressed bytes come in slowly. There is a new We don't have to solve the progressive JPEG case now, but I'm hesitant to e.g. commit to an API in Go 1.12 that makes it harder to solve that case in Go 1.16. One possible design approach for that is to use something that's more like a That's the approach I'm taking in my Wuffs project. It's a little hard to see, but that's what the Wuffs That But using a A final, minor point. I don't think we need a |
@nigeltao Thanks for the comments. I will do some more research on the reader point. It seems @dsnet's comment on #23154 is relevant, particularly the BufferedReader type he mentions. |
Motivation
The current
Decode
function in theimage
package provides no way to configure the underlyingformat decoder. The registration system used by
image
makes it difficult to extend thedecoding behaviour of the registered format handlers. However there are many open issues that
could be resolved with a small number of decoding options. This proposal describes a way of
extending the existing format registration system to enable options to be passed to the individual
format decoders. It introduces a
DecodeOptions
type to serve as an extension point.There are two broad areas of configuration that are considered. This proposal tackles them both
but they are orthogonal and may be independently evaluated and implemented. The areas are:
Avoiding large allocations on unprocessable images
This class of problem is generally caused by faulty or malicious header information in the image file.
Typically this could be a very large x or y dimension that causes a huge buffer to be allocated in
preparation for reading a stream of pixel data. This is currently possible to mitigate by first
decoding the image config to check the dimensions before proceeding to a full decode. However this has
the disadvantage of either reading the input twice or buffering and re-reading to decode. Discussion in
the relevant issues suggested that a 16k buffer would be suitable. The following issues refer to this
use case (with #5050 being the overarching issue)
Being more tolerant of invalid input
The image decoders in the standard library are strict and fail on invalid input. There are classes
of invalid input that may be acceptable for some uses. The following issues suggest that a lenient
decoding mode would be helpful:
unknown block type: 0x01
errorframe bounds larger than image bounds
errorOther options related issues
In addition, the following issues suggest other areas that could benefit from decoding options but are
not considered further in this proposal:
Package Changes
The primary extensibility point is a new type. Its fields are discussed at the end of this section.
Format decoders are registered via a new package level function
RegisterFormatDecoder
The FormatDecoder interface needs to be implemented by any package providing image format decoding:
A new exported Decoder type is introduced:
with a basic constructor function.
The Decoder type has the following method set:
These Decode methods will sniff the type of the image from the reader and look up an appropriate
registered FormatDecoder. If one is available then its corresponding Decode method is called,
passing the Reader and the Decoder's options. This requires the Decode to have access to package
level registered format decoders.
To configure decoding the developer will create a new Decoder and then set the appropriate fields
before calling Decode or DecodeConfig.
The following options are proposed.
MaxHeight and MaxWidth
MaxHeight and MaxWidth are DecodeOptions fields that set the maximum allowable dimensions of a decoded image.
These fields restrict the allocation of large amounts of memory for faulty or malicious images.
These options are only used by the Decode method. When a Decoder attempts to decode an image with dimensions
exceeding either MaxHeight or MaxWidth then it should stop processing and return an error. A new error in the
image package
ErrDimensionsExceeded
could be defined as standard or it could be left to the decoder to returnits own error.
DecodeConfig should return a Config containing the width and height described in the image data stream
regardless of the config options.
ReturnPartial
ReturnPartial is a DecodeOptions field that instructs the decoder that it may return a partially decoded
image when an error is encountered.
The current Decode behaviour is that no image data is returned on error. When this option is true the caller
may receive a partial image from the decoding process when the decoder encounters a format related error
during the decoding process.
Backwards compatibility with existing registered formats
Existing callers of RegisterFormat will be supported by adapting the existing
format
type andpassing it to RegisterFormatDecoder, along these lines:
The existing package level
Decode
andDecodeConfig
functions will be rewritten to create a decoder and call itwithout any options:
Deprecation of RegisterFormat
RegisterFormat would be marked as deprecated in favour of RegisterFormatDecoder.
The text was updated successfully, but these errors were encountered: