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

LibGfx+Tests(+AK): Add the beginning of a JPEG2000 loader #23682

Merged
merged 25 commits into from Mar 25, 2024

Conversation

nico
Copy link
Collaborator

@nico nico commented Mar 23, 2024

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:

% Build/lagom/bin/isobmff ~/Desktop/demo.jp2                                    
Unknown Box ('jP  ')
[ 4 bytes ]
('ftyp') (version = 0, flags = 0x0)
- major_brand = 'jp2 '
- minor_version = 0
- compatible_brands = { 'jp2 ' }
Unknown Box ('jp2h')
[ 3211 bytes ]
Unknown Box ('jp2c')
[ 6399 bytes ]

After (this is the same file):

 % Build/lagom/bin/isobmff Tests/LibGfx/test-inputs/jpeg2000/simple.jp2 
('jP  ')
- signature = 0x0d0a870a
('ftyp')
- major_brand = 'jp2 '
- minor_version = 0
- compatible_brands = { 'jp2 ' }
('jp2h')
  ('ihdr')
  - height = 101
  - width = 119
  - num_components = 4
  - are_components_signed = false
  - bits_per_component = 8
  - compression_type = 7
  - is_colorspace_unknown = 1
  - contains_intellectual_property_rights = 0
  ('colr')
  - method = 2
  - precedence = 0
  - approximation = 0
  - icc_data = 3144 bytes
  ('cdef')
  - channel_index = 0
  - channel_type = 0 (color)
  - channel_association = 1
  - channel_index = 3
  - channel_type = 1 (opacity)
  - channel_association = 0
  - channel_index = 1
  - channel_type = 0 (color)
  - channel_association = 2
  - channel_index = 2
  - channel_type = 0 (color)
  - channel_association = 3
('jp2c')
- codestream = 6399 bytes

Furthermore:

% Build/lagom/bin/file  Tests/LibGfx/test-inputs/jpeg2000/simple.jp2            
Tests/LibGfx/test-inputs/jpeg2000/simple.jp2: JPEG2000 image data, 119 x 101

% Build/lagom/bin/icc Tests/LibGfx/test-inputs/jpeg2000/simple.jp2 | grep ascii:
    ascii: "sRGB IEC61966-2.1"
    ascii: "IEC http://www.iec.ch"
    ascii: "IEC 61966-2.1 Default RGB colour space - sRGB"
    ascii: "Reference Viewing Condition in IEC61966-2.1"

@nico nico requested a review from timschumi as a code owner March 23, 2024 00:28
@github-actions github-actions bot added the 👀 pr-needs-review PR needs review from a maintainer or community member label Mar 23, 2024
@nico
Copy link
Collaborator Author

nico commented Mar 23, 2024

@Zaggy1024 because it's mostly ISOBMFF.

@nico nico force-pushed the like-its-19-90-9 branch 4 times, most recently from 7501fa8 to efdccde Compare March 23, 2024 01:28
Copy link
Member

@LucasChollet LucasChollet left a 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 😄

Copy link
Member

@timschumi timschumi left a 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.

@nico
Copy link
Collaborator Author

nico commented Mar 23, 2024

All addressed, ready for another look!

AK/MaybeOwned.h Outdated
Comment on lines 66 to 78
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;
Copy link
Member

@timschumi timschumi Mar 24, 2024

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.)

Copy link
Collaborator Author

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.)

Copy link
Member

@timschumi timschumi Mar 25, 2024

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.

@nico nico requested a review from timschumi March 25, 2024 16:17
Copy link
Member

@timschumi timschumi left a 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).

Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp Outdated Show resolved Hide resolved
AK/MaybeOwned.h Outdated
Comment on lines 66 to 78
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;
Copy link
Member

@timschumi timschumi Mar 25, 2024

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.

Copy link
Collaborator Author

@nico nico left a comment

Choose a reason for hiding this comment

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

Thanks, all done.

Userland/Libraries/LibGfx/ImageFormats/JPEG2000Loader.cpp Outdated Show resolved Hide resolved
@nico
Copy link
Collaborator Author

nico commented Mar 25, 2024

(Also threw in 14b9a8e since I'm touching this file anyways.)

@timschumi timschumi added ✅ pr-maintainer-approved-but-awaiting-ci PR has been approved by a maintainer and can be merged after CI has passed and removed 👀 pr-needs-review PR needs review from a maintainer or community member labels Mar 25, 2024
@timschumi
Copy link
Member

(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).

@nico
Copy link
Collaborator Author

nico commented Mar 25, 2024

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)

nico added 20 commits March 25, 2024 14:41
...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.
@github-actions github-actions bot added 👀 pr-needs-review PR needs review from a maintainer or community member and removed ✅ pr-maintainer-approved-but-awaiting-ci PR has been approved by a maintainer and can be merged after CI has passed labels Mar 25, 2024
@nico
Copy link
Collaborator Author

nico commented Mar 25, 2024

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 :)

@timschumi timschumi added ✅ pr-maintainer-approved-but-awaiting-ci PR has been approved by a maintainer and can be merged after CI has passed and removed 👀 pr-needs-review PR needs review from a maintainer or community member labels Mar 25, 2024
@timschumi timschumi merged commit 2e14210 into SerenityOS:master Mar 25, 2024
7 checks passed
@github-actions github-actions bot removed the ✅ pr-maintainer-approved-but-awaiting-ci PR has been approved by a maintainer and can be merged after CI has passed label Mar 25, 2024
@nico nico deleted the like-its-19-90-9 branch March 25, 2024 19:39
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.

None yet

4 participants