-
Notifications
You must be signed in to change notification settings - Fork 209
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
Allow creating images with a different grid for the gain map. #2397
base: main
Are you sure you want to change the base?
Conversation
|
Thanks for the feedback. I thought this might be a bit controversial so happy to hear other people's opinions. I think it's nice to be able to create a wider variety of images from within the code base without having to keep some old branch lying around, or doing some surgery on the files (either manual or in test code as in this example). But I acknowledge that this adds some extra complexity to the already complex/long write.c file. |
The main image can have a different number of cols/rows than the gain map, or one can be a grid and the other be a single image. Also allow setting differnet values for gain map metadata version fields. Add code in gainmaptest.cc to generate test images. These images are used in tests and as seeds by the fuzzer.
9ad2707
to
af5863a
Compare
Maryla: I will take a closer look at this pull request tomorrow. |
uint16_t tmapWriterVersion; // Value that should be written for the 'writerVersion' field (use default if 0) | ||
avifBool tmapAddExtraBytes; // Add arbitrary bytes at the end of the box | ||
#endif | ||
char dummy; // Avoid emptry struct error when AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP is off |
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.
Nit: dummy => unused
@@ -786,6 +786,37 @@ avifResult avifFindMinMaxWithoutOutliers(const float * gainMapF, int numPixels, | |||
|
|||
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP | |||
|
|||
// --------------------------------------------------------------------------- | |||
// Internal encode |
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.
(This is a comment on the pull request.) I probably would add the generated test images to the source tree rather than generate them on the fly during testing.
This PR consists of two parts. The avifEncoderInternalOptions
part is straightforward. On the other hand, it is also easy to rewrite this part from scratch when necessary -- one just needs to make simple changes to the avifWriteToneMappedImagePayload()
function. So it is less valuable to check in this part.
The avifEncoderAddImageInternal
part is more complicated. It could be difficult to maintain. The new function parameters also need to be documented.
// --------------------------------------------------------------------------- | ||
// Internal encode | ||
// | ||
// These functions/options give extra flexibility to create non standard images for use in testing. |
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.
Nit: non standard => nonstandard
uint8_t tmapVersion; // Value that should be written for the 'version' field (use default if 0) | ||
uint16_t tmapMinimumVersion; // Value that should be written for the 'minimum_version' field (use default if 0) | ||
uint16_t tmapWriterVersion; // Value that should be written for the 'writerVersion' field (use default if 0) | ||
avifBool tmapAddExtraBytes; // Add arbitrary bytes at the end of the box |
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.
Nit: replace "the box" with the name of the class (ToneMapImage or GainMapMetadata?)
@@ -952,7 +966,7 @@ size_t avifEncoderGetGainMapSizeBytes(avifEncoder * encoder) | |||
} | |||
|
|||
// Sets altImageMetadata's metadata values to represent the "alternate" image as if applying the gain map to the base image. | |||
static avifResult avifImageCopyAltImageMetadata(avifImage * altImageMetadata, const avifImage * imageWithGainMap) | |||
static avifResult avifImageCopyAltImageMetadata(avifImage * altImageMetadata, const avifImage * imageWithGainMap, const avifImage * gainMapImage) |
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.
The only thing this function needs from gainMapImage
is gainMapImage->depth
. Should we change this parameter to uint32_t gainMapImageDepth
?
@@ -1596,6 +1609,9 @@ static avifResult avifEncoderAddImageInternal(avifEncoder * encoder, | |||
uint32_t gridCols, | |||
uint32_t gridRows, | |||
const avifImage * const * cellImages, | |||
uint32_t gainMapGridCols, | |||
uint32_t gainMapGridRows, | |||
const avifImage * const * gainMapCellImages, |
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.
This change introduces an asymmetry between the alpha grid and the gain map grid, because the alpha grid is not allowed to have a different tile configuration.
if ((gridCols == 0) || (gridCols > 256) || (gridRows == 0) || (gridRows > 256) || (gainMapGridCols == 0) || | ||
(gainMapGridCols > 256) || (gainMapGridRows == 0) || (gainMapGridRows > 256)) { | ||
return AVIF_RESULT_INVALID_IMAGE_GRID; | ||
} |
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.
Nit: It is better to ignore gainMapGridCols
and gainMapGridRows
when gainMapCellImages
is null:
if ((gridCols == 0) || (gridCols > 256) || (gridRows == 0) || (gridRows > 256)) {
return AVIF_RESULT_INVALID_IMAGE_GRID;
}
if (gainMapCellImages &&
((gainMapGridCols == 0) || (gainMapGridCols > 256) || (gainMapGridRows == 0) || (gainMapGridRows > 256))) {
return AVIF_RESULT_INVALID_IMAGE_GRID;
}
/*gridRows=*/1, | ||
&image, | ||
/*gainMapGridCols=*/1, | ||
/*gainMapGridRows=*/1, |
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.
If we make the changes I suggested at line 2163, we can pass 0 and 0 here.
gridRows, | ||
cellImages, | ||
/*gainMapGridCols=*/gridCols, | ||
/*gainMapGridRows=*/gridRows, |
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.
If we make the changes I suggested at line 2163, we can pass 0 and 0 here.
@@ -1596,6 +1609,9 @@ static avifResult avifEncoderAddImageInternal(avifEncoder * encoder, | |||
uint32_t gridCols, | |||
uint32_t gridRows, | |||
const avifImage * const * cellImages, | |||
uint32_t gainMapGridCols, | |||
uint32_t gainMapGridRows, | |||
const avifImage * const * gainMapCellImages, |
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 clearer if we always use the gainMapCellImages
input parameter when there is a gain map. This requires building the gainMapCellImages
array in the normal/standard case. If we do this, then a null gainMapCellImages
means there is no gain map.
Thanks for the review Wan-Teh. |
Hi Maryla, I would add the generated test images to the source tree rather than generate them on the fly during testing. The code you used to generate the test images should be made available so that other people can reproduce your work. Publishing this pull request achieves that goal; we don't need to merge the pull request. If you ask us for our opinion, we are likely to only consider the maintenance cost and ignore the efforts you spent on generating the test images. You are in the best position to evaluate the trade-offs and decide whether this pull request should be merged. I trust your judgment. |
Indeed currently we guarantee that gainMapPresent == (gainMap != NULL) so getting rid of the boolean could be an option. Although that might change if we changed the definition of gainMapPresent... We can revisit this later. As long as this is behind and EXPERIMENTAL compile flag I think it's ok to change the API (and I doubt a lot of people use it right now). |
The main image can have a different number of cols/rows than the gain map, or one can be a grid and the other be a single image. Also allow setting differnet values for gain map metadata version fields.
Add code in gainmaptest.cc to generate test images. These images are used in tests and as seeds by the fuzzer.
This PR removes the need to maintain a separate branch to generate/update some of the test images which was becoming burdernsome.
WIth the ability to create these test images in the main branch, the images don't actually need to be stored in the repo but could be created on the fly in the relevant tests. However, having them in the repo allows them to be used as seeds by the fuzzer, and they can be copied easily to CrabbyAvif for testing there.
#2391