add some code

This commit is contained in:
2025-09-05 13:25:11 +08:00
parent 9ff0a99e7a
commit 3cf1229a85
8911 changed files with 2535396 additions and 0 deletions

View File

@@ -0,0 +1 @@
7c07831bbf11d15f84f42dc0e127094c78063b03d0dce688495773656f998d2b

View File

@@ -0,0 +1,15 @@
# Changelog
## v0.5.1
### Bug Fixes
- Fix memory leakage on jpeg_enc_open fail
- Fix memory allocation fail when dram is insufficient
## v0.5.0
### Features
- Initial version of `esp_new_jpeg`
- Add JPEG encoder and decoder library

View File

@@ -0,0 +1 @@
{"version": "1.0", "algorithm": "sha256", "created_at": "2025-05-21T15:49:57.954035+00:00", "files": [{"path": "CMakeLists.txt", "size": 310, "hash": "742e44bed0ef8fc9d323759e70afbee8e037d4404855e467e202b0b7987a8e42"}, {"path": "LICENSE", "size": 1186, "hash": "0bf7f2018fffa1caff5ecbf10d79707b218eea4e26b8c705d744de4556552815"}, {"path": "CHANGELOG.md", "size": 238, "hash": "cc965c5eb636548d8ac18c7b4314e980699cc657f33cf1fd1102cfabdadb857a"}, {"path": "idf_component.yml", "size": 423, "hash": "74474a55e1f1685f2337b360b7600d3f80d90c3f9057685aa5179d2e908575bb"}, {"path": "README.md", "size": 12158, "hash": "89f5889bd62bc8635ea83f42deb1549f1368153fd9c510816227c0aeffed7b62"}, {"path": "test_app/pytest_esp_new_jpeg.py", "size": 397, "hash": "a55268d59c15700b575acfadbb53656935e107aba1bdb79aaa9313ccb2399927"}, {"path": "test_app/CMakeLists.txt", "size": 313, "hash": "711b7d7d02dfba1a742bae8891c22bd7fc2d6a415c1223eb52bb35a750efac3d"}, {"path": "test_app/sdkconfig.defaults.esp32s3", "size": 238, "hash": "3288c88412caf5a00e3aecb5300444f01764cd64de20a18a852b6697839cc75d"}, {"path": "test_app/sdkconfig.defaults", "size": 333, "hash": "a2de67417c4b9d838abacfd076725a85293d96a1dad780fbf4d03bded2beeddb"}, {"path": "include/esp_jpeg_dec.h", "size": 6944, "hash": "20617996a22401ce805dc64ce368824c93fd20f7c68a969a9f364d9587a0f0f5"}, {"path": "include/esp_jpeg_enc.h", "size": 5385, "hash": "5ad339f8da076861454b6f56864f6864d0bde82ef1ac5d43272e8d86153089dc"}, {"path": "include/esp_jpeg_version.h", "size": 1710, "hash": "767958e1cbf0da550e0ed781daa87940fb239ea60cd8cfe1b805f87889c51459"}, {"path": "include/esp_jpeg_common.h", "size": 4481, "hash": "548c85257c3cecd19c07015be2257ea870b8c9b5c31de9668c1884d5fe387351"}, {"path": "lib/esp32c2/libesp_new_jpeg.a", "size": 2738456, "hash": "2b73f68323bf674c87025e1310fa3e4a9dd26b166771da803575e4cfb8756e00"}, {"path": "lib/esp32c5/libesp_new_jpeg.a", "size": 2738652, "hash": "f2005122ee2d2cc8ff7e705ff66fe59337a5daabab9cf267e17d4da3c99d8601"}, {"path": "lib/esp32c3/libesp_new_jpeg.a", "size": 2738456, "hash": "2b73f68323bf674c87025e1310fa3e4a9dd26b166771da803575e4cfb8756e00"}, {"path": "lib/esp32/libesp_new_jpeg.a", "size": 1701478, "hash": "e9f034dd58276419b05ee9ddba9883fa79af0050d59ab496356f1cab168fead8"}, {"path": "lib/esp32c6/libesp_new_jpeg.a", "size": 2738648, "hash": "97e1eb652b14121f684bf0bfd4dac982788001e93418e5bf79929b94936673e3"}, {"path": "lib/esp32s3/libesp_new_jpeg.a", "size": 1217068, "hash": "01a1dc7e3a1ae6fc3f4d1faa918603ea4f4b43bc8b73b20457a883672601409d"}, {"path": "lib/esp32s2/libesp_new_jpeg.a", "size": 1708230, "hash": "1bb07734ecdec81a2542df748faf560dd15f4cc85606620cfb4fdbcd5fd0b731"}, {"path": "lib/esp32p4/libesp_new_jpeg.a", "size": 2739524, "hash": "59b081e3ff005ff5fda5956d7a0adedbc3e9e62065a460077c7f4263f2436362"}, {"path": "test_app/main/test_case.c", "size": 5578, "hash": "cedb4111916cc64b8ddd747257cb80e4b4c4be68784e5911a58ae58367040ea9"}, {"path": "test_app/main/test_encoder.h", "size": 629, "hash": "eddfaf1fea0907e98af877e53967b6535d466fdf83aa90076007d9dff8ce72de"}, {"path": "test_app/main/CMakeLists.txt", "size": 382, "hash": "b001bc4b6d2e711ee0be17c264ae059aa479a5ccad07c1454442f7c05ff31467"}, {"path": "test_app/main/image_io.c", "size": 4269, "hash": "0049630686b6ed85eff35426f83889e50ffa6d1ff2a20c5efb73a2dbe18edb17"}, {"path": "test_app/main/test_decoder.c", "size": 9091, "hash": "68c07bbf649182e75266d8d4a9d0b68104004d3a9d7c96b6fe08ab8b918e712c"}, {"path": "test_app/main/idf_component.yml", "size": 42, "hash": "43d0de6527c82c1b474b1bf719968c68a1368863e653b60cafb51e689194a61e"}, {"path": "test_app/main/image_io.h", "size": 13309, "hash": "fbf692344c8dc5c843e91046f557601ae6930fbeae3a436e6013e8e2c2b6a3dd"}, {"path": "test_app/main/test_encoder.c", "size": 4054, "hash": "1b7fd97504ceef8d3e181ee70761df43a907f8eb1875f53db39c40f2f01d005d"}, {"path": "test_app/main/test_decoder.h", "size": 2675, "hash": "c55a83399a13d6e7b9bef97647881eb7bd40bece0e701ce129952636434e04f8"}, {"path": "test_app/main/test_app_main.c", "size": 1035, "hash": "92d80a8f04ef1700dfaec6d3742b8ae24d87a60ca655a4a461eb8ef44653b317"}]}

View File

@@ -0,0 +1,6 @@
set(public_include_dirs "./include")
idf_component_register(INCLUDE_DIRS "${public_include_dirs}")
add_prebuilt_library(esp_new_jpeg "${CMAKE_CURRENT_SOURCE_DIR}/lib/${CONFIG_IDF_TARGET}/libesp_new_jpeg.a")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--start-group" esp_new_jpeg "-Wl,--end-group")

View File

@@ -0,0 +1,20 @@
ESPRESSIF MIT License
Copyright (c) 2024 <ESPRESSIF SYSTEMS (SHANGHAI) CO.LTD>
Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
it is 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.

View File

