Skip to content

Commit 682218a

Browse files
committed
refactor
1 parent 6f52a0d commit 682218a

File tree

5 files changed

+71
-56
lines changed

5 files changed

+71
-56
lines changed

src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Six Labors Split License.
33

44
using System.Buffers.Binary;
5-
using System.Drawing;
65
using System.Runtime.InteropServices;
76
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
87
using SixLabors.ImageSharp.Metadata.Profiles.Xmp;
@@ -181,7 +180,7 @@ protected void WriteAnimationParameter(Stream stream, uint background, ushort lo
181180
/// <param name="stream">The stream to write to.</param>
182181
/// <param name="animation">Animation frame data.</param>
183182
/// <param name="data">Frame data.</param>
184-
protected void WriteAnimationFrame(Stream stream, AnimationFrameData animation, byte[] data)
183+
protected void WriteAnimationFrame(Stream stream, AnimationFrameData animation, Span<byte> data)
185184
{
186185
uint size = AnimationFrameData.HeaderSize + (uint)data.Length;
187186
Span<byte> buf = this.scratchBuffer.Span[..4];
@@ -260,6 +259,12 @@ protected void WriteVp8XHeader(Stream stream, ExifProfile? exifProfile, XmpProfi
260259
flags |= 8;
261260
}
262261

262+
// if (isAnimated)
263+
// {
264+
// // Set animated flag.
265+
// flags |= 2;
266+
// }
267+
263268
if (xmpProfile != null)
264269
{
265270
// Set xmp bit.

src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public int PutCoeffs(int ctx, Vp8Residual residual)
116116
else
117117
{
118118
this.PutBit(v >= 9, 165);
119-
this.PutBit(!((v & 1) != 0), 145);
119+
this.PutBit((v & 1) == 0, 145);
120120
}
121121
}
122122
else
@@ -462,7 +462,7 @@ public void WriteEncodedImageToStream(
462462
Vp8BitWriter bitWriterPartZero = new(expectedSize, this.enc);
463463

464464
// Partition #0 with header and partition sizes.
465-
uint size0 = this.GeneratePartition0(bitWriterPartZero);
465+
uint size0 = bitWriterPartZero.GeneratePartition0();
466466

467467
uint vp8Size = WebpConstants.Vp8FrameHeaderSize + size0;
468468
vp8Size += numBytes;
@@ -495,98 +495,98 @@ public void WriteEncodedImageToStream(
495495
}
496496
}
497497

498-
private uint GeneratePartition0(Vp8BitWriter bitWriter)
498+
private uint GeneratePartition0()
499499
{
500-
bitWriter.PutBitUniform(0); // colorspace
501-
bitWriter.PutBitUniform(0); // clamp type
500+
this.PutBitUniform(0); // colorspace
501+
this.PutBitUniform(0); // clamp type
502502

503-
this.WriteSegmentHeader(bitWriter);
504-
this.WriteFilterHeader(bitWriter);
503+
this.WriteSegmentHeader();
504+
this.WriteFilterHeader();
505505

506-
bitWriter.PutBits(0, 2);
506+
this.PutBits(0, 2);
507507

508-
this.WriteQuant(bitWriter);
509-
bitWriter.PutBitUniform(0);
510-
this.WriteProbas(bitWriter);
511-
this.CodeIntraModes(bitWriter);
508+
this.WriteQuant();
509+
this.PutBitUniform(0);
510+
this.WriteProbas();
511+
this.CodeIntraModes();
512512

513-
bitWriter.Finish();
513+
this.Finish();
514514

515-
return (uint)bitWriter.NumBytes();
515+
return (uint)this.NumBytes();
516516
}
517517

518-
private void WriteSegmentHeader(Vp8BitWriter bitWriter)
518+
private void WriteSegmentHeader()
519519
{
520520
Vp8EncSegmentHeader hdr = this.enc.SegmentHeader;
521521
Vp8EncProba proba = this.enc.Proba;
522-
if (bitWriter.PutBitUniform(hdr.NumSegments > 1 ? 1 : 0) != 0)
522+
if (this.PutBitUniform(hdr.NumSegments > 1 ? 1 : 0) != 0)
523523
{
524524
// We always 'update' the quant and filter strength values.
525525
int updateData = 1;
526-
bitWriter.PutBitUniform(hdr.UpdateMap ? 1 : 0);
527-
if (bitWriter.PutBitUniform(updateData) != 0)
526+
this.PutBitUniform(hdr.UpdateMap ? 1 : 0);
527+
if (this.PutBitUniform(updateData) != 0)
528528
{
529529
// We always use absolute values, not relative ones.
530-
bitWriter.PutBitUniform(1); // (segment_feature_mode = 1. Paragraph 9.3.)
530+
this.PutBitUniform(1); // (segment_feature_mode = 1. Paragraph 9.3.)
531531
for (int s = 0; s < WebpConstants.NumMbSegments; ++s)
532532
{
533-
bitWriter.PutSignedBits(this.enc.SegmentInfos[s].Quant, 7);
533+
this.PutSignedBits(this.enc.SegmentInfos[s].Quant, 7);
534534
}
535535

536536
for (int s = 0; s < WebpConstants.NumMbSegments; ++s)
537537
{
538-
bitWriter.PutSignedBits(this.enc.SegmentInfos[s].FStrength, 6);
538+
this.PutSignedBits(this.enc.SegmentInfos[s].FStrength, 6);
539539
}
540540
}
541541

542542
if (hdr.UpdateMap)
543543
{
544544
for (int s = 0; s < 3; ++s)
545545
{
546-
if (bitWriter.PutBitUniform(proba.Segments[s] != 255 ? 1 : 0) != 0)
546+
if (this.PutBitUniform(proba.Segments[s] != 255 ? 1 : 0) != 0)
547547
{
548-
bitWriter.PutBits(proba.Segments[s], 8);
548+
this.PutBits(proba.Segments[s], 8);
549549
}
550550
}
551551
}
552552
}
553553
}
554554

555-
private void WriteFilterHeader(Vp8BitWriter bitWriter)
555+
private void WriteFilterHeader()
556556
{
557557
Vp8FilterHeader hdr = this.enc.FilterHeader;
558558
bool useLfDelta = hdr.I4x4LfDelta != 0;
559-
bitWriter.PutBitUniform(hdr.Simple ? 1 : 0);
560-
bitWriter.PutBits((uint)hdr.FilterLevel, 6);
561-
bitWriter.PutBits((uint)hdr.Sharpness, 3);
562-
if (bitWriter.PutBitUniform(useLfDelta ? 1 : 0) != 0)
559+
this.PutBitUniform(hdr.Simple ? 1 : 0);
560+
this.PutBits((uint)hdr.FilterLevel, 6);
561+
this.PutBits((uint)hdr.Sharpness, 3);
562+
if (this.PutBitUniform(useLfDelta ? 1 : 0) != 0)
563563
{
564564
// '0' is the default value for i4x4LfDelta at frame #0.
565565
bool needUpdate = hdr.I4x4LfDelta != 0;
566-
if (bitWriter.PutBitUniform(needUpdate ? 1 : 0) != 0)
566+
if (this.PutBitUniform(needUpdate ? 1 : 0) != 0)
567567
{
568568
// we don't use refLfDelta => emit four 0 bits.
569-
bitWriter.PutBits(0, 4);
569+
this.PutBits(0, 4);
570570

571571
// we use modeLfDelta for i4x4
572-
bitWriter.PutSignedBits(hdr.I4x4LfDelta, 6);
573-
bitWriter.PutBits(0, 3); // all others unused.
572+
this.PutSignedBits(hdr.I4x4LfDelta, 6);
573+
this.PutBits(0, 3); // all others unused.
574574
}
575575
}
576576
}
577577

578578
// Nominal quantization parameters
579-
private void WriteQuant(Vp8BitWriter bitWriter)
579+
private void WriteQuant()
580580
{
581-
bitWriter.PutBits((uint)this.enc.BaseQuant, 7);
582-
bitWriter.PutSignedBits(this.enc.DqY1Dc, 4);
583-
bitWriter.PutSignedBits(this.enc.DqY2Dc, 4);
584-
bitWriter.PutSignedBits(this.enc.DqY2Ac, 4);
585-
bitWriter.PutSignedBits(this.enc.DqUvDc, 4);
586-
bitWriter.PutSignedBits(this.enc.DqUvAc, 4);
581+
this.PutBits((uint)this.enc.BaseQuant, 7);
582+
this.PutSignedBits(this.enc.DqY1Dc, 4);
583+
this.PutSignedBits(this.enc.DqY2Dc, 4);
584+
this.PutSignedBits(this.enc.DqY2Ac, 4);
585+
this.PutSignedBits(this.enc.DqUvDc, 4);
586+
this.PutSignedBits(this.enc.DqUvAc, 4);
587587
}
588588

589-
private void WriteProbas(Vp8BitWriter bitWriter)
589+
private void WriteProbas()
590590
{
591591
Vp8EncProba probas = this.enc.Proba;
592592
for (int t = 0; t < WebpConstants.NumTypes; ++t)
@@ -599,25 +599,25 @@ private void WriteProbas(Vp8BitWriter bitWriter)
599599
{
600600
byte p0 = probas.Coeffs[t][b].Probabilities[c].Probabilities[p];
601601
bool update = p0 != WebpLookupTables.DefaultCoeffsProba[t, b, c, p];
602-
if (bitWriter.PutBit(update, WebpLookupTables.CoeffsUpdateProba[t, b, c, p]))
602+
if (this.PutBit(update, WebpLookupTables.CoeffsUpdateProba[t, b, c, p]))
603603
{
604-
bitWriter.PutBits(p0, 8);
604+
this.PutBits(p0, 8);
605605
}
606606
}
607607
}
608608
}
609609
}
610610

