@@ -12,12 +12,11 @@ namespace SixLabors.ImageSharp.Formats.Qoi;
12
12
/// </summary>
13
13
public class QoiEncoderCore : IImageEncoderInternals
14
14
{
15
+ private readonly QoiEncoder encoder ;
15
16
/// <summary>
16
17
/// Initializes a new instance of the <see cref="QoiEncoderCore"/> class.
17
18
/// </summary>
18
- public QoiEncoderCore ( )
19
- {
20
- }
19
+ public QoiEncoderCore ( QoiEncoder encoder ) => this . encoder = encoder ;
21
20
22
21
/// <inheritdoc />
23
22
public void Encode < TPixel > ( Image < TPixel > image , Stream stream , CancellationToken cancellationToken )
@@ -26,23 +25,21 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
26
25
Guard . NotNull ( image , nameof ( image ) ) ;
27
26
Guard . NotNull ( stream , nameof ( stream ) ) ;
28
27
29
- WriteHeader ( image , stream ) ;
28
+ this . WriteHeader ( image , stream ) ;
30
29
WritePixels ( image , stream ) ;
31
30
WriteEndOfStream ( stream ) ;
32
31
stream . Flush ( ) ;
33
32
}
34
33
35
- private static void WriteHeader ( Image image , Stream stream )
34
+ private void WriteHeader ( Image image , Stream stream )
36
35
{
37
36
// Get metadata
38
37
Span < byte > width = stackalloc byte [ 4 ] ;
39
38
Span < byte > height = stackalloc byte [ 4 ] ;
40
39
BinaryPrimitives . WriteUInt32BigEndian ( width , ( uint ) image . Width ) ;
41
40
BinaryPrimitives . WriteUInt32BigEndian ( height , ( uint ) image . Height ) ;
42
- QoiChannels qoiChannels = image . PixelType . BitsPerPixel == 24 ? QoiChannels . Rgb : QoiChannels . Rgba ;
43
-
44
- // I need to check this, how do I check it with the pixel type or metadata of the original image?
45
- const QoiColorSpace qoiColorSpace = QoiColorSpace . SrgbWithLinearAlpha ;
41
+ QoiChannels qoiChannels = this . encoder . Channels ?? QoiChannels . Rgba ;
42
+ QoiColorSpace qoiColorSpace = this . encoder . ColorSpace ?? QoiColorSpace . SrgbWithLinearAlpha ;
46
43
47
44
// Write header to the stream
48
45
stream . Write ( QoiConstants . Magic ) ;
@@ -58,11 +55,9 @@ private static void WritePixels<TPixel>(Image<TPixel> image, Stream stream)
58
55
// Start image encoding
59
56
Rgba32 [ ] previouslySeenPixels = new Rgba32 [ 64 ] ;
60
57
Rgba32 previousPixel = new ( 0 , 0 , 0 , 255 ) ;
61
- int pixelArrayPosition = GetArrayPosition ( previousPixel ) ;
62
- previouslySeenPixels [ pixelArrayPosition ] = previousPixel ;
63
-
64
- Buffer2D < TPixel > pixels = image . Frames [ 0 ] . PixelBuffer ;
65
58
Rgba32 currentRgba32 = default ;
59
+ Buffer2D < TPixel > pixels = image . Frames [ 0 ] . PixelBuffer ;
60
+
66
61
for ( int i = 0 ; i < pixels . Height ; i ++ )
67
62
{
68
63
for ( int j = 0 ; j < pixels . Width && i < pixels . Height ; j ++ )
@@ -105,7 +100,7 @@ private static void WritePixels<TPixel>(Image<TPixel> image, Stream stream)
105
100
while ( currentRgba32 . Equals ( previousPixel ) && repetitions < 62 ) ;
106
101
107
102
j -- ;
108
- stream . WriteByte ( ( byte ) ( ( byte ) QoiChunkEnum . QoiOpRun | ( repetitions - 1 ) ) ) ;
103
+ stream . WriteByte ( ( byte ) ( ( byte ) QoiChunk . QoiOpRun | ( repetitions - 1 ) ) ) ;
109
104
110
105
/* If it's a QOI_OP_RUN, we don't overwrite the previous pixel since
111
106
* it will be taken and compared on the next iteration
@@ -115,7 +110,7 @@ private static void WritePixels<TPixel>(Image<TPixel> image, Stream stream)
115
110
116
111
// else, we check if it exists in the previously seen pixels
117
112
// If so, we do a QOI_OP_INDEX
118
- pixelArrayPosition = GetArrayPosition ( currentRgba32 ) ;
113
+ int pixelArrayPosition = GetArrayPosition ( currentRgba32 ) ;
119
114
if ( previouslySeenPixels [ pixelArrayPosition ] . Equals ( currentPixel ) )
120
115
{
121
116
stream . WriteByte ( ( byte ) pixelArrayPosition ) ;
@@ -140,7 +135,7 @@ diffBlue is > -3 and < 2 &&
140
135
byte dr = ( byte ) ( diffRed + 2 ) ,
141
136
dg = ( byte ) ( diffGreen + 2 ) ,
142
137
db = ( byte ) ( diffBlue + 2 ) ,
143
- valueToWrite = ( byte ) ( ( byte ) QoiChunkEnum . QoiOpDiff | ( dr << 4 ) | ( dg << 2 ) | db ) ;
138
+ valueToWrite = ( byte ) ( ( byte ) QoiChunk . QoiOpDiff | ( dr << 4 ) | ( dg << 2 ) | db ) ;
144
139
stream . WriteByte ( valueToWrite ) ;
145
140
}
146
141
else
@@ -156,7 +151,7 @@ diffBlueGreen is > -9 and < 8 &&
156
151
{
157
152
byte dr_dg = ( byte ) ( diffRedGreen + 8 ) ,
158
153
db_dg = ( byte ) ( diffBlueGreen + 8 ) ,
159
- byteToWrite1 = ( byte ) ( ( byte ) QoiChunkEnum . QoiOpLuma | ( diffGreen + 32 ) ) ,
154
+ byteToWrite1 = ( byte ) ( ( byte ) QoiChunk . QoiOpLuma | ( diffGreen + 32 ) ) ,
160
155
byteToWrite2 = ( byte ) ( ( dr_dg << 4 ) | db_dg ) ;
161
156
stream . WriteByte ( byteToWrite1 ) ;
162
157
stream . WriteByte ( byteToWrite2 ) ;
@@ -167,15 +162,15 @@ diffBlueGreen is > -9 and < 8 &&
167
162
// If so, we do a QOI_OP_RGB
168
163
if ( currentRgba32 . A == previousPixel . A )
169
164
{
170
- stream . WriteByte ( ( byte ) QoiChunkEnum . QoiOpRgb ) ;
165
+ stream . WriteByte ( ( byte ) QoiChunk . QoiOpRgb ) ;
171
166
stream . WriteByte ( currentRgba32 . R ) ;
172
167
stream . WriteByte ( currentRgba32 . G ) ;
173
168
stream . WriteByte ( currentRgba32 . B ) ;
174
169
}
175
170
else
176
171
{
177
172
// else, we do a QOI_OP_RGBA
178
- stream . WriteByte ( ( byte ) QoiChunkEnum . QoiOpRgba ) ;
173
+ stream . WriteByte ( ( byte ) QoiChunk . QoiOpRgba ) ;
179
174
stream . WriteByte ( currentRgba32 . R ) ;
180
175
stream . WriteByte ( currentRgba32 . G ) ;
181
176
stream . WriteByte ( currentRgba32 . B ) ;
0 commit comments