1 /**
2  * @file lv_img_buf.h
3  *
4  */
5 
6 #ifndef LV_IMG_BUF_H
7 #define LV_IMG_BUF_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include <stdbool.h>
17 #include "../misc/lv_color.h"
18 #include "../misc/lv_area.h"
19 
20 /*********************
21  *      DEFINES
22  *********************/
23 /*If image pixels contains alpha we need to know how much byte is a pixel*/
24 #if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
25 #define LV_IMG_PX_SIZE_ALPHA_BYTE 2
26 #elif LV_COLOR_DEPTH == 16
27 #define LV_IMG_PX_SIZE_ALPHA_BYTE 3
28 #elif LV_COLOR_DEPTH == 32
29 #define LV_IMG_PX_SIZE_ALPHA_BYTE 4
30 #endif
31 
32 #define LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
33 #define LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
34 #define LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
35 
36 /*+ 1: to be sure no fractional row*/
37 #define LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h))
38 #define LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h))
39 #define LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h))
40 #define LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))
41 
42 /*4 * X: for palette*/
43 #define LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2)
44 #define LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4)
45 #define LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16)
46 #define LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256)
47 
48 #define _LV_TRANSFORM_TRIGO_SHIFT 10
49 #define _LV_ZOOM_INV_UPSCALE 5
50 
51 /**********************
52  *      TYPEDEFS
53  **********************/
54 
55 /*Image color format*/
56 enum {
57     LV_IMG_CF_UNKNOWN = 0,
58 
59     LV_IMG_CF_RAW,              /**< Contains the file as it is. Needs custom decoder function*/
60     LV_IMG_CF_RAW_ALPHA,        /**< Contains the file as it is. The image has alpha. Needs custom decoder
61                                    function*/
62     LV_IMG_CF_RAW_CHROMA_KEYED, /**< Contains the file as it is. The image is chroma keyed. Needs
63                                    custom decoder function*/
64 
65     LV_IMG_CF_TRUE_COLOR,              /**< Color format and depth should match with LV_COLOR settings*/
66     LV_IMG_CF_TRUE_COLOR_ALPHA,        /**< Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/
67     LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /**< Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels
68                                           will be transparent*/
69 
70     LV_IMG_CF_INDEXED_1BIT, /**< Can have 2 different colors in a palette (always chroma keyed)*/
71     LV_IMG_CF_INDEXED_2BIT, /**< Can have 4 different colors in a palette (always chroma keyed)*/
72     LV_IMG_CF_INDEXED_4BIT, /**< Can have 16 different colors in a palette (always chroma keyed)*/
73     LV_IMG_CF_INDEXED_8BIT, /**< Can have 256 different colors in a palette (always chroma keyed)*/
74 
75     LV_IMG_CF_ALPHA_1BIT, /**< Can have one color and it can be drawn or not*/
76     LV_IMG_CF_ALPHA_2BIT, /**< Can have one color but 4 different alpha value*/
77     LV_IMG_CF_ALPHA_4BIT, /**< Can have one color but 16 different alpha value*/
78     LV_IMG_CF_ALPHA_8BIT, /**< Can have one color but 256 different alpha value*/
79 
80     LV_IMG_CF_RESERVED_15,              /**< Reserved for further use.*/
81     LV_IMG_CF_RESERVED_16,              /**< Reserved for further use.*/
82     LV_IMG_CF_RESERVED_17,              /**< Reserved for further use.*/
83     LV_IMG_CF_RESERVED_18,              /**< Reserved for further use.*/
84     LV_IMG_CF_RESERVED_19,              /**< Reserved for further use.*/
85     LV_IMG_CF_RESERVED_20,              /**< Reserved for further use.*/
86     LV_IMG_CF_RESERVED_21,              /**< Reserved for further use.*/
87     LV_IMG_CF_RESERVED_22,              /**< Reserved for further use.*/
88     LV_IMG_CF_RESERVED_23,              /**< Reserved for further use.*/
89 
90     LV_IMG_CF_USER_ENCODED_0,          /**< User holder encoding format.*/
91     LV_IMG_CF_USER_ENCODED_1,          /**< User holder encoding format.*/
92     LV_IMG_CF_USER_ENCODED_2,          /**< User holder encoding format.*/
93     LV_IMG_CF_USER_ENCODED_3,          /**< User holder encoding format.*/
94     LV_IMG_CF_USER_ENCODED_4,          /**< User holder encoding format.*/
95     LV_IMG_CF_USER_ENCODED_5,          /**< User holder encoding format.*/
96     LV_IMG_CF_USER_ENCODED_6,          /**< User holder encoding format.*/
97     LV_IMG_CF_USER_ENCODED_7,          /**< User holder encoding format.*/
98 };
99 typedef uint8_t lv_img_cf_t;
100 
101 
102 /**
103  * The first 8 bit is very important to distinguish the different source types.
104  * For more info see `lv_img_get_src_type()` in lv_img.c
105  * On big endian systems the order is reversed so cf and always_zero must be at
106  * the end of the struct.
107  */
108 #if LV_BIG_ENDIAN_SYSTEM
109 typedef struct {
110 
111     uint32_t h : 11; /*Height of the image map*/
112     uint32_t w : 11; /*Width of the image map*/
113     uint32_t reserved : 2; /*Reserved to be used later*/
114     uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
115                                  non-printable character*/
116     uint32_t cf : 5;          /*Color format: See `lv_img_color_format_t`*/
117 
118 } lv_img_header_t;
119 #else
120 typedef struct {
121 
122     uint32_t cf : 5;          /*Color format: See `lv_img_color_format_t`*/
123     uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
124                                  non-printable character*/
125 
126     uint32_t reserved : 2; /*Reserved to be used later*/
127 
128     uint32_t w : 11; /*Width of the image map*/
129     uint32_t h : 11; /*Height of the image map*/
130 } lv_img_header_t;
131 #endif
132 
133 /** Image header it is compatible with
134  * the result from image converter utility*/
135 typedef struct {
136     lv_img_header_t header; /**< A header describing the basics of the image*/
137     uint32_t data_size;     /**< Size of the image in bytes*/
138     const uint8_t * data;   /**< Pointer to the data of the image*/
139 } lv_img_dsc_t;
140 
141 typedef struct {
142     struct {
143         const void * src;           /*image source (array of pixels)*/
144         lv_coord_t src_w;           /*width of the image source*/
145         lv_coord_t src_h;           /*height of the image source*/
146         lv_coord_t pivot_x;         /*pivot x*/
147         lv_coord_t pivot_y;         /*pivot y*/
148         int16_t angle;              /*angle to rotate*/
149         uint16_t zoom;              /*256 no zoom, 128 half size, 512 double size*/
150         lv_color_t color;           /*a color used for `LV_IMG_CF_INDEXED_1/2/4/8BIT` color formats*/
151         lv_img_cf_t cf;             /*color format of the image to rotate*/
152         bool antialias;
153     } cfg;
154 
155     struct {
156         lv_color_t color;
157         lv_opa_t opa;
158     } res;
159 
160     struct {
161         lv_img_dsc_t img_dsc;
162         int32_t pivot_x_256;
163         int32_t pivot_y_256;
164         int32_t sinma;
165         int32_t cosma;
166 
167         uint8_t chroma_keyed : 1;
168         uint8_t has_alpha : 1;
169         uint8_t native_color : 1;
170 
171         uint32_t zoom_inv;
172 
173         /*Runtime data*/
174         lv_coord_t xs;
175         lv_coord_t ys;
176         lv_coord_t xs_int;
177         lv_coord_t ys_int;
178         uint32_t pxi;
179         uint8_t px_size;
180     } tmp;
181 } lv_img_transform_dsc_t;
182 
183 
184 /**********************
185  * GLOBAL PROTOTYPES
186  **********************/
187 
188 /**
189  * Allocate an image buffer in RAM
190  * @param w width of image
191  * @param h height of image
192  * @param cf a color format (`LV_IMG_CF_...`)
193  * @return an allocated image, or NULL on failure
194  */
195 lv_img_dsc_t * lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
196 
197 /**
198  * Get the color of an image's pixel
199  * @param dsc an image descriptor
200  * @param x x coordinate of the point to get
201  * @param y x coordinate of the point to get
202  * @param color the color of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` this color is used.
203  * Not used in other cases.
204  * @param safe true: check out of bounds
205  * @return color of the point
206  */
207 lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t color);
208 
209 /**
210  * Get the alpha value of an image's pixel
211  * @param dsc pointer to an image descriptor
212  * @param x x coordinate of the point to set
213  * @param y x coordinate of the point to set
214  * @param safe true: check out of bounds
215  * @return alpha value of the point
216  */
217 lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y);
218 
219 /**
220  * Set the color of a pixel of an image. The alpha channel won't be affected.
221  * @param dsc pointer to an image descriptor
222  * @param x x coordinate of the point to set
223  * @param y x coordinate of the point to set
224  * @param c color of the point
225  * @param safe true: check out of bounds
226  */
227 void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c);
228 
229 /**
230  * Set the alpha value of a pixel of an image. The color won't be affected
231  * @param dsc pointer to an image descriptor
232  * @param x x coordinate of the point to set
233  * @param y x coordinate of the point to set
234  * @param opa the desired opacity
235  * @param safe true: check out of bounds
236  */
237 void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa);
238 
239 /**
240  * Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`
241  * @param dsc pointer to an image descriptor
242  * @param id the palette color to set:
243  *   - for `LV_IMG_CF_INDEXED1`: 0..1
244  *   - for `LV_IMG_CF_INDEXED2`: 0..3
245  *   - for `LV_IMG_CF_INDEXED4`: 0..15
246  *   - for `LV_IMG_CF_INDEXED8`: 0..255
247  * @param c the color to set
248  */
249 void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c);
250 
251 /**
252  * Free an allocated image buffer
253  * @param dsc image buffer to free
254  */
255 void lv_img_buf_free(lv_img_dsc_t * dsc);
256 
257 /**
258  * Get the memory consumption of a raw bitmap, given color format and dimensions.
259  * @param w width
260  * @param h height
261  * @param cf color format
262  * @return size in bytes
263  */
264 uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
265 
266 #if LV_DRAW_COMPLEX
267 /**
268  * Initialize a descriptor to rotate an image
269  * @param dsc pointer to an `lv_img_transform_dsc_t` variable whose `cfg` field is initialized
270  */
271 void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc);
272 
273 /**
274  * Continue transformation by taking the neighbors into account
275  * @param dsc pointer to the transformation descriptor
276  */
277 bool _lv_img_buf_transform_anti_alias(lv_img_transform_dsc_t * dsc);
278 
279 /**
280  * Get which color and opa would come to a pixel if it were rotated
281  * @param dsc a descriptor initialized by `lv_img_buf_rotate_init`
282  * @param x the coordinate which color and opa should be get
283  * @param y the coordinate which color and opa should be get
284  * @return true: there is valid pixel on these x/y coordinates; false: the rotated pixel was out of the image
285  * @note the result is written back to `dsc->res_color` and `dsc->res_opa`
286  */
287 bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_t x, lv_coord_t y);
288 
289 #endif
290 /**
291  * Get the area of a rectangle if its rotated and scaled
292  * @param res store the coordinates here
293  * @param w width of the rectangle to transform
294  * @param h height of the rectangle to transform
295  * @param angle angle of rotation
296  * @param zoom zoom, (256 no zoom)
297  * @param pivot x,y pivot coordinates of rotation
298  */
299 void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom,
300                                       const lv_point_t * pivot);
301 
302 /**********************
303  *      MACROS
304  **********************/
305 
306 #ifdef __cplusplus
307 } /*extern "C"*/
308 #endif
309 
310 #endif /*LV_IMG_BUF_H*/
311