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

Trade: KTX importer #103

Closed
wants to merge 95 commits into from
Closed

Trade: KTX importer #103

wants to merge 95 commits into from

Conversation

pezcode
Copy link
Contributor

@pezcode pezcode commented Jul 14, 2021

👋

Here's a first draft for the KTX2 image importer. It supports block-compressed and uncompressed 1D, 2D, 3D images.

Array layers are imported as separate images, cube faces and mips are imported as image levels (in the same order as DdsImporter: all mips for face 0, then face 1, etc.).

Array layers and cubemap faces are imported as extra image dimensions (so 1D array images become Image2D, (layered) cube maps become Image3D with n*6 z slices). The exception are 3D array images, those are imported as separate Image3D for each layer. No API supports those and there is no Image4D.

I wanted to get some early feedback on a few design decisions, so there's still a long list of todos, roughly sorted by importance:

  • tests, tests, tests
    • enable the plugin(s) in package/ci/*.{bat,sh} for the CIs to pick them up
  • accompanying KtxImageConverter
    • support for block-compressed images
    • support for cube and layered image types once those are queryable
    • tests
  • swizzling into existing PixelFormat where possible
  • arbitrary Vulkan formats, wrapped as custom PixelFormat out of scope of this PR
  • make sure the cubemap order is somehow standardized (compare with DdsImporter) or at least documented
  • Basis compression out of scope of this PR
  • supercompression (zstd etc.) out of scope of this PR

@pezcode
Copy link
Contributor Author

pezcode commented Jul 14, 2021

The dependency on Magnum::Vk is not great for obvious reason, and I mainly used it to get something working quickly. My plan is to just copy the VkFormat definition from the Vulkan headers (which needs attribution I think, Apache 2 license) and create the mapping to PixelFormat using raw Vulkan values. What's a little more involved is getting the block size for all formats, and I was considering grabbing that from https://github.com/KhronosGroup/KTX-Specification/blob/master/formats.json.

Also, what Vulkan formats should we support? 1.0 only?

else
f->dimensions = 1;

/** @todo Assert that 3D images can't have depth format */
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought it would be handy to have a function that tells you if a PixelFormat is a depth and/or stencil format. Might have to do this manually in this plugin to support all Vulkan formats, but maybe an idea for your ever-growing todo list 👀

Copy link
Owner

Choose a reason for hiding this comment

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

Yes, this makes sense to have directly in Magnum, isDepthStencilPixelFormat() for example. I have many such utils for VertexFormat already, so a similar set could be for pixel formats.

@codecov
Copy link

codecov bot commented Jul 14, 2021

Codecov Report

Merging #103 (76dd769) into master (6e8a22d) will increase coverage by 0.26%.
The diff coverage is 95.53%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #103      +/-   ##
==========================================
+ Coverage   94.70%   94.97%   +0.26%     
==========================================
  Files         104      112       +8     
  Lines        7673     8917    +1244     
==========================================
+ Hits         7267     8469    +1202     
- Misses        406      448      +42     
Impacted Files Coverage Δ
src/MagnumPlugins/KtxImporter/KtxImporter.cpp 90.20% <90.20%> (ø)
...numPlugins/KtxImageConverter/KtxImageConverter.cpp 99.05% <99.05%> (ø)
...agnumPlugins/KtxImageConverter/KtxImageConverter.h 100.00% <100.00%> (ø)
...umPlugins/KtxImageConverter/importStaticPlugin.cpp 100.00% <100.00%> (ø)
src/MagnumPlugins/KtxImporter/KtxImporter.h 100.00% <100.00%> (ø)
...numPlugins/KtxImporter/compressedFormatMapping.hpp 100.00% <100.00%> (ø)
src/MagnumPlugins/KtxImporter/formatMapping.hpp 100.00% <100.00%> (ø)
...c/MagnumPlugins/KtxImporter/importStaticPlugin.cpp 100.00% <100.00%> (ø)
...rc/MagnumPlugins/OpenExrImporter/OpenExrImporter.h 100.00% <0.00%> (ø)
...mPlugins/BasisImageConverter/BasisImageConverter.h 100.00% <0.00%> (ø)
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6e8a22d...76dd769. Read the comment docs.

