26
26
27
27
#include "shared-bindings/gifio/OnDiskGif.h"
28
28
#include "shared-bindings/displayio/Bitmap.h"
29
+ #include "shared-bindings/displayio/Palette.h"
29
30
30
31
#include <string.h>
31
32
34
35
35
36
36
37
static int32_t GIFReadFile (GIFFILE * pFile , uint8_t * pBuf , int32_t iLen ) {
37
- // mp_printf(&mp_plat_print, "GifReadFile len %d ", iLen);
38
38
uint32_t iBytesRead ;
39
39
iBytesRead = iLen ;
40
40
pyb_file_obj_t * f = pFile -> fHandle ;
@@ -50,18 +50,15 @@ static int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) {
50
50
mp_raise_OSError (MP_EIO );
51
51
}
52
52
pFile -> iPos = f -> fp .fptr ;
53
- // mp_printf(&mp_plat_print, " now at %d\n", pFile->iPos);
54
53
55
54
return bytes_read ;
56
55
} /* GIFReadFile() */
57
56
58
57
static int32_t GIFSeekFile (GIFFILE * pFile , int32_t iPosition ) {
59
- // mp_printf(&mp_plat_print, "GifSeekFile %d ", iPosition);
60
58
pyb_file_obj_t * f = pFile -> fHandle ;
61
59
62
60
f_lseek (& f -> fp , iPosition );
63
61
pFile -> iPos = f -> fp .fptr ;
64
- // mp_printf(&mp_plat_print, " now at %d\n", pFile->iPos);
65
62
return pFile -> iPos ;
66
63
} /* GIFSeekFile() */
67
64
@@ -71,10 +68,25 @@ static void GIFDraw(GIFDRAW *pDraw) {
71
68
// The palette is either RGB565 or the original 24-bit RGB values
72
69
// depending on the pixel type selected with gif.begin()
73
70
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
+ }
78
90
79
91
int iWidth = pDraw -> iWidth ;
80
92
if (iWidth + pDraw -> iX > bitmap -> width ) {
@@ -87,11 +99,6 @@ static void GIFDraw(GIFDRAW *pDraw) {
87
99
88
100
int32_t row_start = (pDraw -> y + pDraw -> iY ) * bitmap -> stride ;
89
101
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 ;
95
102
96
103
if (pDraw -> ucDisposalMethod == 2 ) { // restore to background color
97
104
// Not supported currently. Need to reset the area the previous frame occupied
@@ -101,31 +108,53 @@ static void GIFDraw(GIFDRAW *pDraw) {
101
108
// To workaround clear the gif.bitmap object yourself as required.
102
109
}
103
110
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 ;
107
116
for (int x = 0 ; x < iWidth ; x ++ )
108
117
{
109
- c = * s ++ ;
110
- if (c != ucTransparent ) {
111
- * d = pPal [c ];
112
- }
113
- d ++ ;
118
+ * d ++ = * s ++ ;
114
119
}
115
120
} 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
+ }
120
146
}
121
147
}
122
148
}
123
149
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 ) {
126
151
self -> file = file ;
127
152
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
+ }
129
158
130
159
self -> gif .iError = GIF_SUCCESS ;
131
160
self -> gif .pfnRead = GIFReadFile ;
@@ -143,9 +172,20 @@ void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_
143
172
mp_arg_error_invalid (MP_QSTR_file );
144
173
}
145
174
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
+
146
186
displayio_bitmap_t * bitmap = m_new_obj (displayio_bitmap_t );
147
187
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 );
149
189
self -> bitmap = bitmap ;
150
190
151
191
GIFINFO info ;
@@ -160,6 +200,7 @@ void common_hal_gifio_ondiskgif_deinit(gifio_ondiskgif_t *self) {
160
200
self -> file = NULL ;
161
201
common_hal_displayio_bitmap_deinit (self -> bitmap );
162
202
self -> bitmap = NULL ;
203
+ self -> palette = NULL ;
163
204
}
164
205
165
206
bool 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) {
178
219
return MP_OBJ_FROM_PTR (self -> bitmap );
179
220
}
180
221
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
+
181
229
int32_t common_hal_gifio_ondiskgif_get_duration (gifio_ondiskgif_t * self ) {
182
230
return self -> duration ;
183
231
}
@@ -196,7 +244,8 @@ int32_t common_hal_gifio_ondiskgif_get_max_delay(gifio_ondiskgif_t *self) {
196
244
197
245
uint32_t common_hal_gifio_ondiskgif_next_frame (gifio_ondiskgif_t * self , bool setDirty ) {
198
246
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 );
200
249
201
250
if ((result >= 0 ) && (setDirty )) {
202
251
displayio_area_t dirty_area = {
0 commit comments