Commit 7c3d0761 authored by Wan-Teh Chang's avatar Wan-Teh Chang Committed by Chromium LUCI CQ

Implement mirroring and rotation of AVIF images

Implement mirroring and rotation of AVIF images by converting the 'irot'
and 'imir' image item properties to the equivalent Exif orientation
value. The Exif metadata, if present in the AVIF image, is ignored.

Add several AVIF test images with the 'irot' or 'imir' image item
properties. Check the image orientation in avif_image_decoder_test.cc.

Update and fix TODO comments in avif_image_decoder_test.cc.

Bug: 1087059
Change-Id: I79c4d325407ce373c849c4e91058f98fd3397ff8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2634311Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Cr-Commit-Position: refs/heads/master@{#845038}
parent d38e3851
......@@ -798,6 +798,45 @@ bool AVIFImageDecoder::UpdateDemuxer() {
}
}
// |angle| * 90 specifies the angle of anti-clockwise rotation in degrees.
// Legal values: [0-3].
int angle = 0;
if (container->transformFlags & AVIF_TRANSFORM_IROT)
angle = container->irot.angle;
// |axis| specifies the axis for the mirroring operation.
// -1: No mirroring.
// 0: Mirror about a vertical axis ("left-to-right").
// 1: Mirror about a horizontal axis ("top-to-bottom").
int axis = -1;
if (container->transformFlags & AVIF_TRANSFORM_IMIR)
axis = container->imir.axis;
// MIAF Section 7.3.6.7 (Clean aperture, rotation and mirror) says:
// These properties, if used, shall be indicated to be applied in the
// following order: clean aperture first, then rotation, then mirror.
//
// In the kAxisAngleToOrientation array, the first dimension is axis (with an
// offset of 1). The second dimension is angle.
constexpr ImageOrientationEnum kAxisAngleToOrientation[3][4] = {
// No mirroring.
{ImageOrientationEnum::kOriginTopLeft,
ImageOrientationEnum::kOriginLeftBottom,
ImageOrientationEnum::kOriginBottomRight,
ImageOrientationEnum::kOriginRightTop},
// Mirror about a vertical axis ("left-to-right"). Change Left<->Right in
// the first row.
{ImageOrientationEnum::kOriginTopRight,
ImageOrientationEnum::kOriginRightBottom,
ImageOrientationEnum::kOriginBottomLeft,
ImageOrientationEnum::kOriginLeftTop},
// Mirror about a horizontal axis ("top-to-bottom"). Change Top<->Bottom
// in the first row.
{ImageOrientationEnum::kOriginBottomLeft,
ImageOrientationEnum::kOriginLeftTop,
ImageOrientationEnum::kOriginTopRight,
ImageOrientationEnum::kOriginRightBottom},
};
orientation_ = kAxisAngleToOrientation[axis + 1][angle];
// Determine whether the image can be decoded to YUV.
// * Alpha channel is not supported.
// * Multi-frame images (animations) are not supported. (The DecodeToYUV()
......
......@@ -73,4 +73,15 @@ avifenc command line:
avifenc -r f -d 8 -y 420 -s 0 --nclx 1/13/1 silver.png silver-full-range-srgb-420-8bpc.avif
```
### red-full-range-angle-(0|1|2|3)-axis-(0|1)-420-8bpc.avif
These are all generated from red.png with the appropriate avifenc command line:
```
avifenc -r f -d 8 -y 420 -s 0 --irot 1 red.png red-full-range-angle-1-420-8bpc.avif
avifenc -r f -d 8 -y 420 -s 0 --imir 0 red.png red-full-range-axis-0-420-8bpc.avif
avifenc -r f -d 8 -y 420 -s 0 --imir 1 red.png red-full-range-axis-1-420-8bpc.avif
avifenc -r f -d 8 -y 420 -s 0 --irot 2 --imir 0 red.png red-full-range-angle-2-axis-0-420-8bpc.avif
avifenc -r f -d 8 -y 420 -s 0 --irot 3 --imir 1 red.png red-full-range-angle-3-axis-1-420-8bpc.avif
```
### TODO(crbug.com/960620): Figure out how the rest of files were generated.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment