@@ -146,6 +146,12 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
146
146
{
147
147
Rgba32 [ ] previouslySeenPixels = new Rgba32 [ 64 ] ;
148
148
Rgba32 previousPixel = new ( 0 , 0 , 0 , 255 ) ;
149
+
150
+ // We save the pixel to avoid loosing the fully opaque black pixel
151
+ // See https://github.com/phoboslab/qoi/issues/258
152
+ int pixelArrayPosition = this . GetArrayPosition ( previousPixel ) ;
153
+ previouslySeenPixels [ pixelArrayPosition ] = previousPixel ;
154
+
149
155
for ( int i = 0 ; i < this . header . Height ; i ++ )
150
156
{
151
157
for ( int j = 0 ; j < this . header . Width ; j ++ )
@@ -154,9 +160,9 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
154
160
byte [ ] pixelBytes ;
155
161
Rgba32 readPixel ;
156
162
TPixel pixel = new ( ) ;
157
- int pixelArrayPosition ;
158
163
switch ( ( QoiChunkEnum ) operationByte )
159
164
{
165
+ // Reading one pixel with previous alpha intact
160
166
case QoiChunkEnum . QOI_OP_RGB :
161
167
pixelBytes = new byte [ 3 ] ;
162
168
if ( stream . Read ( pixelBytes ) < 3 )
@@ -170,6 +176,7 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
170
176
previouslySeenPixels [ pixelArrayPosition ] = readPixel ;
171
177
break ;
172
178
179
+ // Reading one pixel with new alpha
173
180
case QoiChunkEnum . QOI_OP_RGBA :
174
181
pixelBytes = new byte [ 4 ] ;
175
182
if ( stream . Read ( pixelBytes ) < 4 )
@@ -186,12 +193,14 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
186
193
default :
187
194
switch ( ( QoiChunkEnum ) ( operationByte & 0b11000000 ) )
188
195
{
196
+ // Getting one pixel from previously seen pixels
189
197
case QoiChunkEnum . QOI_OP_INDEX :
190
198
readPixel = previouslySeenPixels [ operationByte ] ;
191
199
pixel . FromRgba32 ( readPixel ) ;
192
200
break ;
201
+
202
+ // Get one pixel from the difference (-2..1) of the previous pixel
193
203
case QoiChunkEnum . QOI_OP_DIFF :
194
- // Get each value
195
204
byte redDifference = ( byte ) ( ( operationByte & 0b00110000 ) >> 4 ) ,
196
205
greenDifference = ( byte ) ( ( operationByte & 0b00001100 ) >> 2 ) ,
197
206
blueDifference = ( byte ) ( operationByte & 0b00000011 ) ;
@@ -205,8 +214,10 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
205
214
pixelArrayPosition = this . GetArrayPosition ( readPixel ) ;
206
215
previouslySeenPixels [ pixelArrayPosition ] = readPixel ;
207
216
break ;
217
+
218
+ // Get green difference in 6 bits and red and blue differences
219
+ // depending on the green one
208
220
case QoiChunkEnum . QOI_OP_LUMA :
209
- // Get difference green channel
210
221
byte diffGreen = ( byte ) ( operationByte & 0b00111111 ) ,
211
222
currentGreen = ( byte ) ( ( previousPixel . G + ( diffGreen - 32 ) ) % 256 ) ,
212
223
nextByte = ( byte ) stream . ReadByte ( ) ,
@@ -219,6 +230,8 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
219
230
pixelArrayPosition = this . GetArrayPosition ( readPixel ) ;
220
231
previouslySeenPixels [ pixelArrayPosition ] = readPixel ;
221
232
break ;
233
+
234
+ // Repeating the previous pixel 1..63 times
222
235
case QoiChunkEnum . QOI_OP_RUN :
223
236
byte repetitions = ( byte ) ( operationByte & 0b00111111 ) ;
224
237
if ( repetitions is 62 or 63 )
0 commit comments