@@ -0,0 +1,200 @@
# ESP_NEW_JPEG
ESP_NEW_JPEG is Espressif's lightweight JPEG encoder and decoder library. The memory and CPU loading are optimized to make better use of Espressif chips.
## Features
### Encoder
- Support variety of width and height to encoder
- Support RGB888 RGBA YCbYCr YCbY2YCrY2 GRAY pixel format
- Support YUV444 YUV422 YUV420 subsampling
- Support quality(1-100)
- Support 0 90 180 270 degree clockwise rotation, under the follow cases
1. src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_420 and width and height are multiply of 16
2. src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_GRAY and width and height are multiply of 8
- Support mono-task and dual-task
- Support two mode encoder, respectively one image encoder and block encoder
### Decoder
- Support variety of width and height to decoder
- Support one and three channels decoder
- Support RGB888 RGB565(big endian) RGB565(little endian) CbYCrY pixel format output
- Support 0 90 180 270 degree clockwise rotation, under width and height are multiply of 8
- Support clipper and scale, under width and height are multiply of 8
- Support two mode decoder, respectively one image decoder and block decoder
## Performance
### Test on chip ESP32-S3
#### Encoder
For **mono task** encoder, the consume memory(10 kByte DRAM) is constant.
| Resolution | Source Pixel Format | Output Quality | Output Subsampling | Frames Per Second(fps) |
|-------------|--------------------------|----------------|--------------------|------------------------|
| 1920 * 1080 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 1.59 |
| 1920 * 1080 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 1.33 |
| 1280 * 720 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 4.84 |
| 1280 * 720 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 2.92 |
| 800 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 10.82 |
| 800 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 6.74 |
| 640 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 13.24 |
| 640 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 8.32 |
| 480 * 320 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 24.35 |
| 480 * 320 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 15.84 |
| 320 * 240 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 45.30 |
| 320 * 240 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 30.37 |
When **dual task** encoder in enabled, the wider the image, the more memory is consumed.
| Resolution | Source Pixel Format | Output Quality | Output Subsampling | Frames Per Second(fps) |
|------------|--------------------------|----------------|--------------------|------------------------|
| 1280 * 720 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 4.62 |
| 800 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 10.46 |
| 640 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 12.89 |
| 480 * 320 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 23.57 |
| 320 * 240 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 43.97 |
#### Decoder
The consume memory(10 kByte DRAM) is constant.
Rotate JPEG_ROTATE_0D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|-------------|--------------------|----------------|-----------------------------|------------------------|
| 1920 * 1080 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 3.27 |
| 1920 * 1080 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 3.78 |
| 1280 * 720 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 6.77 |
| 1280 * 720 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 7.82 |
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 14.73 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 16.87 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 17.90 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 20.46 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 32.27 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 36.29 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 58.95 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 66.28 |
Rotate JPEG_ROTATE_90D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|-------------|--------------------|----------------|-----------------------------|------------------------|
| 1920 * 1080 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 2.23 |
| 1920 * 1080 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 3.11 |
| 1280 * 720 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.02 |
| 1280 * 720 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 7.13 |
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 14.09 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 16.85 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 17.16 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 20.45 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 30.87 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 36.15 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 59.17 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 70.78 |
### Test on chip ESP32-S2
#### Encoder
Only support mono task. The consume memory(10 kByte DRAM) is constant.
| Resolution | Source Pixel Format | Output Quality | Output Subsampling | Frames Per Second(fps) |
|------------|--------------------------|----------------|--------------------|------------------------|
| 800 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 3.60 |
| 800 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 2.76 |
| 640 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 4.47 |
| 640 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 3.43 |
| 480 * 320 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 8.64 |
| 480 * 320 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 6.69 |
| 320 * 240 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 16.30 |
| 320 * 240 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 13.05 |
#### Decoder
The consume memory(10 kByte DRAM) is constant.
Rotate JPEG_ROTATE_0D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|------------|--------------------|----------------|-----------------------------|------------------------|
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.44 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.76 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 6.70 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 7.09 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 12.71 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 13.42 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 24.18 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 25.60 |
Rotate JPEG_ROTATE_90D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|------------|--------------------|----------------|-----------------------------|------------------------|
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 4.53 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 4.81 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.59 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.94 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 10.69 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 11.33 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 22.40 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 21.77 |
## Usage
Please refer to the `test_app` folder for more details on API usage.
- `test_app/main/test_encoder.c` for encoder
- Encode a single picture
- Encode a single picture with block encoder API
- `test_app/main/test_decoder.c` for decoder
- Decode a single JPEG picture
- Decode a single JPEG picture with block deocder API
- Decode JPEG stream of the same size
## FAQ
1. Does ESP_NEW_JPEG support decoding progressive JPEG?
No, ESP_NEW_JPEG only support decoding baseline JPEG.
You can use the following code to check if the image is progressive JPEG. Output 1 means progressive JPEG, 0 means baseline JPEG.
```bash
python
>>> from PIL import Image
>>> Image.open("file_name.jpg").info.get('progressive', 0)
```
2. Why does the decoded output image appear misaligned?
The issue typically occurs when a few columns of the image on the far left or right side appear on the opposite side. If you are using the ESP32-S3, a possible cause is that the output buffer is not 16-byte aligned. Please use the `jpeg_calloc_align` function to allocate output buffer.
3. How can I use a simpler method to check if the encoder's output is correct?
You can use the following code to directly print the output JPEG data. Copy the output data, paste it into a hex editor, and save it as a .jpg file.
```c
for (int i = 0; i < out_len; i++) {
printf("%02x", outbuf[i]);
}
printf("\n");
```
## Supported chip
The following table shows the support of ESP_NEW_JPEG for Espressif SoCs. The "&#10004;" means supported, and the "&#10006;" means not supported.
| Chip | v0.5.1 |
|----------|----------|
| ESP32 | &#10004; |
| ESP32-S2 | &#10004; |
| ESP32-S3 | &#10004; |
| ESP32-P4 | &#10004; |
| ESP32-C2 | &#10004; |
| ESP32-C3 | &#10004; |
| ESP32-C5 | &#10004; |
| ESP32-C6 | &#10004; |

View File

@@ -0,0 +1,17 @@
description: Espressif JPEG encoder and decoder
issues: https://github.com/espressif/esp-adf/issues
repository: git://github.com/espressif/esp-adf-libs.git
repository_info:
commit_sha: 891d0b0fe7a04ddf5ddbffc93bd828ce58cc942e
path: esp_new_jpeg
targets:
- esp32
- esp32s2
- esp32s3
- esp32p4
- esp32c2
- esp32c3
- esp32c5
- esp32c6
url: https://github.com/espressif/esp-adf-libs/tree/master/esp_new_jpeg
version: 0.5.1

View File