611-
if (bitWriter.PutBitUniform(probas.UseSkipProba ? 1 : 0) != 0)
611+
if (this.PutBitUniform(probas.UseSkipProba ? 1 : 0) != 0)
612612
{
613-
bitWriter.PutBits(probas.SkipProba, 8);
613+
this.PutBits(probas.SkipProba, 8);
614614
}
615615
}
616616

617617
// Writes the partition #0 modes (that is: all intra modes)
618-
private void CodeIntraModes(Vp8BitWriter bitWriter)
618+
private void CodeIntraModes()
619619
{
620-
var it = new Vp8EncIterator(this.enc.YTop, this.enc.UvTop, this.enc.Nz, this.enc.MbInfo, this.enc.Preds, this.enc.TopDerr, this.enc.Mbw, this.enc.Mbh);
620+
Vp8EncIterator it = new(this.enc);
621621
int predsWidth = this.enc.PredsWidth;
622622

623623
do
@@ -627,18 +627,18 @@ private void CodeIntraModes(Vp8BitWriter bitWriter)
627627
Span<byte> preds = it.Preds.AsSpan(predIdx);
628628
if (this.enc.SegmentHeader.UpdateMap)
629629
{
630-
bitWriter.PutSegment(mb.Segment, this.enc.Proba.Segments);
630+
this.PutSegment(mb.Segment, this.enc.Proba.Segments);
631631
}
632632

633633
if (this.enc.Proba.UseSkipProba)
634634
{
635-
bitWriter.PutBit(mb.Skip, this.enc.Proba.SkipProba);
635+
this.PutBit(mb.Skip, this.enc.Proba.SkipProba);
636636
}
637637

638-
if (bitWriter.PutBit(mb.MacroBlockType != 0, 145))
638+
if (this.PutBit(mb.MacroBlockType != 0, 145))
639639
{
640640
// i16x16
641-
bitWriter.PutI16Mode(preds[0]);
641+
this.PutI16Mode(preds[0]);
642642
}
643643
else
644644
{
@@ -649,15 +649,15 @@ private void CodeIntraModes(Vp8BitWriter bitWriter)
649649
for (int x = 0; x < 4; x++)
650650
{
651651
byte[] probas = WebpLookupTables.ModesProba[topPred[x], left];
652-
left = bitWriter.PutI4Mode(it.Preds[predIdx + x], probas);
652+
left = this.PutI4Mode(it.Preds[predIdx + x], probas);
653653
}
654654

655655
topPred = it.Preds.AsSpan(predIdx);
656656
predIdx += predsWidth;
657657
}
658658
}
659659

