2626
2727#include "shared-bindings/gifio/OnDiskGif.h"
2828#include "shared-bindings/displayio/Bitmap.h"
29+ #include "shared-bindings/displayio/Palette.h"
2930
3031#include <string.h>
3132
3435
3536
3637static int32_t GIFReadFile (GIFFILE * pFile , uint8_t * pBuf , int32_t iLen ) {
37- // mp_printf(&mp_plat_print, "GifReadFile len %d ", iLen);
3838 uint32_t iBytesRead ;
3939 iBytesRead = iLen ;
4040 pyb_file_obj_t * f = pFile -> fHandle ;
@@ -50,18 +50,15 @@ static int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) {
5050 mp_raise_OSError (MP_EIO );
5151 }
5252 pFile -> iPos = f -> fp .fptr ;
53- // mp_printf(&mp_plat_print, " now at %d\n", pFile->iPos);
5453
5554 return bytes_read ;
5655} /* GIFReadFile() */
5756
5857static int32_t GIFSeekFile (GIFFILE * pFile , int32_t iPosition ) {
59- // mp_printf(&mp_plat_print, "GifSeekFile %d ", iPosition);
6058 pyb_file_obj_t * f = pFile -> fHandle ;
6159
6260 f_lseek (& f -> fp , iPosition );
6361 pFile -> iPos = f -> fp .fptr ;
64- // mp_printf(&mp_plat_print, " now at %d\n", pFile->iPos);
6562 return pFile -> iPos ;
6663} /* GIFSeekFile() */
6764
@@ -71,10 +68,25 @@ static void GIFDraw(GIFDRAW *pDraw) {
7168 // The palette is either RGB565 or the original 24-bit RGB values
7269 // depending on the pixel type selected with gif.begin()
7370
74- displayio_bitmap_t * bitmap = (displayio_bitmap_t * )pDraw -> pUser ;
75-
76- uint8_t * s ;
77- uint16_t * d ;
71+ gifio_ondiskgif_displayio_objs_t * displayio_objs = (gifio_ondiskgif_displayio_objs_t * )pDraw -> pUser ;
72+ displayio_bitmap_t * bitmap = displayio_objs -> bitmap ;
73+ displayio_palette_t * palette = displayio_objs -> palette ;
74+
75+ // Update the palette if we have one in RGB888
76+ if (palette != NULL ) {
77+ uint8_t * pPal = pDraw -> pPalette24 ;
78+ for (int p = 0 ; p < 256 ; p ++ ) {
79+ uint8_t r = * pPal ++ ;
80+ uint8_t g = * pPal ++ ;
81+ uint8_t b = * pPal ++ ;
82+ uint32_t color = (r << 16 ) + (g << 8 ) + b ;
83+ common_hal_displayio_palette_set_color (palette , p , color );
84+ common_hal_displayio_palette_make_opaque (palette , p ); // Transparency can change frame to frame
85+ }
86+ if (pDraw -> ucHasTransparency ) {
87+ common_hal_displayio_palette_make_transparent (palette , pDraw -> ucTransparent );
88+ }
89+ }
7890
7991 int iWidth = pDraw -> iWidth ;
8092 if (iWidth + pDraw -> iX > bitmap -> width ) {
@@ -87,11 +99,6 @@ static void GIFDraw(GIFDRAW *pDraw) {
8799
88100 int32_t row_start = (pDraw -> y + pDraw -> iY ) * bitmap -> stride ;
89101 uint32_t * row = bitmap -> data + row_start ;
90- s = pDraw -> pPixels ;
91- d = (uint16_t * )row ;
92-
93- uint16_t * pPal ;
94- pPal = (uint16_t * )pDraw -> pPalette ;
95102
96103 if (pDraw -> ucDisposalMethod == 2 ) { // restore to background color
97104 // Not supported currently. Need to reset the area the previous frame occupied
@@ -101,31 +108,53 @@ static void GIFDraw(GIFDRAW *pDraw) {
101108 // To workaround clear the gif.bitmap object yourself as required.
102109 }
103110
104- uint8_t c , ucTransparent = pDraw -> ucTransparent ;
105- d += pDraw -> iX ;
106- if (pDraw -> ucHasTransparency == 1 ) {
111+ if (palette != NULL ) {
112+ uint8_t * s = pDraw -> pPixels ;
113+ uint8_t * d = (uint8_t * )row ;
114+
115+ d += pDraw -> iX ;
107116 for (int x = 0 ; x < iWidth ; x ++ )
108117 {
109- c = * s ++ ;
110- if (c != ucTransparent ) {
111- * d = pPal [c ];
112- }
113- d ++ ;
118+ * d ++ = * s ++ ;
114119 }
115120 } else {
116- for (int x = 0 ; x < iWidth ; x ++ )
117- {
118- c = * s ++ ;
119- * d ++ = pPal [c ];
121+ // No palette writing RGB565_SWAPPED right to bitmap buffer
122+ uint8_t * s = pDraw -> pPixels ;
123+ ;
124+ uint16_t * d = (uint16_t * )row ;
125+
126+ uint16_t * pPal ;
127+ pPal = (uint16_t * )pDraw -> pPalette ;
128+
129+ uint8_t c , ucTransparent = pDraw -> ucTransparent ;
130+ d += pDraw -> iX ;
131+ if (pDraw -> ucHasTransparency == 1 ) {
132+ for (int x = 0 ; x < iWidth ; x ++ )
133+ {
134+ c = * s ++ ;
135+ if (c != ucTransparent ) {
136+ * d = pPal [c ];
137+ }
138+ d ++ ;
139+ }
140+ } else {
141+ for (int x = 0 ; x < iWidth ; x ++ )
142+ {
143+ c = * s ++ ;
144+ * d ++ = pPal [c ];
145+ }
120146 }
121147 }
122148}
123149
124- void common_hal_gifio_ondiskgif_construct (gifio_ondiskgif_t * self , pyb_file_obj_t * file ) {
125- // mp_printf(&mp_plat_print, "Begin OnDiskGif\n");
150+ void common_hal_gifio_ondiskgif_construct (gifio_ondiskgif_t * self , pyb_file_obj_t * file , bool use_palette ) {
126151 self -> file = file ;
127152
128- GIF_begin (& self -> gif , GIF_PALETTE_RGB565_BE );
153+ if (use_palette == true) {
154+ GIF_begin (& self -> gif , GIF_PALETTE_RGB888 );
155+ } else {
156+ GIF_begin (& self -> gif , GIF_PALETTE_RGB565_BE );
157+ }
129158
130159 self -> gif .iError = GIF_SUCCESS ;
131160 self -> gif .pfnRead = GIFReadFile ;
@@ -143,10 +172,22 @@ void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_
143172 mp_arg_error_invalid (MP_QSTR_file );
144173 }
145174
175+ int bpp = 16 ;
176+ if (use_palette == true) {
177+ mp_printf (& mp_plat_print , "Using palette\n" );
178+ displayio_palette_t * palette = m_new_obj (displayio_palette_t );
179+ palette -> base .type = & displayio_palette_type ;
180+ common_hal_displayio_palette_construct (palette , 256 , false);
181+ self -> displayio_objs .palette = palette ;
182+ bpp = 8 ;
183+ } else {
184+ self -> displayio_objs .palette = NULL ;
185+ }
186+
146187 displayio_bitmap_t * bitmap = m_new_obj (displayio_bitmap_t );
147188 bitmap -> base .type = & displayio_bitmap_type ;
148- common_hal_displayio_bitmap_construct (bitmap , self -> gif .iCanvasWidth , self -> gif .iCanvasHeight , 16 );
149- self -> bitmap = bitmap ;
189+ common_hal_displayio_bitmap_construct (bitmap , self -> gif .iCanvasWidth , self -> gif .iCanvasHeight , bpp );
190+ self -> displayio_objs . bitmap = bitmap ;
150191
151192 GIFINFO info ;
152193 GIF_getInfo (& self -> gif , & info );
@@ -158,12 +199,13 @@ void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_
158199
159200void common_hal_gifio_ondiskgif_deinit (gifio_ondiskgif_t * self ) {
160201 self -> file = NULL ;
161- common_hal_displayio_bitmap_deinit (self -> bitmap );
162- self -> bitmap = NULL ;
202+ common_hal_displayio_bitmap_deinit (self -> displayio_objs .bitmap );
203+ self -> displayio_objs .bitmap = NULL ;
204+ self -> displayio_objs .palette = NULL ;
163205}
164206
165207bool common_hal_gifio_ondiskgif_deinited (gifio_ondiskgif_t * self ) {
166- return self -> bitmap == NULL ;
208+ return self -> displayio_objs . bitmap == NULL ;
167209}
168210
169211uint16_t common_hal_gifio_ondiskgif_get_height (gifio_ondiskgif_t * self ) {
@@ -175,7 +217,11 @@ uint16_t common_hal_gifio_ondiskgif_get_width(gifio_ondiskgif_t *self) {
175217}
176218
177219mp_obj_t common_hal_gifio_ondiskgif_get_bitmap (gifio_ondiskgif_t * self ) {
178- return MP_OBJ_FROM_PTR (self -> bitmap );
220+ return MP_OBJ_FROM_PTR (self -> displayio_objs .bitmap );
221+ }
222+
223+ mp_obj_t common_hal_gifio_ondiskgif_get_palette (gifio_ondiskgif_t * self ) {
224+ return MP_OBJ_FROM_PTR (self -> displayio_objs .palette );
179225}
180226
181227int32_t common_hal_gifio_ondiskgif_get_duration (gifio_ondiskgif_t * self ) {
@@ -196,17 +242,18 @@ int32_t common_hal_gifio_ondiskgif_get_max_delay(gifio_ondiskgif_t *self) {
196242
197243uint32_t common_hal_gifio_ondiskgif_next_frame (gifio_ondiskgif_t * self , bool setDirty ) {
198244 int nextDelay = 0 ;
199- int result = GIF_playFrame (& self -> gif , & nextDelay , self -> bitmap );
245+ int result = 0 ;
246+ result = GIF_playFrame (& self -> gif , & nextDelay , & self -> displayio_objs );
200247
201248 if ((result >= 0 ) && (setDirty )) {
202249 displayio_area_t dirty_area = {
203250 .x1 = 0 ,
204251 .y1 = 0 ,
205- .x2 = self -> bitmap -> width ,
206- .y2 = self -> bitmap -> height ,
252+ .x2 = self -> displayio_objs . bitmap -> width ,
253+ .y2 = self -> displayio_objs . bitmap -> height ,
207254 };
208255
209- displayio_bitmap_set_dirty_area (self -> bitmap , & dirty_area );
256+ displayio_bitmap_set_dirty_area (self -> displayio_objs . bitmap , & dirty_area );
210257 }
211258
212259 return nextDelay ;
0 commit comments