1 /**
2  * @file lv_img_decoder.h
3  *
4  */
5 
6 #ifndef LV_IMG_DEOCER_H
7 #define LV_IMG_DEOCER_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #ifdef LV_CONF_INCLUDE_SIMPLE
17 #include "lv_conf.h"
18 #else
19 #include "../../lv_conf.h"
20 #endif
21 
22 #include <stdint.h>
23 #include "../lv_misc/lv_fs.h"
24 #include "../lv_misc/lv_types.h"
25 #include "../lv_misc/lv_area.h"
26 #include "../lv_core/lv_style.h"
27 
28 /*********************
29  *      DEFINES
30  *********************/
31 /*If image pixels contains alpha we need to know how much byte is a pixel*/
32 #if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
33 #define LV_IMG_PX_SIZE_ALPHA_BYTE 2
34 #elif LV_COLOR_DEPTH == 16
35 #define LV_IMG_PX_SIZE_ALPHA_BYTE 3
36 #elif LV_COLOR_DEPTH == 32
37 #define LV_IMG_PX_SIZE_ALPHA_BYTE 4
38 #endif
39 
40 /**********************
41  *      TYPEDEFS
42  **********************/
43 
44 /**
45  * Source of image. */
46 enum {
47     LV_IMG_SRC_VARIABLE, /** Binary/C variable */
48     LV_IMG_SRC_FILE, /** File in filesystem */
49     LV_IMG_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h) */
50     LV_IMG_SRC_UNKNOWN, /** Unknown source */
51 };
52 
53 typedef uint8_t lv_img_src_t;
54 /**
55  * LittlevGL image header
56  */
57 typedef struct
58 {
59 
60     /* The first 8 bit is very important to distinguish the different source types.
61      * For more info see `lv_img_get_src_type()` in lv_img.c */
62     uint32_t cf : 5;          /* Color format: See `lv_img_color_format_t`*/
63     uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
64                                  non-printable character*/
65 
66     uint32_t reserved : 2; /*Reserved to be used later*/
67 
68     uint32_t w : 11; /*Width of the image map*/
69     uint32_t h : 11; /*Height of the image map*/
70 } lv_img_header_t;
71 
72 /*Image color format*/
73 enum {
74     LV_IMG_CF_UNKNOWN = 0,
75 
76     LV_IMG_CF_RAW,              /**< Contains the file as it is. Needs custom decoder function*/
77     LV_IMG_CF_RAW_ALPHA,        /**< Contains the file as it is. The image has alpha. Needs custom decoder
78                                    function*/
79     LV_IMG_CF_RAW_CHROMA_KEYED, /**< Contains the file as it is. The image is chroma keyed. Needs
80                                    custom decoder function*/
81 
82     LV_IMG_CF_TRUE_COLOR,              /**< Color format and depth should match with LV_COLOR settings*/
83     LV_IMG_CF_TRUE_COLOR_ALPHA,        /**< Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/
84     LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /**< Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels
85                                           will be transparent*/
86 
87     LV_IMG_CF_INDEXED_1BIT, /**< Can have 2 different colors in a palette (always chroma keyed)*/
88     LV_IMG_CF_INDEXED_2BIT, /**< Can have 4 different colors in a palette (always chroma keyed)*/
89     LV_IMG_CF_INDEXED_4BIT, /**< Can have 16 different colors in a palette (always chroma keyed)*/
90     LV_IMG_CF_INDEXED_8BIT, /**< Can have 256 different colors in a palette (always chroma keyed)*/
91 
92     LV_IMG_CF_ALPHA_1BIT, /**< Can have one color and it can be drawn or not*/
93     LV_IMG_CF_ALPHA_2BIT, /**< Can have one color but 4 different alpha value*/
94     LV_IMG_CF_ALPHA_4BIT, /**< Can have one color but 16 different alpha value*/
95     LV_IMG_CF_ALPHA_8BIT, /**< Can have one color but 256 different alpha value*/
96 
97     LV_IMG_CF_RESERVED_15,              /**< Reserved for further use. */
98     LV_IMG_CF_RESERVED_16,              /**< Reserved for further use. */
99     LV_IMG_CF_RESERVED_17,              /**< Reserved for further use. */
100     LV_IMG_CF_RESERVED_18,              /**< Reserved for further use. */
101     LV_IMG_CF_RESERVED_19,              /**< Reserved for further use. */
102     LV_IMG_CF_RESERVED_20,              /**< Reserved for further use. */
103     LV_IMG_CF_RESERVED_21,              /**< Reserved for further use. */
104     LV_IMG_CF_RESERVED_22,              /**< Reserved for further use. */
105     LV_IMG_CF_RESERVED_23,              /**< Reserved for further use. */
106 
107     LV_IMG_CF_USER_ENCODED_0,          /**< User holder encoding format. */
108     LV_IMG_CF_USER_ENCODED_1,          /**< User holder encoding format. */
109     LV_IMG_CF_USER_ENCODED_2,          /**< User holder encoding format. */
110     LV_IMG_CF_USER_ENCODED_3,          /**< User holder encoding format. */
111     LV_IMG_CF_USER_ENCODED_4,          /**< User holder encoding format. */
112     LV_IMG_CF_USER_ENCODED_5,          /**< User holder encoding format. */
113     LV_IMG_CF_USER_ENCODED_6,          /**< User holder encoding format. */
114     LV_IMG_CF_USER_ENCODED_7,          /**< User holder encoding format. */
115 };
116 typedef uint8_t lv_img_cf_t;
117 
118 /** Image header it is compatible with
119  * the result from image converter utility*/
120 typedef struct
121 {
122     lv_img_header_t header;
123     uint32_t data_size;
124     const uint8_t * data;
125 } lv_img_dsc_t;
126 
127 /* Decoder function definitions */
128 
129 struct _lv_img_decoder;
130 struct _lv_img_decoder_dsc;
131 
132 /**
133  * Get info from an image and store in the `header`
134  * @param src the image source. Can be a pointer to a C array or a file name (Use
135  * `lv_img_src_get_type` to determine the type)
136  * @param header store the info here
137  * @return LV_RES_OK: info written correctly; LV_RES_INV: failed
138  */
139 typedef lv_res_t (*lv_img_decoder_info_f_t)(struct _lv_img_decoder * decoder, const void * src,
140                                             lv_img_header_t * header);
141 
142 /**
143  * Open an image for decoding. Prepare it as it is required to read it later
144  * @param decoder pointer to the decoder the function associated with
145  * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
146  */
147 typedef lv_res_t (*lv_img_decoder_open_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);
148 
149 /**
150  * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
151  * Required only if the "open" function can't return with the whole decoded pixel array.
152  * @param decoder pointer to the decoder the function associated with
153  * @param dsc pointer to decoder descriptor
154  * @param x start x coordinate
155  * @param y start y coordinate
156  * @param len number of pixels to decode
157  * @param buf a buffer to store the decoded pixels
158  * @return LV_RES_OK: ok; LV_RES_INV: failed
159  */
160 typedef lv_res_t (*lv_img_decoder_read_line_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc,
161                                                  lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);
162 
163 /**
164  * Close the pending decoding. Free resources etc.
165  * @param decoder pointer to the decoder the function associated with
166  * @param dsc pointer to decoder descriptor
167  */
168 typedef void (*lv_img_decoder_close_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);
169 
170 typedef struct _lv_img_decoder
171 {
172     lv_img_decoder_info_f_t info_cb;
173     lv_img_decoder_open_f_t open_cb;
174     lv_img_decoder_read_line_f_t read_line_cb;
175     lv_img_decoder_close_f_t close_cb;
176 
177 #if LV_USE_USER_DATA
178     lv_img_decoder_user_data_t user_data;
179 #endif
180 } lv_img_decoder_t;
181 
182 /**Describe an image decoding session. Stores data about the decoding*/
183 typedef struct _lv_img_decoder_dsc
184 {
185     /**The decoder which was able to open the image source*/
186     lv_img_decoder_t * decoder;
187 
188     /**The image source. A file path like "S:my_img.png" or pointer to an `lv_img_dsc_t` variable*/
189     const void * src;
190 
191     /**Style to draw the image.*/
192     const lv_style_t * style;
193 
194     /**Type of the source: file or variable. Can be set in `open` function if required*/
195     lv_img_src_t src_type;
196 
197     /**Info about the opened image: color format, size, etc. MUST be set in `open` function*/
198     lv_img_header_t header;
199 
200     /** Pointer to a buffer where the image's data (pixels) are stored in a decoded, plain format.
201      *  MUST be set in `open` function*/
202     const uint8_t * img_data;
203 
204     /** How much time did it take to open the image. [ms]
205      *  If not set `lv_img_cache` will measure and set the time to open*/
206     uint32_t time_to_open;
207 
208     /**A text to display instead of the image when the image can't be opened.
209      * Can be set in `open` function or set NULL. */
210     const char * error_msg;
211 
212     /**Store any custom data here is required*/
213     void * user_data;
214 } lv_img_decoder_dsc_t;
215 
216 /**********************
217  * GLOBAL PROTOTYPES
218  **********************/
219 
220 /**
221  * Initialize the image decoder module
222  */
223 void lv_img_decoder_init(void);
224 
225 /**
226  * Get information about an image.
227  * Try the created image decoder one by one. Once one is able to get info that info will be used.
228  * @param src the image source. Can be
229  *  1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
230  *  2) Variable: Pointer to an `lv_img_dsc_t` variable
231  *  3) Symbol: E.g. `LV_SYMBOL_OK`
232  * @param header the image info will be stored here
233  * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image
234  */
235 lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header);
236 
237 /**
238  * Open an image.
239  * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`
240  * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
241  * @param src the image source. Can be
242  *  1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
243  *  2) Variable: Pointer to an `lv_img_dsc_t` variable
244  *  3) Symbol: E.g. `LV_SYMBOL_OK`
245  * @param style the style of the image
246  * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
247  *         LV_RES_INV: none of the registered image decoders were able to open the image.
248  */
249 lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style);
250 
251 /**
252  * Read a line from an opened image
253  * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
254  * @param x start X coordinate (from left)
255  * @param y start Y coordinate (from top)
256  * @param len number of pixels to read
257  * @param buf store the data here
258  * @return LV_RES_OK: success; LV_RES_INV: an error occurred
259  */
260 lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len,
261                                   uint8_t * buf);
262 
263 /**
264  * Close a decoding session
265  * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
266  */
267 void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc);
268 
269 /**
270  * Create a new image decoder
271  * @return pointer to the new image decoder
272  */
273 lv_img_decoder_t * lv_img_decoder_create(void);
274 
275 /**
276  * Delete an image decoder
277  * @param decoder pointer to an image decoder
278  */
279 void lv_img_decoder_delete(lv_img_decoder_t * decoder);
280 
281 /**
282  * Set a callback to get information about the image
283  * @param decoder pointer to an image decoder
284  * @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)
285  */
286 void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb);
287 
288 /**
289  * Set a callback to open an image
290  * @param decoder pointer to an image decoder
291  * @param open_cb a function to open an image
292  */
293 void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb);
294 
295 /**
296  * Set a callback to a decoded line of an image
297  * @param decoder pointer to an image decoder
298  * @param read_line_cb a function to read a line of an image
299  */
300 void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb);
301 
302 /**
303  * Set a callback to close a decoding session. E.g. close files and free other resources.
304  * @param decoder pointer to an image decoder
305  * @param close_cb a function to close a decoding session
306  */
307 void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb);
308 
309 
310 
311 /**
312  * Get info about a built-in image
313  * @param decoder the decoder where this function belongs
314  * @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol
315  * @param header store the image data here
316  * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
317  */
318 lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header);
319 
320 /**
321  * Open a built in image
322  * @param decoder the decoder where this function belongs
323  * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
324  * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
325  */
326 lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
327 
328 /**
329  * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
330  * Required only if the "open" function can't return with the whole decoded pixel array.
331  * @param decoder pointer to the decoder the function associated with
332  * @param dsc pointer to decoder descriptor
333  * @param x start x coordinate
334  * @param y start y coordinate
335  * @param len number of pixels to decode
336  * @param buf a buffer to store the decoded pixels
337  * @return LV_RES_OK: ok; LV_RES_INV: failed
338  */
339 lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
340                                                   lv_coord_t y, lv_coord_t len, uint8_t * buf);
341 
342 /**
343  * Close the pending decoding. Free resources etc.
344  * @param decoder pointer to the decoder the function associated with
345  * @param dsc pointer to decoder descriptor
346  */
347 void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
348 
349 /**********************
350  *      MACROS
351  **********************/
352 
353 #ifdef __cplusplus
354 } /* extern "C" */
355 #endif
356 
357 #endif /*LV_TEMPL_H*/
358