godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Implement TIFF saving support (specially for Movie Writer) #5803

Open DeeJayLSP opened 1 year ago

DeeJayLSP commented 1 year ago

I brought a talk about this on developers' chat, and fire asked for a proposal to be recorded.

Describe the project you are working on

The editor, I believe.

Describe the problem or limitation you are having in your project

Inspired by Godot's Movie Writer, I've decided to test some encoding formats.

Both MJPEG and PNG have some problems that may be evaded with adoption of TIFF.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

TIFF may not be a widely used image format, but Godot's Movie Writer would be a good use case for it.

Unlike PNG, TIFF is able to encode to YUV formats, which may greatly reduce the file size. While being an uncompressed format by default, TIFF natively supports compression algorithms like packbits, lzw and deflate.

Compared to encoding to PNG, combining YUV420 (although this will result in some quality loss) with packbits on TIFF is about 200% faster and the frames have 31% less file size.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

At the options available in Movie Writer settings, the user could name the extension as .tiff, as well as choosing compression algorithm and pixel format.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No.

Is there a reason why this should be core and not an add-on in the asset library?

If this could be done as an addon in the asset library, it would have to be done with a pre-compiled GDExtension. I don't think binaries should be there.

fire commented 1 year ago

Subscribed to keep track of this. Since I asked for the proposal to be recorded.

fire commented 1 year ago

Can you post an example tiff file in this format?

DeeJayLSP commented 1 year ago

An example taken from one of Kenney's asset sample images (Tiny Dungeon):

This is the original one (PNG): Sample_cut

And this what TIFF YUV420 looks like (it's not much different than Lossy WebP at quality 100): Sample_cut_converted

fire commented 1 year ago

Oh I mean as a tiff, so I can check for support. (zipped)

DeeJayLSP commented 1 year ago

OK, here you go: Sample_cut.zip

Calinou commented 1 year ago

Note that you could also record to AVI and extract JPEG images (as MJPEG is effectively a JPEG image within a video). However, JPEG compression will usually exhibit more artifacts compared to mere 4:2:0 chroma subsampling in most scenes.

(You can opt out of chroma subsampling in JPEG by using a quality greater than or equal to 90, but this does not remove artifacts that are especially present around text or in drawings.)

If we're talking about expanding image format support, it may be worth changing MovieWriterPNGWAV to MovieWriterImageWAV to support more image formats within a single MovieWriter. The file extension would determine the output format and codepath internally used within the MovieWriter. This would allow adding support for even more formats in the future, such as OpenEXR (for saving HDR image data, which is useful for compositing and post-processing).

Calinou commented 1 year ago

There's already a proposal about adding TIFF import: https://github.com/godotengine/godot-proposals/issues/4620

I suggest repurposing this proposal to be about saving TIFF files and allowing MovieWriter to use formats other than PNG in its MovieWriterPNGWAV implementation.

DeeJayLSP commented 1 year ago

Anyway, to implement something like this conveniently, the TIFF packer needs to support packbits.

TinyDNG (which is what fire wants to implement) seems to support only uncompressed and LZW.