mirror of https://github.com/SixLabors/ImageSharp
5 changed files with 200 additions and 0 deletions
@ -0,0 +1,38 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Runtime.CompilerServices; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl; |
|||
|
|||
internal static class JxlAspectRatioHelpers |
|||
{ |
|||
private static readonly SignedRational[] Ratios = |
|||
[ |
|||
new(1, 1), |
|||
new(12, 10), |
|||
new(4, 3), |
|||
new(3, 2), |
|||
new(16, 9), |
|||
new(5, 4), |
|||
new(2, 1) |
|||
]; |
|||
|
|||
public static SignedRational FixedAspectRatios(int ratio) => Ratios[ratio - 1]; |
|||
|
|||
public static int FindAspectRatio(int x, int y) |
|||
{ |
|||
for (int i = 0; i < 7; i++) |
|||
{ |
|||
if (x == MultiplyTruncate(Ratios[i], y)) |
|||
{ |
|||
return i; |
|||
} |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static int MultiplyTruncate(SignedRational rational, int multiplicand) => (multiplicand * rational.Numerator) / rational.Denominator; |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.IO; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Metadata; |
|||
|
|||
internal sealed class JxlAnimationHeader : IJxlFields |
|||
{ |
|||
public int TpsNumerator { get; set; } |
|||
|
|||
public int TpsDenominator { get; set; } |
|||
|
|||
public int LoopCount { get; set; } |
|||
|
|||
public bool ContainsTimecodes { get; set; } |
|||
|
|||
public bool Visit(JxlVisitor visitor) => throw new NotImplementedException(); |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.IO; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Metadata; |
|||
|
|||
internal sealed class JxlPreviewHeader : IJxlFields |
|||
{ |
|||
private bool div8; |
|||
private int ySizeDiv8; |
|||
private int ySize; |
|||
private int ratio; |
|||
private int xSizeDiv8; |
|||
private int xSize; |
|||
|
|||
public int YSize => this.div8 ? (this.ySizeDiv8 * 8) : this.ySize; |
|||
|
|||
public int XSize |
|||
{ |
|||
get |
|||
{ |
|||
if (this.ratio != 0) |
|||
{ |
|||
SignedRational signedRational = JxlAspectRatioHelpers.FixedAspectRatios(this.ratio); |
|||
|
|||
return JxlAspectRatioHelpers.MultiplyTruncate(signedRational, this.YSize); |
|||
} |
|||
|
|||
return this.div8 ? (this.xSizeDiv8 * 8) : this.xSize; |
|||
} |
|||
} |
|||
|
|||
public void Set(int x, int y) |
|||
{ |
|||
if (x == 0 || y == 0) |
|||
{ |
|||
throw new ArgumentException("Empty preview"); |
|||
} |
|||
|
|||
this.div8 = ((x % JxlFrameDimensions.BlockDimensions) | (y % JxlFrameDimensions.BlockDimensions)) == 0; |
|||
|
|||
if (this.div8) |
|||
{ |
|||
this.ySizeDiv8 = y / 8; |
|||
} |
|||
else |
|||
{ |
|||
this.ySize = y; |
|||
} |
|||
|
|||
this.ratio = JxlAspectRatioHelpers.FindAspectRatio(x, y); |
|||
|
|||
if (this.ratio == 0) |
|||
{ |
|||
if (this.div8) |
|||
{ |
|||
this.xSizeDiv8 = x / 8; |
|||
} |
|||
else |
|||
{ |
|||
this.xSize = x; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public bool Visit(JxlVisitor visitor) => throw new NotImplementedException(); |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.IO; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Metadata; |
|||
|
|||
internal sealed class JxlSizeHeader : IJxlFields |
|||
{ |
|||
private bool isSmall; |
|||
private int ySizeDiv8Minus1; |
|||
private int ySize; |
|||
private int ratio; |
|||
private int xSizeDiv8Minus1; |
|||
private int xSize; |
|||
|
|||
public int YSize => this.isSmall ? ((this.ySizeDiv8Minus1 + 1) * 8) : this.ySize; |
|||
|
|||
public int XSize |
|||
{ |
|||
get |
|||
{ |
|||
if (this.ratio != 0) |
|||
{ |
|||
SignedRational aspectRatio = JxlAspectRatioHelpers.FixedAspectRatios(this.ratio); |
|||
|
|||
return JxlAspectRatioHelpers.MultiplyTruncate(aspectRatio, this.YSize); |
|||
} |
|||
|
|||
return this.isSmall ? ((this.xSizeDiv8Minus1 + 1) * 8) : this.xSize; |
|||
} |
|||
} |
|||
|
|||
public void Set(int x, int y) |
|||
{ |
|||
if (x > int.MaxValue || y > int.MaxValue) |
|||
{ |
|||
throw new ArgumentException("Image too large"); |
|||
} |
|||
|
|||
if (x == 0 || y == 0) |
|||
{ |
|||
throw new ArgumentException("Empty image"); |
|||
} |
|||
|
|||
this.ratio = JxlAspectRatioHelpers.FindAspectRatio(x, y); |
|||
this.isSmall = y < 256 && (y % JxlFrameDimensions.BlockDimensions) == 0 |
|||
&& (this.ratio != 0 || (x <= 256 && (x % JxlFrameDimensions.BlockDimensions) == 0)); |
|||
|
|||
if (this.isSmall) |
|||
{ |
|||
this.ySizeDiv8Minus1 = (y / 8) - 1; |
|||
} |
|||
else |
|||
{ |
|||
this.ySize = y; |
|||
} |
|||
|
|||
if (this.ratio == 0) |
|||
{ |
|||
if (this.isSmall) |
|||
{ |
|||
this.xSizeDiv8Minus1 = (x / 8) - 1; |
|||
} |
|||
else |
|||
{ |
|||
this.xSize = x; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public bool Visit(JxlVisitor visitor) => throw new NotImplementedException(); |
|||
} |
|||
Loading…
Reference in new issue