1010
1111#include "Imaging.h"
1212
13- #include "Bcn.h"
14-
1513typedef struct {
1614 UINT8 color [3 ];
1715} rgb ;
@@ -57,14 +55,18 @@ encode_bc1_color(Imaging im, ImagingCodecState state, UINT8 *dst, int separate_a
5755 int transparency = 0 ;
5856 for (i = 0 ; i < 4 ; i ++ ) {
5957 for (j = 0 ; j < 4 ; j ++ ) {
58+ current_rgba = & block [i + j * 4 ];
59+
6060 int x = state -> x + i * im -> pixelsize ;
6161 int y = state -> y + j ;
6262 if (x >= state -> xsize * im -> pixelsize || y >= state -> ysize ) {
6363 // The 4x4 block extends past the edge of the image
64+ for (k = 0 ; k < 3 ; k ++ ) {
65+ current_rgba -> color [k ] = 0 ;
66+ }
6467 continue ;
6568 }
6669
67- current_rgba = & block [i + j * 4 ];
6870 for (k = 0 ; k < 3 ; k ++ ) {
6971 current_rgba -> color [k ] =
7072 (UINT8 )im -> image [y ][x + (im -> pixelsize == 1 ? 0 : k )];
@@ -152,6 +154,36 @@ encode_bc1_color(Imaging im, ImagingCodecState state, UINT8 *dst, int separate_a
152154 }
153155}
154156
157+ static void
158+ encode_bc2_block (Imaging im , ImagingCodecState state , UINT8 * dst ) {
159+ int i , j ;
160+ UINT8 block [16 ], current_alpha ;
161+ for (i = 0 ; i < 4 ; i ++ ) {
162+ for (j = 0 ; j < 4 ; j ++ ) {
163+ int x = state -> x + i * im -> pixelsize ;
164+ int y = state -> y + j ;
165+ if (x >= state -> xsize * im -> pixelsize || y >= state -> ysize ) {
166+ // The 4x4 block extends past the edge of the image
167+ block [i + j * 4 ] = 0 ;
168+ continue ;
169+ }
170+
171+ current_alpha = (UINT8 )im -> image [y ][x + 3 ];
172+ block [i + j * 4 ] = current_alpha ;
173+ }
174+ }
175+
176+ for (i = 0 ; i < 4 ; i ++ ) {
177+ UINT16 l = 0 ;
178+ for (j = 3 ; j > -1 ; j -- ) {
179+ current_alpha = block [i * 4 + j ];
180+ l |= current_alpha << (j * 4 );
181+ }
182+ * dst ++ = l ;
183+ * dst ++ = l >> 8 ;
184+ }
185+ }
186+
155187static void
156188encode_bc3_alpha (Imaging im , ImagingCodecState state , UINT8 * dst ) {
157189 int i , j ;
@@ -166,6 +198,7 @@ encode_bc3_alpha(Imaging im, ImagingCodecState state, UINT8 *dst) {
166198 int y = state -> y + j ;
167199 if (x >= state -> xsize * im -> pixelsize || y >= state -> ysize ) {
168200 // The 4x4 block extends past the edge of the image
201+ block [i + j * 4 ] = 0 ;
169202 continue ;
170203 }
171204
@@ -217,17 +250,20 @@ encode_bc3_alpha(Imaging im, ImagingCodecState state, UINT8 *dst) {
217250
218251int
219252ImagingBcnEncode (Imaging im , ImagingCodecState state , UINT8 * buf , int bytes ) {
220- char * pixel_format = ((BCNSTATE * )state -> context )-> pixel_format ;
221- int n = strcmp (pixel_format , "DXT1" ) == 0 ? 1 : 3 ;
253+ int n = state -> state ;
222254 int has_alpha_channel =
223255 strcmp (im -> mode , "RGBA" ) == 0 || strcmp (im -> mode , "LA" ) == 0 ;
224256
225257 UINT8 * dst = buf ;
226258
227259 for (;;) {
228- if (n == 3 ) {
260+ if (n == 2 || n == 3 ) {
229261 if (has_alpha_channel ) {
230- encode_bc3_alpha (im , state , dst );
262+ if (n == 2 ) {
263+ encode_bc2_block (im , state , dst );
264+ } else {
265+ encode_bc3_alpha (im , state , dst );
266+ }
231267 dst += 8 ;
232268 } else {
233269 for (int i = 0 ; i < 8 ; i ++ ) {
0 commit comments