@@ -0,0 +1,97 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @brief JPEG error code
*/
typedef enum {
JPEG_ERR_OK = 0, /*!< Succeeded */
JPEG_ERR_FAIL = -1, /*!< Device error or wrong termination of input stream */
JPEG_ERR_NO_MEM = -2, /*!< Insufficient memory for the image */
JPEG_ERR_NO_MORE_DATA = -3, /*!< Input data is not enough */
JPEG_ERR_INVALID_PARAM = -4, /*!< Parameter error */
JPEG_ERR_BAD_DATA = -5, /*!< Data format error (may be damaged data) */
JPEG_ERR_UNSUPPORT_FMT = -6, /*!< Right format but not supported */
JPEG_ERR_UNSUPPORT_STD = -7, /*!< Not supported JPEG standard */
} jpeg_error_t;
/**
* @brief JPEG pixel format
*/
typedef enum {
JPEG_PIXEL_FORMAT_GRAY = 0, /*!< Grayscale. 1-byte luminance component stored in memory for each pixel.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_RGB888 = 1, /*!< RGB888. 3-bytes red, green and blue components stored in memory from low to high address for each pixel.
Encoder supported. Decoder supported. */
JPEG_PIXEL_FORMAT_RGBA = 2, /*!< RGBA. 4-bytes red, green, blue and alpha components stored in memory from low to high address for each pixel.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_YCbYCr = 3, /*!< YCbYCr (belongs to packed yuv422). 4-bytes Y, Cb, Y and Cr components stored in memory from low to high address for each 2 pixels.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_YCbY2YCrY2 = 4, /*!< YCbY2YCrY2 (belongs to packed yuv420). 12-bytes Y, Cb, Y, Y, Cb, Y, Y, Cr, Y, Y, Cr and Y components stored in memory from low to high address for each 8 pixels.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_RGB565_BE = 5, /*!< RGB565. 2-bytes RGB565 big-endian data stored in memory for each pixel.
Encoder un-supported. Decoder supported. */
JPEG_PIXEL_FORMAT_RGB565_LE = 6, /*!< RGB565. 2-bytes RGB565 little-endian data stored in memory for each pixel.
Encoder un-supported. Decoder supported. */
JPEG_PIXEL_FORMAT_CbYCrY = 7, /*!< CbYCrY (belongs to packed yuv422). 4-bytes Cb, Y, Cr and Y components stored in memory from low to high address for each 2 pixels.
Encoder un-supported. Decoder supported. */
} jpeg_pixel_format_t;
/**
* @brief JPEG chrominance subsampling type
*/
typedef enum {
JPEG_SUBSAMPLE_GRAY = 0, /*!< Grayscale, no chrominance components */
JPEG_SUBSAMPLE_444 = 1, /*!< 4:4:4 chrominance subsampling, one chroma component for every pixel in the source image */
JPEG_SUBSAMPLE_422 = 2, /*!< 4:2:2 chrominance subsampling, one chroma component for every 2x1 block of pixels in the source image */
JPEG_SUBSAMPLE_420 = 3, /*!< 4:2:0 chrominance subsampling, one chroma component for every 2x2 block of pixels in the source image */
} jpeg_subsampling_t;
/**
* @brief JPEG rotation type
*/
typedef enum {
JPEG_ROTATE_0D = 0, /*!< Source image rotates clockwise 0 degree before encoding */
JPEG_ROTATE_90D = 1, /*!< Source image rotates clockwise 90 degree before encoding */
JPEG_ROTATE_180D = 2, /*!< Source image rotates clockwise 180 degree before encoding */
JPEG_ROTATE_270D = 3, /*!< Source image rotates clockwise 270 degree before encoding */
} jpeg_rotate_t;
/**
* @brief JPEG resize resolution parameter
*/
typedef struct {
uint16_t width; /*!< Image width */
uint16_t height; /*!< Image height */
} jpeg_resolution_t;
/**
* @brief Allocate buffer. The buffer address will be aligned.
*
* @param[in] size Allocate buffer size
* @param[in] aligned Aligned byte
*
* @return
* - NULL Failed
* - Others Allocated buffer address
*/
void *jpeg_calloc_align(size_t size, int aligned);
/**
* @brief Free buffer. The buffer address come from `jpeg_calloc_align`
*
* @param[in] buf Buffer address
*/
void jpeg_free_align(void *data);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,162 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stdbool.h>
#include "esp_jpeg_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DEFAULT_JPEG_DEC_CONFIG() { \
.output_type = JPEG_PIXEL_FORMAT_RGB888, \
.scale = {.width = 0, .height = 0}, \
.clipper = {.width = 0, .height = 0}, \
.rotate = JPEG_ROTATE_0D, \
.block_enable = false, \
}
/**
* @brief JPEG decoder handle
*/
typedef void *jpeg_dec_handle_t;
/**
* @brief Configuration for JPEG decoder
*
* @note Feature supported and limitations
* - support scale. Maximum scale ratio is 1/8. Scale.height and scale.width require integer multiples of 8.
* - support clipper. Clipper.height and clipper.width require integer multiples of 8.
* - support 0, 90, 180 and 270 clockwise rotation. Width and height require integer multiples of 8.
* - support block decoder mode.
*
* The general flow of decoder
* image data ----> decoding (required) ----> scale (optional) ----> clipper (optional) ----> rotation (optional)
*
* Each case of general flow:
* image -> decoding: The variety of width and height supported.
* image -> decoding -> scale: The scale.height and scale.width require integer multiples of 8.
* image -> decoding -> clipper: The clipper.height and clipper.width require integer multiples of 8.
* image -> decoding -> rotation: The height and width of image require integer multiples of 8.
* image -> decoding -> scale -> clipper: The scale.height, scale.width, clipper.height and clipper.width require integer multiples of 8. The resolution of clipper should be less or equal than scale.
* image -> decoding -> scale -> rotation: The scale.height and scale.width require integer multiples of 8.
* image -> decoding -> clipper -> rotation: The clipper.height and clipper.width require integer multiples of 8.
* image -> decoding -> scale -> clipper -> rotation: The scale.height, scale.width, clipper.height and clipper.width require integer multiples of 8. The resolution of clipper should be less or equal than scale.
*
* Flow of block decoder mode
* image data ----> decoding
*/
typedef struct {
jpeg_pixel_format_t output_type; /*!< Output pixel format. Support RGB888 RGB565_BE RGB565_LE CbYCrY, see jpeg_pixel_format_t enumeration. */
jpeg_resolution_t scale; /*!< Resolution of scale. scale.width = 0 means disable the width scale. scale.height = 0 means disable the height scale.
If enable this mode, scale.width and scale.height require integer multiples of 8. */
jpeg_resolution_t clipper; /*!< Resolution of clipper. clipper.width = 0 means disable the width clipper. clipper.height = 0 means disable the height clipper.
If enable this mode, clipper.width and clipper.height require integer multiples of 8. */
jpeg_rotate_t rotate; /*!< Support 0 90 180 270 degree clockwise rotation.
Only support when both width and height are multiples of 8. Otherwise unsupported. */
bool block_enable; /*!< Configured to true to enable block mode, each time output 8 or 16 line data depending on the height of MCU(Minimum Coded Unit).
If enabled this mode, scale and clipper are not supported, the width and height require integer multiples of 8 and rotate require JPEG_ROTATE_0D.
Configured to false to disable block mode. */
} jpeg_dec_config_t;
/**
* @brief JPEG decoder output infomation
*/
typedef struct {
uint16_t width; /*!< Image width */
uint16_t height; /*!< Image height */
} jpeg_dec_header_info_t;
/**
* @brief JPEG decoder io control
*/
typedef struct {
uint8_t *inbuf; /*!< The input buffer pointer */
int inbuf_len; /*!< The length of the input buffer in bytes */
int inbuf_remain; /*!< Not used length of the input buffer */
uint8_t *outbuf; /*!< The buffer to store decoded data. The buffer must be aligned 16 byte. */
int out_size; /*!< Output size of current block when block mode is enabled.
Size of entire image when block mode is disabled. */
} jpeg_dec_io_t;
/**
* @brief Create a JPEG decoder handle, set user configuration infomation to decoder handle
*
* @param[in] config Pointer to configuration information
* @param[out] jpeg_dec Pointer to JPEG decoder handle
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to create handle
*/
jpeg_error_t jpeg_dec_open(jpeg_dec_config_t *config, jpeg_dec_handle_t *jpeg_dec);
/**
* @brief Parse JPEG header, and output infomation to user
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[in] io Pointer to io control struct
* @param[out] out_info Pointer to output infomation struct
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to parse JPEG header
*/
jpeg_error_t jpeg_dec_parse_header(jpeg_dec_handle_t jpeg_dec, jpeg_dec_io_t *io, jpeg_dec_header_info_t *out_info);
/**
* @brief Get image buffer size
*
* @note User buffer must align to 16 bytes, user can malloc it through helper function `jpeg_calloc_align`.
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[out] outbuf_len Image buffer size
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to get output buffer size
*/
jpeg_error_t jpeg_dec_get_outbuf_len(jpeg_dec_handle_t jpeg_dec, int *outbuf_len);
/**
* @brief Get the number of times to call `jpeg_dec_process`
*
* @note If disable block decoder mode, the process_count always be 1.
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[out] process_count Number of times
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to get process times
*/
jpeg_error_t jpeg_dec_get_process_count(jpeg_dec_handle_t jpeg_dec, int *process_count);
/**
* @brief Decode JPEG picture
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[in] io Pointer to io control struct
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to decode JPEG picture
*/
jpeg_error_t jpeg_dec_process(jpeg_dec_handle_t jpeg_dec, jpeg_dec_io_t *io);
/**
* @brief Close JPEG decoder
*
* @param[in] jpeg_dec JPEG decoder handle
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to close JPEG decoder
*/
jpeg_error_t jpeg_dec_close(jpeg_dec_handle_t jpeg_dec);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,129 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_jpeg_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DEFAULT_JPEG_ENC_CONFIG() { \
.width = 320, \
.height = 240, \
.src_type = JPEG_PIXEL_FORMAT_YCbYCr, \
.subsampling = JPEG_SUBSAMPLE_420, \
.quality = 40, \
.rotate = JPEG_ROTATE_0D, \
.task_enable = false, \
.hfm_task_priority = 13, \
.hfm_task_core = 1, \
}
/**
* @brief JPEG encoder handle
*/
typedef void *jpeg_enc_handle_t;
/* JPEG configure Configuration */
typedef struct jpeg_info {
int width; /*!< Image width */
int height; /*!< Image height */
jpeg_pixel_format_t src_type; /*!< Input image type */
jpeg_subsampling_t subsampling; /*!< JPEG chroma subsampling factors. If `src_type` is JPEG_PIXEL_FORMAT_YCbY2YCrY2, this must be `JPEG_SUBSAMPLE_GRAY` or `JPEG_SUBSAMPLE_420`. Others is un-support */
uint8_t quality; /*!< Quality: 1-100, higher is better. Typical values are around 40 - 100. */
jpeg_rotate_t rotate; /*!< Supports 0, 90 180 270 degree clockwise rotation.
Under src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_420, width % 16 == 0. height % 16 = 0 conditions, rotation enabled.
Otherwise unsupported */
bool task_enable; /*!< True: `jpeg_enc_open` would create task to finish part of encoding work. false: no task help the encoder encode */
uint8_t hfm_task_priority; /*!< Task priority. If task_enable is true, this must be set */
uint8_t hfm_task_core; /*!< Task core. If task_enable is true, this must be set */
} jpeg_enc_config_t;
/**
* @brief Open JPEG encoder
*
* @param[in] info The configuration information
* @param[out] jpeg_enc The JPEG encoder handle
*
* @return
* - positive value JPEG encoder handle
* - NULL refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_open(jpeg_enc_config_t *info, jpeg_enc_handle_t *jpeg_enc);
/**
* @brief Encode one image
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
* @param[in] in_buf The input buffer, It needs a completed image. The buffer must be aligned 16 byte.
* @param[in] inbuf_size The size of `in_buf`. The value must be size of a completed image.
* @param[out] out_buf The output buffer
* @param[out] outbuf_size The size of output buffer
* @param[out] out_size The size of JPEG image
*
* @return
* - JPEG_ERR_OK It has finished to encode one image.
* - other values refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_process(const jpeg_enc_handle_t jpeg_enc, const uint8_t *in_buf, int inbuf_size, uint8_t *out_buf, int outbuf_size, int *out_size);
/**
* @brief Get block size. Block size is minimum process unit.
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
*
* @return
* - positive value block size
* - other values not valid data
*/
int jpeg_enc_get_block_size(const jpeg_enc_handle_t jpeg_enc);
/**
* @brief Encode block size image. Get block size from `jpeg_enc_get_block_size`
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
* @param[in] in_buf The input buffer, It needs a completed image.
* @param[in] inbuf_size The size of `in_buf`. Get block size from `jpeg_enc_get_block_size`
* @param[out] out_buf The output buffer, it saves a completed JPEG image.
* @param[out] outbuf_size The size of output buffer
* @param[out] out_size The size of JPEG image
*
* @return
* - block size It has finished to encode current block size image.
* - JPEG_ERR_OK It has finished to encode one image.
* - JPEG_ERR_FAIL Encoder failed.
*/
jpeg_error_t jpeg_enc_process_with_block(const jpeg_enc_handle_t jpeg_enc, const uint8_t *in_buf, int inbuf_size, uint8_t *out_buf, int outbuf_size, int *out_size);
/**
* @brief Reset quality.
*
* @note After encoding an entire image, user can call this function to change the quality value.
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
* @param[in] q Quality: 1-100, higher is better. Typical values are around 40 - 100.
*
* @return
* - JPEG_ERR_OK succeed
* - others values refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_set_quality(const jpeg_enc_handle_t jpeg_enc, uint8_t q);
/**
* @brief Close JPEG encoder
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
*
* @return
* - JPEG_ERR_OK It has finished to deinit.
* - other values refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_close(jpeg_enc_handle_t jpeg_enc);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,46 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define ESP_JPEG_VERION "0.5.1"
/**
* @version 0.5.0:
* Features:
* Encoder:
* - Support variety of width and height to encoder
* - Support RGB888 RGBA YCbYCr YCbY2YCrY2 GRAY pixel format
* - Support YUV444 YUV422 YUV420 subsampling
* - Support quality(1-100)
* - Support 0 90 180 270 degree clockwise rotation, under src_type = JPEG_PIXEL_FORMAT_YCbYCr,
* subsampling = JPEG_SUBSAMPLE_420, width and height are multiply of 16 and
* src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_GRAY, width and height are multiply of 8
* - Support mono-task and dual-task
* - Support two mode encoder, respectively one image encoder and block encoder
* Decoder:
* - Support variety of width and height to decoder
* - Support one and three channels decoder
* - Support RGB888 RGB565(big endian) RGB565(little endian) CbYCrY pixel format output
* - Support 0 90 180 270 degree clockwise rotation, under width and height are multiply of 8
* - Support clipper and scale, under width and height are multiply of 8
* - Support two mode decoder, respectively one image decoder and block decoder
*
* @note The encoder/decoder do ASM optimization in ESP32S3. Frame rate performs better than the others chips.
*/
/**
* @brief Get JPEG version string
*
* @return
* - JPEG codec version
*/
const char *esp_jpeg_get_version();
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,9 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.5)
# Include the components directory of the main application:
set(EXTRA_COMPONENT_DIRS "../")
add_compile_options(-fdiagnostics-color=always)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_app)

