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
LibGfx+Tests(+AK): Add the beginning of a JPEG2000 loader #23682
Conversation
@Zaggy1024 because it's mostly ISOBMFF. |
7501fa8
to
efdccde
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a comment about a small nit. I only had a glance, but I haven't seen anything too shocking 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good for the most part, just a few nitpicks.
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp
Outdated
Show resolved
Hide resolved
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp
Outdated
Show resolved
Hide resolved
Userland/Libraries/LibGfx/ImageFormats/ISOBMFF/JPEG2000Boxes.cpp
Outdated
Show resolved
Hide resolved
All addressed, ready for another look! |
AK/MaybeOwned.h
Outdated
template<typename F> | ||
friend class MaybeOwned; | ||
|
||
template<class U, class D> | ||
Variant<NonnullOwnPtr<D>, D*> | ||
downcast(Variant<NonnullOwnPtr<U>, U*>&& variant) | ||
{ | ||
if (variant.template has<U*>()) | ||
return variant.template get<U*>(); | ||
return static_cast<NonnullOwnPtr<T>&&>(move(variant.template get<NonnullOwnPtr<U>>())); | ||
} | ||
|
||
Variant<NonnullOwnPtr<T>, T*> m_handle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that at some point we could really use a
template<typename T>
using Handle = Variant<NonnullOwnPtr<T>, T*>;
(Review is still pending, this is just something that I thought of randomly.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean generally, not in this PR, yes?
(Should maybe be V<NNOP, WeakPtr>
if we want to make it a whole thing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if at least the type alias is part of this commit, since we are adding two more usages of that type here. However, it's neither urgent nor strictly required, so I'll leave the decision to you.
Making the raw pointer a WeakPtr
requires making the stored object RefCounted
, which is something that we can't do anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last two small things (one new thing and one reopened conversation).
AK/MaybeOwned.h
Outdated
template<typename F> | ||
friend class MaybeOwned; | ||
|
||
template<class U, class D> | ||
Variant<NonnullOwnPtr<D>, D*> | ||
downcast(Variant<NonnullOwnPtr<U>, U*>&& variant) | ||
{ | ||
if (variant.template has<U*>()) | ||
return variant.template get<U*>(); | ||
return static_cast<NonnullOwnPtr<T>&&>(move(variant.template get<NonnullOwnPtr<U>>())); | ||
} | ||
|
||
Variant<NonnullOwnPtr<T>, T*> m_handle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if at least the type alias is part of this commit, since we are adding two more usages of that type here. However, it's neither urgent nor strictly required, so I'll leave the decision to you.
Making the raw pointer a WeakPtr
requires making the stored object RefCounted
, which is something that we can't do anyways.
This allows types that have spaces in their FourCC.
I prefixed the types that are labeled as "JPEG2000" on https://mp4ra.org/registered-types/boxes with "JPEG2000".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, all done.
(Also threw in 14b9a8e since I'm touching this file anyways.) |
For what it's worth, this "design" was kind of intentional on my part, since each branch is equally "important" (compared to, let's say, an early return or error case). |
I don't mind rebasing but clangd also flags it, so I'm not sure what in your message has precedence :) (I always build the cfg in my head somehow, and an if gets a cfg block and an after-if block but an if/else gets an if block, an else block, and an after-both block, but then both if and else blocks end with jumps out of the function and the poor after-if block ends up empty and unused and sad and was like "you made me get out of bed for this 😢" and "what was I made for 😔" etc etc) |
...and make Reader always have a BoxStream.
`isobmff` can now dump the id in a JPEG2000SignatureBox. Creates JPEG2000Boxes.{h,cpp} to house JPEG2000 box types.
...and make SuperBox a pure superclass that's not usable by itself.
This doesn't have to be a virtual method: it's called from various create_from_stream() methods that have a static type that's created. There's no point in the virtual call here, and it makes it harder to add additional parameters to read_from_stream() in some subclasses.
This will allow creating different child boxes in different containers.
JPEG2000 is the last image format used in PDF filters that we don't have a loader for. Let's change that. This adds all the scaffolding, but no actual implementation yet.
This is enough for `file` to print the dimensions of .jp2 / .jpx files, and for `icc` to print color profile information embedded in the 'colr' box.
We can't decode any actual image data yet, but it shows that we can read the basics of the container format. (...as long as there's an Annex I container around the data, not just an Annex A codestream. All files I've found so far have the container.) I drew the thes input in Acorn.app and used "Save as..." to save it as JPEG2000. It's an RGBA image.
I dropped the else removal and put in an else in my new function. I do think it looks very weird, but I'd also rather have this move forward than argue about this :) |
JPEG2000 is the last image format used in PDF filters that we don't have a loader for. Let's change that.
JPEG2000 in practice come in an ISOBMFF container, so most commits in here teach our ISOBMFF code about JPEG2000 types. Our
isobmff
tool can now print JPEG2000 types. Before:After (this is the same file):
Furthermore: