22#include " wled.h"
33#include < PNGdec.h>
44#include < AnimatedGIF.h>
5- #define BRI 3
5+ #define BRIGHT_SHIFT 3
66#define FX_MODE_POV_IMAGE 255
7+ #define FX_MODE_2D_IMAGE 255
78static const char _data_FX_MODE_POV_IMAGE[] PROGMEM = " POV Image@!;;;1" ;
8-
9+ static const char _data_FX_MODE_2D_IMAGE[] PROGMEM = " 2D Image@!;;;2 " ;
910AnimatedGIF gif;
1011PNG png;
1112File f;
@@ -65,7 +66,7 @@ int32_t seekPNG(PNGFILE *pFile, int32_t iPos)
6566int32_t seekGIF (GIFFILE *pFile, int32_t iPos)
6667{ return seekFile ((IMGFILE*) pFile, iPos); }
6768
68- void pngDraw (PNGDRAW *pDraw) {
69+ void pngPOV (PNGDRAW *pDraw) {
6970 uint16_t usPixels[SEGLEN];
7071 png.getLineAsRGB565 (pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0xffffffff );
7172 for (int x=0 ; x < SEGLEN; x++) {
@@ -75,72 +76,129 @@ void pngDraw(PNGDRAW *pDraw) {
7576 byte b = (color & 0x1F );
7677 SEGMENT.setPixelColor (x, RGBW32 (r,g,b,0 ));
7778 }
78- busses.show ();
79+ strip.show ();
80+ }
81+
82+ void png2D (PNGDRAW *pDraw) {
83+ uint16_t usPixels[pDraw->iWidth ];
84+ for (int y=0 ; y < pDraw->iWidth ; y++) {
85+ png.getLineAsRGB565 (pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0xffffffff );
86+ for (int x=0 ; x < SEGLEN; x++) {
87+ uint16_t color = usPixels[x];
88+ byte r = ((color >> 11 ) & 0x1F );
89+ byte g = ((color >> 5 ) & 0x3F );
90+ byte b = (color & 0x1F );
91+ SEGMENT.setPixelColorXY (x, y, RGBW32 (r,g,b,0 ));
92+ }
93+ }
94+ strip.show ();
7995}
8096
81- void gifDraw (GIFDRAW *pDraw) {
97+ void gifPOV (GIFDRAW *pDraw) {
8298 uint8_t r, g, b, *s, *p, *pPal = (uint8_t *)pDraw->pPalette ;
8399 int x, y = pDraw->iY + pDraw->y ;
84-
85100 s = pDraw->pPixels ;
86101 if (pDraw->ucDisposalMethod == 2 ) {
87102 p = &pPal[pDraw->ucBackground * 3 ];
88103 r = p[0 ]; g = p[1 ]; b = p[2 ];
89104 for (x=0 ; x<pDraw->iWidth ; x++)
90- {
91- if (s[x] == pDraw->ucTransparent ) {
105+ if (s[x] == pDraw->ucTransparent )
92106 SEGMENT.setPixelColor (x, RGBW32 (r, g, b, 0 ));
93- }
94- }
95107 pDraw->ucHasTransparency = 0 ;
96108 }
97109
110+
98111 if (pDraw->ucHasTransparency ) {
99112 const uint8_t ucTransparent = pDraw->ucTransparent ;
100- for (x=0 ; x<pDraw->iWidth ; x++) {
113+ for (x=0 ; x<pDraw->iWidth ; x++)
101114 if (s[x] != ucTransparent) {
102115 p = &pPal[s[x] * 3 ];
103- SEGMENT.setPixelColor (x, RGBW32 (p[0 ]>>BRI , p[1 ]>>BRI , p[2 ]>>BRI , 0 ));
116+ SEGMENT.setPixelColor (x, RGBW32 (p[0 ]>>BRIGHT_SHIFT , p[1 ]>>BRIGHT_SHIFT , p[2 ]>>BRIGHT_SHIFT , 0 ));
104117 }
105- }
106118 }
107119
108- else // no transparency, just copy them all
109- {
110- for (x=0 ; x<pDraw->iWidth ; x++)
111- {
120+ else
121+ for (x=0 ; x<pDraw->iWidth ; x++) {
112122 p = &pPal[s[x] * 3 ];
113123 SEGMENT.setPixelColor (x, RGBW32 (p[0 ], p[1 ], p[2 ], 0 ));
114124 }
125+ strip.show ();
126+ }
127+
128+ void gif2D (GIFDRAW *pDraw) {
129+ uint8_t r, g, b, *s, *p, *pPal = (uint8_t *)pDraw->pPalette ;
130+ int x, y = pDraw->iY + pDraw->y ;
131+
132+ s = pDraw->pPixels ;
133+ if (pDraw->ucDisposalMethod == 2 ) {
134+ p = &pPal[pDraw->ucBackground * 3 ];
135+ r = p[0 ] >> BRIGHT_SHIFT; g = p[1 ] >> BRIGHT_SHIFT; b = p[2 ] >> BRIGHT_SHIFT;
136+ for (x=0 ; x<pDraw->iWidth ; x++)
137+ if (s[x] == pDraw->ucTransparent )
138+ SEGMENT.setPixelColorXY (x, y, RGBW32 (r,g,b,0 ));
139+ pDraw->ucHasTransparency = 0 ;
140+ }
141+
142+ if (pDraw->ucHasTransparency ) {
143+ const uint8_t ucTransparent = pDraw->ucTransparent ;
144+ for (x=0 ; x<pDraw->iWidth ; x++)
145+ if (s[x] != ucTransparent) {
146+ p = &pPal[s[x] * 3 ];
147+ r = p[0 ] >> BRIGHT_SHIFT; g = p[1 ] >> BRIGHT_SHIFT; b = p[2 ] >> BRIGHT_SHIFT;
148+ SEGMENT.setPixelColorXY (x, y, RGBW32 (r,g,b,0 ));
149+ }
115150 }
116- busses.show ();
151+
152+ else
153+ for (x=0 ; x<pDraw->iWidth ; x++) {
154+ p = &pPal[s[x] * 3 ];
155+ r = p[0 ] >> BRIGHT_SHIFT; g = p[1 ] >> BRIGHT_SHIFT; b = p[2 ] >> BRIGHT_SHIFT;
156+ SEGMENT.setPixelColorXY (x, y, RGBW32 (r,g,b,0 ));
157+ }
158+
159+ if (pDraw->y == pDraw->iHeight -1 ) // last line has been decoded, display the image
160+ strip.show ();
117161}
118162
119- void pov_image ( ) {
163+ uint16_t mode_pov_image ( void ) {
120164 const char * filepath = SEGMENT.name ;
121- int rc = png.open (filepath, openFile, closeFile, readPNG, seekPNG, pngDraw);
122- if (rc == PNG_SUCCESS) {
123- if (png.getWidth () != SEGLEN) return ;
165+ int rc = png.open (filepath, openFile, closeFile, readPNG, seekPNG, pngPOV);
166+ if (rc == PNG_SUCCESS && png.getWidth () == SEGLEN) {
124167 rc = png.decode (NULL , 0 );
125168 png.close ();
126- return ;
169+ return FRAMETIME ;
127170 }
128171
129172 gif.begin (GIF_PALETTE_RGB888);
130- rc = gif.open (filepath, openFile, closeFile, readGIF, seekGIF, gifDraw);
131- if (rc) {
132- if (gif.getCanvasWidth () != SEGLEN) return ;
173+ rc = gif.open (filepath, openFile, closeFile, readGIF, seekGIF, gifPOV);
174+ if (rc && gif.getCanvasWidth () == SEGLEN) {
133175 while (gif.playFrame (true , NULL )) {}
134176 gif.close ();
177+ return FRAMETIME;
135178 }
179+ return FRAMETIME;
136180}
137181
138- uint16_t mode_pov_image (void ) {
139- pov_image ();
182+ uint16_t mode_2d_image (void ) {
183+ const char * filepath = SEGMENT.name ;
184+ int rc = png.open (filepath, openFile, closeFile, readPNG, seekPNG, png2D);
185+ if (rc == PNG_SUCCESS && png.getWidth () * png.getHeight () == SEGLEN) {
186+ rc = png.decode (NULL , 0 );
187+ png.close ();
188+ return FRAMETIME;
189+ }
190+
191+ gif.begin (GIF_PALETTE_RGB888);
192+ rc = gif.open (filepath, openFile, closeFile, readGIF, seekGIF, gif2D);
193+ if (rc && gif.getCanvasWidth () * gif.getCanvasHeight () == SEGLEN) {
194+ while (gif.playFrame (true , NULL )) {}
195+ gif.close ();
196+ return FRAMETIME;
197+ }
140198 return FRAMETIME;
141199}
142200
143- class PovDisplayUsermod : public Usermod
201+ class ImgDisplayUsermod : public Usermod
144202{
145203 protected:
146204 bool enabled = false ; // WLEDMM
@@ -150,6 +208,7 @@ class PovDisplayUsermod : public Usermod
150208 public:
151209 void setup () {
152210 strip.addEffect (FX_MODE_POV_IMAGE, &mode_pov_image, _data_FX_MODE_POV_IMAGE);
211+ strip.addEffect (FX_MODE_2D_IMAGE, &mode_2d_image, _data_FX_MODE_2D_IMAGE);
153212 initDone=true ;
154213 }
155214
0 commit comments