660-
bitWriter.PutUvMode(mb.UvMode);
660+
this.PutUvMode(mb.UvMode);
661661
}
662662
while (it.Next());
663663
}

src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ internal class Vp8EncIterator
5050

5151
private int uvTopIdx;
5252

53+
public Vp8EncIterator(Vp8Encoder enc)
54+
: this(enc.YTop, enc.UvTop, enc.Nz, enc.MbInfo, enc.Preds, enc.TopDerr, enc.Mbw, enc.Mbh)
55+
{
56+
}
57+
5358
public Vp8EncIterator(byte[] yTop, byte[] uvTop, uint[] nz, Vp8MacroBlockInfo[] mb, byte[] preds, sbyte[] topDerr, int mbw, int mbh)
5459
{
5560
this.YTop = yTop;

src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream)
328328
int yStride = width;
329329
int uvStride = (yStride + 1) >> 1;
330330

331-
Vp8EncIterator it = new(this.YTop, this.UvTop, this.Nz, this.MbInfo, this.Preds, this.TopDerr, this.Mbw, this.Mbh);
331+
Vp8EncIterator it = new(this);
332332
Span<int> alphas = stackalloc int[WebpConstants.MaxAlpha + 1];
333333
this.alpha = this.MacroBlockAnalysis(width, height, it, y, u, v, yStride, uvStride, alphas, out this.uvAlpha);
334334
int totalMb = this.Mbw * this.Mbw;
@@ -520,7 +520,7 @@ private long OneStatPass(int width, int height, int yStride, int uvStride, Vp8Rd
520520
Span<byte> y = this.Y.GetSpan();
521521
Span<byte> u = this.U.GetSpan();
522522
Span<byte> v = this.V.GetSpan();
523-
Vp8EncIterator it = new(this.YTop, this.UvTop, this.Nz, this.MbInfo, this.Preds, this.TopDerr, this.Mbw, this.Mbh);
523+
Vp8EncIterator it = new(this);
524524
long size = 0;
525525
long sizeP0 = 0;
526526
long distortion = 0;

src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ private uint ReadFrame<TPixel>(BufferedReadStream stream, ref Image<TPixel>? ima
162162
features.AlphaChunkHeader = alphaChunkHeader;
163163
break;
164164
case WebpChunkType.Vp8L:
165+
if (hasAlpha)
166+
{
167+
WebpThrowHelper.ThrowNotSupportedException("Alpha channel is not supported for lossless webp images.");
168+
}
169+
165170
webpInfo = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, buffer, features);
166171
break;
167172
default:

0 commit comments

Comments
 (0)