@@ -241,14 +241,35 @@ PNG_STATIC void PNGRGB565(PNGDRAW *pDraw, uint16_t *pPixels, int iEndiannes, uin
241241
242242 switch (pDraw->iPixelType ) {
243243 case PNG_PIXEL_GRAY_ALPHA:
244- for (x=0 ; x<pDraw->iWidth ; x++) {
245- c = *s++; // gray level
246- a = *s++;
247- j = (a * c) >> 8 ; // multiply by the alpha
248- usPixel = usGrayTo565[j];
249- if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
250- usPixel = __builtin_bswap16 (usPixel);
251- *pDest++ = usPixel;
244+ if (u32Bkgd != 0xffffffff ) {
245+ // gray level of background color choice
246+ uint8_t u8BG = (uint8_t )(((u32Bkgd & 0xff ) + ((u32Bkgd >> 7 ) & 0x1fe ) + ((u32Bkgd >> 16 ) & 0xff )) / 4 );
247+ uint16_t usBG = usGrayTo565[u8BG];
248+ for (x=0 ; x<pDraw->iWidth ; x++) {
249+ c = *s++; // gray level
250+ a = *s++;
251+ if (a == 0 ) {
252+ usPixel = usBG;
253+ } else if (a == 255 ) { // fully opaque
254+ usPixel = usGrayTo565[c];
255+ } else { // mix the colors
256+ usPixel = (c * a) + (u8BG * (255 -a));
257+ usPixel = usGrayTo565[(usPixel >> 8 )];
258+ }
259+ if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
260+ usPixel = __builtin_bswap16 (usPixel);
261+ *pDest++ = usPixel;
262+ } // for x
263+ } else {
264+ for (x=0 ; x<pDraw->iWidth ; x++) {
265+ c = *s++; // gray level
266+ a = *s++;
267+ j = (a * c) >> 8 ; // multiply by the alpha
268+ usPixel = usGrayTo565[j];
269+ if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
270+ usPixel = __builtin_bswap16 (usPixel);
271+ *pDest++ = usPixel;
272+ }
252273 }
253274 break ;
254275 case PNG_PIXEL_GRAYSCALE:
@@ -346,18 +367,50 @@ PNG_STATIC void PNGRGB565(PNGDRAW *pDraw, uint16_t *pPixels, int iEndiannes, uin
346367 switch (pDraw->iBpp ) {
347368 case 8 : // 8-bit palette also supports palette alpha
348369 if (pDraw->iHasAlpha ) { // use the alpha to modify the palette
349- for (x=0 ; x<pDraw->iWidth ; x++) {
350- int a;
351- c = *s++;
352- a = pDraw->pPalette [768 +c]; // get alpha
353- pPal = &pDraw->pPalette [c * 3 ];
354- usPixel = ((pPal[2 ] * a) >> 11 ); // blue
355- usPixel |= (((pPal[1 ] * a) >> 10 ) << 5 ); // green
356- usPixel |= (((pPal[0 ] * a) >> 11 ) << 11 ); // red
357- if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
358- usPixel = __builtin_bswap16 (usPixel);
359- *pDest++ = usPixel;
360- } // for x
370+ if (u32Bkgd != 0xffffffff ) { // user wants to blend it with a background color
371+ uint32_t r, g, b, a;
372+ uint32_t b_r, b_g, b_b;
373+ b_r = u32Bkgd & 0xff ; b_g = (u32Bkgd & 0xff00 ) >> 8 ;
374+ b_b = (u32Bkgd >> 16 ) & 0xff ;
375+ uint16_t u16Clr = (u32Bkgd & 0xf8 ) << 8 ;
376+ u16Clr |= ((u32Bkgd & 0xfc00 ) >> 5 );
377+ u16Clr |= ((u32Bkgd & 0xf80000 ) >> 19 );
378+ for (x=0 ; x<pDraw->iWidth ; x++) {
379+ int a;
380+ c = *s++;
381+ a = pDraw->pPalette [768 +c]; // get alpha
382+ if (a == 0 ) { // pure BGColor
383+ usPixel = u16Clr;
384+ } else if (a == 255 ) { // opaque
385+ pPal = &pDraw->pPalette [c * 3 ];
386+ usPixel = ((pPal[2 ] * a) >> 11 ); // blue
387+ usPixel |= (((pPal[1 ] * a) >> 10 ) << 5 ); // green
388+ usPixel |= (((pPal[0 ] * a) >> 11 ) << 11 ); // red
389+ } else { // need to mix the bg & fg colors
390+
391+ pPal = &pDraw->pPalette [c * 3 ];
392+ usPixel = ((((pPal[2 ] * a) + (b_b * (255 -a)))) >> 11 ); // blue
393+ usPixel |= ((((pPal[1 ] * a) + (b_g * (255 -a)))>> 10 ) << 5 ); // green
394+ usPixel |= ((((pPal[0 ] * a) + (b_r * (255 -a)))>> 11 ) << 11 ); // red
395+ } // need to mix with alpha
396+ if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
397+ usPixel = __builtin_bswap16 (usPixel);
398+ *pDest++ = usPixel;
399+ } // for x
400+ } else { // alpha 0 = black
401+ for (x=0 ; x<pDraw->iWidth ; x++) {
402+ int a;
403+ c = *s++;
404+ a = pDraw->pPalette [768 +c]; // get alpha
405+ pPal = &pDraw->pPalette [c * 3 ];
406+ usPixel = ((pPal[2 ] * a) >> 11 ); // blue
407+ usPixel |= (((pPal[1 ] * a) >> 10 ) << 5 ); // green
408+ usPixel |= (((pPal[0 ] * a) >> 11 ) << 11 ); // red
409+ if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
410+ usPixel = __builtin_bswap16 (usPixel);
411+ *pDest++ = usPixel;
412+ } // for x
413+ }
361414 } else {
362415 for (x=0 ; x<pDraw->iWidth ; x++) {
363416 c = *s++;
0 commit comments