Skip to content
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/jpeg: support color channels other than 8 bits, eg Gray16 #51904

Open
DanielHeath opened this issue Mar 23, 2022 · 2 comments
Open
Labels
Projects
Milestone

Comments

@DanielHeath
Copy link

@DanielHeath DanielHeath commented Mar 23, 2022

Go version: All recent, including 1.18.
OS: Linux / AMD64

In (e.g) image/jpeg/writer.go:620 , the encoder switches on the underlying image type (case *image.Gray:).

However, it has no check for color.Grey16, leading to that format being encoded incorrectly (the least significant 8 bits are discarded silently).

While many viewers elect not to implement it, the jpeg format supports wider color channels than 8 bit.

Specifying the number of color components and their size in the encoder options would allow the implementation to be used for e.g. medical imaging & scientific instrument data.

I propose that when the size or number of components is set to 0, the existing detection code is used instead (no change when not using the new options), unless you are encoding an image in the Grey16 color space.

@seankhliao seankhliao changed the title image/jpeg: Support color channels other than 8 bits (eg for color.Grey16 images) proposal: image/jpeg: support color channels other than 8 bits, eg Gray16 Mar 24, 2022
@gopherbot gopherbot added this to the Proposal milestone Mar 24, 2022
@seankhliao
Copy link
Contributor

@seankhliao seankhliao commented Mar 24, 2022

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Mar 30, 2022
@nigeltao
Copy link
Contributor

@nigeltao nigeltao commented Mar 31, 2022

However, it has no check for color.Grey16, leading to that format being encoded incorrectly (the least significant 8 bits are discarded silently).

At the wire format level, Extended or Progressive (as opposed to Baseline) JPEG can still only represent 12 bit depth, not the full 16. Would you still consider that "encoded incorrectly" if the least significant 4 bits are still discarded silently?

Specifying the number of color components and their size in the encoder options would allow the implementation to be used for e.g. medical imaging & scientific instrument data.

An alternative to adding encoder options is to detect case *image.Gray16 near to where it already detects case *image.Gray and treat that as another special case along the same lines. This admittedly changes the behavior (compared to previous Go stdlib versions) when encoding an *image.Gray16. More subtly, it would mean that jpeg.Encode would now potentially emit Extended JPEGs (SOF1), not just Baseline JPEGs (SOF0). Perhaps the new jpeg.Options field, if any, should be an opt-in to emitting Extended JPEGs.


Having said all that, if you're talking about medical imaging, you're probably talking about Lossless JPEG (which does allow 16 bit depth). Go's image/jpeg decoder (let alone its encoder) currently does not support LJPEG. I'll copy/paste here in full what I wrote on the #22535 "support LJPEG" feature request:

As a feature request, I suppose it's a valid feature request.

Whether or not it lives in image or x/image depends on how much code it would share or not share with the existing image/jpeg package. You mention the JPEG parser (which is trivial) and the Huffman coding (less trivial), but on a quick skim, the https://en.wikipedia.org/wiki/Lossless_JPEG page says that "Lossless JPEG... [uses] a completely different technique from the lossy JPEG standard".

Either way, though, I really don't have any spare time to work on this myself. If you want to try doing this yourself, I would suggest starting by forking the standard library's image/jpeg code. It'd be easier to make the image vs x/image decision after we have at least a rough proof of concept implementation to look at.


Back to this issue (encoding, not decoding), the same applies: "it's a valid feature request... [but] I really don't have any spare time to work on this myself."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Proposals
Incoming
Development

No branches or pull requests

4 participants