@@ -146,6 +146,12 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
146146 {
147147 Rgba32 [ ] previouslySeenPixels = new Rgba32 [ 64 ] ;
148148 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+
149155 for ( int i = 0 ; i < this . header . Height ; i ++ )
150156 {
151157 for ( int j = 0 ; j < this . header . Width ; j ++ )
@@ -154,9 +160,9 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
154160 byte [ ] pixelBytes ;
155161 Rgba32 readPixel ;
156162 TPixel pixel = new ( ) ;
157- int pixelArrayPosition ;
158163 switch ( ( QoiChunkEnum ) operationByte )
159164 {
165+ // Reading one pixel with previous alpha intact
160166 case QoiChunkEnum . QOI_OP_RGB :
161167 pixelBytes = new byte [ 3 ] ;
162168 if ( stream . Read ( pixelBytes ) < 3 )
@@ -170,6 +176,7 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
170176 previouslySeenPixels [ pixelArrayPosition ] = readPixel ;
171177 break ;
172178
179+ // Reading one pixel with new alpha
173180 case QoiChunkEnum . QOI_OP_RGBA :
174181 pixelBytes = new byte [ 4 ] ;
175182 if ( stream . Read ( pixelBytes ) < 4 )
@@ -186,12 +193,14 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
186193 default :
187194 switch ( ( QoiChunkEnum ) ( operationByte & 0b11000000 ) )
188195 {
196+ // Getting one pixel from previously seen pixels
189197 case QoiChunkEnum . QOI_OP_INDEX :
190198 readPixel = previouslySeenPixels [ operationByte ] ;
191199 pixel . FromRgba32 ( readPixel ) ;
192200 break ;
201+
202+ // Get one pixel from the difference (-2..1) of the previous pixel
193203 case QoiChunkEnum . QOI_OP_DIFF :
194- // Get each value
195204 byte redDifference = ( byte ) ( ( operationByte & 0b00110000 ) >> 4 ) ,
196205 greenDifference = ( byte ) ( ( operationByte & 0b00001100 ) >> 2 ) ,
197206 blueDifference = ( byte ) ( operationByte & 0b00000011 ) ;
@@ -205,8 +214,10 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
205214 pixelArrayPosition = this . GetArrayPosition ( readPixel ) ;
206215 previouslySeenPixels [ pixelArrayPosition ] = readPixel ;
207216 break ;
217+
218+ // Get green difference in 6 bits and red and blue differences
219+ // depending on the green one
208220 case QoiChunkEnum . QOI_OP_LUMA :
209- // Get difference green channel
210221 byte diffGreen = ( byte ) ( operationByte & 0b00111111 ) ,
211222 currentGreen = ( byte ) ( ( previousPixel . G + ( diffGreen - 32 ) ) % 256 ) ,
212223 nextByte = ( byte ) stream . ReadByte ( ) ,
@@ -219,6 +230,8 @@ private void ProcessPixels<TPixel>(BufferedReadStream stream, Buffer2D<TPixel> p
219230 pixelArrayPosition = this . GetArrayPosition ( readPixel ) ;
220231 previouslySeenPixels [ pixelArrayPosition ] = readPixel ;
221232 break ;
233+
234+ // Repeating the previous pixel 1..63 times
222235 case QoiChunkEnum . QOI_OP_RUN :
223236 byte repetitions = ( byte ) ( operationByte & 0b00111111 ) ;
224237 if ( repetitions is 62 or 63 )
0 commit comments