@mosra mosra added this to the 2021.0a milestone Jul 15, 2021
@mosra mosra added this to TODO in Asset management via automation Jul 15, 2021
CMakeLists.txt Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxHeader.h Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxHeader.h Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxHeader.h Outdated Show resolved Hide resolved
@mosra
Copy link
Owner

mosra commented Jul 15, 2021

My plan is to just copy the VkFormat definition from the Vulkan headers

what Vulkan formats should we support? 1.0 only?

Copy the enum from Magnum's own flextVk.h, that way it's in sync with the set of formats Magnum supports.

which needs attribution I think, Apache 2 license

If you copy from the flextVk.h I think not anymore, and this file is credited elsewhere.

cube faces and mips are imported as image levels in the same order as DdsImporter

Huh, not sure if that was a good decision back then. I'd import cube maps as 3D images instead, one reason is that the GL::CubeMapTexture APIs can operate with 3D images directly, which would be way more convenient than having to deal with 6 separate images. To distinguish between a 3D, array and cubemap image I think it could make sense to expose a TextureData via texture(), containing the corresponding Type enum (argh, I need to add Texture1DArray / 2DArray / CubeArray fields there ASAP, TODO #1 for me).

Actually, the KTX file is always just one image, right? It can have multiple layers (in which case it's a 1D / 2D array, 3D or a cubemap) and multiple mip levels (which are exposed under via the level parameter), but all in all it's always just one, right? So then for this TextureData the textureCount() would always give you a 1, the TextureData::Type tells how the image is supposed to be interpreted and only one of image1DCount() / image2DCount() / image3DCount() would be 1, with all other 0.

make sure the cubemap order is somehow standardized (compare with DdsImporter) or at least documented

Yeah, the weird GL coordinate system. For now (until the above-mentioned ImporterFlag::FlipY flag lands) the importer should ensure the cubemap is in a coordinate system matching GL, which, depending on how KTX defines that, may involve flips along both X and Y. What might help you a bit:

  • I half-did this for OpenExrImporter, abusing their decoder to do the flips for me, but didn't finish yet. Related WIP change is in a branch: 429785d
  • And here's a (again WIP dirty) patch to the magnum-cubemap example to make it load single-file images, for easy visual testing: mosra/magnum-examples@3bab326

Honestly I have no idea how it is in DDS, I suspect nobody ever tested that. So don't take that as the ground truth :)

tests, tests, tests

A problem is that the AbstractImageConverter doesn't support multiple mips right now, which means you can't use the KtxImageConverter to generate multi-mip-level test data. Two options:

  • put the related tests on hold for a ~week until I add that (it's been on my list for several other reasons already anyway and should be rather easy, TODO #2 for me)
  • temporarily use some Khronos' own utility to generate those files ... but I suspect this would further complicate things instead of helping you

TODO #3 for me would be making CompressedImage store the block size parameters (and require them), which (I hope) could help you when accepting Vk-specific formats in KtxImageConverter? TODO #4 would be adding that Trade::AnimationTrackTargetType::ImageLayer value in case you really want to bother with animations.

@pezcode
Copy link
Contributor Author

pezcode commented Jul 15, 2021

Actually, the KTX file is always just one image, right? It can have multiple layers (in which case it's a 1D / 2D array, 3D or a cubemap) and multiple mip levels (which are exposed under via the level parameter), but all in all it's always just one, right? So then for this TextureData the textureCount() would always give you a 1, the TextureData::Type tells how the image is supposed to be interpreted and only one of image1DCount() / image2DCount() / image3DCount() would be 1, with all other 0.

Every single one of 1D, 2D, 3D, cubemap can have array levels in a KTX file, so for cubemap arrays and 3D arrays you'd still have image3DCount() >= 1. We could also just not support some of these cases, like 3D and cubemap arrays and spit out a warning like "only the first array layer was imported", but I don't see this being too tricky to not support. The only thing that might be confusing is that 1D array texture is a 2D image, etc. but then 3D array textures need to be spread across multiple images and TextureData. Maybe add imageRange to TextureData, then you could have the full family of Type, including Texture3DArray and TextureCubeArray?

* temporarily use some Khronos' own utility to generate those files ... but I suspect this would further complicate things instead of helping you

I'm okay with this option, at least a few tests should use external data to make sure the converter and importer don't have some shared faulty assumption about the format, writing and then accepting broken files 👀

TODO #3 for me would be making CompressedImage store the block size parameters (and require them), which (I hope) could help you when accepting Vk-specific formats in KtxImageConverter?

If that isn't more work than me just getting that data in a switch, that would be handy. Do any other importers have a use for this?

@pezcode
Copy link
Contributor Author

pezcode commented Jul 16, 2021

Feel free to ignore commits for now, mainly just pushing things for backup reasons. When I have tests and/or the converter working, I'll ping you again.

@mosra
Copy link
Owner

mosra commented Jul 19, 2021

Every single one of 1D, 2D, 3D, cubemap can have array levels in a KTX file

Cube map arrays are a thing though, and GL/Vulkan implements them simply as a bunch of cubemaps following each other in a 3D image. So in case of these I'd still make them a single image3D(0), with the texture(0) specifying it's a CubeMapArray and not a 3D texture or a 2D array (..once I add that to the enum).

4D textures, on the other hand... were a thing in 1997 but I don't remember any recent driver / platform bothering with these anymore. Since these don't map to hardware anyway, I'd say having them special-cased with multiple image3D()s & multiple texture()s wouldn't really be a problem?

Maybe add imageRange to TextureData

That's not really mapping to hardware either, TextureData primarily specifies texture type and sampler options in order to form a texture out of ImageData. Why forcing the users to split the ImageData3D to multiple 3D textures to be able to use them at all if the importer can do that directly?

at least a few tests should use external data to make sure the converter and importer don't have some shared faulty assumption about the format

Great point, yep, that definitely needs to be done :)

If that isn't more work than me just getting that data in a switch

Right now I got stuck in a "fixing a lightbulb" loop while adding mip level support to the image converter, hopefully getting unstuck soon. After that I'll see how involved this is.

@pezcode
Copy link
Contributor Author

pezcode commented Jul 22, 2021

Made a bit of progress in the last few days 🤠

  • array layers and cubemap faces are now always exposed as extra dimensions of the imported ImageData, along with texture() giving the correct type (pending the additional enum types in TextureData::Type being added to Magnum)
  • 3d array images are imported as separate images/textures per array layer
  • image data is now flipped to match GL's texture origin, taking KTX orientation metadata into account
  • a basic version of KtxImageConverter supporting 1D/2D/3D with uncompressed formats, but it shouldn't be too tricky to expand
  • a first round of tests for KtxImporter, missing a few of the 'special' cases like 3D, all array images, cubemaps

Apart from what I mentioned, the major missing pain point is cubemaps. They're imported just fine, but there are still a few oddities with orientations and coordinate space I don't full understand. Going to have to do a bit more reading and testing to see how this interacts with GL and what the official Khronos tools do.

@pezcode
Copy link
Contributor Author

pezcode commented Jul 22, 2021

I was bored and spent a few minutes implementing the frame animation data reading, so I'll just put the snippet here if one of us goes back to implementing it on top of a new animation type:

KtxHeader.h:

/* KTX2 animation frame */
struct KtxAnimationFrame {
    UnsignedInt duration;  /* Number of time units per frame */
    UnsignedInt timescale; /* Number of time units per 1 second */
    UnsignedInt loopCount; /* Loop count, 0 = infinite */
};

static_assert(sizeof(KtxAnimationFrame) == 12, "Improper size of KtxAnimationFrame struct");

KtxImporter::doOpenData():

    /* Read animation data */
    if(isLayered) {
        const auto found = keyValueMap.find("KTXanimData"_s);
        if(found != keyValueMap.end()) {
            if(numLayers*sizeof(Implementation::KtxAnimationFrame) <= found->second.size()) {
                const auto frames = Containers::arrayCast<const Implementation::KtxAnimationFrame>(found->second);
                Float key = 0.0f;
                for(UnsignedInt layer = 0; layer != numLayers; ++layer) {
                    /** @todo import as animation track with {key, layer} */
                    Implementation::KtxAnimationFrame frame = frames[layer];
                    Utility::Endianness::littleEndianInPlace(frame.duration, frame.timescale);
                    Float duration = frame.duration;
                    if(frame.timescale > 0)
                        duration /= frame.timescale;
                    key += duration;
                }
            }
            else
                Warning{} << "Trade::KtxImporter::openData(): invalid animation data, ignoring";
        }
    }

Copy link
Owner

@mosra mosra left a comment

Choose a reason for hiding this comment

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

Went thoroughly through the importer code, great job so far 👍

I have some of the needed additions to Magnum halfway done, will try to push them ASAP and then will look at the converter.

src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.h Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/KtxImporter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/Test/KtxImporterTest.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/Test/KtxImporterTest.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/Test/KtxImporterTest.cpp Outdated Show resolved Hide resolved
package/archlinux/PKGBUILD-android-arm64 Outdated Show resolved Hide resolved
@mosra
Copy link
Owner

mosra commented Jul 24, 2021

a few oddities with orientations and coordinate space I don't full understand. Going to have to do a bit more reading and testing to see how this interacts with GL and what the official Khronos tools do.

I'd say "just" import (and store) them in a way that makes them work properly with the expaded cubemap example (link to the code above)? This will need to get rethought for Vulkan and the flipping flags later anyway, but until I have something tangible to test this with I don't think you should need to care beyond what GL needs. Or am I missing something?

@mosra
Copy link
Owner

mosra commented Jul 24, 2021

The new TextureType enums got added in mosra/magnum@4c4b259 (together with a bunch of deprecations/renames in mosra/magnum@046b955), but I realized there's one related issue on the converter side -- how to tell it how a certain 2D/3D image should be interpreted? Right now there's just 1D/2D/3D variants but without any builtin way to specify if it's an array or a cube map, and introducing plugin-specific stringly typed configuration options for this sounds dirty to me.

  • One option would be to reuse TextureData there somehow, but since that converter deals with images only and not related texture/sampling info (which is a job for the scene converters instead), plus the interface is one-off functions, adding some extra function to specify a TextureData referencing some image ID doesn't feel like a good match. (On the other hand eventually I may need to be able to accept AnimationData for animated images (video?), but that needs an API for batch images anyway...)

  • Another is adding a completely new enum and a setImageType() API, which would be orthogonal to the functions called (the goal is so one doesn't have to explicitly setImageType(ImageType::Image1D) in order to call convert() with a 1D image because that would be annoying). So, for example:

    enum class ImageType { // naming pending™
        Default,
        Array, // 2D images get interpreted as 1D arrays, 3D as 2D arrays
        CubeMap, // 3D images get interpreted as cube maps
        CubeMapArray // 3D images get interpreted as cube map arrays
    };
    
    converter.setImageType(ImageType::Array);
    converter.convertImageToFile(ImageView3D{...}, "foo.ktx"); // interpreted as 2D array
    converter.setImageType(ImageType::Default);
    converter.convertImageToFile(ImageView3D{...}, "bar.ktx"); // as a 3D again

    This however means there's two different ways to encode the same thing (TextureType vs ImageType) and now the requirement of having to expose TextureData in order to be able to distinguish cube maps / arrays and 3D images feels unnecessarily complex... Or maybe the image classes should have a flags() field on their own that describes the image beyond just size and format (what's the Y and Z direction, if the alpha is premultiplied, ..., and what type of image it actually is)

  • An alternative to the ImageType enum is expanding the ImageConverterFlags with Array and CubeMap flags (so it's also possible to say Array|CubeMap) instead? Sounds like a better option to me, plus there will soon be various other flags like the YUp etc. having the same usage / effect.

Opinions / ideas? :)

src/MagnumPlugins/KtxImageConverter/KtxImageConverter.cpp Outdated Show resolved Hide resolved
Comment on lines 429 to 695
UnsignedInt leastCommonMultiple(UnsignedInt a, UnsignedInt b) {
const UnsignedInt product = a*b;

/* Greatest common divisor */
while(b != 0) {
const UnsignedInt t = a % b;
a = b;
b = t;
}
const UnsignedInt gcd = a;

return product/gcd;
}
Copy link
Owner

Choose a reason for hiding this comment

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

Interesting that I still don't have such utils in the Math lib. TODO for me.

src/MagnumPlugins/KtxImporter/KtxHeader.h Show resolved Hide resolved
@pezcode
Copy link
Contributor Author

pezcode commented Jul 27, 2021

Thanks for reviewing 👍 I adressed all the minor items locally, they'll be pushed along with the completed tests once I finished those.

a few oddities with orientations and coordinate space I don't full understand. Going to have to do a bit more reading and testing to see how this interacts with GL and what the official Khronos tools do.

I'd say "just" import (and store) them in a way that makes them work properly with the expaded cubemap example (link to the code above)? This will need to get rethought for Vulkan and the flipping flags later anyway, but until I have something tangible to test this with I don't think you should need to care beyond what GL needs. Or am I missing something?

Mostly I need to make sure that image flips don't affect the coordinate space. The KTX spec mentioned e.g. having to flip faces for mismatching y-orientation. But there's no major code to write, just needs testing with GL.

Opinions / ideas? :)

I'm a fan of the last option. Ideally, there'd also be a way to query those flags per image. Then we could even scrap exposing the image type through texture() for image-only importers. Something like imageFlags2D()? But I'm not sure if you want to mix this all with importer config or create a new enum.

@mosra
Copy link
Owner

mosra commented Jul 28, 2021

I'm a fan of the last option. Ideally, there'd also be a way to query those flags per image.

Yep, I settled on the same conclusion, this is essential to have otherwise dealing with GL/Vulkan coordinate system differences would quickly turn into a nightmare. So basically:

  • have Image, ImageView and ImageData a flags() field that can store YUp / ZBackward / NonPremultipliedAlpha and potentially other bits, where lack of the bit (the default) means the saner / more common variant (so Y down, Z forward and premultiplied alpha)
  • these flags get filled by various APIs as needed, for example reading a GL framebuffer / texture would set the YUp bit
  • image converters would have an option to override this when saving the image and encode the information into the file where possible (so e.g. KtxImageConverter would implicitly save with Y down because that's what everything else expects, but could be told otherwise with ImageConverterFlag::YUp, in which case it would flip the image if it doesn't have YUp already, and it also saves this orientation into file metadata; but PngImageConverter would always save with Y down as the file doesn't support arbitrary orientation)
  • image importers would implicitly import the file with the orientation specified in the metadata (and would save that into flags() of the returned image), but again can be told to override this on import -- so for example when importing images for a GL pipeline it makes sense to implicitly enable the YUp bit on the importer

I still need to think about backwards compatibility to avoid breaking everyone's projects, but most probably the defaults would be "import with Y up" and "save with Y down", and somehow begging people to set these explicitly.

@pezcode
Copy link
Contributor Author

pezcode commented Jul 31, 2021

Starting to get to the finish line 🥉

I converted the cubemap example files to KTX and everything just seemlessly works when loaded in GL, so no special code needed there. If you want to try yourself, here's the output of PVRTexTool:
cubemap.zip
Colors are a bit messed up, but the orientations are fine. You'll also need mosra/magnum#529.

Apart from that, I'm just finishing tests, a few esoteric cases need covering, but the majority is there.

For compressed formats, how do I best go about getting ground truth data? From a quick glance, --save-diagnostics requires CompareImage, which doesn't support compressed formats.

CIs are failing because I forgot to update the test files in CMake, but they do seem to compile, so there's that.

Copy link
Owner

@mosra mosra left a comment

Choose a reason for hiding this comment

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

Great work, again.

Is this finishable without me implementing the CubeMap / Array / ... image and converter flags first? Anything else this is being blocked on?

I probably won't be able to finish CompressedImage::blocks() and related APIs anytime soon, but also I don't want to put this on hold just because of these -- I think it should be doable without these, if you won't support the pixel storage parameters for now.

src/MagnumPlugins/KtxImageConverter/KtxImageConverter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImageConverter/KtxImageConverter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImageConverter/KtxImageConverter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImageConverter/KtxImageConverter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImageConverter/KtxImageConverter.cpp Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/formatMapping.py Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/formatMapping.py Outdated Show resolved Hide resolved
src/MagnumPlugins/KtxImporter/Test/generate.sh Outdated Show resolved Hide resolved
@pezcode
Copy link
Contributor Author

pezcode commented Jul 31, 2021

That was a great review round, mostly just deleting things 😆

Is this finishable without me implementing the CubeMap / Array / ... image and converter flags first? Anything else this is being blocked on?

Absolutely, once those are added it shouldn't take a whole lot more than setting the correct values in the KTX header. The layout of the level data won't change. Until then all data is exported as 1D/2D/3D. Nothing blocking I'm aware of.

I probably won't be able to finish CompressedImage::blocks() and related APIs anytime soon, but also I don't want to put this on hold just because of these -- I think it should be doable without these, if you won't support the pixel storage parameters for now.

Yeah, I just fixed the last remaining issue with block-compressed image export, and if I ignore the storage parameters, this is 99% done. Just need some more code for depth/stencil format DFD writing, and then tests.

WIP and missing tests
friendly reminder to implement support
Similarly to uncompressed mipmapped 3D images, we have to generate them with the converter tests. We, however, have to manually generate the .bin data with compressed blocks. Not ideal, but better than not testing these at all.
Raw DFD data is bundled with the test, generated from a patch to a dfdutils program, see README.md
We only needed that many to get some DFD test coverage, but we have a separate DFD test for all formats now
@pezcode
Copy link
Contributor Author

pezcode commented Aug 25, 2021

I'm going to strangle GCC 4.8 one of these days 🤡

@pezcode
Copy link
Contributor Author

pezcode commented Aug 25, 2021

I addressed all your review comments and fixed a few remaining DFD bugs, but the DFD is now tested against dfdutils output for all formats.

Emscripten CI is still failing, I'll do some investigating on my own machine. Directory::list() doesn't seem to interact well with the virtual filesystem, or I'm doing something wrong with the paths in CMakeLists.txt Turns out test files are added to the root of the file system, which makes perfect sense considering I didn't give Corrade an output path

@pezcode pezcode marked this pull request as ready for review August 25, 2021 16:00
@mosra
Copy link
Owner

mosra commented Aug 31, 2021

Okay, I did a final pass over the latest changes and this looks exceptionally good and the test coverage is amazing as well. I'll do a bunch of tests locally (playing with magnum-imageconverter, especially), wire up the remaining 1D and compressed cases to AnyImageImporter / AnyImageConverter and merge.

One remaining thing -- I was thinking to to put all the dfd blobs into a single file, having them separately feels a bit excessive 😆 Thinking of rewriting the patch to open the file for append instead and then prefix each DFD blob with size + format ID as two 32bit numbers, that could hopefully do the trick. If you have time to do it yourself, great, if not, I'll do it during merge.

@pezcode
Copy link
Contributor Author

pezcode commented Aug 31, 2021

If you have time to do it yourself, great, if not, I'll do it during merge.

I can do that, yeah. That would also fix an interesting error on Windows with Ninja about the max command line length being exceeded 👀 Ran into that when testing Emscripten and I couldn't figure out how to get it to use a response file for command line arguments (and not just object files.)

@mosra
Copy link
Owner

mosra commented Sep 4, 2021

Squashed into a few commits (didn't really find a way how to break it up better, without leaving a lot of noise in the history) and merged as 2114bf2...bd3f16e. Thank you for this work! 👍

Once I manage to finish the leftovers (array/cube annotation flags for images), I might have some followup tasks for this, and the Basis detection/proxying as well.

@pezcode
Copy link
Contributor Author

pezcode commented Sep 4, 2021

didn't really find a way how to break it up better, without leaving a lot of noise in the history

I tried to break it up into commits specific to each importer, but the test dependency (as well as the single commit for registering both plugins for CI) kinda defeated that plan. Hope it wasn't too much work to squash these.

Thanks for the (as always) smooth review process and speedy addition of required Magnum changes along the way ☺️

@mosra
Copy link
Owner

mosra commented Sep 12, 2021

Ha, did I not close this yet? Interesting.

@mosra mosra closed this Sep 12, 2021
Asset management automation moved this from TODO to Done Sep 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

None yet

2 participants