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_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
+ }
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,10 +172,22 @@ 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
+ 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
+
146
187
displayio_bitmap_t * bitmap = m_new_obj (displayio_bitmap_t );
147
188
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 ;
150
191
151
192
GIFINFO info ;
152
193
GIF_getInfo (& self -> gif , & info );
@@ -158,12 +199,13 @@ void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_
158
199
159
200
void common_hal_gifio_ondiskgif_deinit (gifio_ondiskgif_t * self ) {
160
201
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 ;
163
205
}
164
206
165
207
bool common_hal_gifio_ondiskgif_deinited (gifio_ondiskgif_t * self ) {
166
- return self -> bitmap == NULL ;
208
+ return self -> displayio_objs . bitmap == NULL ;
167
209
}
168
210
169
211
uint16_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) {
175
217
}
176
218
177
219
mp_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 );
179
225
}
180
226
181
227
int32_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) {
196
242
197
243
uint32_t common_hal_gifio_ondiskgif_next_frame (gifio_ondiskgif_t * self , bool setDirty ) {
198
244
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 );
200
247
201
248
if ((result >= 0 ) && (setDirty )) {
202
249
displayio_area_t dirty_area = {
203
250
.x1 = 0 ,
204
251
.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 ,
207
254
};
208
255
209
- displayio_bitmap_set_dirty_area (self -> bitmap , & dirty_area );
256
+ displayio_bitmap_set_dirty_area (self -> displayio_objs . bitmap , & dirty_area );
210
257
}
211
258
212
259
return nextDelay ;
0 commit comments