View File

@@ -0,0 +1,12 @@
set(src_dirs "./")
set(public_include_dirs "./")
set(priv_requires unity
esp_new_jpeg
fatfs)
idf_component_register(SRC_DIRS "${src_dirs}"
INCLUDE_DIRS "${public_include_dirs}"
PRIV_REQUIRES "${priv_requires}"
WHOLE_ARCHIVE)

View File

@@ -0,0 +1,3 @@
dependencies:
idf:
version: '>=5.0'

View File

@@ -0,0 +1,142 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_system.h"
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "image_io.h"
#define MOUNT_POINT "/sdcard"
#define PIN_NUM_MISO 38
#define PIN_NUM_MOSI 39
#define PIN_NUM_CLK 40
#define PIN_NUM_CS 41
static sdmmc_host_t host = SDSPI_HOST_DEFAULT();
static sdmmc_card_t *card;
static const char mount_point[] = MOUNT_POINT;
void mount_sd(void)
{
esp_err_t ret;
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
printf("Initializing SD card\n");
// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
// Please check its source code and implement error recovery when developing
// production applications.
printf("Using SPI peripheral\n");
// sdmmc_host_t host = SDSPI_HOST_DEFAULT();
// host.slot = SPI3_HOST;
spi_bus_config_t bus_cfg = {
.mosi_io_num = PIN_NUM_MOSI,
.miso_io_num = PIN_NUM_MISO,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
if (ret != ESP_OK) {
printf("Failed to initialize bus.\n");
return;
}
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = PIN_NUM_CS;
slot_config.host_id = host.slot;
printf("Mounting filesystem\n");
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
printf("Failed to mount filesystem. "
"If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.\n");
} else {
printf("Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.\n", esp_err_to_name(ret));
}
return;
}
printf("Filesystem mounted\n");
// Card has been initialized, print its properties
// sdmmc_card_print_info(stdout, card);
#if 0
// First create a file.
const char *file_hello = MOUNT_POINT"/hello.txt";
printf("Opening file %s\n", file_hello);
FILE *f = fopen(file_hello, "w");
if (f == NULL) {
printf("Failed to open file for writing\n");
return;
}
fprintf(f, "Hello %s!\n", card->cid.name);
fclose(f);
printf("File written\n");
const char *file_foo = MOUNT_POINT"/foo.txt";
// Check if destination file exists before renaming
struct stat st;
if (stat(file_foo, &st) == 0) {
// Delete it if it exists
unlink(file_foo);
}
// Rename original file
printf("Renaming file %s to %s\n", file_hello, file_foo);
if (rename(file_hello, file_foo) != 0) {
printf("Rename failed\n");
return;
}
// Open renamed file for reading
printf("Reading file %s\n", file_foo);
f = fopen(file_foo, "r");
if (f == NULL) {
printf("Failed to open file for reading\n");
return;
}
// Read a line from file
char line[64];
fgets(line, sizeof(line), f);
fclose(f);
// Strip newline
char *pos = strchr(line, '\n');
if (pos) {
*pos = '\0';
}
printf("Read from file: '%s'\n", line);
#endif /* 0 */
}
void unmount_sd(void)
{
// All done, unmount partition and disable SPI peripheral
esp_vfs_fat_sdcard_unmount(mount_point, card);
printf("Card unmounted\n");
// deinitialize the bus after all devices are removed
spi_bus_free(host.slot);
}

