image/jpeg: Unable to decode concatenated JPEGs (MIME-less "MJPEG") #22170
What did you do?
The following example illustrates the error by creating an MJPEG stream using a sample image: https://play.golang.org/p/lppyHZftWA
The same program but using a PNG stream and
The following is a test that is expected to pass:
Grabbing a number of frames from a video and inspecting the output we can verify that there's no unexpected bytes after the EOI marker (
What did you expect to see?
The MJPEG stream is a concatenation of JPEG images and the decoder should be able to successfully decode multiple images in sequence without forcing caller to keep track of and seek to next frame.
The program https://play.golang.org/p/lppyHZftWA is expected to not give any output but decode all stream frames correctly and exit cleanly when hitting
What did you see instead?
The program prints an error message as it hits
Does this issue reproduce with the latest release (go1.9.1)?
The text was updated successfully, but these errors were encountered:
The decoder eats your entire stream 4096 bytes at a time, along with all images in between. You will have to use a bytes.Reader instead of a bytes.Buffer and seek to the starting position of the stream to get this to work how you expect.
That out of the way, I can confirm that image/png works in the scenario above without reading past the next image.
Thanks for pointing this out. To be clear, I'm expecting the behaviour of
Upon further inspection of the png, gif, and jpeg packages, I don't think this issue can be easily resolved at the package level.
The data structures are simple for byte formats where a bitstream doesn't cross byte-boundaries (e.g., PNG), and it turns out that streamable PNGs are part of the png standard itself:
The jpeg package has a custom reader for decoding the variable length bitstream, it fills the buffer 4k bytes at a time. There is generally no way to stuff those unprocessed bytes back into the underling reader after the decode is done, short of reading the bitstream and detecting the
A container format solves this problem, but MJPEG has no formal standardization that I know of, and a bit of research also shows that other decoders have had this problem too:
@john-dev You need to seek to the beginning of the next image yourself. Here's an example for a specific type of MJPEG