99using SixLabors . ImageSharp . Memory ;
1010using SixLabors . ImageSharp . Metadata ;
1111using SixLabors . ImageSharp . PixelFormats ;
12- using SixLabors . ImageSharp . Processing ;
1312using SixLabors . ImageSharp . Processing . Processors . Quantization ;
1413
1514namespace SixLabors . ImageSharp . Formats . Bmp ;
@@ -92,17 +91,23 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals
9291 /// </summary>
9392 private readonly IQuantizer quantizer ;
9493
94+ /// <summary>
95+ /// The pixel sampling strategy for quantization.
96+ /// </summary>
97+ private readonly IPixelSamplingStrategy pixelSamplingStrategy ;
98+
9599 /// <summary>
96100 /// Initializes a new instance of the <see cref="BmpEncoderCore"/> class.
97101 /// </summary>
98- /// <param name="options ">The encoder options.</param>
102+ /// <param name="encoder ">The encoder with options.</param>
99103 /// <param name="memoryAllocator">The memory manager.</param>
100- public BmpEncoderCore ( IBmpEncoderOptions options , MemoryAllocator memoryAllocator )
104+ public BmpEncoderCore ( BmpEncoder encoder , MemoryAllocator memoryAllocator )
101105 {
102106 this . memoryAllocator = memoryAllocator ;
103- this . bitsPerPixel = options . BitsPerPixel ;
104- this . quantizer = options . Quantizer ?? KnownQuantizers . Octree ;
105- this . infoHeaderType = options . SupportTransparency ? BmpInfoHeaderType . WinVersion4 : BmpInfoHeaderType . WinVersion3 ;
107+ this . bitsPerPixel = encoder . BitsPerPixel ;
108+ this . quantizer = encoder . Quantizer ;
109+ this . pixelSamplingStrategy = encoder . PixelSamplingStrategy ;
110+ this . infoHeaderType = encoder . SupportTransparency ? BmpInfoHeaderType . WinVersion4 : BmpInfoHeaderType . WinVersion3 ;
106111 }
107112
108113 /// <summary>
@@ -159,7 +164,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
159164
160165 WriteBitmapFileHeader ( stream , infoHeaderSize , colorPaletteSize , iccProfileSize , infoHeader , buffer ) ;
161166 this . WriteBitmapInfoHeader ( stream , infoHeader , buffer , infoHeaderSize ) ;
162- this . WriteImage ( stream , image . Frames . RootFrame ) ;
167+ this . WriteImage ( stream , image ) ;
163168 WriteColorProfile ( stream , iccProfileData , buffer ) ;
164169
165170 stream . Flush ( ) ;
@@ -311,10 +316,10 @@ private void WriteBitmapInfoHeader(Stream stream, BmpInfoHeader infoHeader, Span
311316 /// <param name="image">
312317 /// The <see cref="ImageFrame{TPixel}"/> containing pixel data.
313318 /// </param>
314- private void WriteImage < TPixel > ( Stream stream , ImageFrame < TPixel > image )
319+ private void WriteImage < TPixel > ( Stream stream , Image < TPixel > image )
315320 where TPixel : unmanaged, IPixel < TPixel >
316321 {
317- Buffer2D < TPixel > pixels = image . PixelBuffer ;
322+ Buffer2D < TPixel > pixels = image . Frames . RootFrame . PixelBuffer ;
318323 switch ( this . bitsPerPixel )
319324 {
320325 case BmpBitsPerPixel . Pixel32 :
@@ -433,8 +438,8 @@ private void Write16BitPixelData<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
433438 /// </summary>
434439 /// <typeparam name="TPixel">The type of the pixel.</typeparam>
435440 /// <param name="stream">The <see cref="Stream"/> to write to.</param>
436- /// <param name="image"> The <see cref="ImageFrame {TPixel}"/> containing pixel data.</param>
437- private void Write8BitPixelData < TPixel > ( Stream stream , ImageFrame < TPixel > image )
441+ /// <param name="image"> The <see cref="Image {TPixel}"/> containing pixel data.</param>
442+ private void Write8BitPixelData < TPixel > ( Stream stream , Image < TPixel > image )
438443 where TPixel : unmanaged, IPixel < TPixel >
439444 {
440445 bool isL8 = typeof ( TPixel ) == typeof ( L8 ) ;
@@ -456,13 +461,15 @@ private void Write8BitPixelData<TPixel>(Stream stream, ImageFrame<TPixel> image)
456461 /// </summary>
457462 /// <typeparam name="TPixel">The type of the pixel.</typeparam>
458463 /// <param name="stream">The <see cref="Stream"/> to write to.</param>
459- /// <param name="image"> The <see cref="ImageFrame {TPixel}"/> containing pixel data.</param>
464+ /// <param name="image"> The <see cref="Image {TPixel}"/> containing pixel data.</param>
460465 /// <param name="colorPalette">A byte span of size 1024 for the color palette.</param>
461- private void Write8BitColor < TPixel > ( Stream stream , ImageFrame < TPixel > image , Span < byte > colorPalette )
466+ private void Write8BitColor < TPixel > ( Stream stream , Image < TPixel > image , Span < byte > colorPalette )
462467 where TPixel : unmanaged, IPixel < TPixel >
463468 {
464469 using IQuantizer < TPixel > frameQuantizer = this . quantizer . CreatePixelSpecificQuantizer < TPixel > ( this . configuration ) ;
465- using IndexedImageFrame < TPixel > quantized = frameQuantizer . BuildPaletteAndQuantizeFrame ( image , image . Bounds ( ) ) ;
470+
471+ frameQuantizer . BuildPalette ( this . pixelSamplingStrategy , image ) ;
472+ using IndexedImageFrame < TPixel > quantized = frameQuantizer . QuantizeFrame ( image . Frames . RootFrame , image . Bounds ( ) ) ;
466473
467474 ReadOnlySpan < TPixel > quantizedColorPalette = quantized . Palette . Span ;
468475 this . WriteColorPalette ( stream , quantizedColorPalette , colorPalette ) ;
@@ -486,7 +493,7 @@ private void Write8BitColor<TPixel>(Stream stream, ImageFrame<TPixel> image, Spa
486493 /// <param name="stream">The <see cref="Stream"/> to write to.</param>
487494 /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
488495 /// <param name="colorPalette">A byte span of size 1024 for the color palette.</param>
489- private void Write8BitPixelData < TPixel > ( Stream stream , ImageFrame < TPixel > image , Span < byte > colorPalette )
496+ private void Write8BitPixelData < TPixel > ( Stream stream , Image < TPixel > image , Span < byte > colorPalette )
490497 where TPixel : unmanaged, IPixel < TPixel >
491498 {
492499 // Create a color palette with 256 different gray values.
@@ -503,7 +510,7 @@ private void Write8BitPixelData<TPixel>(Stream stream, ImageFrame<TPixel> image,
503510 }
504511
505512 stream . Write ( colorPalette ) ;
506- Buffer2D < TPixel > imageBuffer = image . PixelBuffer ;
513+ Buffer2D < TPixel > imageBuffer = image . GetRootFramePixelBuffer ( ) ;
507514 for ( int y = image . Height - 1 ; y >= 0 ; y -- )
508515 {
509516 ReadOnlySpan < TPixel > inputPixelRow = imageBuffer . DangerousGetRowSpan ( y ) ;
@@ -523,14 +530,17 @@ private void Write8BitPixelData<TPixel>(Stream stream, ImageFrame<TPixel> image,
523530 /// <typeparam name="TPixel">The type of the pixel.</typeparam>
524531 /// <param name="stream">The <see cref="Stream"/> to write to.</param>
525532 /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
526- private void Write4BitPixelData < TPixel > ( Stream stream , ImageFrame < TPixel > image )
533+ private void Write4BitPixelData < TPixel > ( Stream stream , Image < TPixel > image )
527534 where TPixel : unmanaged, IPixel < TPixel >
528535 {
529536 using IQuantizer < TPixel > frameQuantizer = this . quantizer . CreatePixelSpecificQuantizer < TPixel > ( this . configuration , new QuantizerOptions ( )
530537 {
531538 MaxColors = 16
532539 } ) ;
533- using IndexedImageFrame < TPixel > quantized = frameQuantizer . BuildPaletteAndQuantizeFrame ( image , image . Bounds ( ) ) ;
540+
541+ frameQuantizer . BuildPalette ( this . pixelSamplingStrategy , image ) ;
542+
543+ using IndexedImageFrame < TPixel > quantized = frameQuantizer . QuantizeFrame ( image . Frames . RootFrame , image . Bounds ( ) ) ;
534544 using IMemoryOwner < byte > colorPaletteBuffer = this . memoryAllocator . Allocate < byte > ( ColorPaletteSize4Bit , AllocationOptions . Clean ) ;
535545
536546 Span < byte > colorPalette = colorPaletteBuffer . GetSpan ( ) ;
@@ -567,14 +577,17 @@ private void Write4BitPixelData<TPixel>(Stream stream, ImageFrame<TPixel> image)
567577 /// <typeparam name="TPixel">The type of the pixel.</typeparam>
568578 /// <param name="stream">The <see cref="Stream"/> to write to.</param>
569579 /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
570- private void Write2BitPixelData < TPixel > ( Stream stream , ImageFrame < TPixel > image )
580+ private void Write2BitPixelData < TPixel > ( Stream stream , Image < TPixel > image )
571581 where TPixel : unmanaged, IPixel < TPixel >
572582 {
573583 using IQuantizer < TPixel > frameQuantizer = this . quantizer . CreatePixelSpecificQuantizer < TPixel > ( this . configuration , new QuantizerOptions ( )
574584 {
575585 MaxColors = 4
576586 } ) ;
577- using IndexedImageFrame < TPixel > quantized = frameQuantizer . BuildPaletteAndQuantizeFrame ( image , image . Bounds ( ) ) ;
587+
588+ frameQuantizer . BuildPalette ( this . pixelSamplingStrategy , image ) ;
589+
590+ using IndexedImageFrame < TPixel > quantized = frameQuantizer . QuantizeFrame ( image . Frames . RootFrame , image . Bounds ( ) ) ;
578591 using IMemoryOwner < byte > colorPaletteBuffer = this . memoryAllocator . Allocate < byte > ( ColorPaletteSize2Bit , AllocationOptions . Clean ) ;
579592
580593 Span < byte > colorPalette = colorPaletteBuffer . GetSpan ( ) ;
@@ -620,14 +633,17 @@ private void Write2BitPixelData<TPixel>(Stream stream, ImageFrame<TPixel> image)
620633 /// <typeparam name="TPixel">The type of the pixel.</typeparam>
621634 /// <param name="stream">The <see cref="Stream"/> to write to.</param>
622635 /// <param name="image"> The <see cref="ImageFrame{TPixel}"/> containing pixel data.</param>
623- private void Write1BitPixelData < TPixel > ( Stream stream , ImageFrame < TPixel > image )
636+ private void Write1BitPixelData < TPixel > ( Stream stream , Image < TPixel > image )
624637 where TPixel : unmanaged, IPixel < TPixel >
625638 {
626639 using IQuantizer < TPixel > frameQuantizer = this . quantizer . CreatePixelSpecificQuantizer < TPixel > ( this . configuration , new QuantizerOptions ( )
627640 {
628641 MaxColors = 2
629642 } ) ;
630- using IndexedImageFrame < TPixel > quantized = frameQuantizer . BuildPaletteAndQuantizeFrame ( image , image . Bounds ( ) ) ;
643+
644+ frameQuantizer . BuildPalette ( this . pixelSamplingStrategy , image ) ;
645+
646+ using IndexedImageFrame < TPixel > quantized = frameQuantizer . QuantizeFrame ( image . Frames . RootFrame , image . Bounds ( ) ) ;
631647 using IMemoryOwner < byte > colorPaletteBuffer = this . memoryAllocator . Allocate < byte > ( ColorPaletteSize1Bit , AllocationOptions . Clean ) ;
632648
633649 Span < byte > colorPalette = colorPaletteBuffer . GetSpan ( ) ;
0 commit comments