View File

@@ -0,0 +1,191 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define TEST_USE_SDCARD 0
#define TEST_JPEG_X 24 // width
#define TEST_JPEG_Y 16 // height
#define TEST_JPEG_WHITE_X 4
#define TEST_JPEG_WHITE_Y 4
#define TEST_JPEG_BLACK_X 12
#define TEST_JPEG_BLACK_Y 4
#define TEST_JPEG_CYAN_X 20
#define TEST_JPEG_CYAN_Y 4
#define TEST_JPEG_RED_X 4
#define TEST_JPEG_RED_Y 12
#define TEST_JPEG_GREEN_X 12
#define TEST_JPEG_GREEN_Y 12
#define TEST_JPEG_BLUE_X 20
#define TEST_JPEG_BLUE_Y 12
/**
* @brief Color array containing RGB color values
*/
static const uint8_t test_color_value[][3] = {
{255, 255, 255}, // white #FFFFFF
{0, 0, 0}, // black #000000
{0, 255, 255}, // cyan #00FFFF
{255, 0, 0}, // red #FF0000
{0, 255, 0}, // green #00FF00
{0, 0, 255}, // blue #0000FF
};
/**
* @brief Test JPEG file, resolution 24x16
* Contain six color: white #FFFFFF, black #000000, cyan #00FFFF, red #FF0000, green #00FF00, blue #0000FF
* │< 8px >│< 8px >│< 8px >│
* │ │ │ │
* ───┌───────────┬───────────┬───────────┐
* ^ │ │ │ │
* │ │ │ │
* 8px │ white │ black │ cyan │
* │ │ │ │
* v │ │ │ │
* ───├───────────┼───────────┼───────────┤
* ^ │ │ │ │
* │ │ │ │
* 8px │ red │ green │ blue │
* │ │ │ │
* v │ │ │ │
* ───└───────────┴───────────┴───────────┘
*/
static const uint8_t test_jpeg_data[371] = {
0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, 0x02, 0x03,
0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0A, 0x07,
0x07, 0x06, 0x08, 0x0C, 0x0A, 0x0C, 0x0C, 0x0B, 0x0A, 0x0B, 0x0B, 0x0D, 0x0E, 0x12, 0x10, 0x0D,
0x0E, 0x11, 0x0E, 0x0B, 0x0B, 0x10, 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0C, 0x0F,
0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xFF, 0xDB, 0x00, 0x43, 0x01, 0x03, 0x04,
0x04, 0x05, 0x04, 0x05, 0x09, 0x05, 0x05, 0x09, 0x14, 0x0D, 0x0B, 0x0D, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xFF, 0xC0,
0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x18, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
0x01, 0xFF, 0xC4, 0x00, 0x18, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x07, 0x0A, 0xFF, 0xC4, 0x00, 0x14, 0x10,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xC4, 0x00, 0x17, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x08, 0x09, 0xFF, 0xC4, 0x00, 0x2D, 0x11, 0x00,
0x00, 0x03, 0x02, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
0x12, 0x13, 0x00, 0x17, 0x01, 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x21, 0x64, 0xA3, 0x24, 0x31,
0x41, 0x42, 0x51, 0x61, 0x62, 0x63, 0x73, 0xE2, 0xE3, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00,
0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, 0xAA, 0x6E, 0x55, 0xCE, 0x51, 0xC6, 0x2A, 0xA5, 0x39,
0xF5, 0x67, 0x13, 0x46, 0x31, 0x87, 0x7C, 0x35, 0x07, 0x4C, 0x3C, 0x58, 0xDA, 0x6A, 0x8B, 0x39,
0xFB, 0x3A, 0xFA, 0xD5, 0x69, 0x5E, 0xD1, 0x52, 0x4F, 0xC8, 0x63, 0x29, 0xC8, 0x03, 0x68, 0xDD,
0xA6, 0x84, 0x6F, 0x0D, 0x38, 0x76, 0x78, 0xCC, 0xBF, 0x76, 0x8A, 0xDC, 0xF6, 0x3F, 0x2B, 0xE8,
0xDF, 0xFF, 0xD9,
};
/**
* @brief Test RGB888 file, resolution 24x16
* Contain six color: white #FFFFFF, black #000000, cyan #00FFFF, red #FF0000, green #00FF00, blue #0000FF
* │< 8px >│< 8px >│< 8px >│
* │ │ │ │
* ───┌───────────┬───────────┬───────────┐
* ^ │ │ │ │
* │ │ │ │
* 8px │ white │ black │ cyan │
* │ │ │ │
* v │ │ │ │
* ───├───────────┼───────────┼───────────┤
* ^ │ │ │ │
* │ │ │ │
* 8px │ red │ green │ blue │
* │ │ │ │
* v │ │ │ │
* ───└───────────┴───────────┴───────────┘
*/
static const uint8_t test_rgb888_data[1152] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
};
/**
* @brief Mount the SD card
*/
void mount_sd(void);
/**
* @brief Unmount the SD card
*/
void unmount_sd(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,35 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#include "unity.h"
#include "unity_test_runner.h"
#include "unity_test_utils_memory.h"
#define TEST_MEMORY_LEAK_THRESHOLD (500)
void setUp(void)
{
unity_utils_record_free_mem();
}
void tearDown(void)
{
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main()
{
// _____ _____ ____ _____ _ ____ _____ ____
// |_ _| ____/ ___|_ _| | | _ \| ____/ ___|
// | | | _| \___ \ | | _ | | |_) | _|| | _
// | | | |___ ___) || | | |_| | __/| |__| |_| |
// |_| |_____|____/ |_| \___/|_| |_____\____|
printf(" _____ _____ ____ _____ _ ____ _____ ____ \n");
printf("|_ _| ____/ ___|_ _| | | _ \\| ____/ ___|\n");
printf(" | | | _| \\___ \\ | | _ | | |_) | _|| | _ \n");
printf(" | | | |___ ___) || | | |_| | __/| |__| |_| |\n");
printf(" |_| |_____|____/ |_| \\___/|_| |_____\\____|\n");
unity_run_menu();
}

View File

@@ -0,0 +1,158 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_system.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "unity.h"
#include "test_decoder.h"
#include "test_encoder.h"
#include "image_io.h"
static const char *TAG = "JPEG";
#define JPEG_DECODER_LIMIT 16
TEST_CASE("test_demo", "[sys]")
{
ESP_LOGI(TAG, "TEST");
}
TEST_CASE("test_system_heap", "[sys]")
{
ESP_LOGI(TAG, "Internal free heap size: %ld bytes", esp_get_free_internal_heap_size());
ESP_LOGI(TAG, "PSRAM free heap size: %ld bytes", esp_get_free_heap_size() - esp_get_free_internal_heap_size());
ESP_LOGI(TAG, "Total free heap size: %ld bytes", esp_get_free_heap_size());
}
TEST_CASE("test_decoder_once", "[dec]")
{
unsigned char *input_buffer = test_jpeg_data;
int intput_len = sizeof(test_jpeg_data);
unsigned char *ouput_buffer = NULL;
int output_len = 0;
uint8_t *curpix = NULL;
// Test for decode process
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_decode_one_picture(input_buffer, intput_len, &ouput_buffer, &output_len));
// Print output buffer
// ESP_LOG_BUFFER_HEX(TAG, ouput_buffer, output_len);
// Test for while pixel
curpix = &ouput_buffer[(TEST_JPEG_WHITE_Y * TEST_JPEG_X + TEST_JPEG_WHITE_X) * 3];
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[0][0], curpix[0]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[0][1], curpix[1]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[0][2], curpix[2]);
// Test for black pixel
curpix = &ouput_buffer[(TEST_JPEG_BLACK_Y * TEST_JPEG_X + TEST_JPEG_BLACK_X) * 3];
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[1][0], curpix[0]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[1][1], curpix[1]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[1][2], curpix[2]);
// Test for cyan pixel
curpix = &ouput_buffer[(TEST_JPEG_CYAN_Y * TEST_JPEG_X + TEST_JPEG_CYAN_X) * 3];
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[2][0], curpix[0]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[2][1], curpix[1]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[2][2], curpix[2]);
// Test for red pixel
curpix = &ouput_buffer[(TEST_JPEG_RED_Y * TEST_JPEG_X + TEST_JPEG_RED_X) * 3];
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[3][0], curpix[0]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[3][1], curpix[1]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[3][2], curpix[2]);
// Test for green pixel
curpix = &ouput_buffer[(TEST_JPEG_GREEN_Y * TEST_JPEG_X + TEST_JPEG_GREEN_X) * 3];
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[4][0], curpix[0]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[4][1], curpix[1]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[4][2], curpix[2]);
// Test for blue pixel
curpix = &ouput_buffer[(TEST_JPEG_BLUE_Y * TEST_JPEG_X + TEST_JPEG_BLUE_X) * 3];
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[5][0], curpix[0]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[5][1], curpix[1]);
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[5][2], curpix[2]);
// Free output buffer
if (ouput_buffer) {
jpeg_free_align(ouput_buffer);
}
ESP_LOGI(TAG, "in_buffer: %p, in_len: %d, out_buffer: %p, out_len: %d", input_buffer, intput_len, ouput_buffer, output_len);
}
TEST_CASE("test_decoder_block", "[dec]")
{
unsigned char *input_buffer = test_jpeg_data;
int intput_len = sizeof(test_jpeg_data);
#if TEST_USE_SDCARD
mount_sd();
#endif /* TEST_USE_SDCARD */
// Test for decode process
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_decode_one_picture_block(input_buffer, intput_len));
#if TEST_USE_SDCARD
unmount_sd();
#endif /* TEST_USE_SDCARD */
}
TEST_CASE("test_decoder_stream", "[dec]")
{
unsigned char *input_buffer = test_jpeg_data;
int intput_len = sizeof(test_jpeg_data);
unsigned char *ouput_buffer = NULL;
int output_len = 0;
struct esp_jpeg_stream jpeg_handle = {0};
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_stream_open(&jpeg_handle));
for (int frame_cnt = 0; frame_cnt < 10; frame_cnt++) {
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_stream_decode(&jpeg_handle, input_buffer, intput_len, &ouput_buffer, &output_len));
ESP_LOGI(TAG, "frame_index: %d, in_buffer: %p, in_len: %d, out_buffer: %p, out_len: %d", frame_cnt, input_buffer, intput_len, ouput_buffer, output_len);
// Free output buffer
if (ouput_buffer) {
jpeg_free_align(ouput_buffer);
}
}
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_stream_close(&jpeg_handle));
}
TEST_CASE("test_encoder_once", "[enc]")
{
#if TEST_USE_SDCARD
mount_sd();
#endif /* TEST_USE_SDCARD */
// Test for encode process
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_encode_one_picture());
#if TEST_USE_SDCARD
unmount_sd();
#endif /* TEST_USE_SDCARD */
}
TEST_CASE("test_encoder_block", "[enc]")
{
#if TEST_USE_SDCARD
mount_sd();
#endif /* TEST_USE_SDCARD */
// Test for encode process
TEST_ASSERT_GREATER_OR_EQUAL(JPEG_ERR_OK, esp_jpeg_encode_one_picture_block());
#if TEST_USE_SDCARD
unmount_sd();
#endif /* TEST_USE_SDCARD */
}

