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_t * ondiskgif = (gifio_ondiskgif_t * )pDraw -> pUser ;
72+ displayio_bitmap_t * bitmap = ondiskgif -> bitmap ;
73+ displayio_palette_t * palette = ondiskgif -> 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,9 +172,20 @@ 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+ displayio_palette_t * palette = m_new_obj (displayio_palette_t );
178+ palette -> base .type = & displayio_palette_type ;
179+ common_hal_displayio_palette_construct (palette , 256 , false);
180+ self -> palette = palette ;
181+ bpp = 8 ;
182+ } else {
183+ self -> palette = NULL ;
184+ }
185+
146186 displayio_bitmap_t * bitmap = m_new_obj (displayio_bitmap_t );
147187 bitmap -> base .type = & displayio_bitmap_type ;
148- common_hal_displayio_bitmap_construct (bitmap , self -> gif .iCanvasWidth , self -> gif .iCanvasHeight , 16 );
188+ common_hal_displayio_bitmap_construct (bitmap , self -> gif .iCanvasWidth , self -> gif .iCanvasHeight , bpp );
149189 self -> bitmap = bitmap ;
150190
151191 GIFINFO info ;
@@ -160,6 +200,7 @@ void common_hal_gifio_ondiskgif_deinit(gifio_ondiskgif_t *self) {
160200 self -> file = NULL ;
161201 common_hal_displayio_bitmap_deinit (self -> bitmap );
162202 self -> bitmap = NULL ;
203+ self -> palette = NULL ;
163204}
164205
165206bool common_hal_gifio_ondiskgif_deinited (gifio_ondiskgif_t * self ) {
@@ -178,6 +219,13 @@ mp_obj_t common_hal_gifio_ondiskgif_get_bitmap(gifio_ondiskgif_t *self) {
178219 return MP_OBJ_FROM_PTR (self -> bitmap );
179220}
180221
222+ mp_obj_t common_hal_gifio_ondiskgif_get_palette (gifio_ondiskgif_t * self ) {
223+ if (self -> palette == NULL ) {
224+ return mp_const_none ;
225+ }
226+ return MP_OBJ_FROM_PTR (self -> palette );
227+ }
228+
181229int32_t common_hal_gifio_ondiskgif_get_duration (gifio_ondiskgif_t * self ) {
182230 return self -> duration ;
183231}
@@ -196,7 +244,8 @@ int32_t common_hal_gifio_ondiskgif_get_max_delay(gifio_ondiskgif_t *self) {
196244
197245uint32_t common_hal_gifio_ondiskgif_next_frame (gifio_ondiskgif_t * self , bool setDirty ) {
198246 int nextDelay = 0 ;
199- int result = GIF_playFrame (& self -> gif , & nextDelay , self -> bitmap );
247+ int result = 0 ;
248+ result = GIF_playFrame (& self -> gif , & nextDelay , self );
200249
201250 if ((result >= 0 ) && (setDirty )) {
202251 displayio_area_t dirty_area = {
0 commit comments