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

openjph: HT-J2K encoder #1072

Merged
merged 2 commits into from
Jan 16, 2024
Merged

openjph: HT-J2K encoder #1072

merged 2 commits into from
Jan 16, 2024

Conversation

bradh
Copy link
Contributor

@bradh bradh commented Dec 21, 2023

This is an early-exposure draft of an OpenJPH based High Throughput JPEG-2000 encoder.

Thanks to @aous72 for OpenJPH and for debugging assistance. Also thanks to @Jamaika1 for suggesting this at #420.

An OpenJPH-based decoder is practical, but is not yet written. In the meantime, the OpenJPEG decoder will work.

I'm not sure about the additional codec type (heif_compression_HTJ2K). It seems like the JPEG community think that HT-J2K is really (a variation of) JPEG 2000, but if we want to pick a working encoder for the user, it seems like it would be better to have a different value.

All input appreciated.

Note: This will likely have merge conflicts with #1071, which I'll resolve after that gets merged.

@@ -2304,6 +2304,15 @@ Error HeifContext::encode_image(const std::shared_ptr<HeifPixelImage>& pixel_ima
}
break;

case heif_compression_HTJ2K: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor thing: maybe this case can be simply combined with the heif_compression_JPEG2000 above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will see if we need to add something extra for the HT case, and combine if not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have combined it.

@farindk
Copy link
Contributor

farindk commented Dec 21, 2023

Thank you, this is a great addition.
I also think that adding a new compression format enum heif_compression_HTJ2K makes sense, since (at least for the moment) not all J2K decoders will support HTJ2K and thus it would be difficult to choose the correct plugin.
It might still not be that easy, as, according to #1054, there is no indication in the container whether the coded stream actually uses HT-J2K.
Fortunately, OpenJPEG can decode both, and we can simply add HTJ2K into the list of supported formats for it, but we also might need some code in core libheif to detect whether the stream is HTJ2K.

@bradh
Copy link
Contributor Author

bradh commented Dec 21, 2023

It might still not be that easy, as, according to #1054, there is no indication in the container whether the coded stream actually uses HT-J2K.

It would help to not have to parse the CAP segment. I've flagged that on the HTJ2K discord channel to see if could be possible.

@farindk
Copy link
Contributor

farindk commented Dec 22, 2023

Another reason to have a separate heif_compression_HTJ2K might be that we currently cannot process any encoder parameters before the plugin is selected. And the plugin is only selected based on the compression format.
I.e. if all J2K encoders would support HTJ2K, a simple "-p htj2k=true" would work, but since OpenJPEG doesn't encode HTJ2K yet, there cannot be a "-p htj2k=true".

Second option: we would put the burden on the user when the codec is selected. He has to know that "-e OpenJPEG" is ordinary J2K und "-e OpenJPH" is HTJ2K.
Encoders that support both might have a "-p htj2k" parameters.

Third option: we require that all JPEG2000 plugins have an ht2k parameter option and if it is set to a value not supported by the plugin, it fails with an error. Sounds like a silly idea, but we can have similar cases for other codecs, e.g. a h265 codec that cannot encode monochrome images. (Currently we handle this by the plugin encoding dummy color planes.)

Fourth option: when selecting the encoder, we pass a compression-format specific options struct to libheif. For Jpeg2000, this would include the HTJ2K flag and would be used for plugin selection. However, this may contradict the explicit user choice through "-e".

My subjective summary: option 1 sounds like the easy solution. Maybe in the future, when all encoders support everything, the two enums can be synonyms.
My unexpected second place goes to options 3 and 4, because we might need a more flexible plugin selection anyways.

@bradh
Copy link
Contributor Author

bradh commented Dec 26, 2023

My unexpected second place goes to options 3 and 4, because we might need a more flexible plugin selection anyways.

Maybe this is worth deeper consideration. I did some investigation into hardware based encoding and decoding (e.g. with NVIDIA GPUs).

There are quite a few dimensions to whether the hardware can handle the task, beyond just the codec. NVIDIA documentation for the decoder and encoder shows differences in:

  • bit depth
  • supported profiles
  • maximum size
  • chroma

Running the tests code shows additional variation in MB count, minimum size and output surface format.

This is a tricky tradeoff, because we'd like to use the fastest codec that supports the configuration the user has, but that isn't really exposed in the plugin API.

@bradh bradh force-pushed the openjph branch 2 times, most recently from 4e34df9 to d525dbf Compare January 12, 2024 10:10
@bradh bradh marked this pull request as ready for review January 12, 2024 10:10
@bradh
Copy link
Contributor Author

bradh commented Jan 12, 2024

I have cleaned up the code, and think it is now ready for review.

The one thing that doesn't work yet is the quality setting. That is still to be implemented in OpenJPH.

Also, there is no OpenJPH decoder implementation yet. I do plan to do that, no schedule at this stage.

@bradh bradh changed the title openjph: wip HT-J2K encoder openjph: HT-J2K encoder Jan 12, 2024
@farindk farindk merged commit d7e3fa8 into strukturag:develop-v1.18.0 Jan 16, 2024
1 of 2 checks passed
@farindk
Copy link
Contributor

farindk commented Jan 16, 2024

Thank you.

farindk added a commit that referenced this pull request Jan 16, 2024
@bradh bradh deleted the openjph branch January 16, 2024 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants