arch add small 3rd party libs to lvgl (#2569)

* move png, sjpg, bmp, gif, fs_if to extra/libs

* reorganize the examples

* update lv_conf_internal.h

* fix warnings

* add freetype

* remove unused assets

* add the new libs to build tests

* update the docs
This commit is contained in:
Gabor Kiss-Vamosi
2021-10-04 14:34:11 +02:00
committed by GitHub
parent b20a706112
commit 18f61c5f77
69 changed files with 17841 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/bmp.md
```
# BMP decoder
This extension allows the use of BMP images in LVGL.
This implementation uses [bmp-decoder](https://github.com/caj-johnson/bmp-decoder) library.
The pixel are read on demand (not the whole image is loaded) so using BMP images requires very little RAM.
If enabled in `lv_conf.h` by `LV_USE_BMP` LVGL will register a new image decoder automatically so BMP files can be directly used as image sources. For example:
```
lv_img_set_src(my_img, "S:path/to/picture.bmp");
```
Note that, a file system driver needs to registered to open images from files. Read more about it [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
## Limitations
- Only BMP files are supported and BMP images as C array (`lv_img_dsc_t`) are not. It's because there is no practical differences between how the BMP files and LVGL's image format stores the image data.
- BMP files can be loaded only from file. If you want to store them in flash it's better to convert them to C array with [LVGL's image converter](https://lvgl.io/tools/imageconverter).
- The BMP files color format needs to match with `LV_COLOR_DEPTH`. Use GIMP to save the image in the required format.
Both RGB888 and ARGB888 works with `LV_COLOR_DEPTH 32`
- Palette is not supported.
- Because not the whole image is read in can not be zoomed or rotated.
## Example
```eval_rst
.. include:: ../../../examples/libs/bmp/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_bmp.h
:project: lvgl
```
+39
View File
@@ -0,0 +1,39 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/bmp.md
```
# FreeType support
Interface to [FreeType](https://www.freetype.org/) to generate font bitmaps run time.
## Install FreeType
- Download Freetype from [here](https://sourceforge.net/projects/freetype/files/)
- `make`
- `sudo make install`
## Add FreeType to your project
- Add include path: `/usr/include/freetype2` (for GCC: `-I/usr/include/freetype2 -L/usr/local/lib`)
- Add library: `freetype` (for GCC: `-L/usr/local/lib -lfreetype`)
## Usage
Enable `LV_USE_FREETYPE` in `lv_conf.h`.
See the examples below.
Note that, the FreeType extension doesn't use LVGL's file system.
You can simply pass the path to the font as usual on your operating system or platform.
## Learn more
- FreeType [tutorial](https://www.freetype.org/freetype2/docs/tutorial/step1.html)
- LVGL's [font interface](https://docs.lvgl.io/v7/en/html/overview/font.html#add-a-new-font-engine)
## API
```eval_rst
.. doxygenfile:: lv_freetype.h
:project: lvgl
```
+19
View File
@@ -0,0 +1,19 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/fs.md
```
# File System Interfaces
LVGL has a [File system](https://docs.lvgl.io/master/overview/file-system.html) module to provides an abstraction layer for various file system drivers.
LVG has build in support for
- [FATFS](http://elm-chan.org/fsw/ff/00index_e.html)
- STDIO (Linux and Windows using C standard function .e.g fopen, fread)
- POSIX (Linux and Windows using POSIX function .e.g open, read)
You still need to provide the drivers and libraries, this extensions provide only the bridge between FATFS, STDIO, POSIX and LVGL.
## Usage
In `lv_conf.h` set a driver letter for one or more `LV_FS_USE_...` define(s). After that you can access files using that driver letter. Setting `'\0'` will disable use of that interface.
+48
View File
@@ -0,0 +1,48 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/gif.md
```
# GIF decoder
Allow to use of GIF images in LVGL. Based on https://github.com/lecram/gifdec
When enabled in `lv_conf.h` with `LV_USE_GIF` `lv_gif_create(parent)` can be used to create a gif widget.
`lv_gif_set_src(obj, src)` works very similarly to `lv_img_set_src`. As source It also accepts images as variables (`lv_img_dsc_t`) or files.
## Convert GIF files to C array
To convert a GIF file to byte values array use [LVGL's online converter](https://lvgl.io/tools/imageconverter). Select "Raw" color format and "C array" Output format.
## Use GIF images from file
For example:
```c
lv_gif_set_src(obj, "S:path/to/example.gif");
```
Note that, a file system driver needs to regsitered to open images from files. Read more about it [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
## Memory requirements
To decode and display a GIF animation the following amount of RAM is required:
- `LV_COLOR_DEPTH 8`: 3 x image width x image height
- `LV_COLOR_DEPTH 16`: 4 x image width x image height
- `LV_COLOR_DEPTH 32`: 5 x image width x image height
## Example
```eval_rst
.. include:: ../../../examples/libs/gif/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_gif.h
:project: lvgl
```
+21
View File
@@ -0,0 +1,21 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/index.md
```
# 3rd party libraries
```eval_rst
.. toctree::
:maxdepth: 1
fs
bpm
jpg
png
gif
freetype
qrcode
```
+31
View File
@@ -0,0 +1,31 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/png.md
```
# PNG decoder
Allow the use of PNG images in LVGL. This implementation uses [lodepng](https://github.com/lvandeve/lodepng) library.
If enabled in `lv_conf.h` by `LV_USE_PNG` LVGL will register a new image decoder automatically so PNG files can be directly used as any other image sources.
Note that, a file system driver needs to registered to open images from files. Read more about it [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
The whole PNG image is decoded so during decoding RAM equals to `image width x image height x 4` bytes are required.
As it might take significant time to decode PNG images LVGL's [images caching](https://docs.lvgl.io/master/overview/image.html#image-caching) feature can be useful.
## Example
```eval_rst
.. include:: ../../../examples/libs/png/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_png.h
:project: lvgl
+28
View File
@@ -0,0 +1,28 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/qrcode.md
```
# QR code
QR code generation with LVGL. Uses [QR-Code-generator](https://github.com/nayuki/QR-Code-generator) by [nayuki](https://github.com/nayuki).
## Get started
- Download or clone this repository
- [Download](https://github.com/littlevgl/lv_lib_qrcode.git) from GitHub
- Clone: git clone https://github.com/littlevgl/lv_lib_qrcode.git
- Include the library: `#include "lv_lib_qrcode/lv_qrcode.h"`
- Test with the following code:
```c
const char * data = "Hello world";
/*Create a 100x100 QR code*/
lv_obj_t * qr = lv_qrcode_create(lv_scr_act(), 100, lv_color_hex3(0x33f), lv_color_hex3(0xeef));
/*Set data*/
lv_qrcode_update(qr, data, strlen(data));
```
## Notes
- QR codes with less data are smaller but they scaled by an integer numbers number to best fit to the given size
+77
View File
@@ -0,0 +1,77 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/libs/sjpg.md
```
# JPG decoder
Allow the use of JPG images in LVGL. Besides that it also allows the use of a custom format, called Split JPG (SJPG), which can be decided in more optimal way on embedded systems.
## Overview
- Supports both normal JPG and the custom SJPG formats.
- Decoding normal JPG consumes RAM with the size fo the whole uncompressed image (recommended only for devices with more RAM)
- SJPG is a custom format based on "normal" JPG and specially made for LVGL.
- SJPG is 'split-jpeg' which is a bundle of small jpeg fragments with an sjpg header.
- SJPG size will be almost comparable to the jpg file or might be a slightly larger.
- File read from file and c-array are implemented.
- SJPEG frame fragment cache enables fast fetching of lines if availble in cache.
- By default the sjpg image cache will be image width * 2 * 16 bytes (can be modified)
- Currently only 16 bit image format is supported (TODO)
- Only the required partion of the JPG and SJPG images are decoded, therefore they can't be zoomed or rotated.
## Usage
If enabled in `lv_conf.h` by `LV_USE_SJPG` LVGL will register a new image decoder automatically so JPG and SJPG files can be directly used as image sources. For example:
```
lv_img_set_src(my_img, "S:path/to/picture.jpg");
```
Note that, a file system driver needs to registered to open images from files. Read more about it [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
## Converter
### Converting JPG to C array
- Use lvgl online tool https://lvgl.io/tools/imageconverter
- Color format = RAW, output format = C Array
### Converting JPG to SJPG
python3 and the PIL library required. (PIL can be installed with `pip3 install pillow`)
To create SJPG from JPG:
- Copy the image to convert into `lvgl/scripts`
- `cd lvgl/scripts`
- `python3 jpg_to_sjpg.py image_to_convert.jpg`. It creates both a C files and an SJPG image.
The expected result is:
```sh
Conversion started...
Input:
image_to_convert.jpg
RES = 640 x 480
Output:
Time taken = 1.66 sec
bin size = 77.1 KB
walpaper.sjpg (bin file)
walpaper.c (c array)
All good!
```
## Example
```eval_rst
.. include:: ../../../examples/libs/sjpg/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_sjpg.h
:project: lvgl
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

+6
View File
@@ -0,0 +1,6 @@
Open a BMP image from file
"""""""""""""""""""""""""""""""""""""""""""""""
.. lv_example:: libs/bmp/lv_example_bmp_1
:language: c
+38
View File
@@ -0,0 +1,38 @@
/**
* @file lv_example_bmp.h
*
*/
#ifndef LV_EXAMPLE_BMP_H
#define LV_EXAMPLE_BMP_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_bmp_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_BMP_H*/
+17
View File
@@ -0,0 +1,17 @@
#include "../../lv_examples.h"
#if LV_USE_BMP && LV_BUILD_EXAMPLES
/**
* Open a BMP file from a file
*/
void lv_example_bmp_1(void)
{
lv_obj_t * img = lv_img_create(lv_scr_act());
/* Assuming a File system is attached to letter 'A'
* E.g. set LV_USE_FS_STDIO 'A' in lv_conf.h */
lv_img_set_src(img, "A:lvgl/examples/libs/bmp/example_32bit.bmp");
lv_obj_center(img);
}
#endif
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
Open a front with FreeTpye
"""""""""""""""""""""""""""""""""""""""""""""""
.. lv_example:: libs/freetype/lv_example_freetype_1
:language: c
@@ -0,0 +1,38 @@
/**
* @file lv_example_freetype.h
*
*/
#ifndef LV_EXAMPLE_FREETYPE_H
#define LV_EXAMPLE_FREETYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_freetype_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_FREETYPE_H*/
@@ -0,0 +1,30 @@
#include "../../lv_examples.h"
#if LV_USE_FREETYPE && LV_BUILD_EXAMPLES
/**
* Load a font with FreeType
*/
void lv_example_freetype_1(void)
{
/*Create a font*/
static lv_ft_info_t info;
/*FreeType uses C standard file system, so no driver letter is required.*/
info.name = "./lvgl/examples/libs/freetype/arial.ttf";
info.weight = 24;
info.style = FT_FONT_STYLE_NORMAL;
lv_ft_font_init(&info);
/*Create style with the new font*/
static lv_style_t style;
lv_style_init(&style);
lv_style_set_text_font(&style, info.font);
lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER);
/*Create a label with the new style*/
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_obj_add_style(label, &style, 0);
lv_label_set_text(label, "Hello world\nI'm a font created with FreeType");
lv_obj_center(label);
}
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
Open a GIF image from file and variable
"""""""""""""""""""""""""""""""""""""""""""""""
.. lv_example:: libs/bmp/lv_example_gif_1
:language: c
+38
View File
@@ -0,0 +1,38 @@
/**
* @file lv_example_gif.h
*
*/
#ifndef LV_EXAMPLE_GIF_H
#define LV_EXAMPLE_GIF_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_gif_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_GIF_H*/
+23
View File
@@ -0,0 +1,23 @@
#include "../../lv_examples.h"
#if LV_USE_GIF && LV_BUILD_EXAMPLES
/**
* Open a GIF image from a file and a variable
*/
void lv_example_gif_1(void)
{
LV_IMG_DECLARE(img_bulb_gif);
lv_obj_t * img;
img = lv_gif_create(lv_scr_act());
lv_gif_set_src(img, &img_bulb_gif);
lv_obj_align(img, LV_ALIGN_LEFT_MID, 20, 0);
img = lv_gif_create(lv_scr_act());
/* Assuming a File system is attached to letter 'A'
* E.g. set LV_USE_FS_STDIO 'A' in lv_conf.h */
lv_gif_set_src(img, "A:lvgl/examples/libs/gif/bulb.gif");
lv_obj_align(img, LV_ALIGN_RIGHT_MID, -20, 0);
}
#endif
+43
View File
@@ -0,0 +1,43 @@
/**
* @file lv_example_libs.h
*
*/
#ifndef LV_EXAMPLE_LIBS_H
#define LV_EXAMPLE_LIBS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "bmp/lv_example_bmp.h"
#include "gif/lv_example_gif.h"
#include "png/lv_example_png.h"
#include "sjpg/lv_example_sjpg.h"
#include "qrcode/lv_example_qrcode.h"
#include "freetype/lv_example_freetype.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_LIBS_H*/
+348
View File
@@ -0,0 +1,348 @@
#include "../../../lvgl.h"
#if LV_USE_PNG && LV_BUILD_EXAMPLES
#ifndef LV_ATTRIBUTE_MEM_ALIGN
#define LV_ATTRIBUTE_MEM_ALIGN
#endif
#ifndef LV_ATTRIBUTE_IMG_PNG_DECODER_TEST
#define LV_ATTRIBUTE_IMG_PNG_DECODER_TEST
#endif
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_PNG_DECODER_TEST uint8_t img_wink_png_map[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88,
0xb1, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00,
0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45,
0x07, 0xe5, 0x05, 0x07, 0x0c, 0x1b, 0x26, 0xad, 0x4b, 0x20, 0x5b, 0x00, 0x00, 0x00, 0x1d, 0x69,
0x54, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50,
0x64, 0x2e, 0x65, 0x07, 0x00, 0x00, 0x13, 0x8a, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xad, 0x9a,
0x69, 0x94, 0x5d, 0xd5, 0x75, 0xe7, 0x7f, 0xe7, 0xdc, 0x7b, 0xdf, 0x7d, 0x43, 0xd5, 0xab, 0xe9,
0x55, 0x49, 0x05, 0xaa, 0xd2, 0x80, 0x10, 0x12, 0x48, 0xa8, 0x24, 0x04, 0x66, 0x72, 0x6c, 0xec,
0xd8, 0xd0, 0x6e, 0x27, 0xc4, 0x6d, 0x4c, 0x08, 0x21, 0xdd, 0xed, 0x24, 0xbd, 0x1c, 0x67, 0x39,
0xcb, 0x6d, 0x33, 0xc7, 0x6e, 0x9b, 0xc6, 0x18, 0x64, 0x90, 0x43, 0xda, 0xb1, 0x1d, 0x7f, 0x31,
0x89, 0x93, 0xb8, 0x33, 0x38, 0x84, 0x15, 0x63, 0xe3, 0x38, 0x84, 0x80, 0x99, 0x67, 0x24, 0x10,
0x83, 0x06, 0x84, 0x84, 0x54, 0x52, 0x95, 0x6a, 0x7e, 0xf5, 0xa6, 0x3b, 0x9c, 0xb3, 0xfb, 0xc3,
0xbd, 0x6f, 0x28, 0xa1, 0xac, 0x0e, 0x8e, 0x6b, 0xad, 0xb3, 0x6e, 0xd5, 0x7b, 0xa7, 0xce, 0xd9,
0xff, 0xb3, 0xa7, 0xff, 0xde, 0xf7, 0x28, 0x7e, 0x8e, 0x9f, 0x97, 0x6f, 0x18, 0xe2, 0xec, 0x3b,
0x8f, 0x03, 0xf0, 0xe0, 0xd5, 0x5b, 0x19, 0x1e, 0xdd, 0xa7, 0x4b, 0xab, 0x95, 0x5a, 0x98, 0xee,
0xe9, 0x6d, 0xcc, 0x95, 0xcf, 0xcb, 0xf5, 0xc8, 0xe6, 0x6c, 0x97, 0x3e, 0x5d, 0x3b, 0x76, 0xd0,
0x51, 0xaa, 0x28, 0x56, 0x10, 0xc3, 0xa2, 0x89, 0xd5, 0x74, 0x58, 0xe3, 0x50, 0xa3, 0xa6, 0x5e,
0x15, 0xed, 0xbf, 0x30, 0x30, 0x5c, 0x38, 0x52, 0x9f, 0x1a, 0x8f, 0xe7, 0xaa, 0x3d, 0xb2, 0xed,
0xee, 0xe3, 0xd2, 0x5e, 0x7f, 0x19, 0x67, 0xdf, 0x39, 0xf9, 0xae, 0x64, 0x52, 0xef, 0x66, 0xf2,
0x4b, 0xd7, 0x0d, 0xb3, 0x65, 0xc7, 0x31, 0x00, 0x7e, 0x70, 0xee, 0x6a, 0xb5, 0xed, 0x13, 0xc7,
0xfd, 0x58, 0x7a, 0x46, 0x95, 0xa9, 0x7c, 0xa2, 0xab, 0xa4, 0xaf, 0xcc, 0xe4, 0xe3, 0xb3, 0xf3,
0xbd, 0x1a, 0x37, 0x23, 0x80, 0x80, 0xa8, 0xe4, 0x69, 0x01, 0x63, 0x51, 0x06, 0xc4, 0x28, 0x6c,
0x03, 0x1a, 0x65, 0xa1, 0x51, 0xd3, 0xc7, 0xeb, 0x55, 0x1e, 0x08, 0x43, 0xef, 0xaf, 0x5d, 0x47,
0xbf, 0x30, 0xb7, 0xa0, 0xcb, 0x5b, 0xef, 0x9e, 0x8a, 0x9a, 0xfb, 0xed, 0xba, 0x6e, 0x19, 0x9b,
0x77, 0x4c, 0xfe, 0xe2, 0x80, 0xec, 0xff, 0xf6, 0xc7, 0x88, 0x8f, 0xfd, 0x88, 0xf5, 0x5f, 0x49,
0xf6, 0x78, 0xe3, 0xcb, 0x5d, 0x5d, 0x5e, 0x2e, 0x7b, 0x6e, 0xb6, 0x18, 0x7f, 0x26, 0xdf, 0x6b,
0xff, 0x4b, 0xd7, 0xa0, 0x42, 0x39, 0x2e, 0x38, 0x59, 0x20, 0x83, 0x68, 0x0f, 0x94, 0x87, 0xd2,
0x39, 0x40, 0x83, 0x44, 0x88, 0xa9, 0x83, 0x09, 0xc0, 0x84, 0xa8, 0x30, 0x40, 0x05, 0x01, 0x84,
0x06, 0x22, 0x45, 0xa3, 0x6c, 0xa9, 0x2e, 0xea, 0xb7, 0xea, 0x81, 0xf7, 0x4d, 0x1b, 0xdb, 0xfb,
0x0e, 0x8e, 0x17, 0x0f, 0x5f, 0xf2, 0xdd, 0x23, 0x31, 0xc0, 0xab, 0x5f, 0x7b, 0x2f, 0x67, 0xdd,
0xf8, 0xd8, 0x7f, 0x1c, 0xc8, 0xae, 0x1b, 0x47, 0xd8, 0xfc, 0xb5, 0xc3, 0x00, 0xfc, 0xf4, 0xd2,
0x62, 0x66, 0xed, 0x07, 0x33, 0x9b, 0xb3, 0xdd, 0xe6, 0xf3, 0xdd, 0x83, 0x72, 0x55, 0xae, 0x17,
0x54, 0xa6, 0x1b, 0x71, 0xfb, 0x20, 0xbb, 0x12, 0xd5, 0xb3, 0x09, 0x95, 0x3f, 0x1d, 0x72, 0x23,
0xe0, 0xf5, 0x82, 0xd2, 0xed, 0x85, 0x24, 0x86, 0x60, 0x06, 0xea, 0x87, 0x91, 0xea, 0x5e, 0x98,
0x7f, 0x05, 0x16, 0x0f, 0x41, 0x75, 0x0e, 0x55, 0xab, 0xa0, 0x02, 0x4b, 0x54, 0x83, 0xc5, 0xb2,
0x3a, 0xdc, 0x08, 0xdd, 0xdb, 0xe6, 0xe6, 0xd5, 0x8f, 0x37, 0x7d, 0x7d, 0x61, 0x1c, 0xe0, 0xa5,
0xeb, 0x57, 0xb0, 0xe5, 0xae, 0x23, 0x3f, 0x3f, 0x90, 0x5d, 0xd7, 0x95, 0xd8, 0xbc, 0x63, 0x3a,
0xb5, 0xdb, 0x81, 0xc1, 0xbe, 0x11, 0xf9, 0xaf, 0x85, 0x12, 0x37, 0x15, 0x06, 0x28, 0x39, 0xd9,
0x02, 0xf8, 0xa3, 0xd0, 0x77, 0x1e, 0xaa, 0xff, 0x62, 0xc8, 0xad, 0x04, 0x31, 0xe9, 0xb0, 0x24,
0xf6, 0x74, 0x92, 0xed, 0x54, 0x3a, 0x50, 0x50, 0x3f, 0x02, 0x33, 0xcf, 0x20, 0x53, 0xcf, 0xc3,
0xec, 0x01, 0x58, 0x9c, 0x46, 0x87, 0x50, 0xaf, 0xc2, 0x62, 0xc5, 0xf9, 0x49, 0xad, 0xae, 0xef,
0x58, 0x73, 0x6b, 0xf9, 0x31, 0x80, 0x9d, 0x37, 0x0c, 0x33, 0x76, 0xe7, 0xb1, 0x77, 0x0f, 0x64,
0xd7, 0xf5, 0x7d, 0x6c, 0xbe, 0x6b, 0x0e, 0x80, 0x3d, 0xb7, 0x0e, 0x9c, 0xd5, 0x73, 0x8a, 0xfa,
0x52, 0xf7, 0x32, 0x75, 0xa5, 0xdf, 0x25, 0x90, 0x1d, 0x81, 0xbe, 0x8b, 0x50, 0x43, 0x97, 0x42,
0x66, 0x28, 0x39, 0x6d, 0x31, 0x27, 0x59, 0x45, 0xda, 0xcf, 0x14, 0xa0, 0x12, 0x83, 0x60, 0xdb,
0xf3, 0xb5, 0x87, 0x8a, 0xab, 0xc8, 0xec, 0x0b, 0xc8, 0xb1, 0xa7, 0x60, 0xe2, 0x15, 0x54, 0xb5,
0x82, 0xc4, 0x9a, 0x85, 0x05, 0xa6, 0x2a, 0x55, 0xe7, 0xe6, 0xaf, 0xfd, 0xf0, 0xb2, 0xef, 0x7d,
0xfb, 0xc5, 0x1f, 0xc4, 0x3b, 0x3f, 0xd7, 0xcb, 0xd8, 0xdd, 0xf3, 0xff, 0x7e, 0x20, 0x2f, 0xdf,
0x50, 0xe2, 0xec, 0x3b, 0x13, 0x4d, 0xec, 0xbb, 0xbd, 0xff, 0xe2, 0xbe, 0x11, 0xe7, 0xae, 0xc2,
0xa0, 0x3e, 0xdf, 0xcb, 0x6b, 0xe8, 0xda, 0x8c, 0x5a, 0x76, 0x39, 0x14, 0xcf, 0x4e, 0x65, 0x3c,
0x19, 0x00, 0x8b, 0x12, 0x69, 0x09, 0xac, 0xc4, 0x22, 0x62, 0x81, 0xb6, 0xb6, 0x94, 0x98, 0x44,
0x6b, 0x62, 0x12, 0xa0, 0xda, 0x43, 0xa2, 0x05, 0x98, 0x7c, 0x16, 0x79, 0xfb, 0x31, 0x98, 0x3c,
0x80, 0xb2, 0x0e, 0xd5, 0x2a, 0x71, 0xb9, 0xa2, 0xbf, 0xf2, 0xe1, 0xff, 0x75, 0xda, 0x57, 0x5f,
0x63, 0x97, 0xd9, 0x79, 0xfd, 0x72, 0xc6, 0xee, 0x9a, 0xf8, 0xff, 0x03, 0xd9, 0x79, 0xdd, 0x10,
0x63, 0x3b, 0x92, 0xd0, 0xba, 0xff, 0x8e, 0xfe, 0x4b, 0xfa, 0x56, 0x39, 0xdf, 0x28, 0x94, 0xdc,
0x8d, 0xae, 0xef, 0x42, 0xdf, 0xc5, 0xa8, 0xe1, 0x2b, 0xc0, 0x1f, 0x6e, 0x0b, 0xd0, 0x71, 0xfa,
0x0a, 0x0b, 0xa9, 0xd0, 0x4b, 0x4e, 0x5e, 0x92, 0xcf, 0x15, 0x6d, 0xe1, 0x45, 0x2c, 0x8a, 0x14,
0x60, 0x13, 0x14, 0x02, 0xca, 0x81, 0x85, 0x03, 0x70, 0xe8, 0x11, 0xe4, 0xd0, 0x73, 0x28, 0xeb,
0xd0, 0x68, 0x88, 0x99, 0x9d, 0x77, 0x76, 0x8c, 0x7c, 0xa9, 0x72, 0x13, 0xc0, 0xce, 0x9b, 0x4f,
0x63, 0xec, 0x8e, 0x37, 0xff, 0x6d, 0x20, 0xaf, 0x7c, 0x69, 0x3d, 0x9b, 0x6e, 0x7d, 0x23, 0xd1,
0xc4, 0xf6, 0xd2, 0x7b, 0xfa, 0x47, 0xf5, 0x9f, 0x77, 0x2d, 0xf3, 0xd6, 0x3b, 0x9e, 0x03, 0xfd,
0xef, 0x47, 0x9d, 0x72, 0x25, 0x78, 0xfd, 0x20, 0x31, 0xda, 0x71, 0x00, 0x41, 0x4c, 0x94, 0x0a,
0xd3, 0x71, 0xe2, 0x1d, 0xc2, 0xa9, 0xa6, 0xbf, 0x88, 0x41, 0x3a, 0xb5, 0xd0, 0xfa, 0xbc, 0x03,
0x88, 0x4d, 0xd7, 0x50, 0x1a, 0x82, 0x39, 0xe4, 0xd0, 0xa3, 0xb0, 0xff, 0x31, 0xb0, 0x2e, 0x41,
0x40, 0x70, 0x7c, 0x46, 0x6f, 0x5f, 0xfd, 0xbf, 0x2b, 0xb7, 0xc8, 0x93, 0xb0, 0xff, 0xe0, 0xe7,
0x38, 0xfd, 0xea, 0xbb, 0x4f, 0x0e, 0x44, 0x9e, 0x06, 0x75, 0x3e, 0xec, 0xbf, 0x63, 0x68, 0x4d,
0xf7, 0x72, 0xfe, 0xae, 0x6f, 0xa5, 0x7f, 0x8e, 0x76, 0x25, 0xf1, 0x87, 0x53, 0xaf, 0x49, 0x40,
0xd8, 0x08, 0x9d, 0xcd, 0x30, 0x77, 0xe8, 0x6d, 0x4c, 0x14, 0xd2, 0x37, 0x3c, 0x88, 0x52, 0xd2,
0x21, 0x98, 0x39, 0x41, 0xf8, 0x26, 0xc0, 0x7f, 0x43, 0x78, 0x39, 0x11, 0x4c, 0xf2, 0x14, 0x80,
0xb8, 0x06, 0x6f, 0xfd, 0x0c, 0xde, 0x7c, 0x0a, 0xf0, 0x68, 0x04, 0xcc, 0x1e, 0x3e, 0xea, 0x5d,
0xbf, 0x61, 0xfb, 0xc2, 0x3d, 0x6f, 0x5c, 0xeb, 0xa9, 0xf5, 0x5f, 0x8f, 0x5a, 0x26, 0xd1, 0x8a,
0x8f, 0xbb, 0x6f, 0x2e, 0xa1, 0xce, 0x87, 0xdd, 0x37, 0xf6, 0xf4, 0xe6, 0x7a, 0xf8, 0x4a, 0xdf,
0x68, 0x36, 0x01, 0xd1, 0x75, 0x26, 0x6a, 0xf9, 0xc7, 0x50, 0x6e, 0x2f, 0xd8, 0x06, 0xda, 0x85,
0xf1, 0x5d, 0x3b, 0xf9, 0xfe, 0x1f, 0x7e, 0x95, 0x3f, 0xbe, 0xe6, 0xb3, 0x4c, 0xee, 0x7f, 0x13,
0x4c, 0x80, 0xb2, 0x01, 0x2a, 0x7d, 0x62, 0x1b, 0x88, 0x69, 0x20, 0x36, 0x00, 0x69, 0x80, 0x0d,
0xc0, 0x86, 0x1d, 0x23, 0x48, 0x86, 0x49, 0x9f, 0x36, 0x99, 0x23, 0x26, 0x40, 0x6c, 0x88, 0x98,
0x10, 0xe2, 0x46, 0x22, 0xd8, 0xc8, 0x36, 0x18, 0x5c, 0x05, 0x62, 0xf1, 0x33, 0xf4, 0x9f, 0xb2,
0x2c, 0xba, 0xe1, 0xa9, 0x4f, 0x97, 0xc6, 0xd6, 0x7f, 0x3d, 0x92, 0x97, 0x3e, 0x37, 0xc0, 0x12,
0x20, 0xaf, 0x6f, 0xbf, 0x90, 0x8d, 0x77, 0x4c, 0xf3, 0xd3, 0x4b, 0xbb, 0xbd, 0xc2, 0x90, 0x7f,
0x79, 0xef, 0x4a, 0xef, 0x6a, 0x27, 0xa3, 0x21, 0xb3, 0x1c, 0x55, 0xfa, 0x00, 0x64, 0x96, 0x23,
0xa6, 0x86, 0x92, 0x64, 0xd3, 0x87, 0xee, 0xf9, 0x1b, 0x0e, 0xbc, 0xf0, 0x0a, 0xc3, 0x83, 0x73,
0x44, 0xf3, 0x7b, 0xc0, 0xd4, 0x11, 0xdb, 0x48, 0x47, 0x80, 0x48, 0x08, 0xd2, 0x21, 0x6c, 0x4b,
0xe0, 0xce, 0xbf, 0xc3, 0xb6, 0xf0, 0x26, 0x15, 0xde, 0x86, 0xe9, 0x77, 0x8d, 0xf6, 0x50, 0x0a,
0xd6, 0x5c, 0x08, 0x19, 0x8d, 0x52, 0x90, 0xf5, 0x39, 0x63, 0xf5, 0x68, 0xfd, 0x36, 0x80, 0x2d,
0x77, 0xcf, 0x2c, 0x05, 0xb2, 0xe1, 0xa6, 0x27, 0x01, 0xd8, 0xf0, 0xab, 0xbd, 0xc3, 0x85, 0x41,
0xbd, 0x23, 0xdb, 0xe3, 0x23, 0x78, 0xd0, 0xbd, 0x11, 0xba, 0xb7, 0x82, 0xa9, 0x82, 0x6d, 0xa0,
0x1c, 0x61, 0xdf, 0x53, 0xcf, 0x72, 0xf4, 0x8d, 0xfd, 0xfc, 0xca, 0x15, 0x9a, 0x2b, 0x3e, 0xbd,
0x8e, 0xe5, 0xab, 0x4a, 0x40, 0x08, 0x92, 0x0e, 0xdb, 0x00, 0xd3, 0xe8, 0x10, 0xbe, 0x53, 0xc0,
0xf6, 0x48, 0x34, 0x76, 0xc2, 0x77, 0xa6, 0x91, 0x1e, 0x40, 0x73, 0xad, 0x44, 0xa3, 0x2a, 0x9b,
0x85, 0xe5, 0xa7, 0x03, 0x06, 0xc7, 0x81, 0x62, 0xb7, 0x5c, 0xb0, 0xf7, 0x0b, 0xdd, 0xbf, 0xdf,
0xcc, 0x75, 0x00, 0xfa, 0xf5, 0x3b, 0xce, 0x4f, 0xf2, 0xc6, 0xb5, 0x3d, 0x59, 0x1b, 0x36, 0x3e,
0xdd, 0x37, 0x9a, 0x2d, 0x89, 0x08, 0xe4, 0x4e, 0x41, 0xf5, 0x5d, 0x90, 0x2e, 0xdc, 0x40, 0xd9,
0x10, 0x1c, 0xc3, 0x6b, 0x8f, 0xbf, 0xc4, 0x59, 0x1b, 0xa6, 0xd9, 0xf4, 0xc1, 0x8b, 0x29, 0x9d,
0xf7, 0x07, 0x78, 0x3d, 0x2b, 0x52, 0x61, 0x52, 0x00, 0x9d, 0x26, 0x74, 0x52, 0xd3, 0x09, 0x96,
0x9e, 0xbe, 0x09, 0xda, 0xda, 0x6b, 0x3d, 0x1b, 0x09, 0x00, 0x09, 0x50, 0x12, 0x02, 0x21, 0xaa,
0x74, 0x2a, 0xe8, 0xc4, 0x25, 0x5c, 0x87, 0xfe, 0xc1, 0x7e, 0x73, 0xcd, 0x7d, 0x57, 0xad, 0x1c,
0x68, 0x26, 0x6c, 0x77, 0xc3, 0xcd, 0x4f, 0x03, 0xd0, 0xbf, 0xba, 0xbb, 0x94, 0xef, 0x33, 0x9f,
0xd7, 0x9e, 0x83, 0xe0, 0x43, 0x7e, 0x2d, 0xf8, 0xa7, 0xa0, 0x4c, 0x2d, 0x71, 0x44, 0x25, 0x44,
0x0b, 0x55, 0xa4, 0x72, 0x80, 0xb5, 0xdb, 0xce, 0x64, 0x60, 0xe3, 0xaf, 0x22, 0xda, 0x4f, 0x4f,
0x51, 0x3a, 0x9c, 0xd9, 0xb4, 0x9d, 0xb7, 0x95, 0x3f, 0x52, 0x87, 0xb6, 0x16, 0x6b, 0x63, 0xac,
0x89, 0x40, 0x2c, 0x5a, 0x83, 0xd6, 0xd2, 0xfe, 0x3f, 0x3a, 0x02, 0x45, 0xcb, 0xf1, 0xd3, 0x40,
0xe1, 0x79, 0xe0, 0x29, 0x08, 0xc0, 0xd1, 0xe0, 0xfb, 0x9c, 0x35, 0xb6, 0x6e, 0xe6, 0x93, 0xc0,
0x0e, 0x00, 0x07, 0x60, 0xe7, 0xb5, 0x3d, 0xae, 0x93, 0x91, 0x4f, 0x2d, 0xdb, 0x50, 0xb8, 0x14,
0xad, 0xc1, 0x2f, 0xa1, 0x4a, 0xef, 0x47, 0x39, 0x99, 0xc4, 0x61, 0x89, 0xd1, 0x8e, 0xe5, 0xf0,
0xee, 0x37, 0xc9, 0x98, 0x43, 0xac, 0x7e, 0xcf, 0x2f, 0x93, 0xe9, 0x1e, 0x02, 0x13, 0x82, 0x8d,
0x41, 0xa2, 0x64, 0x10, 0x81, 0x8d, 0x11, 0x1b, 0xa7, 0xd9, 0xbe, 0x63, 0xd8, 0x88, 0xe9, 0xa3,
0xd3, 0x3c, 0xf3, 0xc0, 0x8b, 0x3c, 0x75, 0xff, 0xf3, 0xbc, 0xf1, 0xcc, 0x1e, 0x2a, 0xb3, 0x0b,
0x14, 0xba, 0x1c, 0x72, 0x79, 0x85, 0x52, 0x06, 0x4d, 0x8c, 0x22, 0x42, 0x49, 0x9c, 0xac, 0x23,
0x21, 0xd8, 0x28, 0xd9, 0xa7, 0x32, 0x0e, 0x8b, 0x53, 0x60, 0x54, 0x33, 0x7d, 0xf9, 0x5a, 0x8b,
0xda, 0xdc, 0x7d, 0xf6, 0x7d, 0xf7, 0xbe, 0x7e, 0x2c, 0x74, 0x13, 0x6d, 0x14, 0x7c, 0xbf, 0xcb,
0xfe, 0x8e, 0xce, 0x38, 0x88, 0x38, 0x90, 0x29, 0x81, 0xbf, 0x0c, 0x69, 0x6a, 0x43, 0x2c, 0x28,
0x85, 0x69, 0xcc, 0xb3, 0x62, 0xec, 0x42, 0xba, 0x4b, 0x43, 0xd8, 0xb8, 0xb6, 0x24, 0xd9, 0xc9,
0x92, 0x70, 0x6a, 0x96, 0x84, 0x54, 0xad, 0x85, 0xb9, 0xa9, 0x05, 0xfe, 0xf5, 0xff, 0x3e, 0xcc,
0xe4, 0xbe, 0x37, 0x39, 0x73, 0x4b, 0x0f, 0x5d, 0x3d, 0x1e, 0x8d, 0xd9, 0x79, 0x9e, 0xbb, 0x7f,
0x1f, 0xe7, 0x7e, 0x64, 0x1b, 0x83, 0x23, 0x7d, 0x2c, 0xcc, 0x87, 0xcc, 0x97, 0x03, 0x72, 0xbe,
0xd0, 0xdf, 0x2d, 0x29, 0xa0, 0x06, 0x34, 0x8e, 0x23, 0x0b, 0x87, 0x50, 0x19, 0x07, 0x22, 0x01,
0x23, 0xb8, 0x2e, 0xf8, 0x19, 0xb5, 0x7e, 0xcb, 0xda, 0xbd, 0x97, 0x02, 0xf7, 0xba, 0xcf, 0x7d,
0x66, 0x98, 0xfa, 0x3c, 0xeb, 0xfa, 0x46, 0xdc, 0xd3, 0x11, 0x05, 0x4e, 0x1e, 0x95, 0x5b, 0x09,
0xa6, 0x9e, 0x2c, 0x92, 0x0a, 0x6a, 0x03, 0xcb, 0xea, 0x4d, 0xab, 0x00, 0xc1, 0x5a, 0x83, 0xc2,
0x24, 0x7e, 0x83, 0xc5, 0x88, 0x4e, 0xcc, 0x40, 0xe2, 0x0e, 0xda, 0x61, 0x5b, 0x79, 0x43, 0x8c,
0xc5, 0xcf, 0x84, 0xbc, 0xef, 0x23, 0x25, 0x06, 0x4a, 0x7d, 0xf8, 0xc5, 0x65, 0x90, 0x29, 0x24,
0x59, 0x4c, 0x37, 0xa8, 0x4e, 0x2f, 0xf2, 0xf0, 0xcf, 0x8e, 0xf1, 0xd0, 0xb3, 0x65, 0x76, 0xef,
0x5b, 0xe4, 0x03, 0x5b, 0x35, 0x9f, 0xba, 0x3c, 0x87, 0x23, 0xb5, 0x54, 0x0e, 0x9b, 0xd8, 0x8e,
0x23, 0xe0, 0x28, 0x50, 0x92, 0x90, 0x00, 0xcd, 0x48, 0x5f, 0x2f, 0x17, 0x00, 0xf7, 0xba, 0x5d,
0xa5, 0x50, 0x3b, 0x9e, 0xfe, 0xb5, 0x7c, 0xa9, 0x88, 0xa0, 0x40, 0xfb, 0xe0, 0x2f, 0x03, 0x53,
0x4b, 0xcd, 0x66, 0xa9, 0x50, 0x00, 0x3a, 0x98, 0x62, 0x71, 0x62, 0x9c, 0xc9, 0x63, 0x53, 0x64,
0x33, 0x2e, 0x2b, 0x46, 0x06, 0x90, 0xae, 0x21, 0xac, 0x93, 0x49, 0xe7, 0x37, 0x35, 0x12, 0x03,
0x31, 0xd8, 0x90, 0x7c, 0x3e, 0xa4, 0x70, 0xc6, 0xa9, 0x88, 0x69, 0x60, 0xa2, 0x2a, 0x54, 0x66,
0x70, 0x1c, 0xc3, 0xf4, 0x74, 0x9d, 0xef, 0xde, 0x37, 0xc5, 0x4f, 0x9e, 0xb1, 0x6c, 0x5c, 0x57,
0xe4, 0xca, 0x8b, 0x84, 0x4d, 0x2b, 0x0d, 0xd1, 0x62, 0x15, 0xa7, 0x4b, 0x81, 0xf2, 0x40, 0x27,
0x72, 0x88, 0x23, 0x28, 0x27, 0x2d, 0x71, 0x0c, 0xb8, 0x8e, 0xe0, 0x67, 0xec, 0xfa, 0x7f, 0xf8,
0xf5, 0x95, 0xfd, 0x6e, 0x71, 0x59, 0x84, 0x72, 0xf3, 0x97, 0xb4, 0xa8, 0xb5, 0xe3, 0x83, 0x53,
0x48, 0x9d, 0xd8, 0x74, 0x38, 0xad, 0xa0, 0x94, 0xa0, 0x17, 0x0f, 0xf2, 0xc4, 0x03, 0x0f, 0xf3,
0x8f, 0x3f, 0x3b, 0xc2, 0xa4, 0x9c, 0x42, 0x57, 0x06, 0xce, 0xec, 0x1e, 0xe7, 0xaa, 0xcb, 0x37,
0xd0, 0xbf, 0xe1, 0x5c, 0x6c, 0x26, 0x07, 0x12, 0x27, 0x66, 0x21, 0x21, 0x22, 0x21, 0x22, 0x8d,
0xc4, 0xf4, 0x62, 0x83, 0x12, 0x83, 0x02, 0x94, 0xeb, 0x51, 0xad, 0x5a, 0xbe, 0xf5, 0xf7, 0x65,
0x0e, 0xcd, 0xaf, 0xe1, 0x1b, 0xb7, 0x6d, 0x61, 0x53, 0xdf, 0x01, 0xe2, 0x50, 0x13, 0xeb, 0x6e,
0xa2, 0xb9, 0x37, 0x80, 0xe3, 0x49, 0x1e, 0x91, 0x94, 0xfa, 0x6b, 0x95, 0x24, 0x0c, 0xa5, 0x40,
0x04, 0xc7, 0x01, 0xd7, 0x91, 0x15, 0x6b, 0x86, 0x67, 0xce, 0x70, 0x73, 0xa7, 0x9e, 0xa7, 0x4d,
0xf9, 0xd5, 0x73, 0x40, 0x27, 0x84, 0xcd, 0xc9, 0x27, 0x9a, 0x30, 0x01, 0x82, 0x49, 0xf9, 0x8f,
0x05, 0xa5, 0xd1, 0xf5, 0xc3, 0xfc, 0xe3, 0xf7, 0x7f, 0xc8, 0x9f, 0x3c, 0xd6, 0x83, 0xb7, 0xf5,
0xcb, 0xac, 0x1e, 0x7b, 0x0f, 0x91, 0x11, 0x1e, 0xdc, 0xf3, 0x1c, 0x6f, 0xfd, 0xcd, 0xb7, 0xf8,
0xd2, 0x55, 0x4f, 0xd2, 0xb5, 0xe9, 0xa2, 0x94, 0xb6, 0x47, 0x69, 0x24, 0x22, 0x39, 0xd5, 0x44,
0x7c, 0x04, 0x41, 0xa1, 0x51, 0x1e, 0xfc, 0xdd, 0x3f, 0xcf, 0x12, 0x66, 0xcf, 0x66, 0xfb, 0x6d,
0x57, 0xd2, 0xb7, 0xf8, 0x02, 0x8b, 0x0b, 0x45, 0x0a, 0xcb, 0x47, 0xc8, 0xd6, 0xde, 0xc6, 0xb7,
0x71, 0x12, 0xb4, 0x44, 0xb5, 0xfe, 0x17, 0x9d, 0x9a, 0x97, 0x6e, 0x93, 0x2b, 0xa5, 0xd5, 0xf2,
0xde, 0x5e, 0xbd, 0xca, 0x9d, 0x7c, 0x65, 0x7c, 0xf8, 0x94, 0xf5, 0x3a, 0x9f, 0x14, 0x3d, 0x1a,
0xb4, 0x9f, 0x94, 0xa5, 0x36, 0x5c, 0xc2, 0x4a, 0x1d, 0x15, 0xf0, 0xec, 0xbf, 0x3e, 0xc3, 0x77,
0x9f, 0x1d, 0xe0, 0xcc, 0xdf, 0xbc, 0x9d, 0xf7, 0xff, 0xda, 0xc7, 0xc9, 0xf9, 0xc9, 0xb7, 0xb5,
0xf0, 0xc3, 0x3c, 0xfe, 0xc0, 0x39, 0x7c, 0xe3, 0xfe, 0x4f, 0xf2, 0xc5, 0x55, 0x47, 0xb1, 0xc5,
0x15, 0x2d, 0x66, 0xac, 0x50, 0x88, 0x48, 0x5a, 0x2d, 0x5a, 0x40, 0xa3, 0x5d, 0x87, 0x57, 0x5e,
0x9d, 0x67, 0x31, 0x1a, 0xe4, 0xb7, 0x7f, 0xf3, 0x7d, 0x0c, 0x66, 0xea, 0x94, 0xe7, 0x0f, 0x53,
0x28, 0xe6, 0x61, 0xef, 0x3f, 0x63, 0xe7, 0xf6, 0x42, 0xb7, 0x86, 0xbe, 0xde, 0xb4, 0x10, 0x63,
0xe9, 0xd0, 0x4b, 0x88, 0xef, 0x40, 0xc6, 0x63, 0xb9, 0x8e, 0xca, 0xf3, 0x6b, 0xfd, 0x6e, 0xb7,
0xb5, 0x2d, 0xa2, 0x96, 0x64, 0x60, 0x6c, 0x80, 0x22, 0x22, 0x9e, 0x3a, 0xc4, 0xf7, 0x1f, 0x9a,
0x61, 0xe5, 0xa5, 0x9f, 0xe3, 0xe3, 0x9f, 0xf8, 0x38, 0xa7, 0x75, 0xc1, 0x4a, 0x0f, 0x46, 0x5d,
0x58, 0xdb, 0x0d, 0x57, 0xfc, 0xc6, 0x65, 0x54, 0x2f, 0xde, 0xce, 0xae, 0xa7, 0x5f, 0x45, 0x3b,
0x5e, 0xa2, 0x5d, 0x9c, 0x04, 0x8a, 0xd2, 0x9c, 0x28, 0xcd, 0xc1, 0x63, 0x96, 0xcd, 0x1b, 0x86,
0x38, 0xed, 0xd4, 0x90, 0xf2, 0xde, 0x07, 0xf1, 0x33, 0x35, 0xd4, 0x5b, 0x8f, 0x63, 0x8f, 0xec,
0x85, 0x48, 0x43, 0xa1, 0xa7, 0x5d, 0x49, 0xb6, 0x34, 0xd2, 0x04, 0xd5, 0xe6, 0xba, 0x4a, 0xe1,
0x3a, 0x8e, 0xed, 0x75, 0x91, 0x60, 0xb9, 0x9b, 0xcd, 0x75, 0x14, 0x73, 0x61, 0x9b, 0x5a, 0xd0,
0x0c, 0x9f, 0xf0, 0xe8, 0xd3, 0xfb, 0x31, 0xcb, 0xdf, 0xcb, 0x07, 0x2e, 0xfb, 0x28, 0x6b, 0x7a,
0xa0, 0xa8, 0xc0, 0xd3, 0x90, 0x77, 0xe0, 0xde, 0x07, 0xc7, 0x79, 0xee, 0x65, 0x4d, 0x39, 0x7a,
0x2f, 0x7f, 0xff, 0x7a, 0x89, 0xcd, 0x1f, 0xaa, 0x83, 0xca, 0xa4, 0x94, 0x5c, 0x2d, 0x31, 0x0f,
0xc7, 0xd1, 0x1c, 0x3c, 0x5c, 0x61, 0x59, 0xaf, 0xe2, 0x8c, 0xd5, 0x75, 0xe2, 0xe3, 0xbb, 0x50,
0xf6, 0x18, 0xba, 0x72, 0x14, 0xe2, 0xe3, 0xe8, 0x5e, 0x17, 0xfa, 0xbb, 0xc1, 0xd7, 0x69, 0x80,
0x69, 0x96, 0xc8, 0x27, 0xf0, 0xf5, 0xe6, 0x53, 0x04, 0xa5, 0x9c, 0x6e, 0xd7, 0x71, 0x29, 0x2a,
0xad, 0x12, 0x1c, 0x22, 0x49, 0xb4, 0x6a, 0x51, 0x03, 0x0b, 0xca, 0x42, 0x5c, 0x63, 0xe7, 0xbe,
0x32, 0x83, 0xeb, 0x2f, 0x61, 0xeb, 0xfa, 0x15, 0x94, 0xdc, 0x64, 0x1f, 0x0d, 0xfc, 0xd5, 0xdf,
0x1e, 0xe0, 0xc1, 0xfd, 0xfd, 0xbc, 0xbd, 0xff, 0x11, 0xf2, 0xf9, 0x5e, 0xe6, 0xb8, 0x1a, 0x6a,
0x8f, 0x40, 0xd7, 0x8a, 0x14, 0xc0, 0xd2, 0xea, 0x47, 0x04, 0xb2, 0xae, 0x61, 0xb4, 0x77, 0x81,
0xa2, 0xaa, 0x53, 0x3e, 0x78, 0x98, 0x4c, 0x21, 0xc6, 0xf1, 0x23, 0x18, 0xea, 0x05, 0xd7, 0x87,
0xdc, 0x08, 0x2a, 0xbf, 0x0a, 0x2a, 0x7b, 0x90, 0xda, 0xc1, 0xd4, 0xe7, 0x4e, 0x5e, 0x49, 0x2b,
0x25, 0xe0, 0x78, 0x59, 0xad, 0xb2, 0x5e, 0xbe, 0xb3, 0x44, 0x45, 0xea, 0x28, 0x5b, 0x69, 0x73,
0x2c, 0x13, 0x40, 0x65, 0x96, 0xd8, 0x1f, 0xa6, 0x67, 0xf9, 0x5a, 0xfa, 0x7c, 0xc8, 0xa4, 0x7e,
0x77, 0x64, 0x7c, 0x91, 0xe9, 0x28, 0xc7, 0x1f, 0x7d, 0xb6, 0x97, 0xb3, 0x7a, 0x9e, 0xe0, 0xa1,
0x3f, 0xbb, 0x9c, 0x89, 0x60, 0x82, 0xf2, 0x54, 0x39, 0xd5, 0xbe, 0x24, 0x92, 0x77, 0x6c, 0x6c,
0xad, 0xa5, 0x34, 0x90, 0xa7, 0xb4, 0x62, 0x05, 0xe2, 0x17, 0xc9, 0x14, 0x5d, 0x9c, 0x5c, 0x16,
0xb2, 0x03, 0x90, 0x2d, 0xa2, 0xfc, 0x6e, 0xb4, 0x6b, 0x51, 0x32, 0x0f, 0x85, 0xd1, 0xa5, 0x55,
0xa8, 0x9c, 0xa4, 0xbe, 0x15, 0x50, 0x26, 0xa8, 0x6b, 0xa9, 0xd5, 0x17, 0x97, 0xcc, 0x30, 0x21,
0x04, 0x53, 0x60, 0x42, 0xc4, 0x34, 0x40, 0x42, 0x2a, 0x73, 0x65, 0xdc, 0xc2, 0x20, 0x7d, 0xa5,
0xa1, 0x56, 0xf4, 0x03, 0x78, 0xf8, 0xf1, 0x69, 0x3e, 0xf8, 0x4b, 0x03, 0x0c, 0x74, 0xc1, 0x15,
0x1f, 0xfb, 0x28, 0x71, 0x58, 0xe5, 0xe0, 0xce, 0x7f, 0x61, 0x7e, 0xa1, 0xd1, 0x2e, 0x6b, 0x91,
0x8e, 0x67, 0xb2, 0x4f, 0xc2, 0xb1, 0x34, 0xa2, 0x32, 0x64, 0x8a, 0x79, 0x9c, 0x4c, 0x06, 0x14,
0x58, 0xa3, 0x98, 0xde, 0x3b, 0xc3, 0x9b, 0x0f, 0xed, 0xe6, 0xc8, 0xa3, 0x4f, 0x20, 0x33, 0x2f,
0xbe, 0xb3, 0x1a, 0x97, 0x25, 0x4b, 0x21, 0x4a, 0x63, 0x85, 0xba, 0x6b, 0x6c, 0xa6, 0x62, 0x8d,
0x45, 0xb9, 0xa9, 0xfa, 0x24, 0x46, 0xa2, 0x69, 0x5a, 0x31, 0x4e, 0x2c, 0x36, 0xac, 0xe0, 0xe7,
0x4e, 0xc5, 0xc9, 0x16, 0x08, 0x0c, 0xe4, 0x74, 0xe2, 0x77, 0x95, 0xc8, 0x72, 0x60, 0x41, 0x71,
0x26, 0x70, 0xdf, 0x7d, 0xf7, 0x21, 0x22, 0xe8, 0x8c, 0x8f, 0xb4, 0xba, 0x26, 0x69, 0xb5, 0x27,
0x36, 0xd5, 0x4c, 0x93, 0x40, 0x4a, 0x12, 0xc9, 0x9a, 0x12, 0x29, 0x01, 0x2b, 0x68, 0xad, 0x28,
0x0e, 0x67, 0x71, 0x7d, 0x8b, 0x76, 0x84, 0xc6, 0xdc, 0x3c, 0xd9, 0x1e, 0x67, 0x29, 0x02, 0x51,
0x4b, 0xb4, 0x2c, 0x02, 0x46, 0x54, 0x59, 0xa3, 0x33, 0x6f, 0x47, 0x35, 0xb3, 0x74, 0xb2, 0x69,
0x40, 0x78, 0x14, 0xe2, 0x29, 0xc4, 0x2e, 0xd0, 0x95, 0x37, 0xe4, 0x3c, 0x4b, 0xb9, 0x11, 0x33,
0x1b, 0x42, 0x35, 0x9d, 0x3e, 0x54, 0xd0, 0x3c, 0xb0, 0xc7, 0x63, 0xeb, 0x65, 0xff, 0x8d, 0x3f,
0xf9, 0xe6, 0x9f, 0xa2, 0xbd, 0x2c, 0x6b, 0xce, 0xb9, 0x84, 0xbe, 0x81, 0x7c, 0x42, 0x1c, 0xe9,
0xa8, 0xd3, 0x5b, 0xd9, 0xbe, 0x03, 0x80, 0x2c, 0x7d, 0x2a, 0x47, 0x98, 0x3f, 0x52, 0xa5, 0x7b,
0xc8, 0xa7, 0xd0, 0xe7, 0xe2, 0x75, 0x79, 0x29, 0xb3, 0x4e, 0x0f, 0xd9, 0xb4, 0xe2, 0x4f, 0xe7,
0xcf, 0x7c, 0x1c, 0xe9, 0x29, 0x37, 0x53, 0x1a, 0xde, 0x17, 0x2e, 0x8e, 0xe3, 0x17, 0x7d, 0xa4,
0x89, 0x56, 0x35, 0x37, 0x88, 0x11, 0xd1, 0x38, 0x85, 0x2c, 0x03, 0xde, 0x14, 0xe5, 0xfa, 0x34,
0x13, 0x01, 0xc4, 0x31, 0x04, 0x59, 0x18, 0xbb, 0x60, 0x88, 0x1f, 0x7f, 0x6b, 0x9c, 0x75, 0x1f,
0xb9, 0x0b, 0xaf, 0x6f, 0x03, 0xc5, 0x91, 0xb3, 0xd8, 0x96, 0x7f, 0x91, 0xe2, 0xf0, 0x00, 0x56,
0xc2, 0xa5, 0xf5, 0x7a, 0x53, 0x1b, 0x9d, 0x0d, 0x0a, 0xda, 0xc0, 0x94, 0x08, 0xb5, 0xb9, 0x00,
0xbf, 0xe0, 0x24, 0xa6, 0xeb, 0x24, 0xb4, 0x6a, 0x09, 0xd8, 0x4e, 0x2b, 0x6d, 0x6b, 0x64, 0xaa,
0x5a, 0xb3, 0xe3, 0xfa, 0x8c, 0xb1, 0x17, 0xa6, 0xc3, 0x9a, 0x4c, 0xb4, 0x66, 0x34, 0x4f, 0x2d,
0x1d, 0x36, 0x88, 0x88, 0xa2, 0x2c, 0xeb, 0xbb, 0x67, 0x58, 0x19, 0xbf, 0xc4, 0xc2, 0xf4, 0x24,
0x93, 0xb3, 0xd3, 0xec, 0x9b, 0x8d, 0xa8, 0x14, 0x0b, 0x6c, 0xdd, 0xa6, 0xc9, 0x1e, 0xb1, 0x6c,
0x39, 0xf7, 0x26, 0xfa, 0x2a, 0xa3, 0x7c, 0xb8, 0xf7, 0x27, 0x88, 0xe3, 0x22, 0x4d, 0x9e, 0xd5,
0xe4, 0x5e, 0x36, 0x46, 0x59, 0x83, 0xb2, 0x29, 0x53, 0xee, 0x04, 0x63, 0x0d, 0x41, 0x25, 0xa0,
0x3a, 0x55, 0xa7, 0x6b, 0x28, 0x93, 0x36, 0x33, 0x3a, 0xb5, 0x65, 0x9b, 0x36, 0x94, 0x6a, 0x44,
0x5a, 0x66, 0x25, 0x22, 0xc7, 0x8e, 0x1f, 0x57, 0x6f, 0x39, 0x9f, 0x1c, 0x2b, 0x69, 0x6b, 0x38,
0xb7, 0x7b, 0x38, 0x73, 0x16, 0xa2, 0xdb, 0x6d, 0x4d, 0xad, 0x31, 0xa1, 0xa1, 0x3e, 0x5d, 0x27,
0x8a, 0x72, 0x0c, 0xac, 0x58, 0xc3, 0x5a, 0xbd, 0x97, 0xc1, 0xa3, 0x0f, 0xe0, 0x4c, 0xbe, 0x40,
0x50, 0x99, 0x60, 0xb6, 0x6a, 0xe9, 0x1a, 0x1d, 0x24, 0xbf, 0x26, 0x4b, 0xed, 0xd8, 0xd3, 0x9c,
0x2b, 0xb7, 0xf3, 0x89, 0xff, 0xec, 0x63, 0x95, 0xea, 0x28, 0xb2, 0x4c, 0xda, 0x59, 0x31, 0xed,
0x96, 0x50, 0xab, 0x49, 0x17, 0x23, 0x51, 0x9d, 0x60, 0xbe, 0x4e, 0x65, 0xaa, 0x46, 0xff, 0x68,
0x1e, 0xc7, 0x11, 0xc4, 0x9a, 0x25, 0xcd, 0x3c, 0xac, 0x05, 0x2b, 0xa8, 0x40, 0x20, 0x48, 0xca,
0x1e, 0x48, 0x2c, 0xa3, 0x11, 0xe8, 0xc7, 0x36, 0xdc, 0x59, 0xfe, 0xae, 0x5b, 0x9e, 0x10, 0xf1,
0xbb, 0xd5, 0x0f, 0xa3, 0x5a, 0x7c, 0xa5, 0x9b, 0xd5, 0x09, 0x95, 0x68, 0xd6, 0x12, 0x56, 0xf0,
0xf3, 0x21, 0xbe, 0x3f, 0x89, 0xcc, 0x1e, 0x46, 0x2a, 0x01, 0x03, 0x51, 0xcc, 0xa0, 0xa7, 0x31,
0x95, 0x7b, 0x98, 0x9e, 0x18, 0xe1, 0x70, 0xe9, 0x6a, 0x82, 0xc6, 0x0a, 0x4e, 0x73, 0x7f, 0xc4,
0x2f, 0xff, 0xa7, 0x59, 0xac, 0xdb, 0x9f, 0x16, 0x53, 0xd2, 0xd1, 0x98, 0x6b, 0x6a, 0xa1, 0xdd,
0xd7, 0x52, 0xa6, 0x46, 0xb4, 0x38, 0x4f, 0xa3, 0x96, 0x25, 0x0a, 0x72, 0xf4, 0xae, 0xf0, 0x71,
0xdc, 0x08, 0x31, 0x1d, 0x16, 0xd1, 0xaa, 0x6f, 0x04, 0x8c, 0x4d, 0x8a, 0x2a, 0x63, 0x9b, 0x14,
0x1e, 0x63, 0x55, 0x50, 0x6b, 0xb0, 0x1b, 0x94, 0xb8, 0x47, 0x5e, 0x1d, 0x90, 0xd3, 0x2e, 0xaa,
0x3e, 0x54, 0x9d, 0x0a, 0x83, 0xde, 0x51, 0xd7, 0x4f, 0x9c, 0x53, 0x81, 0xb5, 0x38, 0x9e, 0xc5,
0x09, 0xe7, 0xb1, 0x13, 0x0b, 0xb0, 0x00, 0x36, 0x48, 0x42, 0xa1, 0xf8, 0x02, 0x7d, 0x9a, 0xc1,
0xae, 0xc3, 0x2c, 0x2b, 0x3d, 0xc7, 0xba, 0x89, 0x47, 0x29, 0x8c, 0x81, 0xf5, 0x73, 0x48, 0x1c,
0xa0, 0xb4, 0x4a, 0xc9, 0x66, 0x02, 0x46, 0x68, 0x97, 0xb3, 0xca, 0x54, 0x30, 0x95, 0x59, 0x1a,
0x0b, 0x31, 0xb1, 0x1e, 0x41, 0xe7, 0x87, 0x28, 0x16, 0xe7, 0x70, 0x64, 0x3e, 0x05, 0x61, 0xdb,
0x1e, 0x9d, 0x96, 0xc7, 0x88, 0x45, 0xc5, 0xa9, 0x26, 0x4c, 0x3b, 0xb1, 0x5a, 0x2b, 0xfb, 0x67,
0x66, 0xbd, 0x47, 0x01, 0xdc, 0x8f, 0xfc, 0x78, 0x2f, 0x07, 0x3f, 0x50, 0x9c, 0xae, 0x4e, 0x67,
0x7e, 0xd0, 0xb3, 0xc2, 0x5c, 0x93, 0x78, 0x5a, 0x47, 0x93, 0xd9, 0x2b, 0x40, 0xc1, 0x49, 0xa8,
0x79, 0x2c, 0x28, 0xcf, 0x85, 0x42, 0x06, 0x0a, 0x3e, 0xd2, 0xb5, 0x06, 0x72, 0xc3, 0x28, 0x7f,
0x9a, 0x6a, 0xbd, 0x8c, 0xaa, 0x96, 0xc9, 0x14, 0x32, 0x78, 0x05, 0xbf, 0x1d, 0x5a, 0x34, 0x28,
0x53, 0x87, 0x70, 0x81, 0xb8, 0x3c, 0x4f, 0x6d, 0xc1, 0x26, 0xaf, 0x20, 0x8a, 0xa3, 0x64, 0xf3,
0x19, 0xdc, 0xe8, 0x28, 0x04, 0x8b, 0xe0, 0x06, 0xed, 0x28, 0xd7, 0xa1, 0xcd, 0x96, 0x6f, 0x44,
0x0a, 0x62, 0x69, 0x2d, 0x1b, 0xc7, 0xd0, 0x68, 0xa8, 0xdd, 0x63, 0x77, 0xcf, 0x3d, 0x05, 0x0a,
0x17, 0xe0, 0xc0, 0x53, 0x9e, 0x19, 0xdd, 0xa6, 0xbe, 0x59, 0x9d, 0x0e, 0xaf, 0x29, 0x0c, 0xa6,
0xdc, 0x48, 0x00, 0xe5, 0x42, 0xa6, 0x0b, 0xbc, 0x2e, 0x28, 0x0a, 0x0a, 0x05, 0xda, 0x05, 0x2f,
0x03, 0x8e, 0x87, 0xf2, 0x8b, 0x94, 0x0f, 0xee, 0xa7, 0x36, 0x35, 0x89, 0x58, 0x8b, 0x97, 0xf7,
0x71, 0x32, 0xe0, 0xc6, 0x0a, 0x31, 0x01, 0x71, 0xb5, 0x4a, 0xb0, 0xb0, 0x88, 0x09, 0x2c, 0xb8,
0x3d, 0x38, 0xb9, 0x33, 0xf0, 0x96, 0xf5, 0xa3, 0x5c, 0x0f, 0x4f, 0x37, 0x50, 0x8d, 0x23, 0x48,
0x5c, 0x41, 0x7b, 0x89, 0xe1, 0x4b, 0xb3, 0x9f, 0x2c, 0x69, 0xe3, 0xa1, 0xa9, 0x8d, 0x28, 0xe9,
0x38, 0x11, 0xb7, 0xc3, 0x95, 0xb1, 0xea, 0xf8, 0xf4, 0x9c, 0x73, 0x3f, 0x28, 0x9e, 0xff, 0x5d,
0x70, 0xdf, 0xf8, 0x0c, 0xac, 0xff, 0xe6, 0x8c, 0xec, 0x1d, 0x5b, 0xb6, 0xbb, 0x7c, 0x34, 0xbe,
0xaf, 0x50, 0x72, 0x3f, 0x96, 0xe8, 0x2e, 0x0d, 0x73, 0xda, 0x49, 0x98, 0xac, 0xe7, 0x26, 0x86,
0xa9, 0x9c, 0x94, 0x6b, 0x18, 0xd4, 0xe2, 0xeb, 0xd4, 0x26, 0x6b, 0xf4, 0xac, 0x1c, 0x48, 0x6a,
0x0d, 0x2b, 0x44, 0x95, 0x06, 0xc1, 0x6c, 0x05, 0xc1, 0x26, 0x85, 0x4f, 0xbe, 0x17, 0xaf, 0xcb,
0x07, 0xeb, 0xa2, 0x1c, 0xc1, 0x55, 0x0b, 0x10, 0xd4, 0x92, 0x5e, 0x99, 0x13, 0xa1, 0x33, 0x51,
0x1a, 0xe6, 0x53, 0x1f, 0xb2, 0xcd, 0xca, 0x32, 0x15, 0x20, 0x16, 0x08, 0x15, 0x84, 0xd2, 0x2a,
0x6f, 0x8c, 0x81, 0x6a, 0x4d, 0x5e, 0xdc, 0x7e, 0xcf, 0x39, 0x7f, 0x0b, 0x0f, 0x53, 0x7a, 0xdf,
0xef, 0xa1, 0xe3, 0xd2, 0x46, 0x00, 0xfe, 0xfa, 0x8b, 0x23, 0x55, 0x13, 0x39, 0x77, 0x94, 0xc7,
0x43, 0x51, 0xca, 0x24, 0x91, 0x43, 0x4c, 0x5a, 0x8b, 0x27, 0xe1, 0x33, 0x29, 0xb8, 0xa2, 0xf4,
0xf7, 0x08, 0xab, 0x5c, 0x7a, 0x57, 0x14, 0xc9, 0xe4, 0x34, 0x99, 0xbc, 0xc6, 0x2f, 0x38, 0xe4,
0x7a, 0x5d, 0xf2, 0x25, 0x9f, 0xc2, 0x60, 0x8e, 0x7c, 0x29, 0x87, 0x5f, 0xf0, 0xf0, 0x5c, 0xc1,
0xf3, 0x02, 0x5c, 0x35, 0x8f, 0x8a, 0x27, 0x51, 0x7a, 0x1e, 0x9d, 0x09, 0x50, 0x6e, 0xd8, 0x06,
0x61, 0x6d, 0x1b, 0x44, 0xd3, 0x37, 0x8c, 0x41, 0x85, 0xef, 0xd4, 0x46, 0x1c, 0xcb, 0xc4, 0xe4,
0x94, 0xfb, 0xad, 0xef, 0x1d, 0x7f, 0x38, 0xde, 0xf7, 0xfb, 0xb0, 0xea, 0xb7, 0xbe, 0x83, 0xde,
0x78, 0xcb, 0x6e, 0x0e, 0xff, 0x0f, 0xf8, 0x32, 0xcf, 0x33, 0x7b, 0x48, 0x76, 0x57, 0xa7, 0xed,
0x2d, 0x61, 0x25, 0x4a, 0x5e, 0x0b, 0x48, 0xda, 0x50, 0xb0, 0x71, 0xaa, 0x6a, 0xb3, 0xa4, 0xbd,
0x03, 0xe0, 0xe5, 0x55, 0x0b, 0x18, 0x12, 0xe1, 0xb8, 0x09, 0x81, 0x75, 0x3d, 0xd0, 0xda, 0xa2,
0x74, 0x84, 0xce, 0x04, 0xe9, 0x08, 0x51, 0x5e, 0x84, 0x72, 0x62, 0x50, 0x69, 0xeb, 0xa8, 0xf3,
0xb0, 0x3a, 0x41, 0xd8, 0x14, 0x44, 0xa0, 0x20, 0xb0, 0x2d, 0xdf, 0x30, 0x86, 0x78, 0x66, 0xce,
0xfd, 0xf1, 0xa6, 0x1d, 0xe5, 0x1f, 0x01, 0x34, 0x4a, 0x1b, 0xda, 0x2d, 0xd3, 0x85, 0xb5, 0xbf,
0x04, 0xc0, 0xd6, 0x3f, 0x3e, 0x5e, 0xaf, 0xcd, 0x98, 0x3f, 0x9f, 0x3f, 0x12, 0x3f, 0x91, 0x24,
0xb3, 0xb8, 0x0d, 0xa6, 0xd9, 0xbb, 0x6a, 0x6a, 0x47, 0xe2, 0x0e, 0x60, 0x51, 0x5b, 0x63, 0x36,
0x4c, 0xb5, 0x16, 0xb6, 0xe7, 0x49, 0x94, 0x24, 0x47, 0x96, 0x1e, 0x8c, 0xb4, 0xd6, 0x32, 0x4b,
0x5a, 0x4b, 0x88, 0x4d, 0x4c, 0xa9, 0xa1, 0x20, 0x68, 0x9b, 0x94, 0xb5, 0x50, 0x5e, 0xe4, 0xb5,
0xd7, 0x0f, 0x9e, 0x72, 0x2d, 0xc0, 0xae, 0xdf, 0x83, 0x4d, 0xb7, 0xbe, 0xde, 0x06, 0xb2, 0xf1,
0xc6, 0x47, 0xd9, 0x7d, 0x73, 0xd2, 0x43, 0x3d, 0xe3, 0x96, 0xb9, 0xb7, 0x83, 0xb2, 0xbd, 0x6e,
0xfe, 0xed, 0x70, 0x4e, 0xa9, 0x64, 0x23, 0x31, 0xa6, 0xad, 0x11, 0x1b, 0x2d, 0x05, 0x61, 0x3b,
0xcc, 0xae, 0x25, 0x64, 0xe7, 0xf7, 0x71, 0x87, 0x69, 0x46, 0x2d, 0x8d, 0x4a, 0x6b, 0x4e, 0xc7,
0xb0, 0x36, 0x99, 0x17, 0x5a, 0x54, 0xa0, 0xa0, 0x21, 0x09, 0xa0, 0x34, 0xad, 0xd4, 0xeb, 0x32,
0xf9, 0xd6, 0x78, 0xee, 0x77, 0x2e, 0xfd, 0xb3, 0x3d, 0x0b, 0x00, 0xa5, 0x8f, 0xde, 0xc6, 0x3b,
0x5e, 0x2b, 0x6c, 0xbc, 0x63, 0x9a, 0x97, 0x6f, 0x5e, 0x05, 0xc0, 0xaa, 0x6b, 0x7f, 0xfd, 0x99,
0xea, 0xb4, 0x7c, 0xaa, 0x32, 0x11, 0xc6, 0x09, 0x1d, 0x6f, 0x6e, 0xfc, 0xef, 0x18, 0x9d, 0xfe,
0xf4, 0x8e, 0xef, 0x92, 0x43, 0x69, 0x1f, 0x4c, 0xdc, 0x36, 0xa9, 0xe6, 0x41, 0x45, 0x92, 0x80,
0xa8, 0xb7, 0x41, 0x00, 0x04, 0x81, 0xcc, 0x1f, 0x3a, 0x9a, 0xfb, 0x83, 0xf3, 0xbe, 0x31, 0xf3,
0xfc, 0xee, 0x1b, 0xfa, 0x00, 0x38, 0xf5, 0xa3, 0x5f, 0x6c, 0x01, 0x71, 0x3a, 0x69, 0xe4, 0x9f,
0x3e, 0x3e, 0xcf, 0xce, 0xeb, 0x96, 0xf1, 0x9d, 0x27, 0x1f, 0x61, 0xe0, 0xa7, 0xa5, 0xbd, 0x1b,
0x2e, 0x0e, 0xa7, 0x9d, 0x8c, 0xf9, 0x90, 0x97, 0x4d, 0xe7, 0x75, 0x30, 0x57, 0xd5, 0x34, 0x01,
0x75, 0x32, 0x32, 0xd8, 0xd9, 0x69, 0x34, 0xed, 0x17, 0x3e, 0x9d, 0x1d, 0x48, 0x89, 0x97, 0x6a,
0x42, 0x6c, 0x02, 0xa2, 0xde, 0x01, 0x22, 0x4d, 0x23, 0x41, 0x28, 0x73, 0x87, 0x8e, 0xe4, 0x6e,
0xd8, 0xb4, 0x63, 0xf6, 0xaf, 0xf6, 0xfc, 0x61, 0x2f, 0x67, 0x6e, 0x7f, 0xe7, 0x0b, 0x51, 0xe7,
0xc4, 0x0f, 0xbe, 0xf3, 0x64, 0x95, 0x97, 0x6f, 0x2c, 0x71, 0xe5, 0x13, 0x13, 0x36, 0xff, 0x4f,
0x63, 0x2f, 0x6d, 0xbc, 0x60, 0x7a, 0xde, 0xf5, 0xcc, 0x45, 0x9e, 0x8f, 0x9f, 0x74, 0xc3, 0xe5,
0x24, 0x54, 0xdc, 0x2e, 0xb5, 0xef, 0xce, 0x46, 0xf4, 0x12, 0xa6, 0x7b, 0x42, 0xa3, 0xbb, 0x09,
0xc0, 0x58, 0x08, 0x40, 0x35, 0x7d, 0x22, 0x90, 0x16, 0xc5, 0x6a, 0x34, 0xd4, 0xd1, 0x83, 0xe3,
0xd9, 0xff, 0xb9, 0xf1, 0xae, 0xd9, 0xbf, 0xd8, 0xf7, 0x85, 0x5e, 0xb5, 0xee, 0xf6, 0xf9, 0x77,
0xf7, 0x7a, 0x7a, 0xf7, 0x17, 0x96, 0xb3, 0xf1, 0xab, 0xc9, 0xdb, 0xd3, 0xb7, 0xee, 0xec, 0xfd,
0xef, 0x7d, 0x23, 0xdc, 0x92, 0xeb, 0x57, 0x2b, 0xb5, 0xab, 0xd3, 0x74, 0xad, 0xda, 0x04, 0xf3,
0xc4, 0x06, 0x41, 0x93, 0x72, 0x73, 0x32, 0xc0, 0xd2, 0xe4, 0x17, 0x69, 0x88, 0x15, 0x54, 0x90,
0x46, 0xa7, 0x50, 0x92, 0xde, 0xae, 0x4d, 0x32, 0x77, 0xb5, 0xaa, 0x5e, 0x3c, 0x38, 0x9e, 0xfd,
0xec, 0x39, 0xff, 0x67, 0xe6, 0xf1, 0xbd, 0x5f, 0xe8, 0x65, 0xdd, 0x57, 0xe7, 0x7f, 0xce, 0x0b,
0x03, 0xd7, 0x0f, 0xb0, 0xf9, 0xae, 0xe4, 0xad, 0xd0, 0x6b, 0x5f, 0xec, 0x79, 0xff, 0xe0, 0x69,
0x72, 0x73, 0xbe, 0x5f, 0x5d, 0xe2, 0xe5, 0x94, 0xa7, 0x1d, 0xdd, 0x6e, 0x21, 0x35, 0x8b, 0xe7,
0x13, 0x8b, 0x69, 0x78, 0x27, 0x1d, 0xb7, 0x92, 0x0e, 0x20, 0x14, 0x54, 0xa8, 0x92, 0x3c, 0x11,
0x25, 0x77, 0x55, 0x4c, 0x0c, 0x51, 0xa4, 0xa6, 0xe6, 0xcb, 0x3c, 0xf0, 0xda, 0x81, 0xbe, 0x9b,
0x3e, 0x74, 0xcf, 0x91, 0x89, 0xd7, 0x6f, 0xea, 0x63, 0xc3, 0xf6, 0xb9, 0xff, 0xe0, 0x15, 0x8e,
0xeb, 0x86, 0xd9, 0x9c, 0x5e, 0xa4, 0x79, 0xe4, 0xaa, 0xfe, 0xe1, 0xb5, 0x17, 0xc6, 0xbf, 0xdb,
0x55, 0x52, 0x57, 0x78, 0x79, 0x39, 0x3b, 0x93, 0x07, 0xa5, 0x75, 0xfb, 0xf0, 0x4f, 0xd6, 0xe6,
0x68, 0x6a, 0x47, 0x52, 0x00, 0x46, 0x52, 0x02, 0x98, 0x68, 0x40, 0x45, 0x80, 0x11, 0x6c, 0x24,
0x04, 0x91, 0x0e, 0xc3, 0x90, 0xc7, 0xa6, 0x67, 0xf5, 0xf7, 0xd6, 0xdd, 0xbe, 0xf8, 0x97, 0xc9,
0xfe, 0x83, 0x6c, 0xde, 0x31, 0xf5, 0x8b, 0xb9, 0x54, 0xf3, 0xc6, 0x9d, 0xef, 0x43, 0x55, 0x1e,
0xe5, 0x8c, 0x5b, 0x13, 0x69, 0x77, 0xdf, 0xd4, 0x77, 0xce, 0xc0, 0xca, 0xf8, 0x57, 0xb2, 0xdd,
0xea, 0x43, 0x8e, 0x6b, 0x2f, 0xf4, 0x0b, 0xe0, 0x64, 0xd4, 0xd2, 0x66, 0x87, 0x95, 0x56, 0xa1,
0x89, 0x11, 0xc4, 0x2a, 0x54, 0x2c, 0x10, 0x2b, 0x94, 0x91, 0x94, 0xc9, 0x0a, 0x51, 0x43, 0x08,
0x23, 0xbd, 0x18, 0xc7, 0x3c, 0x5a, 0xa9, 0xe9, 0x7f, 0x3a, 0x74, 0x34, 0x7f, 0xef, 0x7b, 0xbf,
0x33, 0x79, 0xec, 0xdd, 0x5e, 0xbd, 0x7a, 0x57, 0xd7, 0x9c, 0x76, 0x5d, 0xb7, 0x9c, 0xcd, 0x3b,
0xda, 0xb7, 0x0e, 0x5e, 0xbe, 0xbe, 0xef, 0xac, 0x81, 0xd1, 0x68, 0x8b, 0x9b, 0xd1, 0xe7, 0xbb,
0xae, 0xdd, 0xe6, 0x38, 0x6c, 0xd0, 0xda, 0x16, 0xbd, 0x0c, 0xb8, 0xae, 0x4a, 0x62, 0xbb, 0x55,
0xad, 0xca, 0x4e, 0x62, 0x88, 0x03, 0x21, 0x0a, 0x04, 0x13, 0xeb, 0xb2, 0x31, 0x6a, 0xa7, 0xb1,
0x3c, 0xd5, 0x08, 0xd4, 0xb3, 0xe3, 0x13, 0x99, 0x67, 0x2e, 0xf8, 0xf6, 0xcc, 0xf8, 0xc9, 0xee,
0xc1, 0xfc, 0xc2, 0x81, 0xb4, 0x6e, 0x47, 0x5c, 0x3b, 0xc4, 0xd8, 0xd7, 0x8f, 0xb7, 0xfe, 0xfe,
0xe1, 0x65, 0x23, 0xc5, 0xd3, 0xb7, 0x2c, 0x9c, 0x5a, 0xec, 0xb7, 0x43, 0x4e, 0xd6, 0x5d, 0xae,
0x2c, 0x23, 0x62, 0xed, 0x90, 0x42, 0x7a, 0x94, 0x98, 0x0c, 0xa2, 0xb5, 0x18, 0x09, 0xb0, 0x7a,
0x11, 0xd4, 0x04, 0xc2, 0xdb, 0x51, 0x64, 0x8e, 0xcd, 0x96, 0x9d, 0x89, 0xe7, 0xf7, 0xac, 0x3c,
0xf4, 0xdb, 0xf7, 0xbf, 0x12, 0xb4, 0xd6, 0xfe, 0x7c, 0x3f, 0x63, 0x7f, 0x34, 0xfb, 0xae, 0x65,
0xfa, 0x7f, 0x4c, 0xe8, 0x21, 0x04, 0x29, 0xb0, 0x36, 0x16, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const lv_img_dsc_t img_wink_png = {
.header.always_zero = 0,
.header.w = 50,
.header.h = 50,
.data_size = 5158,
.header.cf = LV_IMG_CF_RAW_ALPHA,
.data = img_wink_png_map,
};
#endif /*LV_USE_PNG && LV_BUILD_EXAMPLES*/
+6
View File
@@ -0,0 +1,6 @@
Open a PNG image from file and variable
"""""""""""""""""""""""""""""""""""""""""""""""
.. lv_example:: libs/bmp/lv_example_png_1
:language: c
+38
View File
@@ -0,0 +1,38 @@
/**
* @file lv_example_png.h
*
*/
#ifndef LV_EXAMPLE_PNG_H
#define LV_EXAMPLE_PNG_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_png_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_PNG_H*/
+23
View File
@@ -0,0 +1,23 @@
#include "../../lv_examples.h"
#if LV_USE_PNG && LV_BUILD_EXAMPLES
/**
* Open a PNG image from a file and a variable
*/
void lv_example_png_1(void)
{
LV_IMG_DECLARE(img_wink_png);
lv_obj_t * img;
img = lv_img_create(lv_scr_act());
lv_img_set_src(img, &img_wink_png);
lv_obj_align(img, LV_ALIGN_LEFT_MID, 20, 0);
img = lv_img_create(lv_scr_act());
/* Assuming a File system is attached to letter 'A'
* E.g. set LV_USE_FS_STDIO 'A' in lv_conf.h */
lv_img_set_src(img, "A:lvgl/examples/libs/png/wink.png");
lv_obj_align(img, LV_ALIGN_RIGHT_MID, -20, 0);
}
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

+6
View File
@@ -0,0 +1,6 @@
Create a QR Code
"""""""""""""""""""""""""""""""""""""""""""""""
.. lv_example:: libs/bmp/lv_example_qrcode_1
:language: c
+38
View File
@@ -0,0 +1,38 @@
/**
* @file lv_example_qrcode.h
*
*/
#ifndef LV_EXAMPLE_QRCODE_H
#define LV_EXAMPLE_QRCODE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_qrcode_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_QRCODE_H*/
@@ -0,0 +1,32 @@
#include "../../lv_examples.h"
#if LV_USE_QRCODE && LV_BUILD_EXAMPLES
/**
* Create a QR Code
*/
void lv_example_qrcode_1(void)
{
lv_color_t bg_color = lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 5);
lv_color_t fg_color = lv_palette_darken(LV_PALETTE_BLUE, 4);
lv_obj_t * qr = lv_qrcode_create(lv_scr_act(), 150, fg_color, bg_color);
/*Set data*/
const char * data = "https://lvgl.io";
lv_qrcode_update(qr, data, strlen(data));
lv_obj_center(qr);
/*Add a border with bg_color*/
lv_obj_set_style_border_color(qr, bg_color, 0);
lv_obj_set_style_border_width(qr, 5, 0);
}
#endif
+38
View File
@@ -0,0 +1,38 @@
/**
* @file lv_example_sjpg.h
*
*/
#ifndef LV_EXAMPLE_SJPG_H
#define LV_EXAMPLE_SJPG_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_sjpg_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_SJPG_H*/
+14
View File
@@ -0,0 +1,14 @@
#include "../../lv_examples.h"
#if LV_USE_SJPG && LV_BUILD_EXAMPLES
void lv_example_sjpg_1(void)
{
lv_obj_t * wp;
wp = lv_img_create(lv_scr_act());
/* Assuming a File system is attached to letter 'A'
* E.g. set LV_USE_FS_STDIO 'A' in lv_conf.h */
lv_img_set_src(wp, "A:lvgl/examples/libs/sjpg/small_image.sjpg");
}
#endif
Binary file not shown.
+1
View File
@@ -24,6 +24,7 @@ extern "C" {
#include "event/lv_example_event.h"
#include "styles/lv_example_style.h"
#include "others/lv_example_others.h"
#include "libs/lv_example_libs.h"
/*********************
* DEFINES
+38
View File
@@ -537,6 +537,44 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
/*A layout similar to Grid in CSS.*/
#define LV_USE_GRID 1
/*---------------------
* 3rd party libraries
*--------------------*/
/*File system interfaces for common APIs
*To enable set a driver letter for that API*/
#define LV_USE_FS_STDIO '\0' /*Uses fopen, fread, etc*/
//#define LV_FS_STDIO_PATH "/home/john/" /*Set the working directory. If commented it will be "./" */
#define LV_USE_FS_POSIX '\0' /*Uses open, read, etc*/
//#define LV_FS_POSIX_PATH "/home/john/" /*Set the working directory. If commented it will be "./" */
#define LV_USE_FS_FATFS '\0' /*Uses f_open, f_read, etc*/
/*PNG decoder library*/
#define LV_USE_PNG 0
/*BMP decoder library*/
#define LV_USE_BMP 0
/* JPG + split JPG decoder library.
* Split JPG is a custom format optimized for embedded systems. */
#define LV_USE_SJPG 0
/*GIF decoder library*/
#define LV_USE_GIF 0
/*QR code library*/
#define LV_USE_QRCODE 0
/*FreeType library*/
#define LV_USE_FREETYPE 0
#if LV_USE_FREETYPE
/*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
# define LV_FREETYPE_CACHE_SIZE (16 * 1024)
#endif
/*==================
* EXAMPLES
*==================*/
+1
View File
@@ -71,6 +71,7 @@ extern "C" {
#include "src/extra/layouts/lv_layouts.h"
#include "src/extra/themes/lv_themes.h"
#include "src/extra/others/lv_others.h"
#include "src/extra/libs/lv_libs.h"
/*********************
* DEFINES
+138
View File
@@ -0,0 +1,138 @@
##################################################################
# sjpeg converter script version 1.0
# Dependencies: (PYTHON-3)
##################################################################
SJPG_FILE_FORMAT_VERSION = "V1.00" #
JPEG_SPLIT_HEIGHT = 16
##################################################################
import math, os, sys, time
from PIL import Image
OUTPUT_FILE_NAME = ""
INPUT_FILE = ""
if len(sys.argv) == 2:
INPUT_FILE = sys.argv[1]
OUTPUT_FILE_NAME = INPUT_FILE.split("/")[-1].split("\\")[-1].split(".")[0]
else:
print("usage:\n\t python " + sys.argv[0] + " input_file.jpg")
sys.exit(0)
try:
im = Image.open(INPUT_FILE)
except:
print("\nFile not found!")
sys.exit(0)
print("\nConversion started...\n")
start_time = time.time()
width, height = im.size
print("Input:")
print("\t" + INPUT_FILE)
print("\tRES = " + str(width) + " x " + str(height) + '\n')
lenbuf = []
block_size = JPEG_SPLIT_HEIGHT;
spilts = math.ceil(height/block_size)
c_code = '''//LVGL SJPG C ARRAY\n#include "lvgl/lvgl.h"\n\nconst uint8_t ''' + OUTPUT_FILE_NAME + '''_map[] = {\n'''
sjpeg_data = bytearray()
sjpeg = bytearray()
row_remaining = height;
for i in range(spilts):
if row_remaining < block_size:
crop = im.crop((0, i*block_size, width, row_remaining + i*block_size))
else:
crop = im.crop((0, i*block_size, width, block_size + i*block_size))
row_remaining = row_remaining - block_size;
crop.save(str(i)+".jpg", quality=90)
for i in range(spilts):
f = open(str(i)+".jpg", "rb")
a = f.read()
f.close()
sjpeg_data = sjpeg_data + a
lenbuf.append(len(a))
header = bytearray()
#4 BYTES
header = header + bytearray("_SJPG__".encode("UTF-8"));
#6 BYTES VERSION
header = header + bytearray(("\x00" + SJPG_FILE_FORMAT_VERSION + "\x00").encode("UTF-8"));
#WIDTH 2 BYTES
header = header + width.to_bytes(2, byteorder='little');
#HEIGHT 2 BYTES
header = header + height.to_bytes(2, byteorder='little');
#NUMBER OF ITEMS 2 BYTES
header = header + spilts.to_bytes(2, byteorder='little');
#NUMBER OF ITEMS 2 BYTES
header = header + int(JPEG_SPLIT_HEIGHT).to_bytes(2, byteorder='little');
for item_len in lenbuf:
# WIDTH 2 BYTES
header = header + item_len.to_bytes(2, byteorder='little');
data = bytearray()
sjpeg = header + sjpeg_data;
if 1:
for i in range(len(lenbuf)):
os.remove(str(i) + ".jpg")
f = open(OUTPUT_FILE_NAME+".sjpg","wb");
f.write(sjpeg)
f.close()
new_line_threshold = 0
for i in range(len(sjpeg)):
c_code = c_code + "\t" + str(hex(sjpeg[i])) + ","
new_line_threshold = new_line_threshold + 1
if (new_line_threshold >= 16):
c_code = c_code + "\n"
new_line_threshold = 0
c_code = c_code + "\n};\n\nlv_img_dsc_t "
c_code = c_code + OUTPUT_FILE_NAME + " = {\n"
c_code = c_code + "\t.header.always_zero = 0,\n"
c_code = c_code + "\t.header.w = " + str(width) + ",\n"
c_code = c_code + "\t.header.h = " + str(height) + ",\n"
c_code = c_code + "\t.data_size = " + str(len(sjpeg)) + ",\n"
c_code = c_code + "\t.header.cf = LV_IMG_CF_RAW,\n"
c_code = c_code + "\t.data = " + OUTPUT_FILE_NAME+"_map" + ",\n};"
f = open(OUTPUT_FILE_NAME + '.c', 'w')
f.write(c_code)
f.close()
time_taken = (time.time() - start_time)
print("Output:")
print("\tTime taken = " + str(round(time_taken,2)) + " sec")
print("\tbin size = " + str(round(len(sjpeg)/1024, 1)) + " KB" )
print("\t" + OUTPUT_FILE_NAME + ".sjpg\t(bin file)" + "\n\t" + OUTPUT_FILE_NAME + ".c\t\t(c array)")
print("\nAll good!")
+228
View File
@@ -0,0 +1,228 @@
/**
* @file lv_bmp.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../../lvgl.h"
#if LV_USE_BMP
#include <string.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_fs_file_t f;
unsigned int px_offset;
int px_width;
int px_height;
unsigned int bpp;
int row_size_bytes;
} bmp_dsc_t;
/**********************
* STATIC PROTOTYPES
**********************/
static lv_res_t decoder_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header);
static lv_res_t decoder_open(lv_img_decoder_t * dec, lv_img_decoder_dsc_t * dsc);
static lv_res_t decoder_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc,
lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);
static void decoder_close(lv_img_decoder_t * dec, lv_img_decoder_dsc_t * dsc);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_bmp_init(void)
{
lv_img_decoder_t * dec = lv_img_decoder_create();
lv_img_decoder_set_info_cb(dec, decoder_info);
lv_img_decoder_set_open_cb(dec, decoder_open);
lv_img_decoder_set_read_line_cb(dec, decoder_read_line);
lv_img_decoder_set_close_cb(dec, decoder_close);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Get info about a PNG image
* @param src can be file name or pointer to a C array
* @param header store the info here
* @return LV_RES_OK: no error; LV_RES_INV: can't get the info
*/
static lv_res_t decoder_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)
{
LV_UNUSED(decoder);
lv_img_src_t src_type = lv_img_src_get_type(src); /*Get the source type*/
/*If it's a BMP file...*/
if(src_type == LV_IMG_SRC_FILE) {
const char * fn = src;
if(!strcmp(&fn[strlen(fn) - 3], "bmp")) { /*Check the extension*/
/*Save the data in the header*/
lv_fs_file_t f;
lv_fs_res_t res = lv_fs_open(&f, src, LV_FS_MODE_RD);
if(res != LV_FS_RES_OK) return LV_RES_INV;
uint8_t headers[54];
lv_fs_read(&f, headers, 54, NULL);
uint32_t w;
uint32_t h;
memcpy(&w, headers + 18, 4);
memcpy(&h, headers + 22, 4);
header->w = w;
header->h = h;
header->always_zero = 0;
lv_fs_close(&f);
#if LV_COLOR_DEPTH == 32
uint16_t bpp;
memcpy(&bpp, headers + 28, 2);
header->cf = bpp == 32 ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;
#else
header->cf = LV_IMG_CF_TRUE_COLOR;
#endif
return LV_RES_OK;
}
}
/* BMP file as data not supported for simplicity.
* Convert them to LVGL compatible C arrays directly. */
else if(src_type == LV_IMG_SRC_VARIABLE) {
return LV_RES_INV;
}
return LV_RES_INV; /*If didn't succeeded earlier then it's an error*/
}
/**
* Open a PNG image and return the decided image
* @param src can be file name or pointer to a C array
* @param style style of the image object (unused now but certain formats might use it)
* @return pointer to the decoded image or `LV_IMG_DECODER_OPEN_FAIL` if failed
*/
static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
{
LV_UNUSED(decoder);
/*If it's a PNG file...*/
if(dsc->src_type == LV_IMG_SRC_FILE) {
const char * fn = dsc->src;
if(strcmp(&fn[strlen(fn) - 3], "bmp")) return LV_RES_INV; /*Check the extension*/
bmp_dsc_t b;
memset(&b, 0x00, sizeof(b));
lv_fs_res_t res = lv_fs_open(&b.f, dsc->src, LV_FS_MODE_RD);
if(res == LV_RES_OK) return LV_RES_INV;
uint8_t header[54];
lv_fs_read(&b.f, header, 54, NULL);
if (0x42 != header[0] || 0x4d != header[1]) {
return LV_RES_INV;
}
memcpy(&b.px_offset, header + 10, 4);
memcpy(&b.px_width, header + 18, 4);
memcpy(&b.px_height, header + 22, 4);
memcpy(&b.bpp, header + 28, 2);
b.row_size_bytes = (b.bpp * b.px_width) / 8;
dsc->user_data = lv_mem_alloc(sizeof(bmp_dsc_t));
LV_ASSERT_MALLOC(dsc->user_data);
if(dsc->user_data == NULL) return LV_RES_INV;
memcpy(dsc->user_data, &b, sizeof(b));
dsc->img_data = NULL;
return LV_RES_OK;
}
/* BMP file as data not supported for simplicity.
* Convert them to LVGL compatible C arrays directly. */
else if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
return LV_RES_INV;
}
return LV_RES_INV; /*If not returned earlier then it failed*/
}
static lv_res_t decoder_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc,
lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf)
{
LV_UNUSED(decoder);
bmp_dsc_t * b = dsc->user_data;
y = (b->px_height - 1) - y; /*BMP images are stored upside down*/
uint32_t p = b->px_offset + b->row_size_bytes * y;
p += x * (b->bpp / 8);
lv_fs_seek(&b->f, p, LV_FS_SEEK_SET);
lv_fs_read(&b->f, buf, len * (b->bpp / 8), NULL);
#if LV_COLOR_DEPTH == 32
if(b->bpp == 32) {
lv_coord_t i;
for(i = 0; i < len; i++) {
uint8_t b0 = buf[i * 4];
uint8_t b1 = buf[i * 4 + 1];
uint8_t b2 = buf[i * 4 + 2];
uint8_t b3 = buf[i * 4 + 3];
lv_color32_t *c = (lv_color32_t*)&buf[i*4];
c->ch.red = b2;
c->ch.green = b1;
c->ch.blue = b0;
c->ch.alpha = b3;
}
}
if(b->bpp == 24) {
lv_coord_t i;
for(i = len - 1; i >= 0; i--) {
uint8_t * t = &buf[i * 3];
lv_color32_t *c = (lv_color32_t*)&buf[i*4];
c->ch.red = t[2];
c->ch.green = t[1];
c->ch.blue = t[0];
c->ch.alpha = 0xff;
}
}
#endif
return LV_RES_OK;
}
/**
* Free the allocated resources
*/
static void decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
{
LV_UNUSED(decoder);
bmp_dsc_t * b = dsc->user_data;
lv_fs_close(&b->f);
lv_mem_free(dsc->user_data);
}
#endif /*LV_USE_BMP*/
+42
View File
@@ -0,0 +1,42 @@
/**
* @file lv_templ.h
*
*/
#ifndef LV_BMP_H
#define LV_BMP_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../../lv_conf_internal.h"
#if LV_USE_BMP
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_bmp_init(void);
/**********************
* MACROS
**********************/
#endif /*LV_USE_BMP*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_BMP_H*/
Binary file not shown.
+480
View File
@@ -0,0 +1,480 @@
/**
* @file lv_freetype.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_freetype.h"
#if LV_USE_FREETYPE
#include "ft2build.h"
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_CACHE_H
#include FT_SIZES_H
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
char * name;
} lv_face_info_t;
typedef struct {
lv_ll_t face_ll;
} lv_faces_control_t;
typedef struct {
#if LV_FREETYPE_CACHE_SIZE >= 0
void * face_id;
#else
FT_Size size;
#endif
lv_font_t * font;
uint16_t style;
uint16_t height;
} lv_font_fmt_ft_dsc_t;
/**********************
* STATIC PROTOTYPES
**********************/
#if LV_FREETYPE_CACHE_SIZE >= 0
static FT_Error font_face_requester(FTC_FaceID face_id,
FT_Library library_is, FT_Pointer req_data, FT_Face * aface);
static bool lv_ft_font_init_cache(lv_ft_info_t * info);
static void lv_ft_font_destroy_cache(lv_font_t * font);
static bool lv_ft_font_init_cache(lv_ft_info_t * info);
static void lv_ft_font_destroy_cache(lv_font_t * font);
#else
static FT_Face face_find_in_list(lv_ft_info_t * info);
static void face_add_to_list(FT_Face face);
static void face_remove_from_list(FT_Face face);
static void face_generic_finalizer(void * object);
static bool lv_ft_font_init_nocache(lv_ft_info_t * info);
static void lv_ft_font_destroy_nocache(lv_font_t * font);
#endif
/**********************
* STATIC VARIABLES
**********************/
static FT_Library library;
#if LV_FREETYPE_CACHE_SIZE >= 0
static FTC_Manager cache_manager;
static FTC_CMapCache cmap_cache;
static FTC_SBitCache sbit_cache;
static FTC_SBit sbit;
#else
static lv_faces_control_t face_control;
#endif
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes)
{
FT_Error error = FT_Init_FreeType(&library);
if(error) {
LV_LOG_ERROR("init freeType error(%d)", error);
return false;
}
#if LV_FREETYPE_CACHE_SIZE >= 0
error = FTC_Manager_New(library, max_faces, max_sizes,
max_bytes, font_face_requester, NULL, &cache_manager);
if(error) {
FT_Done_FreeType(library);
LV_LOG_ERROR("Failed to open cache manager");
return false;
}
error = FTC_CMapCache_New(cache_manager, &cmap_cache);
if(error) {
LV_LOG_ERROR("Failed to open Cmap Cache");
goto Fail;
}
error = FTC_SBitCache_New(cache_manager, &sbit_cache);
if(error) {
LV_LOG_ERROR("Failed to open sbit cache");
goto Fail;
}
return true;
Fail:
FTC_Manager_Done(cache_manager);
FT_Done_FreeType(library);
return false;
#else
LV_UNUSED(max_faces);
LV_UNUSED(max_sizes);
LV_UNUSED(max_bytes);
_lv_ll_init(&face_control.face_ll, sizeof(FT_Face *));
return true;
#endif/* LV_FREETYPE_CACHE_SIZE */
}
void lv_freetype_destroy(void)
{
#if LV_FREETYPE_CACHE_SIZE >= 0
FTC_Manager_Done(cache_manager);
#endif
FT_Done_FreeType(library);
}
bool lv_ft_font_init(lv_ft_info_t * info)
{
#if LV_FREETYPE_CACHE_SIZE >= 0
return lv_ft_font_init_cache(info);
#else
return lv_ft_font_init_nocache(info);
#endif
}
void lv_ft_font_destroy(lv_font_t * font)
{
#if LV_FREETYPE_CACHE_SIZE >= 0
lv_ft_font_destroy_cache(font);
#else
lv_ft_font_destroy_nocache(font);
#endif
}
/**********************
* STATIC FUNCTIONS
**********************/
#if LV_FREETYPE_CACHE_SIZE >= 0
static FT_Error font_face_requester(FTC_FaceID face_id,
FT_Library library_is, FT_Pointer req_data, FT_Face * aface)
{
LV_UNUSED(library_is);
LV_UNUSED(req_data);
lv_face_info_t * info = (lv_face_info_t *)face_id;
FT_Error error = FT_New_Face(library, info->name, 0, aface);
if(error) {
LV_LOG_ERROR("FT_New_Face error:%d\n", error);
return error;
}
return FT_Err_Ok;
}
static bool get_glyph_dsc_cb_cache(const lv_font_t * font,
lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
{
LV_UNUSED(unicode_letter_next);
if(unicode_letter < 0x20) {
dsc_out->adv_w = 0;
dsc_out->box_h = 0;
dsc_out->box_w = 0;
dsc_out->ofs_x = 0;
dsc_out->ofs_y = 0;
dsc_out->bpp = 0;
return true;
}
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc);
FT_Face face;
FTC_ImageTypeRec desc_sbit_type;
FTC_FaceID face_id = (FTC_FaceID)dsc->face_id;
FTC_Manager_LookupFace(cache_manager, face_id, &face);
desc_sbit_type.face_id = face_id;
desc_sbit_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
desc_sbit_type.height = dsc->height;
desc_sbit_type.width = dsc->height;
FT_UInt charmap_index = FT_Get_Charmap_Index(face->charmap);
FT_UInt glyph_index = FTC_CMapCache_Lookup(cmap_cache, face_id, charmap_index, unicode_letter);
FT_Error error = FTC_SBitCache_Lookup(sbit_cache, &desc_sbit_type, glyph_index, &sbit, NULL);
if(error) {
LV_LOG_ERROR("SBitCache_Lookup error");
}
dsc_out->adv_w = sbit->xadvance;
dsc_out->box_h = sbit->height; /*Height of the bitmap in [px]*/
dsc_out->box_w = sbit->width; /*Width of the bitmap in [px]*/
dsc_out->ofs_x = sbit->left; /*X offset of the bitmap in [pf]*/
dsc_out->ofs_y = sbit->top - sbit->height; /*Y offset of the bitmap measured from the as line*/
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/
return true;
}
static const uint8_t * get_glyph_bitmap_cb_cache(const lv_font_t * font, uint32_t unicode_letter)
{
LV_UNUSED(font);
LV_UNUSED(unicode_letter);
return (const uint8_t *)sbit->buffer;
}
static bool lv_ft_font_init_cache(lv_ft_info_t * info)
{
lv_font_fmt_ft_dsc_t * dsc = lv_mem_alloc(sizeof(lv_font_fmt_ft_dsc_t));
if(dsc == NULL) return false;
dsc->font = lv_mem_alloc(sizeof(lv_font_t));
if(dsc->font == NULL) {
lv_mem_free(dsc);
return false;
}
lv_face_info_t * face_info = NULL;
face_info = lv_mem_alloc(sizeof(lv_face_info_t) + strlen(info->name) + 1);
if(face_info == NULL) {
goto Fail;
}
face_info->name = ((char *)face_info) + sizeof(lv_face_info_t);
strcpy(face_info->name, info->name);
dsc->face_id = face_info;
dsc->height = info->weight;
dsc->style = info->style;
/* use to get font info */
FT_Size face_size;
struct FTC_ScalerRec_ scaler;
scaler.face_id = (FTC_FaceID)dsc->face_id;
scaler.width = info->weight;
scaler.height = info->weight;
scaler.pixel = 1;
FT_Error error = FTC_Manager_LookupSize(cache_manager, &scaler, &face_size);
if(error) {
lv_mem_free(face_info);
LV_LOG_ERROR("Failed to LookupSize");
goto Fail;
}
lv_font_t * font = dsc->font;
font->dsc = dsc;
font->get_glyph_dsc = get_glyph_dsc_cb_cache;
font->get_glyph_bitmap = get_glyph_bitmap_cb_cache;
font->subpx = LV_FONT_SUBPX_NONE;
font->line_height = (face_size->face->size->metrics.height >> 6);
font->base_line = -(face_size->face->size->metrics.descender >> 6);
font->underline_position = face_size->face->underline_position;
font->underline_thickness = face_size->face->underline_thickness;
/* return to user */
info->font = font;
return true;
Fail:
lv_mem_free(dsc->font);
lv_mem_free(dsc);
return false;
}
void lv_ft_font_destroy_cache(lv_font_t * font)
{
if(font == NULL) {
return;
}
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc);
if(dsc) {
lv_mem_free(dsc->face_id);
lv_mem_free(dsc->font);
lv_mem_free(dsc);
}
}
#else/* LV_FREETYPE_CACHE_SIZE */
static FT_Face face_find_in_list(lv_ft_info_t * info)
{
lv_face_info_t * face_info;
FT_Face * pface = _lv_ll_get_head(&face_control.face_ll);
while(pface) {
face_info = (lv_face_info_t *)(*pface)->generic.data;
if(strcmp(face_info->name, info->name) == 0) {
return *pface;
}
pface = _lv_ll_get_next(&face_control.face_ll, pface);
}
return NULL;
}
static void face_add_to_list(FT_Face face)
{
FT_Face * pface;
pface = (FT_Face *)_lv_ll_ins_tail(&face_control.face_ll);
*pface = face;
}
static void face_remove_from_list(FT_Face face)
{
FT_Face * pface = _lv_ll_get_head(&face_control.face_ll);
while(pface) {
if(*pface == face) {
_lv_ll_remove(&face_control.face_ll, pface);
lv_mem_free(pface);
break;
}
pface = _lv_ll_get_next(&face_control.face_ll, pface);
}
}
static void face_generic_finalizer(void * object)
{
FT_Face face = (FT_Face)object;
face_remove_from_list(face);
if(face->generic.data) {
lv_face_info_t * face_info = (lv_face_info_t *)face->generic.data;
lv_mem_free(face_info);
}
LV_LOG_INFO("face finalizer(%p)\n", face);
}
static bool get_glyph_dsc_cb_nocache(const lv_font_t * font,
lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
{
LV_UNUSED(unicode_letter_next);
if(unicode_letter < 0x20) {
dsc_out->adv_w = 0;
dsc_out->box_h = 0;
dsc_out->box_w = 0;
dsc_out->ofs_x = 0;
dsc_out->ofs_y = 0;
dsc_out->bpp = 0;
return true;
}
FT_Error error;
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc);
FT_Face face = dsc->size->face;
FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter);
if(face->size != dsc->size) {
FT_Activate_Size(dsc->size);
}
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
if(error) {
return false;
}
error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
if(error) {
return false;
}
dsc_out->adv_w = (face->glyph->metrics.horiAdvance >> 6);
dsc_out->box_h = face->glyph->bitmap.rows; /*Height of the bitmap in [px]*/
dsc_out->box_w = face->glyph->bitmap.width; /*Width of the bitmap in [px]*/
dsc_out->ofs_x = face->glyph->bitmap_left; /*X offset of the bitmap in [pf]*/
dsc_out->ofs_y = face->glyph->bitmap_top -
face->glyph->bitmap.rows; /*Y offset of the bitmap measured from the as line*/
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/
return true;
}
static const uint8_t * get_glyph_bitmap_cb_nocache(const lv_font_t * font, uint32_t unicode_letter)
{
LV_UNUSED(unicode_letter);
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc);
FT_Face face = dsc->size->face;
return (const uint8_t *)(face->glyph->bitmap.buffer);
}
static bool lv_ft_font_init_nocache(lv_ft_info_t * info)
{
lv_font_fmt_ft_dsc_t * dsc = lv_mem_alloc(sizeof(lv_font_fmt_ft_dsc_t));
if(dsc == NULL) return false;
dsc->font = lv_mem_alloc(sizeof(lv_font_t));
if(dsc->font == NULL) {
lv_mem_free(dsc);
return false;
}
lv_face_info_t * face_info = NULL;
FT_Face face = face_find_in_list(info);
if(face == NULL) {
face_info = lv_mem_alloc(sizeof(lv_face_info_t) + strlen(info->name) + 1);
if(face_info == NULL) {
goto Fail;
}
FT_Error error = FT_New_Face(library, info->name, 0, &face);
if(error) {
lv_mem_free(face_info);
LV_LOG_WARN("create face error(%d)", error);
goto Fail;
}
/* link face and face info */
face_info->name = ((char *)face_info) + sizeof(lv_face_info_t);
strcpy(face_info->name, info->name);
face->generic.data = face_info;
face->generic.finalizer = face_generic_finalizer;
face_add_to_list(face);
}
else {
FT_Size size;
FT_Error error = FT_New_Size(face, &size);
if(error) {
goto Fail;
}
FT_Activate_Size(size);
FT_Reference_Face(face);
}
FT_Set_Pixel_Sizes(face, 0, info->weight);
dsc->size = face->size;
dsc->height = info->weight;
dsc->style = info->style;
lv_font_t * font = dsc->font;
font->dsc = dsc;
font->get_glyph_dsc = get_glyph_dsc_cb_nocache;
font->get_glyph_bitmap = get_glyph_bitmap_cb_nocache;
font->line_height = (face->size->metrics.height >> 6);
font->base_line = -(face->size->metrics.descender >> 6);
font->underline_position = face->underline_position;
font->underline_thickness = face->underline_thickness;
font->subpx = LV_FONT_SUBPX_NONE;
info->font = font;
return true;
Fail:
lv_mem_free(dsc->font);
lv_mem_free(dsc);
return false;
}
static void lv_ft_font_destroy_nocache(lv_font_t * font)
{
if(font == NULL) {
return;
}
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc);
if(dsc) {
FT_Face face = dsc->size->face;
FT_Done_Size(dsc->size);
FT_Done_Face(face);
lv_mem_free(dsc->font);
lv_mem_free(dsc);
}
}
#endif/* LV_FREETYPE_CACHE_SIZE */
#endif /*LV_USE_FREETYPE*/
+81
View File
@@ -0,0 +1,81 @@
/**
* @file lv_freetype.h
*
*/
#ifndef LV_FREETYPE_H
#define LV_FREETYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../../lvgl.h"
#if LV_USE_FREETYPE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef enum {
FT_FONT_STYLE_NORMAL = 0,
FT_FONT_STYLE_ITALIC = 1 << 0,
FT_FONT_STYLE_BOLD = 1 << 1
} LV_FT_FONT_STYLE;
typedef struct {
const char * name; /* The name of the font file */
lv_font_t * font; /* point to lvgl font */
uint16_t weight; /* font size */
uint16_t style; /* font style */
} lv_ft_info_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* init freetype library
* @param max_faces Maximum number of opened FT_Face objects managed by this cache instance. Use 0 for defaults.
* @param max_sizes Maximum number of opened FT_Size objects managed by this cache instance. Use 0 for defaults.
* @param max_bytes Maximum number of bytes to use for cached data nodes. Use 0 for defaults.
* Note that this value does not account for managed FT_Face and FT_Size objects.
* @return true on success, otherwise false.
*/
bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes);
/**
* Destroy freetype library
*/
void lv_freetype_destroy(void);
/**
* Creates a font with info parameter specified.
* @param info See lv_ft_info_t for details.
* when success, lv_ft_info_t->font point to the font you created.
* @return true on success, otherwise false.
*/
bool lv_ft_font_init(lv_ft_info_t * info);
/**
* Destroy a font that has been created.
* @param font pointer to font.
*/
void lv_ft_font_destroy(lv_font_t * font);
/**********************
* MACROS
**********************/
#endif /*LV_USE_FREETYPE*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_FREETYPE_H */
+258
View File
@@ -0,0 +1,258 @@
/**
* @file lv_fs_fatfs.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../../lvgl.h"
#if LV_USE_FS_FATFS != '\0'
#include "ff.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void fs_init(void);
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path);
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * dir_p, char *fn);
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * dir_p);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_fs_if_fatfs_init(void)
{
/*----------------------------------------------------
* Initialize your storage device and File System
* -------------------------------------------------*/
fs_init();
/*---------------------------------------------------
* Register the file system interface in LittlevGL
*--------------------------------------------------*/
/* Add a simple drive to open images */
static lv_fs_drv_t fs_drv; /*A driver descriptor*/
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.letter = LV_USE_FS_FATFS;
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
fs_drv.read_cb = fs_read;
fs_drv.write_cb = fs_write;
fs_drv.seek_cb = fs_seek;
fs_drv.tell_cb = fs_tell;
fs_drv.dir_close_cb = fs_dir_close;
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
lv_fs_drv_register(&fs_drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
/* Initialize your Storage device and File system. */
static void fs_init(void)
{
/* Initialize the SD card and FatFS itself.
* Better to do it in your code to keep this library utouched for easy updating*/
}
/**
* Open a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
uint8_t flags = 0;
if(mode == LV_FS_MODE_WR) flags = FA_WRITE | FA_OPEN_ALWAYS;
else if(mode == LV_FS_MODE_RD) flags = FA_READ;
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = FA_READ | FA_WRITE | FA_OPEN_ALWAYS;
FIL * f = lv_mem_alloc(sizeof(FIL));
if(f == NULL) return NULL;
FRESULT res = f_open(f, path, flags);
if(res == FR_OK) {
f_lseek(f, 0);
return f;
} else {
return NULL;
}
}
/**
* Close an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
{
f_close(file_p);
return LV_FS_RES_OK;
}
/**
* Read data from an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
FRESULT res = f_read(file_p, buf, btr, (UINT*)br);
if(res == FR_OK) return LV_FS_RES_OK;
else return LV_FS_RES_UNKNOWN;
}
/**
* Write into a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param buf pointer to a buffer with the bytes to write
* @param btr Bytes To Write
* @param br the number of real written bytes (Bytes Written). NULL if unused.
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{
FRESULT res = f_write(file_p, buf, btw, (UINT*)bw);
if(res == FR_OK) return LV_FS_RES_OK;
else return LV_FS_RES_UNKNOWN;
}
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open )
* @param pos the new position of read write pointer
* @param whence only LV_SEEK_SET is supported
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
{
LV_UNUSED(whence);
f_lseek(file_p, pos);
return LV_FS_RES_OK;
}
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
*pos_p = f_tell(((FIL *)file_p));
return LV_FS_RES_OK;
}
/**
* Initialize a 'fs_read_dir_t' variable for directory reading
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to a 'fs_read_dir_t' variable
* @param path path to a directory
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path)
{
DIR * d = lv_mem_alloc(sizeof(DIR));
if(d == NULL) return NULL;
FRESULT res = f_opendir(d, path);
if(res != FR_OK) {
lv_mem_free(d);
d = NULL;
}
return d;
}
/**
* Read the next filename form a directory.
* The name of the directories will begin with '/'
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to an initialized 'fs_read_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * dir_p, char *fn)
{
FRESULT res;
FILINFO fno;
fn[0] = '\0';
do {
res = f_readdir(dir_p, &fno);
if(res != FR_OK) return LV_FS_RES_UNKNOWN;
if(fno.fattrib & AM_DIR) {
fn[0] = '/';
strcpy(&fn[1], fno.fname);
}
else strcpy(fn, fno.fname);
} while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
return LV_FS_RES_OK;
}
/**
* Close the directory reading
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to an initialized 'fs_read_dir_t' variable
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * dir_p)
{
f_closedir(dir_p);
return LV_FS_RES_OK;
}
#endif /*LV_USE_FS_FATFS*/
+50
View File
@@ -0,0 +1,50 @@
/**
* @file lv_fs_libs.h
*
*/
#ifndef LV_FS_LIBS_H
#define LV_FS_LIBS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
#if LV_USE_FS_FATFS != '\0'
void lv_fs_fatfs_init(void);
#endif
#if LV_USE_FS_STDIO != '\0'
void lv_fs_stdio_init(void);
#endif
#if LV_USE_FS_POSIX != '\0'
void lv_fs_posix_init(void);
#endif
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_FS_LIBS_H*/
+334
View File
@@ -0,0 +1,334 @@
/**
* @file lv_fs_posix.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../../lvgl.h"
#if LV_USE_FS_POSIX != '\0'
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#endif
/*********************
* DEFINES
*********************/
#ifndef LV_FS_POSIX_PATH
# ifndef WIN32
# define LV_FS_POSIX_PATH "./" /*Project root*/
# else
# define LV_FS_POSIX_PATH ".\\" /*Project root*/
# endif
#endif /*LV_FS_PATH*/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path);
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * dir_p, char *fn);
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * dir_p);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Register a driver for the File system interface
*/
void lv_fs_posix_init(void)
{
/*---------------------------------------------------
* Register the file system interface in LittlevGL
*--------------------------------------------------*/
/* Add a simple drive to open images */
static lv_fs_drv_t fs_drv; /*A driver descriptor*/
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.letter = LV_USE_FS_POSIX;
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
fs_drv.read_cb = fs_read;
fs_drv.write_cb = fs_write;
fs_drv.seek_cb = fs_seek;
fs_drv.tell_cb = fs_tell;
fs_drv.dir_close_cb = fs_dir_close;
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
lv_fs_drv_register(&fs_drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Open a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
(void) drv; /*Unused*/
errno = 0;
uint32_t flags = 0;
if(mode == LV_FS_MODE_WR) flags = O_WRONLY;
else if(mode == LV_FS_MODE_RD) flags = O_RDONLY;
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = O_RDWR;
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
sprintf(buf, LV_FS_POSIX_PATH "%s", path);
int f = open(buf, flags);
if(f < 0) return NULL;
/*Be sure we are the beginning of the file*/
lseek(f, 0, SEEK_SET);
int * fp = lv_mem_alloc(sizeof(int));
if(fp == NULL) return NULL;
*fp = f;
return fp;
}
/**
* Close an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
{
(void) drv; /*Unused*/
int * fp = file_p;
close(*fp);
lv_mem_free(file_p);
return LV_FS_RES_OK;
}
/**
* Read data from an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
(void) drv; /*Unused*/
int * fp = file_p;
*br = read(*fp, buf, btr);
return LV_FS_RES_OK;
}
/**
* Write into a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param buf pointer to a buffer with the bytes to write
* @param btr Bytes To Write
* @param br the number of real written bytes (Bytes Written). NULL if unused.
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{
(void) drv; /*Unused*/
int * fp = file_p;
*bw = write(*fp, buf, btw);
return LV_FS_RES_OK;
}
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open )
* @param pos the new position of read write pointer
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
{
(void) drv; /*Unused*/
int * fp = file_p;
lseek(*fp, pos, whence);
return LV_FS_RES_OK;
}
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
(void) drv; /*Unused*/
int * fp = file_p;
*pos_p = lseek(*fp, 0, SEEK_CUR);
return LV_FS_RES_OK;
}
#ifdef WIN32
static char next_fn[256];
#endif
/**
* Initialize a 'fs_read_dir_t' variable for directory reading
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to a 'fs_read_dir_t' variable
* @param path path to a directory
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path)
{
LV_UNUSED(drv);
#ifndef WIN32
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
sprintf(buf, LV_FS_POSIX_PATH "/%s", path);
return opendir(buf);
#else
HANDLE d = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA fdata;
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
sprintf(buf, LV_FS_PC_PATH "\\%s\\*", path);
strcpy(next_fn, "");
d = FindFirstFile(buf, &fdata);
do {
if (strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) {
continue;
} else {
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
sprintf(next_fn, "/%s", fdata.cFileName);
} else {
sprintf(next_fn, "%s", fdata.cFileName);
}
break;
}
} while(FindNextFileA(d, &fdata));
return d;
#endif
}
/**
* Read the next filename form a directory.
* The name of the directories will begin with '/'
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to an initialized 'fs_read_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * dir_p, char *fn)
{
LV_UNUSED(drv);
LV_UNUSED(dir_p);
LV_UNUSED(fn);
// #ifndef WIN32
// struct dirent *entry;
// do {
// entry = readdir(dir_p);
// if(entry) {
// if(entry->d_type == DT_DIR) sprintf(fn, "/%s", entry->d_name);
// else strcpy(fn, entry->d_name);
// } else {
// strcpy(fn, "");
// }
// } while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
// #else
// strcpy(fn, next_fn);
// strcpy(next_fn, "");
// WIN32_FIND_DATA fdata;
// if(FindNextFile(dir_p, &fdata) == false) return LV_FS_RES_OK;
// do {
// if (strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) {
// continue;
// } else {
// if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
// {
// sprintf(next_fn, "/%s", fdata.cFileName);
// } else {
// sprintf(next_fn, "%s", fdata.cFileName);
// }
// break;
// }
// } while(FindNextFile(dir_p, &fdata));
// #endif
return LV_FS_RES_OK;
}
/**
* Close the directory reading
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to an initialized 'fs_read_dir_t' variable
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * dir_p)
{
LV_UNUSED(drv);
#ifndef WIN32
closedir(dir_p);
#else
FindClose(dir_p);
#endif
return LV_FS_RES_OK;
}
#endif /*LV_USE_FS_POSIX*/
+330
View File
@@ -0,0 +1,330 @@
/**
* @file lv_fs_stdio.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../../lvgl.h"
#if LV_USE_FS_STDIO != '\0'
#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#ifdef WIN32
#include <windows.h>
#endif
/*********************
* DEFINES
*********************/
#ifndef LV_FS_STDIO_PATH
# ifndef WIN32
# define LV_FS_STDIO_PATH "./" /*Project root*/
# else
# define LV_FS_STDIO_PATH ".\\" /*Project root*/
# endif
#endif /*LV_FS_STDIO_PATH*/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path);
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * dir_p, char *fn);
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * dir_p);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Register a driver for the File system interface
*/
void lv_fs_stdio_init(void)
{
/*---------------------------------------------------
* Register the file system interface in LittlevGL
*--------------------------------------------------*/
/* Add a simple drive to open images */
static lv_fs_drv_t fs_drv; /*A driver descriptor*/
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.letter = LV_USE_FS_STDIO;
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
fs_drv.read_cb = fs_read;
fs_drv.write_cb = fs_write;
fs_drv.seek_cb = fs_seek;
fs_drv.tell_cb = fs_tell;
fs_drv.dir_close_cb = fs_dir_close;
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
lv_fs_drv_register(&fs_drv);
char cur_path[512];
getcwd(cur_path, sizeof(cur_path));
LV_LOG_INFO("STDIO file system is initialized with %s root directory.", cur_path);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Open a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
(void) drv; /*Unused*/
errno = 0;
const char * flags = "";
if(mode == LV_FS_MODE_WR) flags = "wb";
else if(mode == LV_FS_MODE_RD) flags = "rb";
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = "rb+";
/*Make the path relative to the current directory (the projects root folder)*/
#ifndef WIN32
char buf[256];
sprintf(buf, LV_FS_STDIO_PATH "%s", path);
#else
char buf[256];
sprintf(buf, LV_FS_STDIO_PATH "%s", path);
#endif
FILE * f = fopen(buf, flags);
if(f == NULL) return NULL;
/*Be sure we are the beginning of the file*/
fseek(f, 0, SEEK_SET);
return f;
}
/**
* Close an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
{
(void) drv; /*Unused*/
fclose(file_p);
return LV_FS_RES_OK;
}
/**
* Read data from an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
(void) drv; /*Unused*/
*br = fread(buf, 1, btr, file_p);
return LV_FS_RES_OK;
}
/**
* Write into a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param buf pointer to a buffer with the bytes to write
* @param btr Bytes To Write
* @param br the number of real written bytes (Bytes Written). NULL if unused.
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{
(void) drv; /*Unused*/
*bw = fwrite(buf, 1, btw, file_p);
return LV_FS_RES_OK;
}
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open )
* @param pos the new position of read write pointer
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
{
(void) drv; /*Unused*/
fseek(file_p, pos, whence);
return LV_FS_RES_OK;
}
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
(void) drv; /*Unused*/
*pos_p = ftell(file_p);
return LV_FS_RES_OK;
}
#ifdef WIN32
static char next_fn[256];
#endif
/**
* Initialize a 'fs_read_dir_t' variable for directory reading
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to a 'fs_read_dir_t' variable
* @param path path to a directory
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path)
{
(void) drv; /*Unused*/
#ifndef WIN32
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
sprintf(buf, LV_FS_STDIO_PATH "/%s", path);
return opendir(buf);
#else
HANDLE d = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA fdata;
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
sprintf(buf, LV_FS_PC_PATH "\\%s\\*", path);
strcpy(next_fn, "");
d = FindFirstFile(buf, &fdata);
do {
if (strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) {
continue;
} else {
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
sprintf(next_fn, "/%s", fdata.cFileName);
} else {
sprintf(next_fn, "%s", fdata.cFileName);
}
break;
}
} while(FindNextFileA(d, &fdata));
return d;
#endif
}
/**
* Read the next filename form a directory.
* The name of the directories will begin with '/'
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to an initialized 'fs_read_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * dir_p, char *fn)
{
(void) drv; /*Unused*/
#ifndef WIN32
struct dirent *entry;
do {
entry = readdir(dir_p);
if(entry) {
if(entry->d_type == DT_DIR) sprintf(fn, "/%s", entry->d_name);
else strcpy(fn, entry->d_name);
} else {
strcpy(fn, "");
}
} while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
#else
strcpy(fn, next_fn);
strcpy(next_fn, "");
WIN32_FIND_DATA fdata;
if(FindNextFile(dir_p, &fdata) == false) return LV_FS_RES_OK;
do {
if (strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) {
continue;
} else {
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
sprintf(next_fn, "/%s", fdata.cFileName);
} else {
sprintf(next_fn, "%s", fdata.cFileName);
}
break;
}
} while(FindNextFile(dir_p, &fdata));
#endif
return LV_FS_RES_OK;
}
/**
* Close the directory reading
* @param drv pointer to a driver where this function belongs
* @param dir_p pointer to an initialized 'fs_read_dir_t' variable
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * dir_p)
{
(void) drv; /*Unused*/
#ifndef WIN32
closedir(dir_p);
#else
FindClose(dir_p);
#endif
return LV_FS_RES_OK;
}
#endif /*LV_FS_FATFS*/
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
#ifndef GIFDEC_H
#define GIFDEC_H
#include <stdint.h>
#include "../../../misc/lv_fs.h"
#if LV_USE_GIF
typedef struct gd_Palette {
int size;
uint8_t colors[0x100 * 3];
} gd_Palette;
typedef struct gd_GCE {
uint16_t delay;
uint8_t tindex;
uint8_t disposal;
int input;
int transparency;
} gd_GCE;
typedef struct gd_GIF {
lv_fs_file_t fd;
const char * data;
uint8_t is_file;
uint32_t f_rw_p;
int32_t anim_start;
uint16_t width, height;
uint16_t depth;
uint16_t loop_count;
gd_GCE gce;
gd_Palette *palette;
gd_Palette lct, gct;
void (*plain_text)(
struct gd_GIF *gif, uint16_t tx, uint16_t ty,
uint16_t tw, uint16_t th, uint8_t cw, uint8_t ch,
uint8_t fg, uint8_t bg
);
void (*comment)(struct gd_GIF *gif);
void (*application)(struct gd_GIF *gif, char id[8], char auth[3]);
uint16_t fx, fy, fw, fh;
uint8_t bgindex;
uint8_t *canvas, *frame;
} gd_GIF;
gd_GIF * gd_open_gif_file(const char *fname);
gd_GIF * gd_open_gif_data(const void *data);
void gd_render_frame(gd_GIF *gif, uint8_t *buffer);
int gd_get_frame(gd_GIF *gif);
void gd_rewind(gd_GIF *gif);
void gd_close_gif(gd_GIF *gif);
#endif /*LV_USE_GIF*/
#endif /* GIFDEC_H */

Some files were not shown because too many files have changed in this diff Show More