Rewrites all of the core texture code to use a new immutable GMImage class, which can be one of four texture types: PNG, raw BGRA pixel data, QOI, or BZip2 + QOI. This class is used as a replacement to the existing byte[] containing compressed PNG data always.
The major benefit of this is that load/save times on games using non-PNG textures are now much faster (some games are at least 5 seconds faster on either end, on my machine). QOI and/or BZ2 textures are now decoded/decompressed on the fly, rather than during the (de)serialization process.
This also mostly replaces System.Drawing.Common calls with ones to ImageMagick instead. In UndertaleModLib, it's used only for PNG encoding/decoding, but I also rewrote a tiny bit of code on the UI side. This should mean the library code itself is cross-platform. Additionally, I performed some tests and found that exporting PNGs with the new UI code preserves colors with 0 alpha.
Caveats
This breaks pretty much every script that interacts with texture data, but that will be resolved in an upcoming PR.
There's also one further memory optimization that can be made with BZ2 + QOI textures, if we can decompress the first 8 bytes of the BZ2 data only. Essentially, it involves finding the size of the inner QOI data, which can be used to initialize the capacity of the buffer used to decompress the BZ2 data later (when called to do so, on the fly). The performance impact is probably not extreme, though - it would prevent a few reallocations at most. It's something maybe worth revisiting in the future.
Notes
Tested on a number of games, including ones with PNG textures, BZ2 + QOI textures, and pre/post GameMaker 2022.5. I haven't yet tested QOI-only games, but the code should theoretically work with them. Files have loaded/saved byte-for-byte, besides a bug in the FONT chunk that's fixed by the serialization cleanup PR (#1864).
I tested collision mask saving/loading, the room editor, the sprite editor, the embedded texture editor (saving/loading), and the texture page item editor (saving/loading).
On the UI front, instances of BitmapSource are cached for as long as the garbage collector doesn't get rid of them from memory, which can prevent unnecessary image decodes.
Description
Rewrites all of the core texture code to use a new immutable
GMImage
class, which can be one of four texture types: PNG, raw BGRA pixel data, QOI, or BZip2 + QOI. This class is used as a replacement to the existingbyte[]
containing compressed PNG data always.The major benefit of this is that load/save times on games using non-PNG textures are now much faster (some games are at least 5 seconds faster on either end, on my machine). QOI and/or BZ2 textures are now decoded/decompressed on the fly, rather than during the (de)serialization process.
This also mostly replaces
System.Drawing.Common
calls with ones toImageMagick
instead. In UndertaleModLib, it's used only for PNG encoding/decoding, but I also rewrote a tiny bit of code on the UI side. This should mean the library code itself is cross-platform. Additionally, I performed some tests and found that exporting PNGs with the new UI code preserves colors with 0 alpha.Caveats
This breaks pretty much every script that interacts with texture data, but that will be resolved in an upcoming PR.
There's also one further memory optimization that can be made with BZ2 + QOI textures, if we can decompress the first 8 bytes of the BZ2 data only. Essentially, it involves finding the size of the inner QOI data, which can be used to initialize the capacity of the buffer used to decompress the BZ2 data later (when called to do so, on the fly). The performance impact is probably not extreme, though - it would prevent a few reallocations at most. It's something maybe worth revisiting in the future.
Notes
Tested on a number of games, including ones with PNG textures, BZ2 + QOI textures, and pre/post GameMaker 2022.5. I haven't yet tested QOI-only games, but the code should theoretically work with them. Files have loaded/saved byte-for-byte, besides a bug in the FONT chunk that's fixed by the serialization cleanup PR (#1864).
I tested collision mask saving/loading, the room editor, the sprite editor, the embedded texture editor (saving/loading), and the texture page item editor (saving/loading).
On the UI front, instances of
BitmapSource
are cached for as long as the garbage collector doesn't get rid of them from memory, which can prevent unnecessary image decodes.