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:
committed by
GitHub
parent
b20a706112
commit
18f61c5f77
42
docs/libs/bmp.md
Normal file
42
docs/libs/bmp.md
Normal 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
docs/libs/freetype.md
Normal file
39
docs/libs/freetype.md
Normal 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
docs/libs/fs.md
Normal file
19
docs/libs/fs.md
Normal 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
docs/libs/gif.md
Normal file
48
docs/libs/gif.md
Normal 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
docs/libs/index.md
Normal file
21
docs/libs/index.md
Normal 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
docs/libs/png.md
Normal file
31
docs/libs/png.md
Normal 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
docs/libs/qrcode.md
Normal file
28
docs/libs/qrcode.md
Normal 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
docs/libs/sjpg.md
Normal file
77
docs/libs/sjpg.md
Normal 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
|
||||
BIN
examples/libs/bmp/example_16bit.bmp
Normal file
BIN
examples/libs/bmp/example_16bit.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
examples/libs/bmp/example_24bit.bmp
Normal file
BIN
examples/libs/bmp/example_24bit.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
examples/libs/bmp/example_32bit.bmp
Normal file
BIN
examples/libs/bmp/example_32bit.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
6
examples/libs/bmp/index.rst
Normal file
6
examples/libs/bmp/index.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
Open a BMP image from file
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. lv_example:: libs/bmp/lv_example_bmp_1
|
||||
:language: c
|
||||
|
||||
38
examples/libs/bmp/lv_example_bmp.h
Normal file
38
examples/libs/bmp/lv_example_bmp.h
Normal 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
examples/libs/bmp/lv_example_bmp_1.c
Normal file
17
examples/libs/bmp/lv_example_bmp_1.c
Normal 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
|
||||
BIN
examples/libs/freetype/arial.ttf
Normal file
BIN
examples/libs/freetype/arial.ttf
Normal file
Binary file not shown.
6
examples/libs/freetype/index.rst
Normal file
6
examples/libs/freetype/index.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
Open a front with FreeTpye
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. lv_example:: libs/freetype/lv_example_freetype_1
|
||||
:language: c
|
||||
|
||||
38
examples/libs/freetype/lv_example_freetype.h
Normal file
38
examples/libs/freetype/lv_example_freetype.h
Normal file
@@ -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*/
|
||||
30
examples/libs/freetype/lv_example_freetype_1.c
Normal file
30
examples/libs/freetype/lv_example_freetype_1.c
Normal file
@@ -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
|
||||
BIN
examples/libs/gif/bulb.gif
Normal file
BIN
examples/libs/gif/bulb.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
1128
examples/libs/gif/img_bulb_gif.c
Normal file
1128
examples/libs/gif/img_bulb_gif.c
Normal file
File diff suppressed because it is too large
Load Diff
6
examples/libs/gif/index.rst
Normal file
6
examples/libs/gif/index.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
Open a GIF image from file and variable
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. lv_example:: libs/bmp/lv_example_gif_1
|
||||
:language: c
|
||||
|
||||
38
examples/libs/gif/lv_example_gif.h
Normal file
38
examples/libs/gif/lv_example_gif.h
Normal 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
examples/libs/gif/lv_example_gif_1.c
Normal file
23
examples/libs/gif/lv_example_gif_1.c
Normal 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
examples/libs/lv_example_libs.h
Normal file
43
examples/libs/lv_example_libs.h
Normal 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
examples/libs/png/img_wing_png.c
Normal file
348
examples/libs/png/img_wing_png.c
Normal 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
examples/libs/png/index.rst
Normal file
6
examples/libs/png/index.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
Open a PNG image from file and variable
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. lv_example:: libs/bmp/lv_example_png_1
|
||||
:language: c
|
||||
|
||||
38
examples/libs/png/lv_example_png.h
Normal file
38
examples/libs/png/lv_example_png.h
Normal 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
examples/libs/png/lv_example_png_1.c
Normal file
23
examples/libs/png/lv_example_png_1.c
Normal 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
|
||||
BIN
examples/libs/png/wink.png
Normal file
BIN
examples/libs/png/wink.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
6
examples/libs/qrcode/index.rst
Normal file
6
examples/libs/qrcode/index.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
Create a QR Code
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
.. lv_example:: libs/bmp/lv_example_qrcode_1
|
||||
:language: c
|
||||
|
||||
38
examples/libs/qrcode/lv_example_qrcode.h
Normal file
38
examples/libs/qrcode/lv_example_qrcode.h
Normal 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*/
|
||||
32
examples/libs/qrcode/lv_example_qrcode_1.c
Normal file
32
examples/libs/qrcode/lv_example_qrcode_1.c
Normal file
@@ -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
examples/libs/sjpg/lv_example_sjpg.h
Normal file
38
examples/libs/sjpg/lv_example_sjpg.h
Normal 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
examples/libs/sjpg/lv_example_sjpg_1.c
Normal file
14
examples/libs/sjpg/lv_example_sjpg_1.c
Normal 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
|
||||
BIN
examples/libs/sjpg/small_image.sjpg
Normal file
BIN
examples/libs/sjpg/small_image.sjpg
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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
lvgl.h
1
lvgl.h
@@ -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
scripts/jpg_to_sjpg.py
Executable file
138
scripts/jpg_to_sjpg.py
Executable 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
src/extra/libs/bmp/lv_bmp.c
Normal file
228
src/extra/libs/bmp/lv_bmp.c
Normal 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
src/extra/libs/bmp/lv_bmp.h
Normal file
42
src/extra/libs/bmp/lv_bmp.h
Normal 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*/
|
||||
BIN
src/extra/libs/freetype/arial.ttf
Normal file
BIN
src/extra/libs/freetype/arial.ttf
Normal file
Binary file not shown.
480
src/extra/libs/freetype/lv_freetype.c
Normal file
480
src/extra/libs/freetype/lv_freetype.c
Normal 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
src/extra/libs/freetype/lv_freetype.h
Normal file
81
src/extra/libs/freetype/lv_freetype.h
Normal 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
src/extra/libs/fs/lv_fs_fatfs.c
Normal file
258
src/extra/libs/fs/lv_fs_fatfs.c
Normal 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
src/extra/libs/fs/lv_fs_libs.h
Normal file
50
src/extra/libs/fs/lv_fs_libs.h
Normal 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
src/extra/libs/fs/lv_fs_posix.c
Normal file
334
src/extra/libs/fs/lv_fs_posix.c
Normal 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
src/extra/libs/fs/lv_fs_stdio.c
Normal file
330
src/extra/libs/fs/lv_fs_stdio.c
Normal 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*/
|
||||
649
src/extra/libs/gif/gifdec.c
Normal file
649
src/extra/libs/gif/gifdec.c
Normal file
@@ -0,0 +1,649 @@
|
||||
#include "gifdec.h"
|
||||
#include "../../../misc/lv_log.h"
|
||||
#include "../../../misc/lv_mem.h"
|
||||
#if LV_USE_GIF
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
typedef struct Entry {
|
||||
uint16_t length;
|
||||
uint16_t prefix;
|
||||
uint8_t suffix;
|
||||
} Entry;
|
||||
|
||||
typedef struct Table {
|
||||
int bulk;
|
||||
int nentries;
|
||||
Entry *entries;
|
||||
} Table;
|
||||
|
||||
static gd_GIF * gif_open(gd_GIF * gif);
|
||||
static bool f_gif_open(gd_GIF * gif, const void * path, bool is_file);
|
||||
static void f_gif_read(gd_GIF * gif, void * buf, size_t len);
|
||||
static int f_gif_seek(gd_GIF * gif, size_t pos, int k);
|
||||
static void f_gif_close(gd_GIF * gif);
|
||||
|
||||
static uint16_t
|
||||
read_num(gd_GIF * gif)
|
||||
{
|
||||
uint8_t bytes[2];
|
||||
|
||||
f_gif_read(gif, bytes, 2);
|
||||
return bytes[0] + (((uint16_t) bytes[1]) << 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gd_GIF *
|
||||
gd_open_gif_file(const char *fname)
|
||||
{
|
||||
gd_GIF gif_base;
|
||||
memset(&gif_base, 0, sizeof(gif_base));
|
||||
|
||||
bool res = f_gif_open(&gif_base, fname, true);
|
||||
if(!res) return NULL;
|
||||
|
||||
return gif_open(&gif_base);
|
||||
}
|
||||
|
||||
|
||||
gd_GIF *
|
||||
gd_open_gif_data(const void *data)
|
||||
{
|
||||
gd_GIF gif_base;
|
||||
memset(&gif_base, 0, sizeof(gif_base));
|
||||
|
||||
bool res = f_gif_open(&gif_base, data, false);
|
||||
if(!res) return NULL;
|
||||
|
||||
return gif_open(&gif_base);
|
||||
}
|
||||
|
||||
static gd_GIF * gif_open(gd_GIF * gif_base)
|
||||
{
|
||||
uint8_t sigver[3];
|
||||
uint16_t width, height, depth;
|
||||
uint8_t fdsz, bgidx, aspect;
|
||||
int i;
|
||||
uint8_t *bgcolor;
|
||||
int gct_sz;
|
||||
gd_GIF *gif;
|
||||
|
||||
/* Header */
|
||||
f_gif_read(gif_base, sigver, 3);
|
||||
if (memcmp(sigver, "GIF", 3) != 0) {
|
||||
fprintf(stderr, "invalid signature\n");
|
||||
goto fail;
|
||||
}
|
||||
/* Version */
|
||||
f_gif_read(gif_base, sigver, 3);
|
||||
if (memcmp(sigver, "89a", 3) != 0) {
|
||||
LV_LOG_WARN("invalid version\n");
|
||||
goto fail;
|
||||
}
|
||||
/* Width x Height */
|
||||
width = read_num(gif_base);
|
||||
height = read_num(gif_base);
|
||||
/* FDSZ */
|
||||
f_gif_read(gif_base, &fdsz, 1);
|
||||
/* Presence of GCT */
|
||||
if (!(fdsz & 0x80)) {
|
||||
LV_LOG_WARN("no global color table\n");
|
||||
goto fail;
|
||||
}
|
||||
/* Color Space's Depth */
|
||||
depth = ((fdsz >> 4) & 7) + 1;
|
||||
/* Ignore Sort Flag. */
|
||||
/* GCT Size */
|
||||
gct_sz = 1 << ((fdsz & 0x07) + 1);
|
||||
/* Background Color Index */
|
||||
f_gif_read(gif_base, &bgidx, 1);
|
||||
/* Aspect Ratio */
|
||||
f_gif_read(gif_base, &aspect, 1);
|
||||
/* Create gd_GIF Structure. */
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
gif = lv_mem_alloc(sizeof(gd_GIF) + 5 * width * height);
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
gif = lv_mem_alloc(sizeof(gd_GIF) + 4 * width * height);
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
gif = lv_mem_alloc(sizeof(gd_GIF) + 3 * width * height);
|
||||
#endif
|
||||
|
||||
if (!gif) goto fail;
|
||||
memcpy(gif, gif_base, sizeof(gd_GIF));
|
||||
gif->width = width;
|
||||
gif->height = height;
|
||||
gif->depth = depth;
|
||||
/* Read GCT */
|
||||
gif->gct.size = gct_sz;
|
||||
f_gif_read(gif, gif->gct.colors, 3 * gif->gct.size);
|
||||
gif->palette = &gif->gct;
|
||||
gif->bgindex = bgidx;
|
||||
gif->canvas = (uint8_t *) &gif[1];
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
gif->frame = &gif->canvas[4 * width * height];
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
gif->frame = &gif->canvas[3 * width * height];
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
gif->frame = &gif->canvas[2 * width * height];
|
||||
#endif
|
||||
if (gif->bgindex)
|
||||
memset(gif->frame, gif->bgindex, gif->width * gif->height);
|
||||
bgcolor = &gif->palette->colors[gif->bgindex*3];
|
||||
|
||||
if (bgcolor[0] || bgcolor[1] || bgcolor [2])
|
||||
for (i = 0; i < gif->width * gif->height; i++) {
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
gif->canvas[i*4 + 0] = *(bgcolor + 2);
|
||||
gif->canvas[i*4 + 1] = *(bgcolor + 1);
|
||||
gif->canvas[i*4 + 2] = *(bgcolor + 0);
|
||||
gif->canvas[i*4 + 3] = 0xff;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
lv_color_t c = lv_color_make(*(bgcolor + 0), *(bgcolor + 1), *(bgcolor + 2));
|
||||
gif->canvas[i*3 + 0] = c.full & 0xff;
|
||||
gif->canvas[i*3 + 1] = (c.full >> 8) & 0xff;
|
||||
gif->canvas[i*3 + 2] = 0xff;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color_t c = lv_color_make(*(bgcolor + 0), *(bgcolor + 1), *(bgcolor + 2));
|
||||
gif->canvas[i*2 + 0] = c.full;
|
||||
gif->canvas[i*2 + 1] = 0xff;
|
||||
#endif
|
||||
}
|
||||
gif->anim_start = f_gif_seek(gif, 0, SEEK_CUR);
|
||||
goto ok;
|
||||
fail:
|
||||
f_gif_close(gif_base);
|
||||
ok:
|
||||
return gif;
|
||||
}
|
||||
|
||||
static void
|
||||
discard_sub_blocks(gd_GIF *gif)
|
||||
{
|
||||
uint8_t size;
|
||||
|
||||
do {
|
||||
f_gif_read(gif, &size, 1);
|
||||
f_gif_seek(gif, size, SEEK_CUR);
|
||||
} while (size);
|
||||
}
|
||||
|
||||
static void
|
||||
read_plain_text_ext(gd_GIF *gif)
|
||||
{
|
||||
if (gif->plain_text) {
|
||||
uint16_t tx, ty, tw, th;
|
||||
uint8_t cw, ch, fg, bg;
|
||||
off_t sub_block;
|
||||
f_gif_seek(gif, 1, SEEK_CUR); /* block size = 12 */
|
||||
tx = read_num(gif);
|
||||
ty = read_num(gif);
|
||||
tw = read_num(gif);
|
||||
th = read_num(gif);
|
||||
f_gif_read(gif, &cw, 1);
|
||||
f_gif_read(gif, &ch, 1);
|
||||
f_gif_read(gif, &fg, 1);
|
||||
f_gif_read(gif, &bg, 1);
|
||||
sub_block = f_gif_seek(gif, 0, SEEK_CUR);
|
||||
gif->plain_text(gif, tx, ty, tw, th, cw, ch, fg, bg);
|
||||
f_gif_seek(gif, sub_block, SEEK_SET);
|
||||
} else {
|
||||
/* Discard plain text metadata. */
|
||||
f_gif_seek(gif, 13, SEEK_CUR);
|
||||
}
|
||||
/* Discard plain text sub-blocks. */
|
||||
discard_sub_blocks(gif);
|
||||
}
|
||||
|
||||
static void
|
||||
read_graphic_control_ext(gd_GIF *gif)
|
||||
{
|
||||
uint8_t rdit;
|
||||
|
||||
/* Discard block size (always 0x04). */
|
||||
f_gif_seek(gif, 1, SEEK_CUR);
|
||||
f_gif_read(gif, &rdit, 1);
|
||||
gif->gce.disposal = (rdit >> 2) & 3;
|
||||
gif->gce.input = rdit & 2;
|
||||
gif->gce.transparency = rdit & 1;
|
||||
gif->gce.delay = read_num(gif);
|
||||
f_gif_read(gif, &gif->gce.tindex, 1);
|
||||
/* Skip block terminator. */
|
||||
f_gif_seek(gif, 1, SEEK_CUR);
|
||||
}
|
||||
|
||||
static void
|
||||
read_comment_ext(gd_GIF *gif)
|
||||
{
|
||||
if (gif->comment) {
|
||||
off_t sub_block = f_gif_seek(gif, 0, SEEK_CUR);
|
||||
gif->comment(gif);
|
||||
f_gif_seek(gif, sub_block, SEEK_SET);
|
||||
}
|
||||
/* Discard comment sub-blocks. */
|
||||
discard_sub_blocks(gif);
|
||||
}
|
||||
|
||||
static void
|
||||
read_application_ext(gd_GIF *gif)
|
||||
{
|
||||
char app_id[8];
|
||||
char app_auth_code[3];
|
||||
|
||||
/* Discard block size (always 0x0B). */
|
||||
f_gif_seek(gif, 1, SEEK_CUR);
|
||||
/* Application Identifier. */
|
||||
f_gif_read(gif, app_id, 8);
|
||||
/* Application Authentication Code. */
|
||||
f_gif_read(gif, app_auth_code, 3);
|
||||
if (!strncmp(app_id, "NETSCAPE", sizeof(app_id))) {
|
||||
/* Discard block size (0x03) and constant byte (0x01). */
|
||||
f_gif_seek(gif, 2, SEEK_CUR);
|
||||
gif->loop_count = read_num(gif);
|
||||
/* Skip block terminator. */
|
||||
f_gif_seek(gif, 1, SEEK_CUR);
|
||||
} else if (gif->application) {
|
||||
off_t sub_block = f_gif_seek(gif, 0, SEEK_CUR);
|
||||
gif->application(gif, app_id, app_auth_code);
|
||||
f_gif_seek(gif, sub_block, SEEK_SET);
|
||||
discard_sub_blocks(gif);
|
||||
} else {
|
||||
discard_sub_blocks(gif);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_ext(gd_GIF *gif)
|
||||
{
|
||||
uint8_t label;
|
||||
|
||||
f_gif_read(gif, &label, 1);
|
||||
switch (label) {
|
||||
case 0x01:
|
||||
read_plain_text_ext(gif);
|
||||
break;
|
||||
case 0xF9:
|
||||
read_graphic_control_ext(gif);
|
||||
break;
|
||||
case 0xFE:
|
||||
read_comment_ext(gif);
|
||||
break;
|
||||
case 0xFF:
|
||||
read_application_ext(gif);
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("unknown extension: %02X\n", label);
|
||||
}
|
||||
}
|
||||
|
||||
static Table *
|
||||
new_table(int key_size)
|
||||
{
|
||||
int key;
|
||||
int init_bulk = MAX(1 << (key_size + 1), 0x100);
|
||||
Table *table = lv_mem_alloc(sizeof(*table) + sizeof(Entry) * init_bulk);
|
||||
if (table) {
|
||||
table->bulk = init_bulk;
|
||||
table->nentries = (1 << key_size) + 2;
|
||||
table->entries = (Entry *) &table[1];
|
||||
for (key = 0; key < (1 << key_size); key++)
|
||||
table->entries[key] = (Entry) {1, 0xFFF, key};
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/* Add table entry. Return value:
|
||||
* 0 on success
|
||||
* +1 if key size must be incremented after this addition
|
||||
* -1 if could not realloc table */
|
||||
static int
|
||||
add_entry(Table **tablep, uint16_t length, uint16_t prefix, uint8_t suffix)
|
||||
{
|
||||
Table *table = *tablep;
|
||||
if (table->nentries == table->bulk) {
|
||||
table->bulk *= 2;
|
||||
table = lv_mem_realloc(table, sizeof(*table) + sizeof(Entry) * table->bulk);
|
||||
if (!table) return -1;
|
||||
table->entries = (Entry *) &table[1];
|
||||
*tablep = table;
|
||||
}
|
||||
table->entries[table->nentries] = (Entry) {length, prefix, suffix};
|
||||
table->nentries++;
|
||||
if ((table->nentries & (table->nentries - 1)) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
get_key(gd_GIF *gif, int key_size, uint8_t *sub_len, uint8_t *shift, uint8_t *byte)
|
||||
{
|
||||
int bits_read;
|
||||
int rpad;
|
||||
int frag_size;
|
||||
uint16_t key;
|
||||
|
||||
key = 0;
|
||||
for (bits_read = 0; bits_read < key_size; bits_read += frag_size) {
|
||||
rpad = (*shift + bits_read) % 8;
|
||||
if (rpad == 0) {
|
||||
/* Update byte. */
|
||||
if (*sub_len == 0) {
|
||||
f_gif_read(gif, sub_len, 1); /* Must be nonzero! */
|
||||
if (*sub_len == 0) return 0x1000;
|
||||
}
|
||||
f_gif_read(gif, byte, 1);
|
||||
(*sub_len)--;
|
||||
}
|
||||
frag_size = MIN(key_size - bits_read, 8 - rpad);
|
||||
key |= ((uint16_t) ((*byte) >> rpad)) << bits_read;
|
||||
}
|
||||
/* Clear extra bits to the left. */
|
||||
key &= (1 << key_size) - 1;
|
||||
*shift = (*shift + key_size) % 8;
|
||||
return key;
|
||||
}
|
||||
|
||||
/* Compute output index of y-th input line, in frame of height h. */
|
||||
static int
|
||||
interlaced_line_index(int h, int y)
|
||||
{
|
||||
int p; /* number of lines in current pass */
|
||||
|
||||
p = (h - 1) / 8 + 1;
|
||||
if (y < p) /* pass 1 */
|
||||
return y * 8;
|
||||
y -= p;
|
||||
p = (h - 5) / 8 + 1;
|
||||
if (y < p) /* pass 2 */
|
||||
return y * 8 + 4;
|
||||
y -= p;
|
||||
p = (h - 3) / 4 + 1;
|
||||
if (y < p) /* pass 3 */
|
||||
return y * 4 + 2;
|
||||
y -= p;
|
||||
/* pass 4 */
|
||||
return y * 2 + 1;
|
||||
}
|
||||
|
||||
/* Decompress image pixels.
|
||||
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */
|
||||
static int
|
||||
read_image_data(gd_GIF *gif, int interlace)
|
||||
{
|
||||
uint8_t sub_len, shift, byte;
|
||||
int init_key_size, key_size, table_is_full;
|
||||
int frm_off, frm_size, str_len, i, p, x, y;
|
||||
uint16_t key, clear, stop;
|
||||
int ret;
|
||||
Table *table;
|
||||
Entry entry;
|
||||
off_t start, end;
|
||||
|
||||
f_gif_read(gif, &byte, 1);
|
||||
key_size = (int) byte;
|
||||
start = f_gif_seek(gif, 0, SEEK_CUR);
|
||||
discard_sub_blocks(gif);
|
||||
end = f_gif_seek(gif, 0, SEEK_CUR);
|
||||
f_gif_seek(gif, start, SEEK_SET);
|
||||
clear = 1 << key_size;
|
||||
stop = clear + 1;
|
||||
table = new_table(key_size);
|
||||
key_size++;
|
||||
init_key_size = key_size;
|
||||
sub_len = shift = 0;
|
||||
key = get_key(gif, key_size, &sub_len, &shift, &byte); /* clear code */
|
||||
frm_off = 0;
|
||||
ret = 0;
|
||||
frm_size = gif->fw*gif->fh;
|
||||
while (frm_off < frm_size) {
|
||||
if (key == clear) {
|
||||
key_size = init_key_size;
|
||||
table->nentries = (1 << (key_size - 1)) + 2;
|
||||
table_is_full = 0;
|
||||
} else if (!table_is_full) {
|
||||
ret = add_entry(&table, str_len + 1, key, entry.suffix);
|
||||
if (ret == -1) {
|
||||
lv_mem_free(table);
|
||||
return -1;
|
||||
}
|
||||
if (table->nentries == 0x1000) {
|
||||
ret = 0;
|
||||
table_is_full = 1;
|
||||
}
|
||||
}
|
||||
key = get_key(gif, key_size, &sub_len, &shift, &byte);
|
||||
if (key == clear) continue;
|
||||
if (key == stop || key == 0x1000) break;
|
||||
if (ret == 1) key_size++;
|
||||
entry = table->entries[key];
|
||||
str_len = entry.length;
|
||||
for (i = 0; i < str_len; i++) {
|
||||
p = frm_off + entry.length - 1;
|
||||
x = p % gif->fw;
|
||||
y = p / gif->fw;
|
||||
if (interlace)
|
||||
y = interlaced_line_index((int) gif->fh, y);
|
||||
gif->frame[(gif->fy + y) * gif->width + gif->fx + x] = entry.suffix;
|
||||
if (entry.prefix == 0xFFF)
|
||||
break;
|
||||
else
|
||||
entry = table->entries[entry.prefix];
|
||||
}
|
||||
frm_off += str_len;
|
||||
if (key < table->nentries - 1 && !table_is_full)
|
||||
table->entries[table->nentries - 1].suffix = entry.suffix;
|
||||
}
|
||||
lv_mem_free(table);
|
||||
if (key == stop) f_gif_read(gif, &sub_len, 1); /* Must be zero! */
|
||||
f_gif_seek(gif, end, SEEK_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read image.
|
||||
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */
|
||||
static int
|
||||
read_image(gd_GIF *gif)
|
||||
{
|
||||
uint8_t fisrz;
|
||||
int interlace;
|
||||
|
||||
/* Image Descriptor. */
|
||||
gif->fx = read_num(gif);
|
||||
gif->fy = read_num(gif);
|
||||
gif->fw = read_num(gif);
|
||||
gif->fh = read_num(gif);
|
||||
f_gif_read(gif, &fisrz, 1);
|
||||
interlace = fisrz & 0x40;
|
||||
/* Ignore Sort Flag. */
|
||||
/* Local Color Table? */
|
||||
if (fisrz & 0x80) {
|
||||
/* Read LCT */
|
||||
gif->lct.size = 1 << ((fisrz & 0x07) + 1);
|
||||
f_gif_read(gif, gif->lct.colors, 3 * gif->lct.size);
|
||||
gif->palette = &gif->lct;
|
||||
} else
|
||||
gif->palette = &gif->gct;
|
||||
/* Image Data. */
|
||||
return read_image_data(gif, interlace);
|
||||
}
|
||||
|
||||
static void
|
||||
render_frame_rect(gd_GIF *gif, uint8_t *buffer)
|
||||
{
|
||||
int i, j, k;
|
||||
uint8_t index, *color;
|
||||
i = gif->fy * gif->width + gif->fx;
|
||||
for (j = 0; j < gif->fh; j++) {
|
||||
for (k = 0; k < gif->fw; k++) {
|
||||
index = gif->frame[(gif->fy + j) * gif->width + gif->fx + k];
|
||||
color = &gif->palette->colors[index*3];
|
||||
if (!gif->gce.transparency || index != gif->gce.tindex) {
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
buffer[(i+k)*4 + 0] = *(color + 2);
|
||||
buffer[(i+k)*4 + 1] = *(color + 1);
|
||||
buffer[(i+k)*4 + 2] = *(color + 0);
|
||||
buffer[(i+k)*4 + 3] = 0xFF;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
lv_color_t c = lv_color_make(*(color + 0), *(color + 1), *(color + 2));
|
||||
buffer[(i+k)*3 + 0] = c.full & 0xff;
|
||||
buffer[(i+k)*3 + 1] = (c.full >> 8) & 0xff;
|
||||
buffer[(i+k)*3 + 2] = 0xff;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color_t c = lv_color_make(*(color + 0), *(color + 1), *(color + 2));
|
||||
buffer[(i+k)*2 + 0] = c.full;
|
||||
buffer[(i+k)*2 + 1] = 0xff;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
i += gif->width;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispose(gd_GIF *gif)
|
||||
{
|
||||
int i, j, k;
|
||||
uint8_t *bgcolor;
|
||||
switch (gif->gce.disposal) {
|
||||
case 2: /* Restore to background color. */
|
||||
bgcolor = &gif->palette->colors[gif->bgindex*3];
|
||||
|
||||
uint8_t opa = 0xff;
|
||||
if(gif->gce.transparency) opa = 0x00;
|
||||
|
||||
i = gif->fy * gif->width + gif->fx;
|
||||
for (j = 0; j < gif->fh; j++) {
|
||||
for (k = 0; k < gif->fw; k++) {
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
gif->canvas[(i+k)*4 + 0] = *(bgcolor + 2);
|
||||
gif->canvas[(i+k)*4 + 1] = *(bgcolor + 1);
|
||||
gif->canvas[(i+k)*4 + 2] = *(bgcolor + 0);
|
||||
gif->canvas[(i+k)*4 + 3] = opa;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
lv_color_t c = lv_color_make(*(bgcolor + 0), *(bgcolor + 1), *(bgcolor + 2));
|
||||
gif->canvas[(i+k)*3 + 0] = c.full & 0xff;
|
||||
gif->canvas[(i+k)*3 + 1] = (c.full >> 8) & 0xff;
|
||||
gif->canvas[(i+k)*3 + 2] = opa;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color_t c = lv_color_make(*(bgcolor + 0), *(bgcolor + 1), *(bgcolor + 2));
|
||||
gif->canvas[(i+k)*2 + 0] = c.full;
|
||||
gif->canvas[(i+k)*2 + 1] = opa;
|
||||
#endif
|
||||
}
|
||||
i += gif->width;
|
||||
}
|
||||
break;
|
||||
case 3: /* Restore to previous, i.e., don't update canvas.*/
|
||||
break;
|
||||
default:
|
||||
/* Add frame non-transparent pixels to canvas. */
|
||||
render_frame_rect(gif, gif->canvas);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if got a frame; 0 if got GIF trailer; -1 if error. */
|
||||
int
|
||||
gd_get_frame(gd_GIF *gif)
|
||||
{
|
||||
char sep;
|
||||
|
||||
dispose(gif);
|
||||
f_gif_read(gif, &sep, 1);
|
||||
while (sep != ',') {
|
||||
if (sep == ';')
|
||||
return 0;
|
||||
if (sep == '!')
|
||||
read_ext(gif);
|
||||
else return -1;
|
||||
f_gif_read(gif, &sep, 1);
|
||||
}
|
||||
if (read_image(gif) == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
gd_render_frame(gd_GIF *gif, uint8_t *buffer)
|
||||
{
|
||||
// uint32_t i;
|
||||
// uint32_t j;
|
||||
// for(i = 0, j = 0; i < gif->width * gif->height * 3; i+= 3, j+=4) {
|
||||
// buffer[j + 0] = gif->canvas[i + 2];
|
||||
// buffer[j + 1] = gif->canvas[i + 1];
|
||||
// buffer[j + 2] = gif->canvas[i + 0];
|
||||
// buffer[j + 3] = 0xFF;
|
||||
// }
|
||||
// memcpy(buffer, gif->canvas, gif->width * gif->height * 3);
|
||||
render_frame_rect(gif, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
gd_rewind(gd_GIF *gif)
|
||||
{
|
||||
f_gif_seek(gif, gif->anim_start, SEEK_SET);
|
||||
}
|
||||
|
||||
void
|
||||
gd_close_gif(gd_GIF *gif)
|
||||
{
|
||||
f_gif_close(gif);
|
||||
lv_mem_free(gif);
|
||||
}
|
||||
|
||||
static bool f_gif_open(gd_GIF * gif, const void * path, bool is_file)
|
||||
{
|
||||
gif->f_rw_p = 0;
|
||||
gif->data = NULL;
|
||||
gif->is_file = is_file;
|
||||
|
||||
if(is_file) {
|
||||
lv_fs_res_t res = lv_fs_open(&gif->fd, path, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) return false;
|
||||
else return true;
|
||||
} else {
|
||||
gif->data = path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void f_gif_read(gd_GIF * gif, void * buf, size_t len)
|
||||
{
|
||||
if(gif->is_file) {
|
||||
lv_fs_read(&gif->fd, buf, len, NULL);
|
||||
} else
|
||||
{
|
||||
memcpy(buf, &gif->data[gif->f_rw_p], len);
|
||||
gif->f_rw_p += len;
|
||||
}
|
||||
}
|
||||
|
||||
static int f_gif_seek(gd_GIF * gif, size_t pos, int k)
|
||||
{
|
||||
if(k == SEEK_CUR) k = LV_FS_SEEK_CUR;
|
||||
else if(k == SEEK_SET) k = LV_FS_SEEK_SET;
|
||||
if(gif->is_file) {
|
||||
lv_fs_seek(&gif->fd, pos, k);
|
||||
uint32_t x;
|
||||
lv_fs_tell(&gif->fd, &x);
|
||||
return x;
|
||||
} else {
|
||||
if(k == LV_FS_SEEK_CUR) gif->f_rw_p += pos;
|
||||
else if(k == LV_FS_SEEK_SET) gif->f_rw_p = pos;
|
||||
return gif->f_rw_p;
|
||||
}
|
||||
}
|
||||
|
||||
static void f_gif_close(gd_GIF * gif)
|
||||
{
|
||||
if(gif->is_file) {
|
||||
lv_fs_close(&gif->fd);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GIF*/
|
||||
60
src/extra/libs/gif/gifdec.h
Normal file
60
src/extra/libs/gif/gifdec.h
Normal 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 */
|
||||
154
src/extra/libs/gif/lv_gif.c
Normal file
154
src/extra/libs/gif/lv_gif.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @file lv_gifenc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_gif.h"
|
||||
#if LV_USE_GIF
|
||||
|
||||
#include "gifdec.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS &lv_gif_class
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void next_frame_task_cb(lv_timer_t * t);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
const lv_obj_class_t lv_gif_class = {
|
||||
.constructor_cb = lv_gif_constructor,
|
||||
.destructor_cb = lv_gif_destructor,
|
||||
.instance_size = sizeof(lv_gif_t),
|
||||
.base_class = &lv_img_class
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_obj_t * lv_gif_create(lv_obj_t * parent)
|
||||
{
|
||||
|
||||
LV_LOG_INFO("begin");
|
||||
lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
|
||||
lv_obj_class_init_obj(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void lv_gif_set_src(lv_obj_t * obj, const void * src)
|
||||
{
|
||||
lv_gif_t * gifobj = (lv_gif_t *) obj;
|
||||
|
||||
/*Close previous gif if any*/
|
||||
if(gifobj->gif) {
|
||||
lv_img_cache_invalidate_src(&gifobj->imgdsc);
|
||||
gd_close_gif(gifobj->gif);
|
||||
gifobj->gif = NULL;
|
||||
gifobj->imgdsc.data = NULL;
|
||||
}
|
||||
|
||||
if(lv_img_src_get_type(src) == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = src;
|
||||
gifobj->gif = gd_open_gif_data(img_dsc->data);
|
||||
}
|
||||
else if(lv_img_src_get_type(src) == LV_IMG_SRC_FILE) {
|
||||
gifobj->gif = gd_open_gif_file(src);
|
||||
}
|
||||
if(gifobj->gif == NULL) {
|
||||
LV_LOG_WARN("Could't load the source");
|
||||
return;
|
||||
}
|
||||
|
||||
gifobj->imgdsc.data = gifobj->gif->canvas;
|
||||
gifobj->imgdsc.header.always_zero = 0;
|
||||
gifobj->imgdsc.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
|
||||
gifobj->imgdsc.header.h = gifobj->gif->height;
|
||||
gifobj->imgdsc.header.w = gifobj->gif->width;
|
||||
gifobj->last_call = lv_tick_get();
|
||||
|
||||
lv_img_set_src(obj, &gifobj->imgdsc);
|
||||
|
||||
lv_timer_resume(gifobj->timer);
|
||||
lv_timer_reset(gifobj->timer);
|
||||
|
||||
next_frame_task_cb(gifobj->timer);
|
||||
|
||||
}
|
||||
|
||||
void lv_gif_restart(lv_obj_t * obj)
|
||||
{
|
||||
lv_gif_t * gifobj = (lv_gif_t *) obj;
|
||||
gd_rewind(gifobj->gif);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
LV_UNUSED(class_p);
|
||||
|
||||
lv_gif_t * gifobj = (lv_gif_t *) obj;
|
||||
|
||||
gifobj->timer = lv_timer_create(next_frame_task_cb, 10, obj);
|
||||
lv_timer_pause(gifobj->timer);
|
||||
}
|
||||
|
||||
static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
LV_UNUSED(class_p);
|
||||
lv_gif_t * gifobj = (lv_gif_t *) obj;
|
||||
lv_img_cache_invalidate_src(&gifobj->imgdsc);
|
||||
gd_close_gif(gifobj->gif);
|
||||
lv_timer_del(gifobj->timer);
|
||||
}
|
||||
|
||||
static void next_frame_task_cb(lv_timer_t * t)
|
||||
{
|
||||
lv_obj_t * obj = t->user_data;
|
||||
lv_gif_t * gifobj = (lv_gif_t *) obj;
|
||||
uint32_t elaps = lv_tick_elaps(gifobj->last_call);
|
||||
if(elaps < gifobj->gif->gce.delay * 10) return;
|
||||
|
||||
gifobj->last_call = lv_tick_get();
|
||||
|
||||
int has_next = gd_get_frame(gifobj->gif);
|
||||
if(has_next == 0) {
|
||||
/*It was the last repeat*/
|
||||
if(gifobj->gif->loop_count == 1) {
|
||||
lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL);
|
||||
if(res != LV_FS_RES_OK) return;
|
||||
} else {
|
||||
if(gifobj->gif->loop_count > 1) gifobj->gif->loop_count--;
|
||||
gd_rewind(gifobj->gif);
|
||||
}
|
||||
}
|
||||
|
||||
gd_render_frame(gifobj->gif, gifobj->imgdsc.data);
|
||||
|
||||
lv_img_cache_invalidate_src(lv_img_get_src(obj));
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GIF*/
|
||||
58
src/extra/libs/gif/lv_gif.h
Normal file
58
src/extra/libs/gif/lv_gif.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file lv_gif.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GIF_H
|
||||
#define LV_GIF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_GIF
|
||||
|
||||
#include "gifdec.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_img_t img;
|
||||
gd_GIF *gif;
|
||||
lv_timer_t * timer;
|
||||
lv_img_dsc_t imgdsc;
|
||||
uint32_t last_call;
|
||||
}lv_gif_t;
|
||||
|
||||
extern const lv_obj_class_t lv_gif_class;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
lv_obj_t * lv_gif_create(lv_obj_t * parent);
|
||||
void lv_gif_set_src(lv_obj_t * obj, const void * src);
|
||||
void lv_gif_restart(lv_obj_t * gif);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GIF*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GIF_H*/
|
||||
49
src/extra/libs/lv_libs.h
Normal file
49
src/extra/libs/lv_libs.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file lv_libs.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_LIBS_H
|
||||
#define LV_LIBS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "bmp/lv_bmp.h"
|
||||
#include "fs/lv_fs_libs.h"
|
||||
#include "png/lv_png.h"
|
||||
#include "gif/lv_gif.h"
|
||||
#include "qrcode/lv_qrcode.h"
|
||||
#include "sjpg/lv_sjpg.h"
|
||||
#include "freetype/lv_freetype.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#if LV_USE_LOG && LV_LOG_TRACE_LAYOUT
|
||||
# define LV_TRACE_LAYOUT(...) LV_LOG_TRACE( __VA_ARGS__)
|
||||
#else
|
||||
# define LV_TRACE_LAYOUT(...)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_LAYOUTS_H*/
|
||||
6466
src/extra/libs/png/lodepng.c
Normal file
6466
src/extra/libs/png/lodepng.c
Normal file
File diff suppressed because it is too large
Load Diff
1981
src/extra/libs/png/lodepng.h
Normal file
1981
src/extra/libs/png/lodepng.h
Normal file
File diff suppressed because it is too large
Load Diff
237
src/extra/libs/png/lv_png.c
Normal file
237
src/extra/libs/png/lv_png.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file lv_png.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_PNG
|
||||
|
||||
#include "lv_png.h"
|
||||
#include "lodepng.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t decoder_info(struct _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 void decoder_close(lv_img_decoder_t * dec, lv_img_decoder_dsc_t * dsc);
|
||||
static void convert_color_depth(uint8_t * img, uint32_t px_cnt);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Register the PNG decoder functions in LittlevGL
|
||||
*/
|
||||
void lv_png_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_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(struct _lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)
|
||||
{
|
||||
(void) decoder; /*Unused*/
|
||||
lv_img_src_t src_type = lv_img_src_get_type(src); /*Get the source type*/
|
||||
|
||||
/*If it's a PNG file...*/
|
||||
if(src_type == LV_IMG_SRC_FILE) {
|
||||
const char * fn = src;
|
||||
if(!strcmp(&fn[strlen(fn) - 3], "png")) { /*Check the extension*/
|
||||
|
||||
/* Read the width and height from the file. They have a constant location:
|
||||
* [16..23]: width
|
||||
* [24..27]: height
|
||||
*/
|
||||
uint32_t size[2];
|
||||
lv_fs_file_t f;
|
||||
lv_fs_res_t res = lv_fs_open(&f, fn, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) return LV_RES_INV;
|
||||
lv_fs_seek(&f, 16, LV_FS_SEEK_SET);
|
||||
uint32_t rn;
|
||||
lv_fs_read(&f, &size, 8, &rn);
|
||||
if(rn != 8) return LV_RES_INV;
|
||||
lv_fs_close(&f);
|
||||
/*Save the data in the header*/
|
||||
header->always_zero = 0;
|
||||
header->cf = LV_IMG_CF_RAW_ALPHA;
|
||||
/*The width and height are stored in Big endian format so convert them to little endian*/
|
||||
header->w = (lv_coord_t) ((size[0] & 0xff000000) >> 24) + ((size[0] & 0x00ff0000) >> 8);
|
||||
header->h = (lv_coord_t) ((size[1] & 0xff000000) >> 24) + ((size[1] & 0x00ff0000) >> 8);
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
}
|
||||
/*If it's a PNG file in a C array...*/
|
||||
else if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = src;
|
||||
header->always_zero = 0;
|
||||
header->cf = img_dsc->header.cf; /*Save the color format*/
|
||||
header->w = img_dsc->header.w; /*Save the color width*/
|
||||
header->h = img_dsc->header.h; /*Save the color height*/
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
(void) decoder; /*Unused*/
|
||||
uint32_t error; /*For the return values of PNG decoder functions*/
|
||||
|
||||
uint8_t * img_data = NULL;
|
||||
|
||||
/*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], "png")) { /*Check the extension*/
|
||||
|
||||
/*Load the PNG file into buffer. It's still compressed (not decoded)*/
|
||||
unsigned char * png_data; /*Pointer to the loaded data. Same as the original file just loaded into the RAM*/
|
||||
size_t png_data_size; /*Size of `png_data` in bytes*/
|
||||
|
||||
error = lodepng_load_file(&png_data, &png_data_size, fn); /*Load the file*/
|
||||
if(error) {
|
||||
printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*Decode the PNG image*/
|
||||
uint32_t png_width; /*Will be the width of the decoded image*/
|
||||
uint32_t png_height; /*Will be the width of the decoded image*/
|
||||
|
||||
/*Decode the loaded image in ARGB8888 */
|
||||
error = lodepng_decode32(&img_data, &png_width, &png_height, png_data, png_data_size);
|
||||
free(png_data); /*Free the loaded file*/
|
||||
if(error) {
|
||||
printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*Convert the image to the system's color depth*/
|
||||
convert_color_depth(img_data, png_width * png_height);
|
||||
dsc->img_data = img_data;
|
||||
return LV_RES_OK; /*The image is fully decoded. Return with its pointer*/
|
||||
}
|
||||
}
|
||||
/*If it's a PNG file in a C array...*/
|
||||
else if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = dsc->src;
|
||||
uint32_t png_width; /*No used, just required by he decoder*/
|
||||
uint32_t png_height; /*No used, just required by he decoder*/
|
||||
|
||||
/*Decode the image in ARGB8888 */
|
||||
error = lodepng_decode32(&img_data, &png_width, &png_height, img_dsc->data, img_dsc->data_size);
|
||||
|
||||
if(error) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*Convert the image to the system's color depth*/
|
||||
convert_color_depth(img_data, png_width * png_height);
|
||||
|
||||
dsc->img_data = img_data;
|
||||
return LV_RES_OK; /*Return with its pointer*/
|
||||
}
|
||||
|
||||
return LV_RES_INV; /*If not returned earlier then it failed*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the allocated resources
|
||||
*/
|
||||
static void decoder_close(lv_img_decoder_t *decoder, lv_img_decoder_dsc_t *dsc)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
if (dsc->img_data) {
|
||||
free((uint8_t *)dsc->img_data);
|
||||
dsc->img_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the display is not in 32 bit format (ARGB888) then covert the image to the current color depth
|
||||
* @param img the ARGB888 image
|
||||
* @param px_cnt number of pixels in `img`
|
||||
*/
|
||||
static void convert_color_depth(uint8_t * img, uint32_t px_cnt)
|
||||
{
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
lv_color32_t * img_argb = (lv_color32_t*)img;
|
||||
lv_color_t c;
|
||||
lv_color_t * img_c = (lv_color_t *) img;
|
||||
uint32_t i;
|
||||
for(i = 0; i < px_cnt; i++) {
|
||||
c = lv_color_make(img_argb[i].ch.red, img_argb[i].ch.green, img_argb[i].ch.blue);
|
||||
img_c[i].ch.red = c.ch.blue;
|
||||
img_c[i].ch.blue = c.ch.red;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
lv_color32_t * img_argb = (lv_color32_t*)img;
|
||||
lv_color_t c;
|
||||
uint32_t i;
|
||||
for(i = 0; i < px_cnt; i++) {
|
||||
c = lv_color_make(img_argb[i].ch.blue, img_argb[i].ch.green, img_argb[i].ch.red);
|
||||
img[i*3 + 2] = img_argb[i].ch.alpha;
|
||||
img[i*3 + 1] = c.full >> 8;
|
||||
img[i*3 + 0] = c.full & 0xFF;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color32_t * img_argb = (lv_color32_t*)img;
|
||||
lv_color_t c;
|
||||
uint32_t i;
|
||||
for(i = 0; i < px_cnt; i++) {
|
||||
c = lv_color_make(img_argb[i].red, img_argb[i].green, img_argb[i].blue);
|
||||
img[i*2 + 1] = img_argb[i].alpha;
|
||||
img[i*2 + 0] = c.full
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /*LV_USE_PNG*/
|
||||
|
||||
|
||||
46
src/extra/libs/png/lv_png.h
Normal file
46
src/extra/libs/png/lv_png.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file lv_png.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_PNG_H
|
||||
#define LV_PNG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_PNG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Register the PNG decoder functions in LittlevGL
|
||||
*/
|
||||
void lv_png_init(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_PNG*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PNG_H*/
|
||||
174
src/extra/libs/qrcode/lv_qrcode.c
Normal file
174
src/extra/libs/qrcode/lv_qrcode.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @file lv_qrcode.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_qrcode.h"
|
||||
#if LV_USE_QRCODE
|
||||
|
||||
#include "qrcodegen.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define QR_SIZE 140
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an empty QR code (an `lv_canvas`) object.
|
||||
* @param parent point to an object where to create the QR code
|
||||
* @param size width and height of the QR code
|
||||
* @param dark_color dark color of the QR code
|
||||
* @param light_color light color of the QR code
|
||||
* @return pointer to the created QR code object
|
||||
*/
|
||||
lv_obj_t * lv_qrcode_create(lv_obj_t * parent, lv_coord_t size, lv_color_t dark_color, lv_color_t light_color)
|
||||
{
|
||||
uint32_t buf_size = LV_CANVAS_BUF_SIZE_INDEXED_1BIT(size, size);
|
||||
uint8_t * buf = lv_mem_alloc(buf_size);
|
||||
LV_ASSERT_MALLOC(buf);
|
||||
if(buf == NULL) return NULL;
|
||||
|
||||
lv_obj_t * canvas = lv_canvas_create(parent);
|
||||
if(canvas == NULL) return NULL;
|
||||
|
||||
lv_canvas_set_buffer(canvas, buf, size, size, LV_IMG_CF_INDEXED_1BIT);
|
||||
lv_canvas_set_palette(canvas, 0, dark_color);
|
||||
lv_canvas_set_palette(canvas, 1, light_color);
|
||||
|
||||
return canvas;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data of a QR code object
|
||||
* @param qrcode pointer to aQ code object
|
||||
* @param data data to display
|
||||
* @param data_len length of data in bytes
|
||||
* @return LV_RES_OK: if no error; LV_RES_INV: on error
|
||||
*/
|
||||
lv_res_t lv_qrcode_update(lv_obj_t * qrcode, const void * data, uint32_t data_len)
|
||||
{
|
||||
lv_color_t c;
|
||||
c.full = 1;
|
||||
lv_canvas_fill_bg(qrcode, c, LV_OPA_COVER);
|
||||
|
||||
if(data_len > qrcodegen_BUFFER_LEN_MAX) return LV_RES_INV;
|
||||
|
||||
uint8_t * qr0 = lv_mem_alloc(qrcodegen_BUFFER_LEN_MAX);
|
||||
LV_ASSERT_MALLOC(qr0);
|
||||
uint8_t * data_tmp = lv_mem_alloc(qrcodegen_BUFFER_LEN_MAX);
|
||||
LV_ASSERT_MALLOC(data_tmp);
|
||||
memcpy(data_tmp, data, data_len);
|
||||
|
||||
bool ok = qrcodegen_encodeBinary(data_tmp, data_len,
|
||||
qr0, qrcodegen_Ecc_MEDIUM,
|
||||
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX,
|
||||
qrcodegen_Mask_AUTO, true);
|
||||
|
||||
if (!ok) {
|
||||
lv_mem_free(qr0);
|
||||
lv_mem_free(data_tmp);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
|
||||
lv_img_dsc_t * imgdsc = lv_canvas_get_img(qrcode);
|
||||
lv_coord_t obj_w = imgdsc->header.w;
|
||||
int qr_size = qrcodegen_getSize(qr0);
|
||||
int scale = obj_w / qr_size;
|
||||
int scaled = qr_size * scale;
|
||||
int margin = (obj_w - scaled) / 2;
|
||||
uint8_t * buf_u8 = (uint8_t *)imgdsc->data + 8; /*+8 skip the palette*/
|
||||
|
||||
/* Copy the qr code canvas:
|
||||
* A simple `lv_canvas_set_px` would work but it's slow for so many pixels.
|
||||
* So buffer 1 byte (8 px) from the qr code and set it in the canvas image */
|
||||
uint32_t row_byte_cnt = (imgdsc->header.w + 7) >> 3;
|
||||
int y;
|
||||
for (y = margin; y < scaled + margin; y+=scale) {
|
||||
uint8_t b = 0;
|
||||
uint8_t p = 0;
|
||||
bool aligned = false;
|
||||
int x;
|
||||
for (x = margin; x < scaled + margin; x++) {
|
||||
bool a = qrcodegen_getModule(qr0, (x - margin) / scale, (y - margin) / scale);
|
||||
|
||||
if(aligned == false && (x & 0x7) == 0) aligned = true;
|
||||
|
||||
if(aligned == false) {
|
||||
c.full = a ? 0 : 1;
|
||||
lv_canvas_set_px(qrcode, x, y, c);
|
||||
} else {
|
||||
if(!a) b |= (1 << (7 - p));
|
||||
p++;
|
||||
if(p == 8) {
|
||||
uint32_t px = row_byte_cnt * y + (x >> 3);
|
||||
buf_u8[px] = b;
|
||||
b = 0;
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Process the last byte of the row*/
|
||||
if(p) {
|
||||
/*Make the rest of the bits white*/
|
||||
b |= (1 << (8 - p)) - 1;
|
||||
|
||||
uint32_t px = row_byte_cnt * y + (x >> 3);
|
||||
buf_u8[px] = b;
|
||||
}
|
||||
|
||||
/*The Qr is probably scaled so simply to the repeated rows*/
|
||||
int s;
|
||||
const uint8_t * row_ori = buf_u8 + row_byte_cnt * y;
|
||||
for(s = 1; s < scale; s++) {
|
||||
memcpy((uint8_t*)buf_u8 + row_byte_cnt * (y + s), row_ori, row_byte_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
lv_mem_free(qr0);
|
||||
lv_mem_free(data_tmp);
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a QR code object
|
||||
* @param qrcode pointer to a QR code obejct
|
||||
*/
|
||||
void lv_qrcode_delete(lv_obj_t * qrcode)
|
||||
{
|
||||
lv_img_dsc_t * img = lv_canvas_get_img(qrcode);
|
||||
lv_img_cache_invalidate_src(img);
|
||||
lv_mem_free((void*)img->data);
|
||||
lv_obj_del(qrcode);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_QRCODE*/
|
||||
66
src/extra/libs/qrcode/lv_qrcode.h
Normal file
66
src/extra/libs/qrcode/lv_qrcode.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file lv_qrcode
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_QRCODE_H
|
||||
#define LV_QRCODE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_QRCODE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an empty QR code (an `lv_canvas`) object.
|
||||
* @param parent point to an object where to create the QR code
|
||||
* @param size width and height of the QR code
|
||||
* @param dark_color dark color of the QR code
|
||||
* @param light_color light color of the QR code
|
||||
* @return pointer to the created QR code object
|
||||
*/
|
||||
lv_obj_t * lv_qrcode_create(lv_obj_t * parent, lv_coord_t size, lv_color_t dark_color, lv_color_t light_color);
|
||||
|
||||
/**
|
||||
* Set the data of a QR code object
|
||||
* @param qrcode pointer to aQ code object
|
||||
* @param data data to display
|
||||
* @param data_len length of data in bytes
|
||||
* @return LV_RES_OK: if no error; LV_RES_INV: on error
|
||||
*/
|
||||
lv_res_t lv_qrcode_update(lv_obj_t * qrcode, const void * data, uint32_t data_len);
|
||||
|
||||
/**
|
||||
* Delete a QR code object
|
||||
* @param qrcode pointer to a QR code object
|
||||
*/
|
||||
void lv_qrcode_delete(lv_obj_t * qrcode);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_QRCODE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_QRCODE_H*/
|
||||
1009
src/extra/libs/qrcode/qrcodegen.c
Normal file
1009
src/extra/libs/qrcode/qrcodegen.c
Normal file
File diff suppressed because it is too large
Load Diff
311
src/extra/libs/qrcode/qrcodegen.h
Normal file
311
src/extra/libs/qrcode/qrcodegen.h
Normal file
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* QR Code generator library (C)
|
||||
*
|
||||
* Copyright (c) Project Nayuki. (MIT License)
|
||||
* https://www.nayuki.io/page/qr-code-generator-library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* - The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
* - The Software is provided "as is", without warranty of any kind, express or
|
||||
* implied, including but not limited to the warranties of merchantability,
|
||||
* fitness for a particular purpose and noninfringement. In no event shall the
|
||||
* authors or copyright holders be liable for any claim, damages or other
|
||||
* liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
* out of or in connection with the Software or the use or other dealings in the
|
||||
* Software.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This library creates QR Code symbols, which is a type of two-dimension barcode.
|
||||
* Invented by Denso Wave and described in the ISO/IEC 18004 standard.
|
||||
* A QR Code structure is an immutable square grid of black and white cells.
|
||||
* The library provides functions to create a QR Code from text or binary data.
|
||||
* The library covers the QR Code Model 2 specification, supporting all versions (sizes)
|
||||
* from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
|
||||
*
|
||||
* Ways to create a QR Code object:
|
||||
* - High level: Take the payload data and call qrcodegen_encodeText() or qrcodegen_encodeBinary().
|
||||
* - Low level: Custom-make the list of segments and call
|
||||
* qrcodegen_encodeSegments() or qrcodegen_encodeSegmentsAdvanced().
|
||||
* (Note that all ways require supplying the desired error correction level and various byte buffers.)
|
||||
*/
|
||||
|
||||
|
||||
/*---- Enum and struct types----*/
|
||||
|
||||
/*
|
||||
* The error correction level in a QR Code symbol.
|
||||
*/
|
||||
enum qrcodegen_Ecc {
|
||||
// Must be declared in ascending order of error protection
|
||||
// so that an internal qrcodegen function works properly
|
||||
qrcodegen_Ecc_LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords
|
||||
qrcodegen_Ecc_MEDIUM , // The QR Code can tolerate about 15% erroneous codewords
|
||||
qrcodegen_Ecc_QUARTILE, // The QR Code can tolerate about 25% erroneous codewords
|
||||
qrcodegen_Ecc_HIGH , // The QR Code can tolerate about 30% erroneous codewords
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The mask pattern used in a QR Code symbol.
|
||||
*/
|
||||
enum qrcodegen_Mask {
|
||||
// A special value to tell the QR Code encoder to
|
||||
// automatically select an appropriate mask pattern
|
||||
qrcodegen_Mask_AUTO = -1,
|
||||
// The eight actual mask patterns
|
||||
qrcodegen_Mask_0 = 0,
|
||||
qrcodegen_Mask_1,
|
||||
qrcodegen_Mask_2,
|
||||
qrcodegen_Mask_3,
|
||||
qrcodegen_Mask_4,
|
||||
qrcodegen_Mask_5,
|
||||
qrcodegen_Mask_6,
|
||||
qrcodegen_Mask_7,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Describes how a segment's data bits are interpreted.
|
||||
*/
|
||||
enum qrcodegen_Mode {
|
||||
qrcodegen_Mode_NUMERIC = 0x1,
|
||||
qrcodegen_Mode_ALPHANUMERIC = 0x2,
|
||||
qrcodegen_Mode_BYTE = 0x4,
|
||||
qrcodegen_Mode_KANJI = 0x8,
|
||||
qrcodegen_Mode_ECI = 0x7,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A segment of character/binary/control data in a QR Code symbol.
|
||||
* The mid-level way to create a segment is to take the payload data
|
||||
* and call a factory function such as qrcodegen_makeNumeric().
|
||||
* The low-level way to create a segment is to custom-make the bit buffer
|
||||
* and initialize a qrcodegen_Segment struct with appropriate values.
|
||||
* Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
|
||||
* Any segment longer than this is meaningless for the purpose of generating QR Codes.
|
||||
* Moreover, the maximum allowed bit length is 32767 because
|
||||
* the largest QR Code (version 40) has 31329 modules.
|
||||
*/
|
||||
struct qrcodegen_Segment {
|
||||
// The mode indicator of this segment.
|
||||
enum qrcodegen_Mode mode;
|
||||
|
||||
// The length of this segment's unencoded data. Measured in characters for
|
||||
// numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
|
||||
// Always zero or positive. Not the same as the data's bit length.
|
||||
int numChars;
|
||||
|
||||
// The data bits of this segment, packed in bitwise big endian.
|
||||
// Can be null if the bit length is zero.
|
||||
uint8_t *data;
|
||||
|
||||
// The number of valid data bits used in the buffer. Requires
|
||||
// 0 <= bitLength <= 32767, and bitLength <= (capacity of data array) * 8.
|
||||
// The character count (numChars) must agree with the mode and the bit buffer length.
|
||||
int bitLength;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*---- Macro constants and functions ----*/
|
||||
|
||||
#define qrcodegen_VERSION_MIN 1 // The minimum version number supported in the QR Code Model 2 standard
|
||||
#define qrcodegen_VERSION_MAX 40 // The maximum version number supported in the QR Code Model 2 standard
|
||||
|
||||
// Calculates the number of bytes needed to store any QR Code up to and including the given version number,
|
||||
// as a compile-time constant. For example, 'uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(25)];'
|
||||
// can store any single QR Code from version 1 to 25 (inclusive). The result fits in an int (or int16).
|
||||
// Requires qrcodegen_VERSION_MIN <= n <= qrcodegen_VERSION_MAX.
|
||||
#define qrcodegen_BUFFER_LEN_FOR_VERSION(n) ((((n) * 4 + 17) * ((n) * 4 + 17) + 7) / 8 + 1)
|
||||
|
||||
// The worst-case number of bytes needed to store one QR Code, up to and including
|
||||
// version 40. This value equals 3918, which is just under 4 kilobytes.
|
||||
// Use this more convenient value to avoid calculating tighter memory bounds for buffers.
|
||||
#define qrcodegen_BUFFER_LEN_MAX qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX)
|
||||
|
||||
|
||||
|
||||
/*---- Functions (high level) to generate QR Codes ----*/
|
||||
|
||||
/*
|
||||
* Encodes the given text string to a QR Code, returning true if encoding succeeded.
|
||||
* If the data is too long to fit in any version in the given range
|
||||
* at the given ECC level, then false is returned.
|
||||
* - The input text must be encoded in UTF-8 and contain no NULs.
|
||||
* - The variables ecl and mask must correspond to enum constant values.
|
||||
* - Requires 1 <= minVersion <= maxVersion <= 40.
|
||||
* - The arrays tempBuffer and qrcode must each have a length
|
||||
* of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion).
|
||||
* - After the function returns, tempBuffer contains no useful data.
|
||||
* - If successful, the resulting QR Code may use numeric,
|
||||
* alphanumeric, or byte mode to encode the text.
|
||||
* - In the most optimistic case, a QR Code at version 40 with low ECC
|
||||
* can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string
|
||||
* up to 4296 characters, or any digit string up to 7089 characters.
|
||||
* These numbers represent the hard upper limit of the QR Code standard.
|
||||
* - Please consult the QR Code specification for information on
|
||||
* data capacities per version, ECC level, and text encoding mode.
|
||||
*/
|
||||
bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[],
|
||||
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);
|
||||
|
||||
|
||||
/*
|
||||
* Encodes the given binary data to a QR Code, returning true if encoding succeeded.
|
||||
* If the data is too long to fit in any version in the given range
|
||||
* at the given ECC level, then false is returned.
|
||||
* - The input array range dataAndTemp[0 : dataLen] should normally be
|
||||
* valid UTF-8 text, but is not required by the QR Code standard.
|
||||
* - The variables ecl and mask must correspond to enum constant values.
|
||||
* - Requires 1 <= minVersion <= maxVersion <= 40.
|
||||
* - The arrays dataAndTemp and qrcode must each have a length
|
||||
* of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion).
|
||||
* - After the function returns, the contents of dataAndTemp may have changed,
|
||||
* and does not represent useful data anymore.
|
||||
* - If successful, the resulting QR Code will use byte mode to encode the data.
|
||||
* - In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte
|
||||
* sequence up to length 2953. This is the hard upper limit of the QR Code standard.
|
||||
* - Please consult the QR Code specification for information on
|
||||
* data capacities per version, ECC level, and text encoding mode.
|
||||
*/
|
||||
bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[],
|
||||
enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl);
|
||||
|
||||
|
||||
/*---- Functions (low level) to generate QR Codes ----*/
|
||||
|
||||
/*
|
||||
* Renders a QR Code representing the given segments at the given error correction level.
|
||||
* The smallest possible QR Code version is automatically chosen for the output. Returns true if
|
||||
* QR Code creation succeeded, or false if the data is too long to fit in any version. The ECC level
|
||||
* of the result may be higher than the ecl argument if it can be done without increasing the version.
|
||||
* This function allows the user to create a custom sequence of segments that switches
|
||||
* between modes (such as alphanumeric and byte) to encode text in less space.
|
||||
* This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary().
|
||||
* To save memory, the segments' data buffers can alias/overlap tempBuffer, and will
|
||||
* result in them being clobbered, but the QR Code output will still be correct.
|
||||
* But the qrcode array must not overlap tempBuffer or any segment's data buffer.
|
||||
*/
|
||||
bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len,
|
||||
enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]);
|
||||
|
||||
|
||||
/*
|
||||
* Renders a QR Code representing the given segments with the given encoding parameters.
|
||||
* Returns true if QR Code creation succeeded, or false if the data is too long to fit in the range of versions.
|
||||
* The smallest possible QR Code version within the given range is automatically
|
||||
* chosen for the output. Iff boostEcl is true, then the ECC level of the result
|
||||
* may be higher than the ecl argument if it can be done without increasing the
|
||||
* version. The mask number is either between 0 to 7 (inclusive) to force that
|
||||
* mask, or -1 to automatically choose an appropriate mask (which may be slow).
|
||||
* This function allows the user to create a custom sequence of segments that switches
|
||||
* between modes (such as alphanumeric and byte) to encode text in less space.
|
||||
* This is a low-level API; the high-level API is qrcodegen_encodeText() and qrcodegen_encodeBinary().
|
||||
* To save memory, the segments' data buffers can alias/overlap tempBuffer, and will
|
||||
* result in them being clobbered, but the QR Code output will still be correct.
|
||||
* But the qrcode array must not overlap tempBuffer or any segment's data buffer.
|
||||
*/
|
||||
bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl,
|
||||
int minVersion, int maxVersion, int mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]);
|
||||
|
||||
|
||||
/*
|
||||
* Tests whether the given string can be encoded as a segment in alphanumeric mode.
|
||||
* A string is encodable iff each character is in the following set: 0 to 9, A to Z
|
||||
* (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
||||
*/
|
||||
bool qrcodegen_isAlphanumeric(const char *text);
|
||||
|
||||
|
||||
/*
|
||||
* Tests whether the given string can be encoded as a segment in numeric mode.
|
||||
* A string is encodable iff each character is in the range 0 to 9.
|
||||
*/
|
||||
bool qrcodegen_isNumeric(const char *text);
|
||||
|
||||
|
||||
/*
|
||||
* Returns the number of bytes (uint8_t) needed for the data buffer of a segment
|
||||
* containing the given number of characters using the given mode. Notes:
|
||||
* - Returns SIZE_MAX on failure, i.e. numChars > INT16_MAX or
|
||||
* the number of needed bits exceeds INT16_MAX (i.e. 32767).
|
||||
* - Otherwise, all valid results are in the range [0, ceil(INT16_MAX / 8)], i.e. at most 4096.
|
||||
* - It is okay for the user to allocate more bytes for the buffer than needed.
|
||||
* - For byte mode, numChars measures the number of bytes, not Unicode code points.
|
||||
* - For ECI mode, numChars must be 0, and the worst-case number of bytes is returned.
|
||||
* An actual ECI segment can have shorter data. For non-ECI modes, the result is exact.
|
||||
*/
|
||||
size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a segment representing the given binary data encoded in
|
||||
* byte mode. All input byte arrays are acceptable. Any text string
|
||||
* can be converted to UTF-8 bytes and encoded as a byte mode segment.
|
||||
*/
|
||||
struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a segment representing the given string of decimal digits encoded in numeric mode.
|
||||
*/
|
||||
struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a segment representing the given text string encoded in alphanumeric mode.
|
||||
* The characters allowed are: 0 to 9, A to Z (uppercase only), space,
|
||||
* dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
||||
*/
|
||||
struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a segment representing an Extended Channel Interpretation
|
||||
* (ECI) designator with the given assignment value.
|
||||
*/
|
||||
struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]);
|
||||
|
||||
|
||||
/*---- Functions to extract raw data from QR Codes ----*/
|
||||
|
||||
/*
|
||||
* Returns the side length of the given QR Code, assuming that encoding succeeded.
|
||||
* The result is in the range [21, 177]. Note that the length of the array buffer
|
||||
* is related to the side length - every 'uint8_t qrcode[]' must have length at least
|
||||
* qrcodegen_BUFFER_LEN_FOR_VERSION(version), which equals ceil(size^2 / 8 + 1).
|
||||
*/
|
||||
int qrcodegen_getSize(const uint8_t qrcode[]);
|
||||
|
||||
|
||||
/*
|
||||
* Returns the color of the module (pixel) at the given coordinates, which is false
|
||||
* for white or true for black. The top left corner has the coordinates (x=0, y=0).
|
||||
* If the given coordinates are out of bounds, then false (white) is returned.
|
||||
*/
|
||||
bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
871
src/extra/libs/sjpg/lv_sjpg.c
Normal file
871
src/extra/libs/sjpg/lv_sjpg.c
Normal file
@@ -0,0 +1,871 @@
|
||||
/**
|
||||
* @file lv_sjpg.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------
|
||||
/ Added normal JPG support [7/10/2020]
|
||||
/ ----------
|
||||
/ SJPEG is a custom created modified JPEG file format for small embedded platforms.
|
||||
/ It will contain multiple JPEG fragments all embedded into a single file with a custom header.
|
||||
/ This makes JPEG decoding easier using any JPEG library. Overall file size will be almost
|
||||
/ similar to the parent jpeg file. We can generate sjpeg from any jpeg using a python script
|
||||
/ provided along with this project.
|
||||
/ (by vinodstanur | 2020 )
|
||||
/ SJPEG FILE STRUCTURE
|
||||
/ --------------------------------------------------------------------------------------------------------------------------------
|
||||
/ Bytes | Value |
|
||||
/ --------------------------------------------------------------------------------------------------------------------------------
|
||||
/
|
||||
/ 0 - 7 | "_SJPG__" followed by '\0'
|
||||
/
|
||||
/ 8 - 13 | "V1.00" followed by '\0' [VERSION OF SJPG FILE for future compatibiliby]
|
||||
/
|
||||
/ 14 - 15 | X_RESOLUTION (width) [little endian]
|
||||
/
|
||||
/ 16 - 17 | Y_RESOLUTION (height) [little endian]
|
||||
/
|
||||
/ 18 - 19 | TOTAL_FRAMES inside sjpeg [little endian]
|
||||
/
|
||||
/ 20 - 21 | JPEG BLOCK WIDTH (16 normally) [little endian]
|
||||
/
|
||||
/ 22 - [(TOTAL_FRAMES*2 )] | SIZE OF EACH JPEG SPLIT FRAGMENTS (FRAME_INFO_ARRAY)
|
||||
/
|
||||
/ SJPEG data | Each JPEG frame can be extracted from SJPEG data by parsing the FRAME_INFO_ARRAY one time.
|
||||
/
|
||||
/----------------------------------------------------------------------------------------------------------------------------------
|
||||
/ JPEG DECODER
|
||||
/ ------------
|
||||
/ We are using TJpgDec - Tiny JPEG Decompressor library from ELM-CHAN for decoding each split-jpeg fragments.
|
||||
/ The tjpgd.c and tjpgd.h is not modified and those are used as it is. So if any update comes for the tiny-jpeg,
|
||||
/ just replace those files with updated files.
|
||||
/---------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_SJPG
|
||||
|
||||
#include "tjpgd.h"
|
||||
#include "lv_sjpg.h"
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define TJPGD_WORKBUFF_SIZE 4096 //Recommended by TJPGD libray
|
||||
|
||||
//NEVER EDIT THESE OFFSET VALUES
|
||||
#define SJPEG_VERSION_OFFSET 8
|
||||
#define SJPEG_X_RES_OFFSET 14
|
||||
#define SJPEG_y_RES_OFFSET 16
|
||||
#define SJPEG_TOTAL_FRAMES_OFFSET 18
|
||||
#define SJPEG_BLOCK_WIDTH_OFFSET 20
|
||||
#define SJPEG_FRAME_INFO_ARRAY_OFFSET 22
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* 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 * decoder, 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 * decoder, lv_img_decoder_dsc_t * dsc );
|
||||
static size_t input_func ( JDEC* jd, uint8_t* buff, size_t ndata );
|
||||
static int is_jpg( const uint8_t *raw_data );
|
||||
static void lv_sjpg_cleanup( SJPEG* sjpeg );
|
||||
static void lv_sjpg_free( SJPEG* sjpeg );
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
void lv_split_jpeg_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_close_cb( dec, decoder_close );
|
||||
lv_img_decoder_set_read_line_cb( dec, decoder_read_line );
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
/**
|
||||
* Get info about an SJPG / JPG image
|
||||
* @param decoder pointer to the decoder where this function belongs
|
||||
* @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);
|
||||
|
||||
/*Check whether the type `src` is known by the decoder*/
|
||||
/* Read the SJPG/JPG header and find `width` and `height` */
|
||||
|
||||
lv_img_src_t src_type = lv_img_src_get_type(src); /*Get the source type*/
|
||||
|
||||
lv_res_t ret = LV_RES_OK;
|
||||
|
||||
if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||
uint8_t *raw_sjpeg_data = (uint8_t *)((lv_img_dsc_t * )src)->data;
|
||||
const uint32_t raw_sjpeg_data_size = ((lv_img_dsc_t *)src)->data_size;
|
||||
|
||||
if(!strncmp((char *)raw_sjpeg_data, "_SJPG__", strlen("_SJPG__") )) {
|
||||
|
||||
raw_sjpeg_data += 14; //seek to res info ... refer sjpeg format
|
||||
header->always_zero = 0;
|
||||
header->cf = LV_IMG_CF_RAW;
|
||||
|
||||
header->w = *raw_sjpeg_data++;
|
||||
header->w |= *raw_sjpeg_data++ << 8;
|
||||
|
||||
header->h = *raw_sjpeg_data++;
|
||||
header->h |= *raw_sjpeg_data++ << 8;
|
||||
|
||||
return ret;
|
||||
|
||||
} else if( is_jpg( raw_sjpeg_data ) == true ) {
|
||||
header->always_zero = 0;
|
||||
header->cf = LV_IMG_CF_RAW;
|
||||
|
||||
uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if(!workb_temp) return LV_RES_INV;
|
||||
|
||||
io_source_t io_source_temp;
|
||||
io_source_temp.type = SJPEG_IO_SOURCE_C_ARRAY;
|
||||
io_source_temp.raw_sjpg_data = raw_sjpeg_data;
|
||||
io_source_temp.raw_sjpg_data_size = raw_sjpeg_data_size;
|
||||
io_source_temp.raw_sjpg_data_next_read_pos = 0;
|
||||
|
||||
JDEC jd_tmp;
|
||||
|
||||
JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp);
|
||||
if(rc == JDR_OK ) {
|
||||
header->w = jd_tmp.width;
|
||||
header->h = jd_tmp.height;
|
||||
|
||||
} else {
|
||||
ret = LV_RES_INV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
lv_mem_free(workb_temp);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
else if( src_type == LV_IMG_SRC_FILE ) {
|
||||
const char * fn = src;
|
||||
if(!strcmp(&fn[strlen(fn) - 5], ".sjpg")) {
|
||||
|
||||
uint8_t buff[22];
|
||||
memset(buff, 0, sizeof(buff));
|
||||
|
||||
lv_fs_file_t file;
|
||||
lv_fs_res_t res = lv_fs_open(&file , fn, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) return 78;
|
||||
|
||||
uint32_t rn;
|
||||
res = lv_fs_read(&file, buff, 8, &rn);
|
||||
if(res != LV_FS_RES_OK || rn != 8) {
|
||||
lv_fs_close(&file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(strcmp((char *)buff, "_SJPG__") == 0 ) {
|
||||
lv_fs_seek(&file, 14, LV_FS_SEEK_SET);
|
||||
res = lv_fs_read(&file, buff, 4, &rn);
|
||||
if(res != LV_FS_RES_OK || rn != 4 ) {
|
||||
lv_fs_close(&file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
header->always_zero = 0;
|
||||
header->cf = LV_IMG_CF_RAW;
|
||||
uint8_t *raw_sjpeg_data = buff;
|
||||
header->w = *raw_sjpeg_data++;
|
||||
header->w |= *raw_sjpeg_data++ << 8;
|
||||
header->h = *raw_sjpeg_data++;
|
||||
header->h |= *raw_sjpeg_data++ << 8;
|
||||
lv_fs_close(&file);
|
||||
return LV_RES_OK;
|
||||
|
||||
}
|
||||
} else if(!strcmp(&fn[strlen(fn) - 4], ".jpg")) {
|
||||
lv_fs_file_t file;
|
||||
lv_fs_res_t res = lv_fs_open(&file , fn, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) return 78;
|
||||
|
||||
uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if(!workb_temp) {
|
||||
lv_fs_close(&file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
io_source_t io_source_temp;
|
||||
io_source_temp.type = SJPEG_IO_SOURCE_DISK;
|
||||
io_source_temp.raw_sjpg_data_next_read_pos = 0;
|
||||
io_source_temp.img_cache_buff = NULL;
|
||||
io_source_temp.lv_file = file;
|
||||
JDEC jd_tmp;
|
||||
|
||||
JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp);
|
||||
lv_mem_free(workb_temp);
|
||||
lv_fs_close(&file);
|
||||
|
||||
if(rc == JDR_OK ) {
|
||||
header->always_zero = 0;
|
||||
header->cf = LV_IMG_CF_RAW;
|
||||
header->w = jd_tmp.width;
|
||||
header->h = jd_tmp.height;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
static int img_data_cb( JDEC* jd, void* data, JRECT* rect )
|
||||
{
|
||||
io_source_t *io = jd->device;
|
||||
uint8_t *cache = io->img_cache_buff;
|
||||
const int xres = io->img_cache_x_res;
|
||||
uint8_t *buf = data;
|
||||
const int INPUT_PIXEL_SIZE = 3;
|
||||
const int row_width = rect->right - rect->left + 1; // Row width in pixels.
|
||||
const int row_size = row_width * INPUT_PIXEL_SIZE; // Row size (bytes).
|
||||
|
||||
for( int y = rect->top; y <= rect->bottom; y++ ) {
|
||||
int row_offset = y * xres * INPUT_PIXEL_SIZE + rect->left * INPUT_PIXEL_SIZE;
|
||||
memcpy( cache + row_offset, buf, row_size );
|
||||
buf += row_size;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t input_func ( JDEC* jd, uint8_t* buff, size_t ndata )
|
||||
{
|
||||
io_source_t *io = jd->device;
|
||||
|
||||
if(!io) return 0;
|
||||
|
||||
if(io->type == SJPEG_IO_SOURCE_C_ARRAY) {
|
||||
const uint32_t bytes_left = io->raw_sjpg_data_size - io->raw_sjpg_data_next_read_pos;
|
||||
const uint32_t to_read = ndata <= bytes_left ? (uint32_t)ndata : bytes_left;
|
||||
if (to_read == 0)
|
||||
return 0;
|
||||
if(buff) {
|
||||
memcpy(buff, io->raw_sjpg_data + io->raw_sjpg_data_next_read_pos, to_read);
|
||||
}
|
||||
io->raw_sjpg_data_next_read_pos += to_read;
|
||||
return to_read;
|
||||
}
|
||||
else if(io->type == SJPEG_IO_SOURCE_DISK) {
|
||||
|
||||
lv_fs_file_t* lv_file_p = &(io->lv_file);
|
||||
|
||||
if( buff ) {
|
||||
uint32_t rn = 0;
|
||||
lv_fs_read(lv_file_p, buff, (uint32_t)ndata, &rn);
|
||||
return rn;
|
||||
} else {
|
||||
uint32_t pos;
|
||||
lv_fs_tell(lv_file_p, &pos);
|
||||
lv_fs_seek(lv_file_p, (uint32_t)(ndata + pos), LV_FS_SEEK_SET);
|
||||
return ndata;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open SJPG image and return the decided image
|
||||
* @param decoder pointer to the decoder where this function belongs
|
||||
* @param dsc pointer to a descriptor which describes this decoding session
|
||||
* @return LV_RES_OK: no error; LV_RES_INV: can't get the info
|
||||
*/
|
||||
static lv_res_t decoder_open( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc )
|
||||
{
|
||||
LV_UNUSED(decoder);
|
||||
lv_res_t lv_ret = LV_RES_OK;
|
||||
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
uint8_t *data;
|
||||
SJPEG* sjpeg = ( SJPEG* ) dsc->user_data;
|
||||
if( sjpeg == NULL ) {
|
||||
sjpeg = lv_mem_alloc( sizeof( SJPEG ) );
|
||||
if( !sjpeg ) return LV_RES_INV;
|
||||
|
||||
memset(sjpeg, 0, sizeof(SJPEG));
|
||||
|
||||
dsc->user_data = sjpeg;
|
||||
sjpeg->sjpeg_data = (uint8_t *)( ( lv_img_dsc_t* )(dsc->src) )->data;
|
||||
sjpeg->sjpeg_data_size = ( ( lv_img_dsc_t* )(dsc->src) )->data_size;
|
||||
}
|
||||
|
||||
if( !strncmp( ( char * ) sjpeg->sjpeg_data, "_SJPG__", strlen("_SJPG__") ) ) {
|
||||
|
||||
data = sjpeg->sjpeg_data;
|
||||
data += 14;
|
||||
|
||||
sjpeg->sjpeg_x_res = *data++;
|
||||
sjpeg->sjpeg_x_res |= *data++ << 8;
|
||||
|
||||
sjpeg->sjpeg_y_res = *data++;
|
||||
sjpeg->sjpeg_y_res |= *data++ << 8;
|
||||
|
||||
sjpeg->sjpeg_total_frames = *data++;
|
||||
sjpeg->sjpeg_total_frames |= *data++ << 8;
|
||||
|
||||
sjpeg->sjpeg_single_frame_height = *data++;
|
||||
sjpeg->sjpeg_single_frame_height |= *data++ << 8;
|
||||
|
||||
sjpeg->frame_base_array = lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames );
|
||||
if( ! sjpeg->frame_base_array ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->frame_base_offset = NULL;
|
||||
|
||||
uint8_t *img_frame_base = data + sjpeg->sjpeg_total_frames *2;
|
||||
sjpeg->frame_base_array[0] = img_frame_base;
|
||||
|
||||
for( int i = 1; i < sjpeg->sjpeg_total_frames; i++ ) {
|
||||
int offset = *data++;
|
||||
offset |= *data++ <<8;
|
||||
sjpeg->frame_base_array[i] = sjpeg->frame_base_array[i-1] + offset;
|
||||
}
|
||||
sjpeg->sjpeg_cache_frame_index = -1;
|
||||
sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3/*2*/ );
|
||||
if( ! sjpeg->frame_cache ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
sjpeg->io.img_cache_buff = sjpeg->frame_cache;
|
||||
sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res;
|
||||
sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if( ! sjpeg->workb ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) );
|
||||
if( ! sjpeg->tjpeg_jd ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
sjpeg->io.type = SJPEG_IO_SOURCE_C_ARRAY;
|
||||
sjpeg->io.lv_file.file_d = NULL;
|
||||
dsc->img_data = NULL;
|
||||
return lv_ret;
|
||||
}
|
||||
|
||||
else if( is_jpg( sjpeg->sjpeg_data ) == true ) {
|
||||
|
||||
uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if( ! workb_temp ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
io_source_t io_source_temp;
|
||||
io_source_temp.type = SJPEG_IO_SOURCE_C_ARRAY;
|
||||
io_source_temp.raw_sjpg_data = sjpeg->sjpeg_data;
|
||||
io_source_temp.raw_sjpg_data_size = sjpeg->sjpeg_data_size;
|
||||
io_source_temp.raw_sjpg_data_next_read_pos = 0;
|
||||
|
||||
JDEC jd_tmp;
|
||||
JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp);
|
||||
lv_mem_free(workb_temp);
|
||||
|
||||
|
||||
if(rc == JDR_OK ) {
|
||||
sjpeg->sjpeg_x_res = jd_tmp.width;
|
||||
sjpeg->sjpeg_y_res = jd_tmp.height;
|
||||
sjpeg->sjpeg_total_frames = 1;
|
||||
sjpeg->sjpeg_single_frame_height = jd_tmp.height;
|
||||
|
||||
sjpeg->frame_base_array = lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames );
|
||||
if( ! sjpeg->frame_base_array ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
sjpeg->frame_base_offset = NULL;
|
||||
|
||||
uint8_t *img_frame_base = sjpeg->sjpeg_data;
|
||||
sjpeg->frame_base_array[0] = img_frame_base;
|
||||
|
||||
sjpeg->sjpeg_cache_frame_index = -1;
|
||||
sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3 );
|
||||
if( ! sjpeg->frame_cache ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->io.img_cache_buff = sjpeg->frame_cache;
|
||||
sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res;
|
||||
sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if( ! sjpeg->workb ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) );
|
||||
if( ! sjpeg->tjpeg_jd ) {
|
||||
lv_sjpg_cleanup( sjpeg );
|
||||
sjpeg = NULL;
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->io.type = SJPEG_IO_SOURCE_C_ARRAY;
|
||||
sjpeg->io.lv_file.file_d = NULL;
|
||||
dsc->img_data = NULL;
|
||||
return lv_ret;
|
||||
} else {
|
||||
lv_ret = LV_RES_INV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
lv_mem_free(workb_temp);
|
||||
|
||||
return lv_ret;
|
||||
}
|
||||
}
|
||||
else if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
/* If all fine, then the file will be kept open */
|
||||
const char * fn = dsc->src;
|
||||
uint8_t *data;
|
||||
|
||||
if(!strcmp(&fn[strlen(fn) - 5], ".sjpg")) {
|
||||
|
||||
uint8_t buff[22];
|
||||
memset(buff, 0, sizeof(buff));
|
||||
|
||||
|
||||
lv_fs_file_t lv_file;
|
||||
lv_fs_res_t res = lv_fs_open(&lv_file , fn, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return 78;
|
||||
}
|
||||
|
||||
|
||||
uint32_t rn;
|
||||
res = lv_fs_read(&lv_file, buff, 22, &rn);
|
||||
if(res != LV_FS_RES_OK || rn != 22 ) {
|
||||
lv_fs_close(&lv_file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(strcmp((char *)buff, "_SJPG__") == 0 ) {
|
||||
|
||||
SJPEG* sjpeg = ( SJPEG* ) dsc->user_data;
|
||||
if(sjpeg == NULL) {
|
||||
sjpeg = lv_mem_alloc(sizeof(SJPEG));
|
||||
|
||||
if( ! sjpeg ) {
|
||||
lv_fs_close(&lv_file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
memset(sjpeg, 0, sizeof(SJPEG));
|
||||
|
||||
dsc->user_data = sjpeg;
|
||||
sjpeg->sjpeg_data = (uint8_t *)( (lv_img_dsc_t* )(dsc->src) )->data;
|
||||
sjpeg->sjpeg_data_size = ( (lv_img_dsc_t* )(dsc->src) )->data_size;
|
||||
}
|
||||
data = buff;
|
||||
data += 14;
|
||||
|
||||
sjpeg->sjpeg_x_res = *data++;
|
||||
sjpeg->sjpeg_x_res |= *data++ << 8;
|
||||
|
||||
sjpeg->sjpeg_y_res = *data++;
|
||||
sjpeg->sjpeg_y_res |= *data++ << 8;
|
||||
|
||||
sjpeg->sjpeg_total_frames = *data++;
|
||||
sjpeg->sjpeg_total_frames |= *data++ << 8;
|
||||
|
||||
sjpeg->sjpeg_single_frame_height = *data++;
|
||||
sjpeg->sjpeg_single_frame_height |= *data++ << 8;
|
||||
|
||||
sjpeg->frame_base_array = NULL;//lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames );
|
||||
sjpeg->frame_base_offset = lv_mem_alloc( sizeof(int) * sjpeg->sjpeg_total_frames );
|
||||
if( ! sjpeg->frame_base_offset ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
int img_frame_start_offset = (SJPEG_FRAME_INFO_ARRAY_OFFSET + sjpeg->sjpeg_total_frames *2);
|
||||
sjpeg->frame_base_offset[0] = img_frame_start_offset; //pointer used to save integer for now...
|
||||
|
||||
for( int i = 1; i < sjpeg->sjpeg_total_frames; i++ ) {
|
||||
res = lv_fs_read(&lv_file, buff, 2, &rn);
|
||||
if(res != LV_FS_RES_OK || rn != 2 ) {
|
||||
lv_fs_close(&lv_file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
data = buff;
|
||||
int offset = *data++;
|
||||
offset |= *data++ <<8;
|
||||
sjpeg->frame_base_offset[i] = sjpeg->frame_base_offset[i-1] + offset;
|
||||
}
|
||||
|
||||
sjpeg->sjpeg_cache_frame_index = -1; //INVALID AT BEGINNING for a forced compare mismatch at first time.
|
||||
sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3 );
|
||||
if( ! sjpeg->frame_cache ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
sjpeg->io.img_cache_buff = sjpeg->frame_cache;
|
||||
sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res;
|
||||
sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if( ! sjpeg->workb ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) );
|
||||
if( ! sjpeg->tjpeg_jd ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->io.type = SJPEG_IO_SOURCE_DISK;
|
||||
sjpeg->io.lv_file = lv_file;
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
}
|
||||
else if( !strcmp(&fn[strlen(fn) - 4], ".jpg" ) ) {
|
||||
|
||||
lv_fs_file_t lv_file;
|
||||
lv_fs_res_t res = lv_fs_open( &lv_file , fn, LV_FS_MODE_RD );
|
||||
if(res != LV_FS_RES_OK) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
SJPEG* sjpeg = ( SJPEG* ) dsc->user_data;
|
||||
if(sjpeg == NULL) {
|
||||
sjpeg = lv_mem_alloc( sizeof( SJPEG ) );
|
||||
if( ! sjpeg ) {
|
||||
lv_fs_close( &lv_file );
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
memset(sjpeg, 0, sizeof(SJPEG));
|
||||
dsc->user_data = sjpeg;
|
||||
sjpeg->sjpeg_data = (uint8_t *)( (lv_img_dsc_t* )(dsc->src) )->data;
|
||||
sjpeg->sjpeg_data_size = ( (lv_img_dsc_t *)(dsc->src) )->data_size;
|
||||
}
|
||||
|
||||
uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if( ! workb_temp ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
io_source_t io_source_temp;
|
||||
io_source_temp.type = SJPEG_IO_SOURCE_DISK;
|
||||
io_source_temp.raw_sjpg_data_next_read_pos = 0;
|
||||
io_source_temp.img_cache_buff = NULL;
|
||||
io_source_temp.lv_file = lv_file;
|
||||
|
||||
JDEC jd_tmp;
|
||||
|
||||
JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp);
|
||||
|
||||
lv_mem_free(workb_temp);
|
||||
|
||||
|
||||
if(rc == JDR_OK ) {
|
||||
sjpeg->sjpeg_x_res = jd_tmp.width;
|
||||
sjpeg->sjpeg_y_res = jd_tmp.height;
|
||||
sjpeg->sjpeg_total_frames = 1;
|
||||
sjpeg->sjpeg_single_frame_height = jd_tmp.height;
|
||||
|
||||
sjpeg->frame_base_array = NULL;
|
||||
sjpeg->frame_base_offset = lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames );
|
||||
if( ! sjpeg->frame_base_offset ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
int img_frame_start_offset = 0;
|
||||
sjpeg->frame_base_offset[0] = img_frame_start_offset;
|
||||
|
||||
sjpeg->sjpeg_cache_frame_index = -1;
|
||||
sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3 );
|
||||
if( ! sjpeg->frame_cache ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->io.img_cache_buff = sjpeg->frame_cache;
|
||||
sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res;
|
||||
sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE );
|
||||
if( ! sjpeg->workb ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) );
|
||||
if( ! sjpeg->tjpeg_jd ) {
|
||||
lv_fs_close(&lv_file);
|
||||
lv_sjpg_cleanup(sjpeg);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
sjpeg->io.type = SJPEG_IO_SOURCE_DISK;
|
||||
sjpeg->io.lv_file = lv_file;
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK;
|
||||
|
||||
} else {
|
||||
if(dsc->user_data) lv_mem_free(dsc->user_data);
|
||||
lv_fs_close(&lv_file);
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't open the whole decoded pixel array. (dsc->img_data == NULL)
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: 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);
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
SJPEG* sjpeg = ( SJPEG* ) dsc->user_data;
|
||||
JRESULT rc;
|
||||
|
||||
int sjpeg_req_frame_index = y / sjpeg->sjpeg_single_frame_height;
|
||||
|
||||
/*If line not from cache, refresh cache */
|
||||
if(sjpeg_req_frame_index != sjpeg->sjpeg_cache_frame_index) {
|
||||
sjpeg->io.raw_sjpg_data = sjpeg->frame_base_array[ sjpeg_req_frame_index ];
|
||||
if (sjpeg_req_frame_index == (sjpeg->sjpeg_total_frames - 1)) {
|
||||
/*This is the last frame. */
|
||||
const uint32_t frame_offset = (uint32_t)(sjpeg->io.raw_sjpg_data - sjpeg->sjpeg_data);
|
||||
sjpeg->io.raw_sjpg_data_size = sjpeg->sjpeg_data_size - frame_offset;
|
||||
} else {
|
||||
sjpeg->io.raw_sjpg_data_size =
|
||||
(uint32_t)(sjpeg->frame_base_array[sjpeg_req_frame_index + 1] - sjpeg->io.raw_sjpg_data);
|
||||
}
|
||||
sjpeg->io.raw_sjpg_data_next_read_pos = 0;
|
||||
rc = jd_prepare( sjpeg->tjpeg_jd, input_func, sjpeg->workb, (size_t)TJPGD_WORKBUFF_SIZE, &(sjpeg->io));
|
||||
if(rc != JDR_OK ) return LV_RES_INV;
|
||||
rc = jd_decomp ( sjpeg->tjpeg_jd, img_data_cb, 0);
|
||||
if(rc != JDR_OK ) return LV_RES_INV;
|
||||
sjpeg->sjpeg_cache_frame_index = sjpeg_req_frame_index;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
uint8_t *cache = (uint8_t *)sjpeg->frame_cache + x*3 + ( y % sjpeg->sjpeg_single_frame_height ) * sjpeg->sjpeg_x_res*3;
|
||||
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
buf[offset + 3] = 0xff;
|
||||
buf[offset + 2] = *cache++;
|
||||
buf[offset + 1] = *cache++;
|
||||
buf[offset + 0] = *cache++;
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
uint16_t col_16bit = (*cache++ & 0xf8) << 8;
|
||||
col_16bit |= (*cache++ & 0xFC) << 3;
|
||||
col_16bit |= (*cache++ >> 3);
|
||||
#if LV_BIG_ENDIAN_SYSTEM == 1
|
||||
buf[offset++] = col_16bit >> 8;
|
||||
buf[offset++] = col_16bit & 0xff;
|
||||
#else
|
||||
buf[offset++] = col_16bit & 0xff;
|
||||
buf[offset++] = col_16bit >> 8;
|
||||
#endif // LV_BIG_ENDIAN_SYSTEM
|
||||
}
|
||||
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
uint8_t col_8bit = (*cache++ & 0xC0);
|
||||
col_8bit |= (*cache++ & 0xe0) >> 2;
|
||||
col_8bit |= (*cache++ & 0xe0) >> 5;
|
||||
buf[offset++] = col_8bit;
|
||||
}
|
||||
#else
|
||||
#error Unsupported LV_COLOR_DEPTH
|
||||
|
||||
|
||||
#endif // LV_COLOR_DEPTH
|
||||
return LV_RES_OK;
|
||||
}
|
||||
else if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
SJPEG* sjpeg = ( SJPEG* ) dsc->user_data;
|
||||
JRESULT rc;
|
||||
int sjpeg_req_frame_index = y / sjpeg->sjpeg_single_frame_height;
|
||||
|
||||
lv_fs_file_t* lv_file_p = &(sjpeg->io.lv_file);
|
||||
if(!lv_file_p) goto end;
|
||||
|
||||
/*If line not from cache, refresh cache */
|
||||
if(sjpeg_req_frame_index != sjpeg->sjpeg_cache_frame_index) {
|
||||
sjpeg->io.raw_sjpg_data_next_read_pos = (int)(sjpeg->frame_base_offset [ sjpeg_req_frame_index ]);
|
||||
lv_fs_seek( &(sjpeg->io.lv_file), sjpeg->io.raw_sjpg_data_next_read_pos, LV_FS_SEEK_SET);
|
||||
|
||||
rc = jd_prepare( sjpeg->tjpeg_jd, input_func, sjpeg->workb, (size_t)TJPGD_WORKBUFF_SIZE, &(sjpeg->io));
|
||||
if(rc != JDR_OK ) return LV_RES_INV;
|
||||
|
||||
rc = jd_decomp ( sjpeg->tjpeg_jd, img_data_cb, 0);
|
||||
if(rc != JDR_OK ) return LV_RES_INV;
|
||||
|
||||
sjpeg->sjpeg_cache_frame_index = sjpeg_req_frame_index;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
uint8_t *cache = (uint8_t *)sjpeg->frame_cache + x*3 + ( y % sjpeg->sjpeg_single_frame_height ) * sjpeg->sjpeg_x_res*3;
|
||||
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
buf[offset + 3] = 0xff;
|
||||
buf[offset + 2] = *cache++;
|
||||
buf[offset + 1] = *cache++;
|
||||
buf[offset + 0] = *cache++;
|
||||
offset += 4;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
uint16_t col_8bit = (*cache++ & 0xf8) << 8;
|
||||
col_8bit |= (*cache++ & 0xFC) << 3;
|
||||
col_8bit |= (*cache++ >> 3);
|
||||
#if LV_BIG_ENDIAN_SYSTEM == 1
|
||||
buf[offset++] = col_8bit >> 8;
|
||||
buf[offset++] = col_8bit & 0xff;
|
||||
#else
|
||||
buf[offset++] = col_8bit & 0xff;
|
||||
buf[offset++] = col_8bit >> 8;
|
||||
#endif // LV_BIG_ENDIAN_SYSTEM
|
||||
}
|
||||
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
|
||||
for( int i = 0; i < len; i++ ) {
|
||||
uint8_t col_8bit = (*cache++ & 0xC0);
|
||||
col_8bit |= (*cache++ & 0xe0) >> 2;
|
||||
col_8bit |= (*cache++ & 0xe0) >> 5;
|
||||
buf[offset++] = col_8bit;
|
||||
}
|
||||
|
||||
#else
|
||||
#error Unsupported LV_COLOR_DEPTH
|
||||
|
||||
|
||||
#endif // LV_COLOR_DEPTH
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
end:
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the allocated resources
|
||||
* @param decoder pointer to the decoder where this function belongs
|
||||
* @param dsc pointer to a descriptor which describes this decoding session
|
||||
*/
|
||||
static void decoder_close( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc )
|
||||
{
|
||||
LV_UNUSED(decoder);
|
||||
/*Free all allocated data*/
|
||||
SJPEG* sjpeg = ( SJPEG* ) dsc->user_data;
|
||||
if(!sjpeg) return;
|
||||
|
||||
switch(dsc->src_type) {
|
||||
case LV_IMG_SRC_FILE:
|
||||
if(sjpeg->io.lv_file.file_d) {
|
||||
lv_fs_close(&(sjpeg->io.lv_file));
|
||||
}
|
||||
lv_sjpg_free(sjpeg);
|
||||
break;
|
||||
|
||||
case LV_IMG_SRC_VARIABLE:
|
||||
lv_sjpg_free(sjpeg);
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static int is_jpg( const uint8_t *raw_data )
|
||||
{
|
||||
const uint8_t jpg_signature[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46};//ÿØÿà<C3BF>JFIF
|
||||
return memcmp( jpg_signature, raw_data, sizeof( jpg_signature ) ) == 0;
|
||||
}
|
||||
|
||||
static void lv_sjpg_free( SJPEG* sjpeg )
|
||||
{
|
||||
if(sjpeg->frame_cache) lv_mem_free(sjpeg->frame_cache);
|
||||
if(sjpeg->frame_base_array) lv_mem_free(sjpeg->frame_base_array);
|
||||
if(sjpeg->frame_base_offset) lv_mem_free(sjpeg->frame_base_offset);
|
||||
if(sjpeg->tjpeg_jd) lv_mem_free(sjpeg->tjpeg_jd);
|
||||
if(sjpeg->workb) lv_mem_free(sjpeg->workb);
|
||||
}
|
||||
|
||||
static void lv_sjpg_cleanup( SJPEG* sjpeg )
|
||||
{
|
||||
if(! sjpeg ) return;
|
||||
|
||||
lv_sjpg_free( sjpeg );
|
||||
lv_mem_free( sjpeg );
|
||||
}
|
||||
|
||||
#endif /*LV_USE_SJPG*/
|
||||
81
src/extra/libs/sjpg/lv_sjpg.h
Normal file
81
src/extra/libs/sjpg/lv_sjpg.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file lv_sjpg.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_SJPEG_H
|
||||
#define LV_SJPEG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tjpgd.h"
|
||||
|
||||
#include "../../../misc/lv_fs.h"
|
||||
#if LV_USE_SJPG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum io_source_type {
|
||||
SJPEG_IO_SOURCE_C_ARRAY,
|
||||
SJPEG_IO_SOURCE_DISK,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum io_source_type type;
|
||||
lv_fs_file_t lv_file;
|
||||
uint8_t* img_cache_buff;
|
||||
int img_cache_x_res;
|
||||
int img_cache_y_res;
|
||||
uint8_t *raw_sjpg_data; //Used when type==SJPEG_IO_SOURCE_C_ARRAY.
|
||||
uint32_t raw_sjpg_data_size; //Num bytes pointed to by raw_sjpg_data.
|
||||
uint32_t raw_sjpg_data_next_read_pos; //Used for all types.
|
||||
} io_source_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t *sjpeg_data;
|
||||
uint32_t sjpeg_data_size;
|
||||
int sjpeg_x_res;
|
||||
int sjpeg_y_res;
|
||||
int sjpeg_total_frames;
|
||||
int sjpeg_single_frame_height;
|
||||
int sjpeg_cache_frame_index;
|
||||
uint8_t **frame_base_array; //to save base address of each split frames upto sjpeg_total_frames.
|
||||
int *frame_base_offset; //to save base offset for fseek
|
||||
uint8_t *frame_cache;
|
||||
uint8_t* workb; //JPG work buffer for jpeg library
|
||||
JDEC *tjpeg_jd;
|
||||
io_source_t io;
|
||||
} SJPEG;
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_split_jpeg_init(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_SJPG*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LV_SJPEG_H */
|
||||
1155
src/extra/libs/sjpg/tjpgd.c
Normal file
1155
src/extra/libs/sjpg/tjpgd.c
Normal file
File diff suppressed because it is too large
Load Diff
102
src/extra/libs/sjpg/tjpgd.h
Normal file
102
src/extra/libs/sjpg/tjpgd.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ TJpgDec - Tiny JPEG Decompressor R0.03 include file (C)ChaN, 2021
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef DEF_TJPGDEC
|
||||
#define DEF_TJPGDEC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
#if LV_USE_SJPG
|
||||
|
||||
#include "tjpgdcnf.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) /* VC++ or some compiler without stdint.h */
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef long int32_t;
|
||||
#else /* Embedded platform */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if JD_FASTDECODE >= 1
|
||||
typedef int16_t jd_yuv_t;
|
||||
#else
|
||||
typedef uint8_t jd_yuv_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* Error code */
|
||||
typedef enum {
|
||||
JDR_OK = 0, /* 0: Succeeded */
|
||||
JDR_INTR, /* 1: Interrupted by output function */
|
||||
JDR_INP, /* 2: Device error or wrong termination of input stream */
|
||||
JDR_MEM1, /* 3: Insufficient memory pool for the image */
|
||||
JDR_MEM2, /* 4: Insufficient stream input buffer */
|
||||
JDR_PAR, /* 5: Parameter error */
|
||||
JDR_FMT1, /* 6: Data format error (may be broken data) */
|
||||
JDR_FMT2, /* 7: Right format but not supported */
|
||||
JDR_FMT3 /* 8: Not supported JPEG standard */
|
||||
} JRESULT;
|
||||
|
||||
/* Rectangular region in the output image */
|
||||
typedef struct {
|
||||
uint16_t left; /* Left end */
|
||||
uint16_t right; /* Right end */
|
||||
uint16_t top; /* Top end */
|
||||
uint16_t bottom; /* Bottom end */
|
||||
} JRECT;
|
||||
|
||||
/* Decompressor object structure */
|
||||
typedef struct JDEC JDEC;
|
||||
struct JDEC {
|
||||
size_t dctr; /* Number of bytes available in the input buffer */
|
||||
uint8_t* dptr; /* Current data read ptr */
|
||||
uint8_t* inbuf; /* Bit stream input buffer */
|
||||
uint8_t dbit; /* Number of bits availavble in wreg or reading bit mask */
|
||||
uint8_t scale; /* Output scaling ratio */
|
||||
uint8_t msx, msy; /* MCU size in unit of block (width, height) */
|
||||
uint8_t qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */
|
||||
uint8_t ncomp; /* Number of color components 1:grayscale, 3:color */
|
||||
int16_t dcv[3]; /* Previous DC element of each component */
|
||||
uint16_t nrst; /* Restart inverval */
|
||||
uint16_t width, height; /* Size of the input image (pixel) */
|
||||
uint8_t* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */
|
||||
uint16_t* huffcode[2][2]; /* Huffman code word tables [id][dcac] */
|
||||
uint8_t* huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */
|
||||
int32_t* qttbl[4]; /* Dequantizer tables [id] */
|
||||
#if JD_FASTDECODE >= 1
|
||||
uint32_t wreg; /* Working shift register */
|
||||
uint8_t marker; /* Detected marker (0:None) */
|
||||
#if JD_FASTDECODE == 2
|
||||
uint8_t longofs[2][2]; /* Table offset of long code [id][dcac] */
|
||||
uint16_t* hufflut_ac[2]; /* Fast huffman decode tables for AC short code [id] */
|
||||
uint8_t* hufflut_dc[2]; /* Fast huffman decode tables for DC short code [id] */
|
||||
#endif
|
||||
#endif
|
||||
void* workbuf; /* Working buffer for IDCT and RGB output */
|
||||
jd_yuv_t* mcubuf; /* Working buffer for the MCU */
|
||||
void* pool; /* Pointer to available memory pool */
|
||||
size_t sz_pool; /* Size of momory pool (bytes available) */
|
||||
size_t (*infunc)(JDEC*, uint8_t*, size_t); /* Pointer to jpeg stream input function */
|
||||
void* device; /* Pointer to I/O device identifiler for the session */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* TJpgDec API functions */
|
||||
JRESULT jd_prepare (JDEC* jd, size_t (*infunc)(JDEC*,uint8_t*,size_t), void* pool, size_t sz_pool, void* dev);
|
||||
JRESULT jd_decomp (JDEC* jd, int (*outfunc)(JDEC*,void*,JRECT*), uint8_t scale);
|
||||
|
||||
#endif /*LV_USE_SJPG*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TJPGDEC */
|
||||
33
src/extra/libs/sjpg/tjpgdcnf.h
Normal file
33
src/extra/libs/sjpg/tjpgdcnf.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*----------------------------------------------*/
|
||||
/* TJpgDec System Configurations R0.03 */
|
||||
/*----------------------------------------------*/
|
||||
|
||||
#define JD_SZBUF 512
|
||||
/* Specifies size of stream input buffer */
|
||||
|
||||
#define JD_FORMAT 0
|
||||
/* Specifies output pixel format.
|
||||
/ 0: RGB888 (24-bit/pix)
|
||||
/ 1: RGB565 (16-bit/pix)
|
||||
/ 2: Grayscale (8-bit/pix)
|
||||
*/
|
||||
|
||||
#define JD_USE_SCALE 1
|
||||
/* Switches output descaling feature.
|
||||
/ 0: Disable
|
||||
/ 1: Enable
|
||||
*/
|
||||
|
||||
#define JD_TBLCLIP 1
|
||||
/* Use table conversion for saturation arithmetic. A bit faster, but increases 1 KB of code size.
|
||||
/ 0: Disable
|
||||
/ 1: Enable
|
||||
*/
|
||||
|
||||
#define JD_FASTDECODE 0
|
||||
/* Optimization level
|
||||
/ 0: Basic optimization. Suitable for 8/16-bit MCUs.
|
||||
/ 1: + 32-bit barrel shifter. Suitable for 32-bit MCUs.
|
||||
/ 2: + Table conversion for huffman decoding (wants 6 << HUFF_BIT bytes of RAM)
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,38 @@ void lv_extra_init(void)
|
||||
#if LV_USE_GRID
|
||||
lv_grid_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_FATFS != '\0'
|
||||
lv_fs_fatfs_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_STDIO != '\0'
|
||||
lv_fs_stdio_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_POSIX != '\0'
|
||||
lv_fs_posix_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_PNG
|
||||
lv_png_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_SJPG
|
||||
lv_split_jpeg_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_BMP
|
||||
lv_bmp_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
/*Init freetype library
|
||||
*Cache max 64 faces and 1 size*/
|
||||
lv_freetype_init(0, 0, LV_FREETYPE_CACHE_SIZE);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -1563,6 +1563,104 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*---------------------
|
||||
* 3rd party libraries
|
||||
*--------------------*/
|
||||
|
||||
/*File system interfaces for common APIs
|
||||
*To enable set a driver letter for that API*/
|
||||
#ifndef LV_USE_FS_STDIO
|
||||
# ifdef CONFIG_LV_USE_FS_STDIO
|
||||
# define LV_USE_FS_STDIO CONFIG_LV_USE_FS_STDIO
|
||||
# else
|
||||
# define LV_USE_FS_STDIO '\0' /*Uses fopen, fread, etc*/
|
||||
# endif
|
||||
#endif
|
||||
//#define LV_FS_STDIO_PATH "/home/john/" /*Set the working directory. If commented it will be "./" */
|
||||
|
||||
#ifndef LV_USE_FS_POSIX
|
||||
# ifdef CONFIG_LV_USE_FS_POSIX
|
||||
# define LV_USE_FS_POSIX CONFIG_LV_USE_FS_POSIX
|
||||
# else
|
||||
# define LV_USE_FS_POSIX '\0' /*Uses open, read, etc*/
|
||||
# endif
|
||||
#endif
|
||||
//#define LV_FS_POSIX_PATH "/home/john/" /*Set the working directory. If commented it will be "./" */
|
||||
|
||||
#ifndef LV_USE_FS_FATFS
|
||||
# ifdef CONFIG_LV_USE_FS_FATFS
|
||||
# define LV_USE_FS_FATFS CONFIG_LV_USE_FS_FATFS
|
||||
# else
|
||||
# define LV_USE_FS_FATFS '\0' /*Uses f_open, f_read, etc*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*PNG decoder library*/
|
||||
#ifndef LV_USE_PNG
|
||||
# ifdef CONFIG_LV_USE_PNG
|
||||
# define LV_USE_PNG CONFIG_LV_USE_PNG
|
||||
# else
|
||||
# define LV_USE_PNG 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*BMP decoder library*/
|
||||
#ifndef LV_USE_BMP
|
||||
# ifdef CONFIG_LV_USE_BMP
|
||||
# define LV_USE_BMP CONFIG_LV_USE_BMP
|
||||
# else
|
||||
# define LV_USE_BMP 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* JPG + split JPG decoder library.
|
||||
* Split JPG is a custom format optimized for embedded systems. */
|
||||
#ifndef LV_USE_SJPG
|
||||
# ifdef CONFIG_LV_USE_SJPG
|
||||
# define LV_USE_SJPG CONFIG_LV_USE_SJPG
|
||||
# else
|
||||
# define LV_USE_SJPG 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*GIF decoder library*/
|
||||
#ifndef LV_USE_GIF
|
||||
# ifdef CONFIG_LV_USE_GIF
|
||||
# define LV_USE_GIF CONFIG_LV_USE_GIF
|
||||
# else
|
||||
# define LV_USE_GIF 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*QR code library*/
|
||||
#ifndef LV_USE_QRCODE
|
||||
# ifdef CONFIG_LV_USE_QRCODE
|
||||
# define LV_USE_QRCODE CONFIG_LV_USE_QRCODE
|
||||
# else
|
||||
# define LV_USE_QRCODE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*FreeType library*/
|
||||
#ifndef LV_USE_FREETYPE
|
||||
# ifdef CONFIG_LV_USE_FREETYPE
|
||||
# define LV_USE_FREETYPE CONFIG_LV_USE_FREETYPE
|
||||
# else
|
||||
# define LV_USE_FREETYPE 0
|
||||
# endif
|
||||
#endif
|
||||
#if LV_USE_FREETYPE
|
||||
/*Memory used by FreeType to cache characters [bytes]*/
|
||||
#ifndef LV_FREETYPE_CACHE_SIZE
|
||||
# ifdef CONFIG_LV_FREETYPE_CACHE_SIZE
|
||||
# define LV_FREETYPE_CACHE_SIZE CONFIG_LV_FREETYPE_CACHE_SIZE
|
||||
# else
|
||||
# define LV_FREETYPE_CACHE_SIZE (16 * 1024)
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
@@ -151,6 +151,13 @@ set(LVGL_TEST_OPTIONS_FULL_32BIT
|
||||
-DLV_LABEL_TEXT_SELECTION=1
|
||||
-DLV_BUILD_EXAMPLES=1
|
||||
-DLV_FONT_DEFAULT=&lv_font_montserrat_24
|
||||
-DLV_USE_FS_STDIO='A'
|
||||
-DLV_USE_FS_POSIX='B'
|
||||
-DLV_USE_PNG=1
|
||||
-DLV_USE_BMP=1
|
||||
-DLV_USE_SJPG=1
|
||||
-DLV_USE_GIF=1
|
||||
-DLV_USE_QRCODE=1
|
||||
)
|
||||
|
||||
set(LVGL_TEST_OPTIONS_TEST
|
||||
|
||||
Reference in New Issue
Block a user