View File

@@ -0,0 +1,310 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "image_io.h"
#include "test_decoder.h"
static jpeg_pixel_format_t j_type = JPEG_PIXEL_FORMAT_RGB888;
static jpeg_rotate_t j_rotation = JPEG_ROTATE_0D;
jpeg_error_t esp_jpeg_decode_one_picture(uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len)
{
uint8_t *out_buf = NULL;
jpeg_error_t ret = JPEG_ERR_OK;
jpeg_dec_io_t *jpeg_io = NULL;
jpeg_dec_header_info_t *out_info = NULL;
// Generate default configuration
jpeg_dec_config_t config = DEFAULT_JPEG_DEC_CONFIG();
config.output_type = j_type;
config.rotate = j_rotation;
// config.scale.width = 0;
// config.scale.height = 0;
// config.clipper.width = 0;
// config.clipper.height = 0;
// Create jpeg_dec handle
jpeg_dec_handle_t jpeg_dec = NULL;
ret = jpeg_dec_open(&config, &jpeg_dec);
if (ret != JPEG_ERR_OK) {
return ret;
}
// Create io_callback handle
jpeg_io = calloc(1, sizeof(jpeg_dec_io_t));
if (jpeg_io == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
// Create out_info handle
out_info = calloc(1, sizeof(jpeg_dec_header_info_t));
if (out_info == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
// Set input buffer and buffer len to io_callback
jpeg_io->inbuf = input_buf;
jpeg_io->inbuf_len = len;
// Parse jpeg picture header and get picture for user and decoder
ret = jpeg_dec_parse_header(jpeg_dec, jpeg_io, out_info);
if (ret != JPEG_ERR_OK) {
goto jpeg_dec_failed;
}
*out_len = out_info->width * out_info->height * 3;
// Calloc out_put data buffer and update inbuf ptr and inbuf_len
if (config.output_type == JPEG_PIXEL_FORMAT_RGB565_LE
|| config.output_type == JPEG_PIXEL_FORMAT_RGB565_BE
|| config.output_type == JPEG_PIXEL_FORMAT_CbYCrY) {
*out_len = out_info->width * out_info->height * 2;
} else if (config.output_type == JPEG_PIXEL_FORMAT_RGB888) {
*out_len = out_info->width * out_info->height * 3;
} else {
ret = JPEG_ERR_INVALID_PARAM;
goto jpeg_dec_failed;
}
out_buf = jpeg_calloc_align(*out_len, 16);
if (out_buf == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
jpeg_io->outbuf = out_buf;
*output_buf = out_buf;
// Start decode jpeg
ret = jpeg_dec_process(jpeg_dec, jpeg_io);
if (ret != JPEG_ERR_OK) {
goto jpeg_dec_failed;
}
// Decoder deinitialize
jpeg_dec_failed:
jpeg_dec_close(jpeg_dec);
if (jpeg_io) {
free(jpeg_io);
}
if (out_info) {
free(out_info);
}
return ret;
}
jpeg_error_t esp_jpeg_decode_one_picture_block(unsigned char *input_buf, int len)
{
unsigned char *output_block = NULL;
jpeg_error_t ret = JPEG_ERR_OK;
jpeg_dec_io_t *jpeg_io = NULL;
jpeg_dec_header_info_t *out_info = NULL;
FILE *f_out = NULL;
// Generate default configuration
jpeg_dec_config_t config = DEFAULT_JPEG_DEC_CONFIG();
config.block_enable = true;
// Empty handle to jpeg_decoder
jpeg_dec_handle_t jpeg_dec = NULL;
ret = jpeg_dec_open(&config, &jpeg_dec);
if (ret != JPEG_ERR_OK) {
return ret;
}
// Create io_callback handle
jpeg_io = calloc(1, sizeof(jpeg_dec_io_t));
if (jpeg_io == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
// Create out_info handle
out_info = calloc(1, sizeof(jpeg_dec_header_info_t));
if (out_info == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
// Set input buffer and buffer len to io_callback
jpeg_io->inbuf = input_buf;
jpeg_io->inbuf_len = len;
// Parse jpeg picture header and get picture for user and decoder
ret = jpeg_dec_parse_header(jpeg_dec, jpeg_io, out_info);
if (ret != JPEG_ERR_OK) {
goto jpeg_dec_failed;
}
// Calloc block output data buffer
int output_len = 0;
ret = jpeg_dec_get_outbuf_len(jpeg_dec, &output_len);
if (ret != JPEG_ERR_OK || output_len == 0) {
goto jpeg_dec_failed;
}
output_block = jpeg_calloc_align(output_len, 16);
if (output_block == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
jpeg_io->outbuf = output_block;
// get process count
int process_count = 0;
ret = jpeg_dec_get_process_count(jpeg_dec, &process_count);
if (ret != JPEG_ERR_OK || process_count == 0) {
goto jpeg_dec_failed;
}
#if TEST_USE_SDCARD
// Open output file on SDCard, should init SDcard first
f_out = fopen("/sdcard/esp_jpeg_decode_one_picture_block.bin", "wb");
if (f_out == NULL) {
ret = JPEG_ERR_FAIL;
goto jpeg_dec_failed;
}
#endif /* TEST_USE_SDCARD */
// Decode jpeg data
for (int block_cnt = 0; block_cnt < process_count; block_cnt++) {
ret = jpeg_dec_process(jpeg_dec, jpeg_io);
if (ret != JPEG_ERR_OK) {
goto jpeg_dec_failed;
}
#if TEST_USE_SDCARD
// do something - to sdcard
int written_data = fwrite(jpeg_io->outbuf, 1, jpeg_io->out_size, f_out);
if (written_data != jpeg_io->out_size) {
ret = JPEG_ERR_FAIL;
goto jpeg_dec_failed;
}
#endif /* TEST_USE_SDCARD */
}
// Decoder deinitialize
jpeg_dec_failed:
jpeg_dec_close(jpeg_dec);
if (jpeg_io) {
free(jpeg_io);
}
if (out_info) {
free(out_info);
}
jpeg_free_align(output_block);
#if TEST_USE_SDCARD
if (f_out) {
fclose(f_out);
}
#endif /* TEST_USE_SDCARD */
return ret;
}
jpeg_error_t esp_jpeg_stream_open(esp_jpeg_stream_handle_t jpeg_handle)
{
jpeg_error_t ret = JPEG_ERR_OK;
// Generate default configuration
jpeg_dec_config_t config = DEFAULT_JPEG_DEC_CONFIG();
config.output_type = j_type;
config.rotate = j_rotation;
// config.scale.width = 0;
// config.scale.height = 0;
// config.clipper.width = 0;
// config.clipper.height = 0;
jpeg_handle->output_type = j_type;
// Create jpeg_dec handle
ret = jpeg_dec_open(&config, &jpeg_handle->jpeg_dec);
if (ret != JPEG_ERR_OK) {
return ret;
}
// Create io_callback handle
jpeg_handle->jpeg_io = calloc(1, sizeof(jpeg_dec_io_t));
if (jpeg_handle->jpeg_io == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
// Create out_info handle
jpeg_handle->out_info = calloc(1, sizeof(jpeg_dec_header_info_t));
if (jpeg_handle->out_info == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_dec_failed;
}
return JPEG_ERR_OK;
// Decoder deinitialize
jpeg_dec_failed:
jpeg_dec_close(jpeg_handle->jpeg_dec);
if (jpeg_handle->jpeg_io) {
free(jpeg_handle->jpeg_io);
}
if (jpeg_handle->out_info) {
free(jpeg_handle->out_info);
}
return ret;
}
jpeg_error_t esp_jpeg_stream_decode(esp_jpeg_stream_handle_t jpeg_handle, uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len)
{
jpeg_error_t ret = JPEG_ERR_OK;
unsigned char *out_buf = NULL;
// Set input buffer and buffer len to io_callback
jpeg_handle->jpeg_io->inbuf = input_buf;
jpeg_handle->jpeg_io->inbuf_len = len;
// Parse jpeg picture header and get picture for user and decoder
ret = jpeg_dec_parse_header(jpeg_handle->jpeg_dec, jpeg_handle->jpeg_io, jpeg_handle->out_info);
if (ret != JPEG_ERR_OK) {
return ret;
}
*out_len = jpeg_handle->out_info->width * jpeg_handle->out_info->height * 3;
// Calloc out_put data buffer and update inbuf ptr and inbuf_len
if (jpeg_handle->output_type == JPEG_PIXEL_FORMAT_RGB565_LE
|| jpeg_handle->output_type == JPEG_PIXEL_FORMAT_RGB565_BE
|| jpeg_handle->output_type == JPEG_PIXEL_FORMAT_CbYCrY) {
*out_len = jpeg_handle->out_info->width * jpeg_handle->out_info->height * 2;
} else if (jpeg_handle->output_type == JPEG_PIXEL_FORMAT_RGB888) {
*out_len = jpeg_handle->out_info->width * jpeg_handle->out_info->height * 3;
} else {
ret = JPEG_ERR_INVALID_PARAM;
return ret;
}
out_buf = jpeg_calloc_align(*out_len, 16);
if (out_buf == NULL) {
ret = JPEG_ERR_NO_MEM;
return ret;
}
jpeg_handle->jpeg_io->outbuf = out_buf;
*output_buf = out_buf;
// Start decode jpeg
ret = jpeg_dec_process(jpeg_handle->jpeg_dec, jpeg_handle->jpeg_io);
if (ret != JPEG_ERR_OK) {
return ret;
}
return ret;
}
jpeg_error_t esp_jpeg_stream_close(esp_jpeg_stream_handle_t jpeg_handle)
{
jpeg_error_t ret = JPEG_ERR_OK;
ret = jpeg_dec_close(jpeg_handle->jpeg_dec);
if (jpeg_handle->jpeg_io) {
free(jpeg_handle->jpeg_io);
}
if (jpeg_handle->out_info) {
free(jpeg_handle->out_info);
}
return ret;
}

View File

@@ -0,0 +1,87 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stdint.h>
#include "esp_jpeg_common.h"
#include "esp_jpeg_dec.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct esp_jpeg_stream {
jpeg_dec_handle_t jpeg_dec;
jpeg_dec_io_t *jpeg_io;
jpeg_dec_header_info_t *out_info;
jpeg_pixel_format_t output_type;
};
typedef struct esp_jpeg_stream *esp_jpeg_stream_handle_t;
/**
* @brief Decode a single JPEG picture
*
* @param input_buf Pointer to the input buffer containing JPEG data
* @param len Length of the input buffer in bytes
* @param output_buf Pointer to output buffer, allocated in `esp_jpeg_decoder_one_picture` but it won't to free. Please release this buffer after decoding is complete.
* @param out_len Acturally output length in bytes
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_decode_one_picture(uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len);
/**
* @brief Decode a single JPEG picture with block deocder API
*
* @param input_buf Pointer to the input buffer containing JPEG data
* @param len Length of the input buffer in bytes
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_decode_one_picture_block(unsigned char *input_buf, int len);
/**
* @brief Open a JPEG stream handle for decoding
*
* @param jpeg_handle Handle to the JPEG stream
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_stream_open(esp_jpeg_stream_handle_t jpeg_handle);
/**
* @brief Decode a portion of the JPEG stream
*
* @param jpeg_handle Handle to the JPEG stream
* @param input_buf Pointer to the input buffer containing JPEG data
* @param len Length of the input buffer in bytes
* @param output_buf Pointer to output buffer, allocated in `esp_jpeg_stream_decode` but it won't to free. Please release this buffer after decoding is complete.
* @param out_len Acturally output length in bytes
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_stream_decode(esp_jpeg_stream_handle_t jpeg_handle, uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len);
/**
* @brief Close the JPEG stream
*
* @param jpeg_handle Handle to the JPEG stream
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_stream_close(esp_jpeg_stream_handle_t jpeg_handle);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,148 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "image_io.h"
#include "test_encoder.h"
jpeg_error_t esp_jpeg_encode_one_picture(void)
{
// configure encoder
jpeg_enc_config_t jpeg_enc_cfg = DEFAULT_JPEG_ENC_CONFIG();
jpeg_enc_cfg.width = TEST_JPEG_X;
jpeg_enc_cfg.height = TEST_JPEG_Y;
jpeg_enc_cfg.src_type = JPEG_PIXEL_FORMAT_RGB888;
jpeg_enc_cfg.subsampling = JPEG_SUBSAMPLE_420;
jpeg_enc_cfg.quality = 60;
jpeg_enc_cfg.rotate = JPEG_ROTATE_0D;
jpeg_enc_cfg.task_enable = false;
jpeg_enc_cfg.hfm_task_priority = 13;
jpeg_enc_cfg.hfm_task_core = 1;
jpeg_error_t ret = JPEG_ERR_OK;
uint8_t *inbuf = test_rgb888_data;
int image_size = jpeg_enc_cfg.width * jpeg_enc_cfg.height * 3;
uint8_t *outbuf = NULL;
int outbuf_size = 100 * 1024;
int out_len = 0;
jpeg_enc_handle_t jpeg_enc = NULL;
FILE *out = NULL;
// open
ret = jpeg_enc_open(&jpeg_enc_cfg, &jpeg_enc);
if (ret != JPEG_ERR_OK) {
return ret;
}
// allocate output buffer to fill encoded image stream
outbuf = (uint8_t *)calloc(1, outbuf_size);
if (outbuf == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_example_exit;
}
// process
ret = jpeg_enc_process(jpeg_enc, inbuf, image_size, outbuf, outbuf_size, &out_len);
if (ret != JPEG_ERR_OK) {
goto jpeg_example_exit;
}
#if TEST_USE_SDCARD
out = fopen("/sdcard/esp_jpeg_encode_one_picture.jpg", "wb");
if (out == NULL) {
goto jpeg_example_exit;
}
fwrite(outbuf, 1, out_len, out);
fclose(out);
#endif /* TEST_USE_SDCARD */
jpeg_example_exit:
// close
jpeg_enc_close(jpeg_enc);
if (outbuf) {
free(outbuf);
}
return ret;
}
jpeg_error_t esp_jpeg_encode_one_picture_block(void)
{
// configure encoder
jpeg_enc_config_t jpeg_enc_cfg = DEFAULT_JPEG_ENC_CONFIG();
jpeg_enc_cfg.width = TEST_JPEG_X;
jpeg_enc_cfg.height = TEST_JPEG_Y;
jpeg_enc_cfg.src_type = JPEG_PIXEL_FORMAT_RGB888;
jpeg_enc_cfg.subsampling = JPEG_SUBSAMPLE_420;
jpeg_enc_cfg.quality = 60;
jpeg_enc_cfg.rotate = JPEG_ROTATE_0D;
jpeg_enc_cfg.task_enable = false;
jpeg_enc_cfg.hfm_task_priority = 13;
jpeg_enc_cfg.hfm_task_core = 1;
jpeg_error_t ret = JPEG_ERR_OK;
uint8_t *inbuf = test_rgb888_data;
int image_size = jpeg_enc_cfg.width * jpeg_enc_cfg.height * 3;
int block_size = 0;
int num_times = 0;
uint8_t *outbuf = NULL;
int outbuf_size = 100 * 1024;
int out_len = 0;
jpeg_enc_handle_t jpeg_enc = NULL;
FILE *out = NULL;
// open
ret = jpeg_enc_open(&jpeg_enc_cfg, &jpeg_enc);
if (ret != JPEG_ERR_OK) {
return ret;
}
// outbuf
if ((outbuf = (uint8_t *)calloc(1, outbuf_size)) == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_example_exit;
}
// inbuf
block_size = jpeg_enc_get_block_size(jpeg_enc);
if ((inbuf = (uint8_t *)jpeg_calloc_align(block_size, 16)) == NULL) {
ret = JPEG_ERR_NO_MEM;
goto jpeg_example_exit;
}
num_times = image_size / block_size;
// process
int in_offset = 0;
for (size_t j = 0; j < num_times; j++) {
// copy memory or read from SDCard
memcpy(inbuf, test_rgb888_data + in_offset, block_size);
in_offset += block_size;
ret = jpeg_enc_process_with_block(jpeg_enc, inbuf, block_size, outbuf, outbuf_size, &out_len);
if (ret < JPEG_ERR_OK) {
goto jpeg_example_exit;
}
}
jpeg_example_exit:
#if TEST_USE_SDCARD
out = fopen("/sdcard/esp_jpeg_encode_one_picture_block.jpg", "wb");
if (out != NULL) {
fwrite(outbuf, 1, out_len, out);
fclose(out);
}
#endif /* TEST_USE_SDCARD */
// close
jpeg_enc_close(jpeg_enc);
if (inbuf) {
jpeg_free_align(inbuf);
}
if (outbuf) {
free(outbuf);
}
return ret;
}

View File

@@ -0,0 +1,33 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include "esp_jpeg_common.h"
#include "esp_jpeg_enc.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @brief Encode a single picture
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_encode_one_picture(void);
/**
* @brief Encode a single picture with block encoder API
*
* @return
* - JPEG_ERR_OK Succeeded
* - Others Failed
*/
jpeg_error_t esp_jpeg_encode_one_picture_block(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32c5
@pytest.mark.esp32c6
def test_esp_system(dut: Dut) -> None:
dut.run_all_single_board_cases()

View File

@@ -0,0 +1,24 @@
#
# ESP System Settings
#
CONFIG_ESP_TASK_WDT_EN=n
#
# FreeRTOS
#
CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
#
# SPI RAM config
#
CONFIG_SPIRAM=y
CONFIG_SPIRAM_BOOT_INIT=y
#
# FAT Filesystem support
#
CONFIG_FATFS_CODEPAGE_936=y
CONFIG_FATFS_LFN_HEAP=y
CONFIG_FATFS_MAX_LFN=255
CONFIG_FATFS_FS_LOCK=5

View File

@@ -0,0 +1,13 @@
#
# ESP32S3-Specific
#
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
#
# SPI RAM config
#
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_TYPE_AUTO=y