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

Experimental AVIF Sample Transform #2050

Merged
merged 9 commits into from
Apr 12, 2024

Conversation

y-guyon
Copy link
Collaborator

@y-guyon y-guyon commented Mar 12, 2024

Allow encoding and decoding images of more than 12 bits, the limit of the AV1 format. This commit experiments 16-bit AVIF images, made of one primary lossless 8-bit image and one hidden lossy/lossless bit depth extension 8-bit image. The two are combined thanks to a Sample Transform derived image item. Alpha is supported.

Warning: This feature is experimental and not covered by the current AVIF specification.

@y-guyon y-guyon changed the title Experimental AVIF Sample Transform bit depth ext Experimental AVIF Sample Transform Mar 12, 2024
@y-guyon y-guyon force-pushed the sample_transform_expression branch from ef9dda8 to 8960194 Compare March 12, 2024 11:50
@y-guyon y-guyon marked this pull request as ready for review March 12, 2024 16:38
@y-guyon y-guyon requested a review from wantehchang March 12, 2024 16:38
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

Yannis: I made a first pass through the pull request, checking only that the pull request is essentially a no-op if AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM is not defined.

I noticed some general cleanup or improvements in src/read.c and src/write.c. I suggest moving those changes and the new avifIsAlpha() function to a separate pull request that can be reviewed and checked in first.

The first version of avifIsAlpha() function would be simply:

avifBool avifIsAlpha(avifItemCategory itemCategory)
{
    if (itemCategory == AVIF_ITEM_ALPHA) {
        return AVIF_TRUE;
    }
    return AVIF_FALSE;
}

src/read.c Outdated Show resolved Hide resolved
src/write.c Outdated Show resolved Hide resolved
@y-guyon y-guyon force-pushed the sample_transform_expression branch 2 times, most recently from b8e3537 to acfbd1e Compare April 5, 2024 11:46
@y-guyon
Copy link
Collaborator Author

y-guyon commented Apr 5, 2024

Rebased to include #2057 and #2059.

@y-guyon y-guyon requested a review from wantehchang April 5, 2024 15:36
@wantehchang
Copy link
Collaborator

Yannis: I have just started reviewing this pull request. I may not be able to post comments until tomorrow. I will mainly verify that the pull request is essentially a no-op if AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM is not defined.

Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

I only reviewed up to avif.h carefully. The rest of the files I only verified that the changes are a no-op if the experimental flag is disabled.

I suggest some small changes (mostly comments).

include/avif/avif.h Outdated Show resolved Hide resolved
include/avif/avif.h Outdated Show resolved Hide resolved
include/avif/avif.h Outdated Show resolved Hide resolved
include/avif/avif.h Show resolved Hide resolved
include/avif/avif.h Outdated Show resolved Hide resolved
src/write.c Outdated Show resolved Hide resolved
src/write.c Show resolved Hide resolved
@y-guyon y-guyon requested a review from wantehchang April 9, 2024 11:25
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

LGTM. I verified that the pull request is essentially a no-op if the experimental feature is disabled.

As real code review, I have reviewed up to avif.c. I also did a little checking in read.c.

include/avif/avif.h Show resolved Hide resolved
include/avif/internal.h Outdated Show resolved Hide resolved
include/avif/internal.h Outdated Show resolved Hide resolved
src/read.c Show resolved Hide resolved
src/read.c Outdated

AVIF_CHECK(avifROStreamRead(s, &token->value, /*size=*/1)); // unsigned int(8) token;
if (token->value == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
// TODO(yguyon): Verify two's complement representation is guaranteed here.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we have verified this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is there some public resource I can cite here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

No. We have verified this by private email with Cyril Concolato and Emmanuel Thomas. There is a clarification in the current draft 14496-34: “Signed integer values shall be represented using the two’s-complement representation.”

// TODO(yguyon): Verify two's complement representation is guaranteed here.
uint32_t constant;
AVIF_CHECK(avifROStreamReadU32(s, &constant)); // signed int(1<<(bit_depth+3)) constant;
token->constant = *(int32_t *)&constant; // maybe =(int32_t)constant; is enough
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, =(int32_t)constant; is enough. Alternatively, we can do this:

    AVIF_CHECK(avifROStreamReadU32(s, (uint32_t *)&token->constant)); // signed int(1<<(bit_depth+3)) constant;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, =(int32_t)constant; is enough.

https://en.cppreference.com/w/c/language/conversion#Integer_conversions seems to say it is implementation-defined. Should we consider it as widespread as two's complement representation?

Alternatively, we can do this:

    AVIF_CHECK(avifROStreamReadU32(s, (uint32_t *)&token->constant)); // signed int(1<<(bit_depth+3)) constant;

I do not think it is equivalent depending on the platform's endianness. Should we consider it as widespread as two's complement representation?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The reason casting a uint32_t value greater than INT32_MAX to int32_t is implementation-defined is that there are three representations of signed integers in C. In practice, the only widely-used repesentation is two's complement.

src/read.c Outdated Show resolved Hide resolved
src/read.c Show resolved Hide resolved
src/read.c Show resolved Hide resolved
src/write.c Outdated Show resolved Hide resolved
typedef struct avifSampleTransformToken
{
uint8_t type; // avifSampleTransformTokenType
int32_t constant; // If value is AVIF_SAMPLE_TRANSFORM_CONSTANT.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: value => type

src/read.c Outdated
@@ -2006,6 +2023,108 @@ static avifBool avifParseToneMappedImageBox(avifGainMapMetadata * metadata, cons
}
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
// bit-depth is assumed to be 2 (32-bit).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: bit-depth => bit_depth ?

src/read.c Show resolved Hide resolved
@y-guyon y-guyon force-pushed the sample_transform_expression branch from e568a38 to 148f165 Compare April 11, 2024 09:24
y-guyon added 8 commits April 11, 2024 17:07
Allow encoding and decoding images of more than 12 bits, the limit of
the AV1 format. This commit experiments 16-bit AVIF images, made of
one primary lossless 8-bit image and one hidden lossy/lossless bit
depth extension 8-bit image. The two are combined thanks to a Sample
Transform derived image item. Alpha is supported.

Warning: This feature is experimental and not covered by the current
         AVIF specification.
@y-guyon y-guyon force-pushed the sample_transform_expression branch from 148f165 to c4919d5 Compare April 11, 2024 15:07
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

Yannis: I checked parts of read.c and sampletransform.c. This is probably the best I can do by the end of this week. You can go ahead and merge this pull request.

src/read.c Show resolved Hide resolved
src/read.c Outdated Show resolved Hide resolved
src/read.c Outdated Show resolved Hide resolved
src/read.c Outdated Show resolved Hide resolved
src/read.c Outdated Show resolved Hide resolved
src/sampletransform.c Outdated Show resolved Hide resolved
@y-guyon y-guyon merged commit 834019c into AOMediaCodec:main Apr 12, 2024
28 checks passed
@y-guyon y-guyon deleted the sample_transform_expression branch April 12, 2024 09:55
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.

2 participants