add some code
This commit is contained in:
@@ -0,0 +1 @@
|
||||
7c07831bbf11d15f84f42dc0e127094c78063b03d0dce688495773656f998d2b
|
||||
15
managed_components/espressif__esp_new_jpeg/CHANGELOG.md
Normal file
15
managed_components/espressif__esp_new_jpeg/CHANGELOG.md
Normal 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
|
||||
@@ -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"}]}
|
||||
@@ -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")
|
||||
20
managed_components/espressif__esp_new_jpeg/LICENSE
Normal file
20
managed_components/espressif__esp_new_jpeg/LICENSE
Normal 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.
|
||||
200
managed_components/espressif__esp_new_jpeg/README.md
Normal file
200
managed_components/espressif__esp_new_jpeg/README.md
Normal 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 "✔" means supported, and the "✖" means not supported.
|
||||
|
||||
| Chip | v0.5.1 |
|
||||
|----------|----------|
|
||||
| ESP32 | ✔ |
|
||||
| ESP32-S2 | ✔ |
|
||||
| ESP32-S3 | ✔ |
|
||||
| ESP32-P4 | ✔ |
|
||||
| ESP32-C2 | ✔ |
|
||||
| ESP32-C3 | ✔ |
|
||||
| ESP32-C5 | ✔ |
|
||||
| ESP32-C6 | ✔ |
|
||||
17
managed_components/espressif__esp_new_jpeg/idf_component.yml
Normal file
17
managed_components/espressif__esp_new_jpeg/idf_component.yml
Normal 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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
idf:
|
||||
version: '>=5.0'
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user