add some code
This commit is contained in:
1
managed_components/espressif__esp_jpeg/.component_hash
Normal file
1
managed_components/espressif__esp_jpeg/.component_hash
Normal file
@@ -0,0 +1 @@
|
||||
defb83669293cbf86d0fa86b475ba5517aceed04ed70db435388c151ab37b5d7
|
||||
40
managed_components/espressif__esp_jpeg/CHANGELOG.md
Normal file
40
managed_components/espressif__esp_jpeg/CHANGELOG.md
Normal file
@@ -0,0 +1,40 @@
|
||||
## 1.3.1
|
||||
|
||||
- Fixed the format of Kconfig file
|
||||
|
||||
## 1.3.0
|
||||
|
||||
- Added option to get image size without decoding it
|
||||
|
||||
## 1.2.1
|
||||
|
||||
- Fixed decoding of non-conforming 0xFFFF marker
|
||||
|
||||
## 1.2.0
|
||||
|
||||
- Added option to for passing user defined working buffer
|
||||
|
||||
## 1.1.0
|
||||
|
||||
- Added support for decoding images without Huffman tables
|
||||
- Fixed undefined configuration options from Kconfig
|
||||
|
||||
## 1.0.5~3
|
||||
|
||||
- Added option to swap output color bytes regardless of JD_FORMAT
|
||||
|
||||
## 1.0.4
|
||||
|
||||
- Added ROM implementation support for ESP32-C6
|
||||
|
||||
## 1.0.2
|
||||
|
||||
- Fixed compiler warnings
|
||||
|
||||
## 1.0.1
|
||||
|
||||
- Fixed: exclude ESP32-C2 from list of ROM implementations
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- Initial version
|
||||
1
managed_components/espressif__esp_jpeg/CHECKSUMS.json
Normal file
1
managed_components/espressif__esp_jpeg/CHECKSUMS.json
Normal file
File diff suppressed because one or more lines are too long
14
managed_components/espressif__esp_jpeg/CMakeLists.txt
Normal file
14
managed_components/espressif__esp_jpeg/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
set(sources "jpeg_decoder.c")
|
||||
set(includes "include")
|
||||
|
||||
# Compile only when cannot use ROM code
|
||||
if(NOT CONFIG_JD_USE_ROM)
|
||||
list(APPEND sources "tjpgd/tjpgd.c")
|
||||
list(APPEND includes "tjpgd")
|
||||
endif()
|
||||
|
||||
if(CONFIG_JD_DEFAULT_HUFFMAN)
|
||||
list(APPEND sources "jpeg_default_huffman_table.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${sources} INCLUDE_DIRS ${includes})
|
||||
80
managed_components/espressif__esp_jpeg/Kconfig
Normal file
80
managed_components/espressif__esp_jpeg/Kconfig
Normal file
@@ -0,0 +1,80 @@
|
||||
menu "JPEG Decoder"
|
||||
|
||||
config JD_USE_ROM
|
||||
bool "Use TinyJPG Decoder from ROM"
|
||||
depends on ESP_ROM_HAS_JPEG_DECODE
|
||||
default y
|
||||
help
|
||||
By default, Espressif SoCs use TJpg decoder implemented in ROM code.
|
||||
If this feature is disabled, new configuration of TJpg decoder can be used.
|
||||
Refer to REAME.md for more details.
|
||||
|
||||
config JD_SZBUF
|
||||
int "Size of stream input buffer"
|
||||
depends on !JD_USE_ROM
|
||||
default 512
|
||||
|
||||
config JD_FORMAT
|
||||
int
|
||||
depends on !JD_USE_ROM
|
||||
default 0 if JD_FORMAT_RGB888
|
||||
default 1 if JD_FORMAT_RGB565
|
||||
|
||||
choice
|
||||
prompt "Output pixel format"
|
||||
depends on !JD_USE_ROM
|
||||
default JD_FORMAT_RGB888
|
||||
help
|
||||
Output format is selected at runtime.
|
||||
|
||||
config JD_FORMAT_RGB888
|
||||
bool "Support RGB565 and RGB888 output (16-bit/pix and 24-bit/pix)"
|
||||
config JD_FORMAT_RGB565
|
||||
bool "Support RGB565 output (16-bit/pix)"
|
||||
endchoice
|
||||
|
||||
config JD_USE_SCALE
|
||||
bool "Enable descaling"
|
||||
depends on !JD_USE_ROM
|
||||
default y
|
||||
help
|
||||
If scaling is enabled, size of output image can be lowered during decoding.
|
||||
|
||||
config JD_TBLCLIP
|
||||
bool "Use table conversion for saturation arithmetic"
|
||||
depends on !JD_USE_ROM
|
||||
default y
|
||||
help
|
||||
Use table conversion for saturation arithmetic. A bit faster, but increases 1 KB of code size.
|
||||
|
||||
config JD_FASTDECODE
|
||||
int
|
||||
depends on !JD_USE_ROM
|
||||
default 0 if JD_FASTDECODE_BASIC
|
||||
default 1 if JD_FASTDECODE_32BIT
|
||||
default 2 if JD_FASTDECODE_TABLE
|
||||
|
||||
choice
|
||||
prompt "Optimization level"
|
||||
depends on !JD_USE_ROM
|
||||
default JD_FASTDECODE_32BIT
|
||||
|
||||
config JD_FASTDECODE_BASIC
|
||||
bool "Basic optimization. Suitable for 8/16-bit MCUs"
|
||||
config JD_FASTDECODE_32BIT
|
||||
bool "+ 32-bit barrel shifter. Suitable for 32-bit MCUs"
|
||||
config JD_FASTDECODE_TABLE
|
||||
bool "+ Table conversion for huffman decoding (wants 6 << HUFF_BIT bytes of RAM)"
|
||||
endchoice
|
||||
|
||||
config JD_DEFAULT_HUFFMAN
|
||||
bool "Support images without Huffman table"
|
||||
depends on !JD_USE_ROM
|
||||
default n
|
||||
help
|
||||
Enable this option to support decoding JPEG images that lack an embedded Huffman table.
|
||||
When enabled, a default Huffman table is used during decoding, allowing the JPEG decoder to handle
|
||||
images without explicitly provided Huffman tables.
|
||||
|
||||
Note: Enabling this option increases ROM usage due to the inclusion of default Huffman tables.
|
||||
endmenu
|
||||
112
managed_components/espressif__esp_jpeg/README.md
Normal file
112
managed_components/espressif__esp_jpeg/README.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# JPEG Decoder: TJpgDec - Tiny JPEG Decompressor
|
||||
|
||||
[](https://components.espressif.com/components/espressif/esp_jpeg)
|
||||

|
||||
|
||||
TJpgDec is a lightweight JPEG image decompressor optimized for embedded systems with minimal memory consumption.
|
||||
|
||||
On some microcontrollers, TJpgDec is available in ROM and will be used by default, though this can be disabled in menuconfig if desired[^1].
|
||||
|
||||
[^1]: **_NOTE:_** When the ROM decoder is used, the configuration can't be changed. The configuration is fixed.
|
||||
|
||||
## Features
|
||||
|
||||
**Compilation configuration:**
|
||||
- Stream input buffer size (default: 512 bytes)
|
||||
- Output pixel format (default: RGB888; options: RGB888/RGB565)
|
||||
- Enable/disable output descaling (default: enabled)
|
||||
- Use table-based saturation for arithmetic operations (default: enabled)
|
||||
- Use default Huffman tables: Useful from decoding frames from cameras, that do not provide Huffman tables (default: disabled to save ROM)
|
||||
- Three optimization levels (default: 32-bit MCUs) for different CPU types:
|
||||
- 8/16-bit MCUs
|
||||
- 32-bit MCUs
|
||||
- Table-based Huffman decoding
|
||||
|
||||
**Runtime configuration:**
|
||||
- Pixel format options: RGB888, RGB565
|
||||
- Selectable scaling ratios: 1/1, 1/2, 1/4, or 1/8 (chosen at decompression)
|
||||
- Option to swap the first and last bytes of color values
|
||||
|
||||
## TJpgDec in ROM
|
||||
|
||||
On certain microcontrollers, TJpgDec is available in ROM and used by default. This can be disabled in menuconfig if you prefer to use the library code provided in this component.
|
||||
|
||||
### List of MCUs, which have TJpgDec in ROM
|
||||
- ESP32
|
||||
- ESP32-S3
|
||||
- ESP32-C3
|
||||
- ESP32-C6
|
||||
- ESP32-C5
|
||||
- ESP32-C61
|
||||
|
||||
### Fixed compilation configuration of the ROM code
|
||||
The ROM version uses the following fixed settings:
|
||||
- Stream input buffer: 512 bytes
|
||||
- Output pixel format: RGB888
|
||||
- Output descaling: enabled
|
||||
- Saturation table: enabled
|
||||
- Optimization level: Basic (JD_FASTDECODE = 0)
|
||||
|
||||
### Pros and cons using ROM code
|
||||
|
||||
**Advantages:**
|
||||
- Saves approximately 5 KB of flash memory with the same configuration
|
||||
|
||||
**Disadvantages:**
|
||||
- Compilation configuration cannot be changed
|
||||
- Certain configurations may provide faster performance
|
||||
|
||||
## Speed comparison
|
||||
|
||||
The table below shows example decoding times for a JPEG image using various configurations:
|
||||
* Image size: 320 x 180 px
|
||||
* Output format: RGB565
|
||||
* CPU: ESP32-S3
|
||||
* CPU frequency: 240 MHz
|
||||
* SPI mode: DIO
|
||||
* Internal RAM used
|
||||
* Measured in 1000 retries
|
||||
|
||||
| ROM used | JD_SZBUF | JD_FORMAT | JD_USE_SCALE | JD_TBLCLIP | JD_FASTDECODE | RAM buffer | Flash size | Approx. time |
|
||||
| :------: | :------: | :-------: | :----------: | :--------: | :-----------: | :--------: | :--------: | :----------: |
|
||||
| YES | 512 | RGB888 | 1 | 1 | 0 | 3.1 kB | 0 kB | 52 ms |
|
||||
| NO | 512 | RGB888 | 1 | 1 | 0 | 3.1 kB | 5 kB | 50 ms |
|
||||
| NO | 512 | RGB888 | 1 | 0 | 0 | 3.1 kB | 4 kB | 68 ms |
|
||||
| NO | 512 | RGB888 | 1 | 1 | 1 | 3.1 kB | 5 kB | 50 ms |
|
||||
| NO | 512 | RGB888 | 1 | 0 | 1 | 3.1 kB | 4 kB | 62 ms |
|
||||
| NO | 512 | RGB888 | 1 | 1 | 2 | 65.5 kB | 5.5 kB | 46 ms |
|
||||
| NO | 512 | RGB888 | 1 | 0 | 2 | 65.5 kB | 4.5 kB | 59 ms |
|
||||
| NO | 512 | RGB565 | 1 | 1 | 0 | 5 kB | 5 kB | 60 ms |
|
||||
| NO | 512 | RGB565 | 1 | 1 | 1 | 5 kB | 5 kB | 59 ms |
|
||||
| NO | 512 | RGB565 | 1 | 1 | 2 | 65.5 kB | 5.5 kB | 56 ms |
|
||||
|
||||
## Add to project
|
||||
|
||||
Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/).
|
||||
You can add them to your project via `idf.py add-dependancy`, e.g.
|
||||
```
|
||||
idf.py add-dependency esp_jpeg==1.0.0
|
||||
```
|
||||
|
||||
Alternatively, you can create `idf_component.yml`. More is in [Espressif's documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html).
|
||||
|
||||
## Example use
|
||||
|
||||
Here is example of usage. This calling is **blocking**.
|
||||
|
||||
```
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)jpeg_img_buf,
|
||||
.indata_size = jpeg_img_buf_size,
|
||||
.outbuf = out_img_buf,
|
||||
.outbuf_size = out_img_buf_size,
|
||||
.out_format = JPEG_IMAGE_OUT_FORMAT_RGB565,
|
||||
.out_scale = JPEG_IMAGE_SCALE_0,
|
||||
.flags = {
|
||||
.swap_color_bytes = 1,
|
||||
}
|
||||
};
|
||||
esp_jpeg_image_output_t outimg;
|
||||
|
||||
esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(COMPONENTS main)
|
||||
project(lcd_tjpgd)
|
||||
@@ -0,0 +1,54 @@
|
||||
# LCD tjpgd example
|
||||
|
||||
This example shows how to decode a jpeg image and display it on an SPI-interfaced LCD, and rotates the image periodically.
|
||||
|
||||
Example using initialization of the LCD from [ESP-BSP](https://github.com/espressif/esp-bsp) project. For change the Espressif's board, go to [idf_component.yml](main/idf_component.yml) and change `esp-box` to another board from BSP.
|
||||
|
||||
## How to Use Example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* An ESP development board
|
||||
* An SPI-interfaced LCD
|
||||
* An USB cable for power supply and programming
|
||||
|
||||
### Hardware Connection
|
||||
|
||||
The connection between ESP Board and the LCD is as follows:
|
||||
|
||||
```text
|
||||
ESP Board LCD Screen
|
||||
+---------+ +---------------------------------+
|
||||
| | | |
|
||||
| 3V3 +--------------+ VCC +----------------------+ |
|
||||
| | | | | |
|
||||
| GND +--------------+ GND | | |
|
||||
| | | | | |
|
||||
| DATA0 +--------------+ MOSI | | |
|
||||
| | | | | |
|
||||
| PCLK +--------------+ SCK | | |
|
||||
| | | | | |
|
||||
| CS +--------------+ CS | | |
|
||||
| | | | | |
|
||||
| D/C +--------------+ D/C | | |
|
||||
| | | | | |
|
||||
| RST +--------------+ RST | | |
|
||||
| | | | | |
|
||||
|BK_LIGHT +--------------+ BCKL +----------------------+ |
|
||||
| | | |
|
||||
+---------+ +---------------------------------+
|
||||
```
|
||||
|
||||
The GPIO numbers used by this example is taken from BSP.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. A flowing picture will be shown on the LCD screen.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For any technical queries, please open an [issue] (https://github.com/espressif/idf-extra-components/issues) on GitHub. We will get back to you soon.
|
||||
@@ -0,0 +1,9 @@
|
||||
set(srcs "pretty_effect.c"
|
||||
"lcd_tjpgd_example_main.c"
|
||||
"decode_image.c"
|
||||
)
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS "."
|
||||
EMBED_FILES image.jpg
|
||||
PRIV_REQUIRES esp_lcd)
|
||||
@@ -0,0 +1,9 @@
|
||||
menu "Example Configuration"
|
||||
config EXAMPLE_LCD_FLUSH_PARALLEL_LINES
|
||||
int "LCD flush parallel lines"
|
||||
default 12 if IDF_TARGET_ESP32C2
|
||||
default 16
|
||||
help
|
||||
To speed up transfers, every SPI transfer sends a bunch of lines.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
The image used for the effect on the LCD in the SPI master example is stored in flash
|
||||
as a jpeg file. This file contains the decode_image routine, which uses the tiny JPEG
|
||||
decoder library to decode this JPEG into a format that can be sent to the display.
|
||||
|
||||
Keep in mind that the decoder library cannot handle progressive files (will give
|
||||
``Image decoder: jd_prepare failed (8)`` as an error) so make sure to save in the correct
|
||||
format if you want to use a different image file.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "decode_image.h"
|
||||
#include "jpeg_decoder.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
//Reference the binary-included jpeg file
|
||||
extern const uint8_t image_jpg_start[] asm("_binary_image_jpg_start");
|
||||
extern const uint8_t image_jpg_end[] asm("_binary_image_jpg_end");
|
||||
//Define the height and width of the jpeg file. Make sure this matches the actual jpeg
|
||||
//dimensions.
|
||||
|
||||
const char *TAG = "ImageDec";
|
||||
|
||||
//Decode the embedded image into pixel lines that can be used with the rest of the logic.
|
||||
esp_err_t decode_image(uint16_t **pixels)
|
||||
{
|
||||
*pixels = NULL;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
//Alocate pixel memory. Each line is an array of IMAGE_W 16-bit pixels; the `*pixels` array itself contains pointers to these lines.
|
||||
*pixels = calloc(IMAGE_H * IMAGE_W, sizeof(uint16_t));
|
||||
ESP_GOTO_ON_FALSE((*pixels), ESP_ERR_NO_MEM, err, TAG, "Error allocating memory for lines");
|
||||
|
||||
//JPEG decode config
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)image_jpg_start,
|
||||
.indata_size = image_jpg_end - image_jpg_start,
|
||||
.outbuf = (uint8_t *)(*pixels),
|
||||
.outbuf_size = IMAGE_W * IMAGE_H * sizeof(uint16_t),
|
||||
.out_format = JPEG_IMAGE_FORMAT_RGB565,
|
||||
.out_scale = JPEG_IMAGE_SCALE_0,
|
||||
.flags = {
|
||||
.swap_color_bytes = 1,
|
||||
}
|
||||
};
|
||||
|
||||
//JPEG decode
|
||||
esp_jpeg_image_output_t outimg;
|
||||
esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
|
||||
ESP_LOGI(TAG, "JPEG image decoded! Size of the decoded image is: %dpx x %dpx", outimg.width, outimg.height);
|
||||
|
||||
return ret;
|
||||
err:
|
||||
//Something went wrong! Exit cleanly, de-allocating everything we allocated.
|
||||
if (*pixels != NULL) {
|
||||
free(*pixels);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#define IMAGE_W 320
|
||||
#define IMAGE_H 240
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Decode the jpeg ``image.jpg`` embedded into the program file into pixel data.
|
||||
*
|
||||
* @param pixels A pointer to a pointer for an array of rows, which themselves are an array of pixels.
|
||||
* Effectively, you can get the pixel data by doing ``decode_image(&myPixels); pixelval=myPixels[ypos][xpos];``
|
||||
* @return - ESP_ERR_NOT_SUPPORTED if image is malformed or a progressive jpeg file
|
||||
* - ESP_ERR_NO_MEM if out of memory
|
||||
* - ESP_OK on succesful decode
|
||||
*/
|
||||
esp_err_t decode_image(uint16_t **pixels);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
dependencies:
|
||||
esp-box:
|
||||
rules:
|
||||
- if: target == esp32s3
|
||||
version: ^2.4
|
||||
esp32_s2_kaluga_kit:
|
||||
rules:
|
||||
- if: target == esp32s2
|
||||
version: ^3.0
|
||||
esp_jpeg:
|
||||
version: '>=1.0.2'
|
||||
esp_wrover_kit:
|
||||
rules:
|
||||
- if: target == esp32
|
||||
version: ^1.5
|
||||
idf: '>=5.0'
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "pretty_effect.h"
|
||||
#include "bsp/esp-bsp.h"
|
||||
#include "bsp/display.h"
|
||||
|
||||
// Using SPI2 in the example, as it also supports octal modes on some targets
|
||||
#define LCD_HOST SPI2_HOST
|
||||
// To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many.
|
||||
// More means more memory use, but less overhead for setting up / finishing transfers. Make sure 240
|
||||
// is dividable by this.
|
||||
#define PARALLEL_LINES CONFIG_EXAMPLE_LCD_FLUSH_PARALLEL_LINES
|
||||
// The number of frames to show before rotate the graph
|
||||
#define ROTATE_FRAME 30
|
||||
|
||||
#if BSP_LCD_H_RES > BSP_LCD_V_RES
|
||||
#define EXAMPLE_LCD_SWAP 0
|
||||
#define EXAMPLE_LCD_H_RES BSP_LCD_H_RES
|
||||
#define EXAMPLE_LCD_V_RES BSP_LCD_V_RES
|
||||
#else
|
||||
#define EXAMPLE_LCD_SWAP 1
|
||||
#define EXAMPLE_LCD_H_RES BSP_LCD_V_RES
|
||||
#define EXAMPLE_LCD_V_RES BSP_LCD_H_RES
|
||||
#endif
|
||||
|
||||
// Simple routine to generate some patterns and send them to the LCD. Because the
|
||||
// SPI driver handles transactions in the background, we can calculate the next line
|
||||
// while the previous one is being sent.
|
||||
static uint16_t *s_lines[2];
|
||||
static void display_pretty_colors(esp_lcd_panel_handle_t panel_handle)
|
||||
{
|
||||
int frame = 0;
|
||||
// Indexes of the line currently being sent to the LCD and the line we're calculating
|
||||
int sending_line = 0;
|
||||
int calc_line = 0;
|
||||
|
||||
// After ROTATE_FRAME frames, the image will be rotated
|
||||
while (frame <= ROTATE_FRAME) {
|
||||
frame++;
|
||||
for (int y = 0; y < EXAMPLE_LCD_V_RES; y += PARALLEL_LINES) {
|
||||
// Calculate a line
|
||||
pretty_effect_calc_lines(s_lines[calc_line], y, frame, PARALLEL_LINES);
|
||||
sending_line = calc_line;
|
||||
calc_line = !calc_line;
|
||||
// Send the calculated data
|
||||
esp_lcd_panel_draw_bitmap(panel_handle, 0, y, 0 + EXAMPLE_LCD_H_RES, y + PARALLEL_LINES, s_lines[sending_line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||
|
||||
bsp_display_config_t disp_cfg = {
|
||||
.max_transfer_sz = EXAMPLE_LCD_H_RES * PARALLEL_LINES * sizeof(uint16_t),
|
||||
};
|
||||
// Display initialize from BSP
|
||||
bsp_display_new(&disp_cfg, &panel_handle, &io_handle);
|
||||
esp_lcd_panel_disp_on_off(panel_handle, true);
|
||||
bsp_display_backlight_on();
|
||||
|
||||
// Initialize the effect displayed
|
||||
ESP_ERROR_CHECK(pretty_effect_init());
|
||||
|
||||
// "Rotate or not" flag
|
||||
bool is_rotated = false;
|
||||
|
||||
// Allocate memory for the pixel buffers
|
||||
for (int i = 0; i < 2; i++) {
|
||||
s_lines[i] = heap_caps_malloc(EXAMPLE_LCD_H_RES * PARALLEL_LINES * sizeof(uint16_t), MALLOC_CAP_DMA);
|
||||
assert(s_lines[i] != NULL);
|
||||
}
|
||||
|
||||
#if EXAMPLE_LCD_SWAP
|
||||
esp_lcd_panel_swap_xy(panel_handle, true);
|
||||
#endif
|
||||
|
||||
// Start and rotate
|
||||
while (1) {
|
||||
// Set driver configuration to rotate 180 degrees each time
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, is_rotated, is_rotated));
|
||||
// Display
|
||||
display_pretty_colors(panel_handle);
|
||||
is_rotated = !is_rotated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "pretty_effect.h"
|
||||
#include "decode_image.h"
|
||||
|
||||
uint16_t *pixels;
|
||||
|
||||
//Grab a rgb16 pixel from the esp32_tiles image
|
||||
static inline uint16_t get_bgnd_pixel(int x, int y)
|
||||
{
|
||||
//Get color of the pixel on x,y coords
|
||||
return (uint16_t) * (pixels + (y * IMAGE_W) + x);
|
||||
}
|
||||
|
||||
//This variable is used to detect the next frame.
|
||||
static int prev_frame = -1;
|
||||
|
||||
//Instead of calculating the offsets for each pixel we grab, we pre-calculate the valueswhenever a frame changes, then re-use
|
||||
//these as we go through all the pixels in the frame. This is much, much faster.
|
||||
static int8_t xofs[320], yofs[240];
|
||||
static int8_t xcomp[320], ycomp[240];
|
||||
|
||||
//Calculate the pixel data for a set of lines (with implied line size of 320). Pixels go in dest, line is the Y-coordinate of the
|
||||
//first line to be calculated, linect is the amount of lines to calculate. Frame increases by one every time the entire image
|
||||
//is displayed; this is used to go to the next frame of animation.
|
||||
void pretty_effect_calc_lines(uint16_t *dest, int line, int frame, int linect)
|
||||
{
|
||||
if (frame != prev_frame) {
|
||||
//We need to calculate a new set of offset coefficients. Take some random sines as offsets to make everything
|
||||
//look pretty and fluid-y.
|
||||
for (int x = 0; x < 320; x++) {
|
||||
xofs[x] = sin(frame * 0.15 + x * 0.06) * 4;
|
||||
}
|
||||
for (int y = 0; y < 240; y++) {
|
||||
yofs[y] = sin(frame * 0.1 + y * 0.05) * 4;
|
||||
}
|
||||
for (int x = 0; x < 320; x++) {
|
||||
xcomp[x] = sin(frame * 0.11 + x * 0.12) * 4;
|
||||
}
|
||||
for (int y = 0; y < 240; y++) {
|
||||
ycomp[y] = sin(frame * 0.07 + y * 0.15) * 4;
|
||||
}
|
||||
prev_frame = frame;
|
||||
}
|
||||
for (int y = line; y < line + linect; y++) {
|
||||
for (int x = 0; x < 320; x++) {
|
||||
*dest++ = get_bgnd_pixel(x + yofs[y] + xcomp[x], y + xofs[x] + ycomp[y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t pretty_effect_init(void)
|
||||
{
|
||||
return decode_image(&pixels);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Calculate the effect for a bunch of lines.
|
||||
*
|
||||
* @param dest Destination for the pixels. Assumed to be LINECT * 320 16-bit pixel values.
|
||||
* @param line Starting line of the chunk of lines.
|
||||
* @param frame Current frame, used for animation
|
||||
* @param linect Amount of lines to calculate
|
||||
*/
|
||||
void pretty_effect_calc_lines(uint16_t *dest, int line, int frame, int linect);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the effect
|
||||
*
|
||||
* @return ESP_OK on success, an error from the jpeg decoder otherwise.
|
||||
*/
|
||||
esp_err_t pretty_effect_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration
|
||||
#
|
||||
CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN=y
|
||||
9
managed_components/espressif__esp_jpeg/idf_component.yml
Normal file
9
managed_components/espressif__esp_jpeg/idf_component.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
dependencies:
|
||||
idf: '>=5.0'
|
||||
description: 'JPEG Decoder: TJpgDec'
|
||||
repository: git://github.com/espressif/idf-extra-components.git
|
||||
repository_info:
|
||||
commit_sha: 746e83ddbea0db9c3d24993a87c4c737a60337ae
|
||||
path: esp_jpeg
|
||||
url: https://github.com/espressif/idf-extra-components/tree/master/esp_jpeg/
|
||||
version: 1.3.1
|
||||
106
managed_components/espressif__esp_jpeg/include/jpeg_decoder.h
Normal file
106
managed_components/espressif__esp_jpeg/include/jpeg_decoder.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Scale of output image
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
JPEG_IMAGE_SCALE_0 = 0, /*!< No scale */
|
||||
JPEG_IMAGE_SCALE_1_2, /*!< Scale 1:2 */
|
||||
JPEG_IMAGE_SCALE_1_4, /*!< Scale 1:4 */
|
||||
JPEG_IMAGE_SCALE_1_8, /*!< Scale 1:8 */
|
||||
} esp_jpeg_image_scale_t;
|
||||
|
||||
/**
|
||||
* @brief Format of output image
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
JPEG_IMAGE_FORMAT_RGB888 = 0, /*!< Format RGB888 */
|
||||
JPEG_IMAGE_FORMAT_RGB565, /*!< Format RGB565 */
|
||||
} esp_jpeg_image_format_t;
|
||||
|
||||
/**
|
||||
* @brief JPEG Configuration Type
|
||||
*
|
||||
*/
|
||||
typedef struct esp_jpeg_image_cfg_s {
|
||||
uint8_t *indata; /*!< Input JPEG image */
|
||||
uint32_t indata_size; /*!< Size of input image */
|
||||
uint8_t *outbuf; /*!< Output buffer */
|
||||
uint32_t outbuf_size; /*!< Output buffer size */
|
||||
esp_jpeg_image_format_t out_format; /*!< Output image format */
|
||||
esp_jpeg_image_scale_t out_scale; /*!< Output scale */
|
||||
|
||||
struct {
|
||||
uint8_t swap_color_bytes: 1; /*!< Swap first and last color bytes */
|
||||
} flags;
|
||||
|
||||
struct {
|
||||
void *working_buffer; /*!< If set to NULL, a working buffer will be allocated in esp_jpeg_decode().
|
||||
Tjpgd does not use dynamic allocation, se we pass this buffer to Tjpgd that uses it as scratchpad */
|
||||
size_t working_buffer_size; /*!< Size of the working buffer. Must be set it working_buffer != NULL.
|
||||
Default size is 3.1kB or 65kB if JD_FASTDECODE == 2 */
|
||||
} advanced;
|
||||
|
||||
struct {
|
||||
uint32_t read; /*!< Internal count of read bytes */
|
||||
} priv;
|
||||
} esp_jpeg_image_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief JPEG output info
|
||||
*/
|
||||
typedef struct esp_jpeg_image_output_s {
|
||||
uint16_t width; /*!< Width of the output image */
|
||||
uint16_t height; /*!< Height of the output image */
|
||||
size_t output_len; /*!< Length of the output image in bytes */
|
||||
} esp_jpeg_image_output_t;
|
||||
|
||||
/**
|
||||
* @brief Decode JPEG image
|
||||
*
|
||||
* @note This function is blocking.
|
||||
*
|
||||
* @param[in] cfg: Configuration structure
|
||||
* @param[out] img: Output image info
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM if there is no memory for allocating main structure
|
||||
* - ESP_FAIL if there is an error in decoding JPEG
|
||||
*/
|
||||
esp_err_t esp_jpeg_decode(esp_jpeg_image_cfg_t *cfg, esp_jpeg_image_output_t *img);
|
||||
|
||||
/**
|
||||
* @brief Get information about the JPEG image
|
||||
*
|
||||
* Use this function to get the size of the JPEG image without decoding it.
|
||||
* Allocate a buffer of size img->output_len to store the decoded image.
|
||||
*
|
||||
* @note cfg->outbuf and cfg->outbuf_size are not used in this function.
|
||||
* @param[in] cfg: Configuration structure
|
||||
* @param[out] img: Output image info
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if cfg or img is NULL
|
||||
* - ESP_FAIL if there is an error in decoding JPEG
|
||||
*/
|
||||
esp_err_t esp_jpeg_get_image_info(esp_jpeg_image_cfg_t *cfg, esp_jpeg_image_output_t *img);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
287
managed_components/espressif__esp_jpeg/jpeg_decoder.c
Normal file
287
managed_components/espressif__esp_jpeg/jpeg_decoder.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_rom_caps.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "jpeg_decoder.h"
|
||||
|
||||
#if CONFIG_JD_USE_ROM
|
||||
/* When supported in ROM, use ROM functions */
|
||||
#if defined(ESP_ROM_HAS_JPEG_DECODE)
|
||||
#include "rom/tjpgd.h"
|
||||
#else
|
||||
#error Using JPEG decoder from ROM is not supported for selected target. Please select external code in menuconfig.
|
||||
#endif
|
||||
|
||||
/* The ROM code of TJPGD is older and has different return type in decode callback */
|
||||
typedef unsigned int jpeg_decode_out_t;
|
||||
#else
|
||||
/* When Tiny JPG Decoder is not in ROM or selected external code */
|
||||
#include "tjpgd.h"
|
||||
|
||||
/* The TJPGD outside the ROM code is newer and has different return type in decode callback */
|
||||
typedef int jpeg_decode_out_t;
|
||||
#endif
|
||||
|
||||
static const char *TAG = "JPEG";
|
||||
|
||||
#define LOBYTE(u16) ((uint8_t)(((uint16_t)(u16)) & 0xff))
|
||||
#define HIBYTE(u16) ((uint8_t)((((uint16_t)(u16))>>8) & 0xff))
|
||||
|
||||
#if defined(JD_FASTDECODE) && (JD_FASTDECODE == 2)
|
||||
#define JPEG_WORK_BUF_SIZE 65472
|
||||
#else
|
||||
#define JPEG_WORK_BUF_SIZE 3100 /* Recommended buffer size; Independent on the size of the image */
|
||||
#endif
|
||||
|
||||
/* If not set JD_FORMAT, it is set in ROM to RGB888, otherwise, it can be set in config */
|
||||
#ifndef JD_FORMAT
|
||||
#define JD_FORMAT 0
|
||||
#endif
|
||||
|
||||
/* Output color bytes from tjpgd (depends on JD_FORMAT) */
|
||||
#if (JD_FORMAT==0)
|
||||
#define ESP_JPEG_COLOR_BYTES 3
|
||||
#elif (JD_FORMAT==1)
|
||||
#define ESP_JPEG_COLOR_BYTES 2
|
||||
#elif (JD_FORMAT==2)
|
||||
#error Grayscale image output format is not supported
|
||||
#define ESP_JPEG_COLOR_BYTES 1
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Function definitions
|
||||
*******************************************************************************/
|
||||
static uint8_t jpeg_get_div_by_scale(esp_jpeg_image_scale_t scale);
|
||||
static uint8_t jpeg_get_color_bytes(esp_jpeg_image_format_t format);
|
||||
|
||||
static unsigned int jpeg_decode_in_cb(JDEC *jd, uint8_t *buff, unsigned int nbyte);
|
||||
static jpeg_decode_out_t jpeg_decode_out_cb(JDEC *jd, void *bitmap, JRECT *rect);
|
||||
static inline uint16_t ldb_word(const void *ptr);
|
||||
/*******************************************************************************
|
||||
* Public API functions
|
||||
*******************************************************************************/
|
||||
|
||||
esp_err_t esp_jpeg_decode(esp_jpeg_image_cfg_t *cfg, esp_jpeg_image_output_t *img)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t *workbuf = NULL;
|
||||
JRESULT res;
|
||||
JDEC JDEC;
|
||||
|
||||
assert(cfg != NULL);
|
||||
assert(img != NULL);
|
||||
|
||||
const bool allocate_buffer = (cfg->advanced.working_buffer == NULL);
|
||||
const size_t workbuf_size = allocate_buffer ? JPEG_WORK_BUF_SIZE : cfg->advanced.working_buffer_size;
|
||||
if (allocate_buffer) {
|
||||
workbuf = heap_caps_malloc(JPEG_WORK_BUF_SIZE, MALLOC_CAP_DEFAULT);
|
||||
ESP_GOTO_ON_FALSE(workbuf, ESP_ERR_NO_MEM, err, TAG, "no mem for JPEG work buffer");
|
||||
} else {
|
||||
workbuf = cfg->advanced.working_buffer;
|
||||
ESP_RETURN_ON_FALSE(workbuf_size != 0, ESP_ERR_INVALID_ARG, TAG, "Working buffer size not defined!");
|
||||
}
|
||||
|
||||
|
||||
cfg->priv.read = 0;
|
||||
|
||||
/* Prepare image */
|
||||
res = jd_prepare(&JDEC, jpeg_decode_in_cb, workbuf, workbuf_size, cfg);
|
||||
ESP_GOTO_ON_FALSE((res == JDR_OK), ESP_FAIL, err, TAG, "Error in preparing JPEG image! %d", res);
|
||||
|
||||
const uint8_t scale_div = jpeg_get_div_by_scale(cfg->out_scale);
|
||||
const uint8_t out_color_bytes = jpeg_get_color_bytes(cfg->out_format);
|
||||
|
||||
/* Size of output image */
|
||||
const uint32_t outsize = (JDEC.height / scale_div) * (JDEC.width / scale_div) * out_color_bytes;
|
||||
ESP_GOTO_ON_FALSE((outsize <= cfg->outbuf_size), ESP_ERR_NO_MEM, err, TAG, "Not enough size in output buffer!");
|
||||
|
||||
/* Size of output image */
|
||||
img->height = JDEC.height / scale_div;
|
||||
img->width = JDEC.width / scale_div;
|
||||
img->output_len = outsize;
|
||||
|
||||
/* Decode JPEG */
|
||||
res = jd_decomp(&JDEC, jpeg_decode_out_cb, cfg->out_scale);
|
||||
ESP_GOTO_ON_FALSE((res == JDR_OK), ESP_FAIL, err, TAG, "Error in decoding JPEG image! %d", res);
|
||||
|
||||
err:
|
||||
if (workbuf && allocate_buffer) {
|
||||
free(workbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_jpeg_get_image_info(esp_jpeg_image_cfg_t *cfg, esp_jpeg_image_output_t *img)
|
||||
{
|
||||
if (cfg == NULL || img == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
} else if (cfg->indata == NULL || cfg->indata_size < 5) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
|
||||
if (ldb_word(cfg->indata) != 0xFFD8) {
|
||||
return ESP_FAIL; /* Err: SOI is not detected */
|
||||
}
|
||||
unsigned ofs = 2; // Start after SOI marker
|
||||
|
||||
while (true) {
|
||||
/* Get a JPEG marker */
|
||||
uint8_t *seg = cfg->indata + ofs; /* Segment pointer */
|
||||
unsigned short marker = ldb_word(seg); /* Marker */
|
||||
unsigned int len = ldb_word(seg + 2); /* Length field */
|
||||
if (len <= 2 || (marker >> 8) != 0xFF) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ofs += 2 + len; /* Number of bytes loaded */
|
||||
if (ofs > cfg->indata_size) {
|
||||
return ESP_FAIL; // No more data
|
||||
}
|
||||
|
||||
if ((marker & 0xFF) == 0xC0) { /* SOF0 (baseline JPEG) */
|
||||
seg += 4; /* Skip marker and length field */
|
||||
|
||||
/* Size of output image */
|
||||
img->height = ldb_word(seg + 1);
|
||||
img->width = ldb_word(seg + 3);
|
||||
const uint8_t scale_div = jpeg_get_div_by_scale(cfg->out_scale);
|
||||
const uint8_t out_color_bytes = jpeg_get_color_bytes(cfg->out_format);
|
||||
img->output_len = (img->height / scale_div) * (img->width / scale_div) * out_color_bytes;
|
||||
ret = ESP_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Private API functions
|
||||
*******************************************************************************/
|
||||
|
||||
static unsigned int jpeg_decode_in_cb(JDEC *dec, uint8_t *buff, unsigned int nbyte)
|
||||
{
|
||||
assert(dec != NULL);
|
||||
|
||||
uint32_t to_read = nbyte;
|
||||
esp_jpeg_image_cfg_t *cfg = (esp_jpeg_image_cfg_t *)dec->device;
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (buff) {
|
||||
if (cfg->priv.read + to_read > cfg->indata_size) {
|
||||
to_read = cfg->indata_size - cfg->priv.read;
|
||||
}
|
||||
|
||||
/* Copy data from JPEG image */
|
||||
memcpy(buff, &cfg->indata[cfg->priv.read], to_read);
|
||||
cfg->priv.read += to_read;
|
||||
} else if (buff == NULL) {
|
||||
/* Skip data */
|
||||
cfg->priv.read += to_read;
|
||||
}
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
||||
static jpeg_decode_out_t jpeg_decode_out_cb(JDEC *dec, void *bitmap, JRECT *rect)
|
||||
{
|
||||
uint16_t color = 0;
|
||||
assert(dec != NULL);
|
||||
|
||||
esp_jpeg_image_cfg_t *cfg = (esp_jpeg_image_cfg_t *)dec->device;
|
||||
assert(cfg != NULL);
|
||||
assert(bitmap != NULL);
|
||||
assert(rect != NULL);
|
||||
|
||||
uint8_t scale_div = jpeg_get_div_by_scale(cfg->out_scale);
|
||||
uint8_t out_color_bytes = jpeg_get_color_bytes(cfg->out_format);
|
||||
|
||||
/* Copy decoded image data to output buffer */
|
||||
uint8_t *in = (uint8_t *)bitmap;
|
||||
uint32_t line = dec->width / scale_div;
|
||||
uint8_t *dst = (uint8_t *)cfg->outbuf;
|
||||
for (int y = rect->top; y <= rect->bottom; y++) {
|
||||
for (int x = rect->left; x <= rect->right; x++) {
|
||||
if ( (JD_FORMAT == 0 && cfg->out_format == JPEG_IMAGE_FORMAT_RGB888) ||
|
||||
(JD_FORMAT == 1 && cfg->out_format == JPEG_IMAGE_FORMAT_RGB565) ) {
|
||||
/* Output image format is same as set in TJPGD */
|
||||
for (int b = 0; b < ESP_JPEG_COLOR_BYTES; b++) {
|
||||
if (cfg->flags.swap_color_bytes) {
|
||||
dst[(y * line * out_color_bytes) + x * out_color_bytes + b] = in[out_color_bytes - b - 1];
|
||||
} else {
|
||||
dst[(y * line * out_color_bytes) + x * out_color_bytes + b] = in[b];
|
||||
}
|
||||
}
|
||||
} else if (JD_FORMAT == 0 && cfg->out_format == JPEG_IMAGE_FORMAT_RGB565) {
|
||||
/* Output image format is not same as set in TJPGD */
|
||||
/* We need to convert the 3 bytes in `in` to a rgb565 value */
|
||||
color = ((in[0] & 0xF8) << 8);
|
||||
color |= ((in[1] & 0xFC) << 3);
|
||||
color |= (in[2] >> 3);
|
||||
|
||||
if (cfg->flags.swap_color_bytes) {
|
||||
dst[(y * line * out_color_bytes) + (x * out_color_bytes)] = HIBYTE(color);
|
||||
dst[(y * line * out_color_bytes) + (x * out_color_bytes) + 1] = LOBYTE(color);
|
||||
} else {
|
||||
dst[(y * line * out_color_bytes) + (x * out_color_bytes) + 1] = HIBYTE(color);
|
||||
dst[(y * line * out_color_bytes) + (x * out_color_bytes)] = LOBYTE(color);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Selected output format is not supported!");
|
||||
assert(0);
|
||||
}
|
||||
in += ESP_JPEG_COLOR_BYTES;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t jpeg_get_div_by_scale(esp_jpeg_image_scale_t scale)
|
||||
{
|
||||
switch (scale) {
|
||||
/* Not scaled */
|
||||
case JPEG_IMAGE_SCALE_0:
|
||||
return 1;
|
||||
/* Scaled 1:2 */
|
||||
case JPEG_IMAGE_SCALE_1_2:
|
||||
return 2;
|
||||
/* Scaled 1:4 */
|
||||
case JPEG_IMAGE_SCALE_1_4:
|
||||
return 4;
|
||||
/* Scaled 1:8 */
|
||||
case JPEG_IMAGE_SCALE_1_8:
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t jpeg_get_color_bytes(esp_jpeg_image_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
/* RGB888 (24-bit/pix) */
|
||||
case JPEG_IMAGE_FORMAT_RGB888:
|
||||
return 3;
|
||||
/* RGB565 (16-bit/pix) */
|
||||
case JPEG_IMAGE_FORMAT_RGB565:
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline uint16_t ldb_word(const void *ptr)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)ptr;
|
||||
return ((uint16_t)p[0] << 8) | p[1];
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// Default Huffman tables for baseline JPEG
|
||||
|
||||
// These values are taken directly from CCITT Rec. T.81 (1992 E) Appendix K.3.3
|
||||
// The *_num_bits array always contains exactly 16 elements.
|
||||
// Each element represents the number of Huffman codes of a specific length:
|
||||
// - The first element corresponds to codes of length 1 bit,
|
||||
// - The second element to codes of length 2 bits, and so forth up to 16 bits.
|
||||
//
|
||||
// The *_values array has a length equal to the sum of all elements in the *_num_bits array,
|
||||
// representing the actual values associated with each Huffman code in order.
|
||||
|
||||
// Luminance DC Table
|
||||
const unsigned char esp_jpeg_lum_dc_num_bits[16] = {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};
|
||||
const unsigned esp_jpeg_lum_dc_codes_total = 12;
|
||||
const unsigned char esp_jpeg_lum_dc_values[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
|
||||
// Chrominance DC Table
|
||||
const unsigned char esp_jpeg_chrom_dc_num_bits[16] = {0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
|
||||
const unsigned esp_jpeg_chrom_dc_codes_total = 12;
|
||||
const unsigned char esp_jpeg_chrom_dc_values[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
|
||||
// Luminance AC Table
|
||||
const unsigned char esp_jpeg_lum_ac_num_bits[16] = {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125};
|
||||
const unsigned esp_jpeg_lum_ac_codes_total = 162;
|
||||
const unsigned char esp_jpeg_lum_ac_values[162] = {
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0,
|
||||
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
|
||||
0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
|
||||
0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
|
||||
0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||
0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5,
|
||||
0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
|
||||
0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
|
||||
0xF9, 0xFA
|
||||
};
|
||||
|
||||
// Chrominance AC Table
|
||||
const unsigned char esp_jpeg_chrom_ac_num_bits[16] = {0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119};
|
||||
const unsigned esp_jpeg_chrom_ac_codes_total = 162;
|
||||
const unsigned char esp_jpeg_chrom_ac_values[162] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
|
||||
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0,
|
||||
0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
|
||||
0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
|
||||
0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5,
|
||||
0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3,
|
||||
0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
|
||||
0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
|
||||
0xF9, 0xFA
|
||||
};
|
||||
202
managed_components/espressif__esp_jpeg/license.txt
Normal file
202
managed_components/espressif__esp_jpeg/license.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(COMPONENTS main)
|
||||
project(esp_jpeg_test)
|
||||
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRCS "tjpgd_test.c" "test_tjpgd_main.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES "unity"
|
||||
WHOLE_ARCHIVE
|
||||
EMBED_FILES "logo.jpg" "usb_camera.jpg" "usb_camera_2.jpg")
|
||||
@@ -0,0 +1,4 @@
|
||||
dependencies:
|
||||
espressif/esp_jpeg:
|
||||
version: "*"
|
||||
override_path: "../../"
|
||||
@@ -0,0 +1,64 @@
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def jpg_to_rgb888_hex_c_array(input_filename: str, output_filename: str) -> str:
|
||||
"""
|
||||
Convert a .jpg file to RGB888 hex data and format it as a C-style array.
|
||||
|
||||
Parameters:
|
||||
input_filename (str): The path to the JPEG file.
|
||||
|
||||
Returns:
|
||||
str: A string representing the RGB888 hex data formatted as a C array.
|
||||
"""
|
||||
# Open the image file
|
||||
with Image.open(input_filename) as img:
|
||||
# Ensure the image is in RGB mode
|
||||
rgb_img = img.convert("RGB")
|
||||
|
||||
# Get image dimensions
|
||||
width, height = rgb_img.size
|
||||
|
||||
# List to store hex values as C-style entries
|
||||
hex_data = []
|
||||
|
||||
# Iterate over each pixel to get RGB values
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
r, g, b = rgb_img.getpixel((x, y))
|
||||
# Format each RGB value as C-style hex (e.g., 0xRRGGBB)
|
||||
hex_data.append(f"0x{r:02X}{g:02X}{b:02X}")
|
||||
|
||||
# Format as a C-style array with line breaks for readability
|
||||
hex_array = ",\n ".join(hex_data)
|
||||
c_array = f"unsigned int image_data[{width * height}] = {{\n {hex_array}\n}};"
|
||||
|
||||
# Write the C array to the output file
|
||||
with open(output_filename, "w") as file:
|
||||
file.write(c_array)
|
||||
|
||||
print(f"C-style RGB888 hex array saved to {output_filename}")
|
||||
|
||||
return c_array
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to convert a JPEG file to an RGB888 C-style hex array.
|
||||
|
||||
Instructions:
|
||||
1. Replace 'input.jpg' with the path to your JPEG file.
|
||||
2. Run the script to get the C-style array output.
|
||||
"""
|
||||
# Input JPEG file path
|
||||
input_filename = "usb_camera.jpg" # Replace with your JPEG file path
|
||||
|
||||
# Output file path for the C array
|
||||
output_filename = "output_array.c" # Specify your desired output filename
|
||||
|
||||
# Convert JPEG to C-style RGB888 hex array
|
||||
jpg_to_rgb888_hex_c_array(input_filename, output_filename)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
managed_components/espressif__esp_jpeg/test_apps/main/logo.jpg
Normal file
BIN
managed_components/espressif__esp_jpeg/test_apps/main/logo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,7 @@
|
||||
// JPEG encoded image 46x46, 7561 bytes
|
||||
extern const unsigned char logo_jpg[] asm("_binary_logo_jpg_start");
|
||||
|
||||
extern char _binary_logo_jpg_start;
|
||||
extern char _binary_logo_jpg_end;
|
||||
// Must be defined as macro because extern variables are not known at compile time (but at link time)
|
||||
#define logo_jpg_len (&_binary_logo_jpg_end - &_binary_logo_jpg_start)
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_newlib.h"
|
||||
|
||||
#include "unity_test_utils_memory.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
|
||||
unity_utils_evaluate_leaks_direct(0);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
printf("Running esp_jpeg component tests\n");
|
||||
unity_run_menu();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Raw data from Logitech C170 USB camera was reconstructed to usb_camera_2.jpg
|
||||
It was converted to RGB888 array with jpg_to_rgb888_hex.py
|
||||
*/
|
||||
|
||||
// JPEG encoded frame 160x120, 1384 bytes, has broken 0xFFFF marker
|
||||
extern const unsigned char camera_2_jpg[] asm("_binary_usb_camera_2_jpg_start");
|
||||
|
||||
extern char _binary_usb_camera_2_jpg_start;
|
||||
extern char _binary_usb_camera_2_jpg_end;
|
||||
// Must be defined as macro because extern variables are not known at compile time (but at link time)
|
||||
#define camera_2_jpg_len (&_binary_usb_camera_2_jpg_end - &_binary_usb_camera_2_jpg_start)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Raw data from Logitech C270 USB camera was reconstructed to usb_camera.jpg
|
||||
It was converted to RGB888 array with jpg_to_rgb888_hex.py
|
||||
*/
|
||||
|
||||
// JPEG encoded frame 160x120, 2632 bytes, no huffman tables, double block size (16x8 pixels)
|
||||
extern const unsigned char jpeg_no_huffman[] asm("_binary_usb_camera_jpg_start");
|
||||
|
||||
extern char _binary_usb_camera_jpg_start;
|
||||
extern char _binary_usb_camera_jpg_end;
|
||||
// Must be defined as macro because extern variables are not known at compile time (but at link time)
|
||||
#define jpeg_no_huffman_len (&_binary_usb_camera_jpg_end - &_binary_usb_camera_jpg_start)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
|
||||
|
||||
#include "jpeg_decoder.h"
|
||||
#include "test_logo_jpg.h"
|
||||
#include "test_logo_rgb888.h"
|
||||
#include "test_usb_camera_2_jpg.h"
|
||||
#include "test_usb_camera_2_rgb888.h"
|
||||
|
||||
#define TESTW 46
|
||||
#define TESTH 46
|
||||
|
||||
void esp_jpeg_print_ascii(unsigned char *rgb888, esp_jpeg_image_output_t *outimg)
|
||||
{
|
||||
char aapix[] = " .:;+=xX$$";
|
||||
unsigned char *p = rgb888 + 2;
|
||||
|
||||
for (int y = 0; y < outimg->width; y++) {
|
||||
for (int x = 0; x < outimg->height; x++) {
|
||||
int v = ((*p) * (sizeof(aapix) - 2) * 2) / 256;
|
||||
printf("%c%c", aapix[v / 2], aapix[(v + 1) / 2]);
|
||||
p += 3;
|
||||
}
|
||||
printf("%c%c", ' ', '\n');
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test JPEG decompression library", "[esp_jpeg]")
|
||||
{
|
||||
unsigned char *decoded, *p;
|
||||
const unsigned char *o;
|
||||
int decoded_outsize = TESTW * TESTH * 3;
|
||||
|
||||
decoded = malloc(decoded_outsize);
|
||||
for (int x = 0; x < decoded_outsize; x += 2) {
|
||||
decoded[x] = 0;
|
||||
decoded[x + 1] = 0xff;
|
||||
}
|
||||
|
||||
/* JPEG decode */
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)logo_jpg,
|
||||
.indata_size = logo_jpg_len,
|
||||
.outbuf = decoded,
|
||||
.outbuf_size = decoded_outsize,
|
||||
.out_format = JPEG_IMAGE_FORMAT_RGB888,
|
||||
.out_scale = JPEG_IMAGE_SCALE_0,
|
||||
.flags = {
|
||||
.swap_color_bytes = 0,
|
||||
}
|
||||
};
|
||||
esp_jpeg_image_output_t outimg;
|
||||
esp_err_t err = esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
TEST_ASSERT_EQUAL(err, ESP_OK);
|
||||
|
||||
/* Decoded image size */
|
||||
TEST_ASSERT_EQUAL(outimg.width, TESTW);
|
||||
TEST_ASSERT_EQUAL(outimg.height, TESTH);
|
||||
|
||||
p = decoded;
|
||||
o = logo_rgb888;
|
||||
for (int x = 0; x < outimg.width * outimg.height; x++) {
|
||||
/* The color can be +- 2 */
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[0], p[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[1], p[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[2], p[2]);
|
||||
|
||||
p += 3;
|
||||
o += 3;
|
||||
}
|
||||
|
||||
esp_jpeg_print_ascii(decoded, &outimg);
|
||||
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief JPEG unknown size test
|
||||
*
|
||||
* This test case verifies the functionality of the JPEG decompression library
|
||||
* when decoding an image with unknown size. The image is decoded from a
|
||||
* JPEG file, and the output size is determined dynamically. The test checks
|
||||
* that the decoded image dimensions match the expected values and that the
|
||||
* pixel data is within an acceptable tolerance range.
|
||||
*/
|
||||
TEST_CASE("Test JPEG unknown size", "[esp_jpeg]")
|
||||
{
|
||||
unsigned char *decoded, *p;
|
||||
const unsigned char *o;
|
||||
|
||||
/* JPEG decode */
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)logo_jpg,
|
||||
.indata_size = logo_jpg_len,
|
||||
.out_format = JPEG_IMAGE_FORMAT_RGB888,
|
||||
};
|
||||
|
||||
// 1. Get required output size
|
||||
esp_jpeg_image_output_t outimg;
|
||||
esp_err_t err = esp_jpeg_get_image_info(&jpeg_cfg, &outimg);
|
||||
TEST_ASSERT_EQUAL(err, ESP_OK);
|
||||
TEST_ASSERT_EQUAL(TESTW * TESTH * 3, outimg.output_len);
|
||||
TEST_ASSERT_EQUAL(outimg.width, TESTW);
|
||||
TEST_ASSERT_EQUAL(outimg.height, TESTH);
|
||||
|
||||
// 2. Allocate output buffer and assign it to the config
|
||||
decoded = malloc(outimg.output_len);
|
||||
TEST_ASSERT_NOT_NULL(decoded);
|
||||
jpeg_cfg.outbuf = decoded;
|
||||
jpeg_cfg.outbuf_size = outimg.output_len;
|
||||
|
||||
// 3. Decode the image
|
||||
err = esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
TEST_ASSERT_EQUAL(err, ESP_OK);
|
||||
|
||||
/* Decoded image size */
|
||||
TEST_ASSERT_EQUAL(TESTW * TESTH * 3, outimg.output_len);
|
||||
TEST_ASSERT_EQUAL(outimg.width, TESTW);
|
||||
TEST_ASSERT_EQUAL(outimg.height, TESTH);
|
||||
|
||||
p = decoded;
|
||||
o = logo_rgb888;
|
||||
for (int x = 0; x < outimg.width * outimg.height; x++) {
|
||||
/* The color can be +- 2 */
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[0], p[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[1], p[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[2], p[2]);
|
||||
|
||||
p += 3;
|
||||
o += 3;
|
||||
}
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
#define WORKING_BUFFER_SIZE 4096
|
||||
TEST_CASE("Test JPEG decompression library: User defined working buffer", "[esp_jpeg]")
|
||||
{
|
||||
unsigned char *decoded, *p;
|
||||
const unsigned char *o;
|
||||
int decoded_outsize = TESTW * TESTH * 3;
|
||||
|
||||
decoded = malloc(decoded_outsize);
|
||||
uint8_t *working_buf = malloc(WORKING_BUFFER_SIZE);
|
||||
assert(decoded);
|
||||
assert(working_buf);
|
||||
|
||||
for (int x = 0; x < decoded_outsize; x += 2) {
|
||||
decoded[x] = 0;
|
||||
decoded[x + 1] = 0xff;
|
||||
}
|
||||
|
||||
/* JPEG decode */
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)logo_jpg,
|
||||
.indata_size = logo_jpg_len,
|
||||
.outbuf = decoded,
|
||||
.outbuf_size = decoded_outsize,
|
||||
.out_format = JPEG_IMAGE_FORMAT_RGB888,
|
||||
.out_scale = JPEG_IMAGE_SCALE_0,
|
||||
.flags = {
|
||||
.swap_color_bytes = 0,
|
||||
},
|
||||
.advanced = {
|
||||
.working_buffer = working_buf,
|
||||
.working_buffer_size = WORKING_BUFFER_SIZE,
|
||||
},
|
||||
};
|
||||
esp_jpeg_image_output_t outimg;
|
||||
esp_err_t err = esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
TEST_ASSERT_EQUAL(err, ESP_OK);
|
||||
|
||||
/* Decoded image size */
|
||||
TEST_ASSERT_EQUAL(outimg.width, TESTW);
|
||||
TEST_ASSERT_EQUAL(outimg.height, TESTH);
|
||||
|
||||
p = decoded;
|
||||
o = logo_rgb888;
|
||||
for (int x = 0; x < outimg.width * outimg.height; x++) {
|
||||
/* The color can be +- 2 */
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[0], p[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[1], p[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(2, o[2], p[2]);
|
||||
|
||||
p += 3;
|
||||
o += 3;
|
||||
}
|
||||
free(working_buf);
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
#if CONFIG_JD_DEFAULT_HUFFMAN
|
||||
#include "test_usb_camera_jpg.h"
|
||||
#include "test_usb_camera_rgb888.h"
|
||||
|
||||
/**
|
||||
* @brief Test for JPEG decompression without Huffman tables
|
||||
*
|
||||
* This test case verifies the functionality of the JPEG decompression library
|
||||
* when decoding an image that lacks Huffman tables, such as a USB frame
|
||||
* from a Logitech C270 USB camera. The image was reconstructed from raw USB data
|
||||
* (using `hex_to_jpg.py`) and then converted into an RGB888 C-style array
|
||||
* (using `jpg_to_rgb888_hex.py`).
|
||||
*
|
||||
* Due to the unique structure of the JPEG data (double block size, 16x8 pixels)
|
||||
* and absence of Huffman tables, this test assesses whether the decompression
|
||||
* library correctly decodes the image and outputs RGB888 pixel data within
|
||||
* an acceptable tolerance range.
|
||||
*
|
||||
* The test performs the following steps:
|
||||
* - Allocates a buffer for the decoded image.
|
||||
* - Configures and runs the JPEG decoder with the RGB888 output format.
|
||||
* - Checks that the decoded image dimensions match expected values.
|
||||
* - Compares the decompressed image data against the reference RGB888 data,
|
||||
* allowing a tolerance of ±16 in each color component due to potential
|
||||
* differences in Huffman tables or decompression accuracy.
|
||||
*
|
||||
* @note This test allows a margin of error in pixel values due to potential
|
||||
* differences in how color data is interpreted across different decoders.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @test Requirements:
|
||||
* - JPEG decompression library support for images without Huffman tables.
|
||||
* - JPEG decompression accuracy within acceptable error margins.
|
||||
*/
|
||||
TEST_CASE("Test JPEG decompression library: No Huffman tables", "[esp_jpeg]")
|
||||
{
|
||||
unsigned char *decoded, *p;
|
||||
const unsigned int *o;
|
||||
int decoded_outsize = 160 * 120 * 3;
|
||||
|
||||
decoded = malloc(decoded_outsize);
|
||||
|
||||
/* JPEG decode */
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)jpeg_no_huffman,
|
||||
.indata_size = jpeg_no_huffman_len,
|
||||
.outbuf = decoded,
|
||||
.outbuf_size = decoded_outsize,
|
||||
.out_format = JPEG_IMAGE_FORMAT_RGB888,
|
||||
.out_scale = JPEG_IMAGE_SCALE_0,
|
||||
.flags = {
|
||||
.swap_color_bytes = 0,
|
||||
}
|
||||
};
|
||||
esp_jpeg_image_output_t outimg;
|
||||
esp_err_t err = esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
TEST_ASSERT_EQUAL(err, ESP_OK);
|
||||
|
||||
/* Decoded image size */
|
||||
TEST_ASSERT_EQUAL(outimg.width, 160);
|
||||
TEST_ASSERT_EQUAL(outimg.height, 120);
|
||||
|
||||
p = decoded;
|
||||
o = jpeg_no_huffman_rgb888;
|
||||
for (int x = 0; x < outimg.width * outimg.height; x++) {
|
||||
/* The color can be +- 16 */
|
||||
// Here we allow bigger decoding error
|
||||
// It might be that the Windows decoder used slightly different Huffman tables
|
||||
TEST_ASSERT_UINT8_WITHIN(16, (*o) & 0xff, p[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(16, (*o >> 8) & 0xff, p[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(16, (*o >> 16) & 0xff, p[2]);
|
||||
|
||||
p += 3; // this is uint8_t
|
||||
o ++; // this is unt32_t
|
||||
}
|
||||
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Invalid JPEG marker test
|
||||
*
|
||||
* This test case verifies the behavior of the JPEG decompression library
|
||||
* when encountering an invalid marker (0xFFFF) in the JPEG data stream.
|
||||
* The test uses a known JPEG image (camera_2_jpg) that contains this invalid
|
||||
* marker. The test checks whether the library can handle the invalid marker
|
||||
* gracefully and still decode the image correctly.
|
||||
*/
|
||||
TEST_CASE("Test JPEG invalid marker 0xFFFF", "[esp_jpeg]")
|
||||
{
|
||||
unsigned char *decoded;
|
||||
int decoded_outsize = 160 * 120 * 3;
|
||||
|
||||
decoded = malloc(decoded_outsize);
|
||||
assert(decoded);
|
||||
for (int x = 0; x < decoded_outsize; x += 2) {
|
||||
decoded[x] = 0;
|
||||
decoded[x + 1] = 0xff;
|
||||
}
|
||||
|
||||
/* JPEG decode */
|
||||
esp_jpeg_image_cfg_t jpeg_cfg = {
|
||||
.indata = (uint8_t *)camera_2_jpg,
|
||||
.indata_size = camera_2_jpg_len,
|
||||
.outbuf = decoded,
|
||||
.outbuf_size = decoded_outsize,
|
||||
.out_format = JPEG_IMAGE_FORMAT_RGB888,
|
||||
.out_scale = JPEG_IMAGE_SCALE_0,
|
||||
.flags = {
|
||||
.swap_color_bytes = 0,
|
||||
}
|
||||
};
|
||||
esp_jpeg_image_output_t outimg;
|
||||
esp_err_t err = esp_jpeg_decode(&jpeg_cfg, &outimg);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
/* Decoded image size */
|
||||
TEST_ASSERT_EQUAL(160, outimg.width);
|
||||
TEST_ASSERT_EQUAL(120, outimg.height);
|
||||
|
||||
free(decoded);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,6 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
def test_esp_jpeg(dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
@@ -0,0 +1,6 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration
|
||||
#
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
CONFIG_JD_USE_ROM=n
|
||||
CONFIG_JD_DEFAULT_HUFFMAN=y
|
||||
@@ -0,0 +1,4 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration
|
||||
#
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
1392
managed_components/espressif__esp_jpeg/tjpgd/tjpgd.c
Normal file
1392
managed_components/espressif__esp_jpeg/tjpgd/tjpgd.c
Normal file
File diff suppressed because it is too large
Load Diff
102
managed_components/espressif__esp_jpeg/tjpgd/tjpgd.h
Normal file
102
managed_components/espressif__esp_jpeg/tjpgd/tjpgd.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ TJpgDec - Tiny JPEG Decompressor R0.03 include file (C)ChaN, 2021
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef DEF_TJPGDEC
|
||||
#define DEF_TJPGDEC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tjpgdcnf.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) /* VC++ or some compiler without stdint.h */
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef long int32_t;
|
||||
#else /* Embedded platform */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if JD_FASTDECODE >= 1
|
||||
typedef int16_t jd_yuv_t;
|
||||
#else
|
||||
typedef uint8_t jd_yuv_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* Error code */
|
||||
typedef enum {
|
||||
JDR_OK = 0, /* 0: Succeeded */
|
||||
JDR_INTR, /* 1: Interrupted by output function */
|
||||
JDR_INP, /* 2: Device error or wrong termination of input stream */
|
||||
JDR_MEM1, /* 3: Insufficient memory pool for the image */
|
||||
JDR_MEM2, /* 4: Insufficient stream input buffer */
|
||||
JDR_PAR, /* 5: Parameter error */
|
||||
JDR_FMT1, /* 6: Data format error (may be broken data) */
|
||||
JDR_FMT2, /* 7: Right format but not supported */
|
||||
JDR_FMT3 /* 8: Not supported JPEG standard */
|
||||
} JRESULT;
|
||||
|
||||
|
||||
|
||||
/* Rectangular region in the output image */
|
||||
typedef struct {
|
||||
uint16_t left; /* Left end */
|
||||
uint16_t right; /* Right end */
|
||||
uint16_t top; /* Top end */
|
||||
uint16_t bottom; /* Bottom end */
|
||||
} JRECT;
|
||||
|
||||
|
||||
|
||||
/* Decompressor object structure */
|
||||
typedef struct JDEC JDEC;
|
||||
struct JDEC {
|
||||
size_t dctr; /* Number of bytes available in the input buffer */
|
||||
uint8_t *dptr; /* Current data read ptr */
|
||||
uint8_t *inbuf; /* Bit stream input buffer */
|
||||
uint8_t dbit; /* Number of bits availavble in wreg or reading bit mask */
|
||||
uint8_t scale; /* Output scaling ratio */
|
||||
uint8_t msx, msy; /* MCU size in unit of block (width, height) */
|
||||
uint8_t qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */
|
||||
uint8_t ncomp; /* Number of color components 1:grayscale, 3:color */
|
||||
int16_t dcv[3]; /* Previous DC element of each component */
|
||||
uint16_t nrst; /* Restart inverval */
|
||||
uint16_t width, height; /* Size of the input image (pixel) */
|
||||
uint8_t *huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */
|
||||
uint16_t *huffcode[2][2]; /* Huffman code word tables [id][dcac] */
|
||||
uint8_t *huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */
|
||||
int32_t *qttbl[4]; /* Dequantizer tables [id] */
|
||||
#if JD_FASTDECODE >= 1
|
||||
uint32_t wreg; /* Working shift register */
|
||||
uint8_t marker; /* Detected marker (0:None) */
|
||||
#if JD_FASTDECODE == 2
|
||||
uint8_t longofs[2][2]; /* Table offset of long code [id][dcac] */
|
||||
uint16_t *hufflut_ac[2]; /* Fast huffman decode tables for AC short code [id] */
|
||||
uint8_t *hufflut_dc[2]; /* Fast huffman decode tables for DC short code [id] */
|
||||
#endif
|
||||
#endif
|
||||
void *workbuf; /* Working buffer for IDCT and RGB output */
|
||||
jd_yuv_t *mcubuf; /* Working buffer for the MCU */
|
||||
void *pool; /* Pointer to available memory pool */
|
||||
size_t sz_pool; /* Size of momory pool (bytes available) */
|
||||
size_t (*infunc)(JDEC *, uint8_t *, size_t); /* Pointer to jpeg stream input function */
|
||||
void *device; /* Pointer to I/O device identifiler for the session */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* TJpgDec API functions */
|
||||
JRESULT jd_prepare (JDEC *jd, size_t (*infunc)(JDEC *, uint8_t *, size_t), void *pool, size_t sz_pool, void *dev);
|
||||
JRESULT jd_decomp (JDEC *jd, int (*outfunc)(JDEC *, void *, JRECT *), uint8_t scale);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TJPGDEC */
|
||||
48
managed_components/espressif__esp_jpeg/tjpgd/tjpgdcnf.h
Normal file
48
managed_components/espressif__esp_jpeg/tjpgd/tjpgdcnf.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*----------------------------------------------*/
|
||||
/* TJpgDec System Configurations R0.03 */
|
||||
/*----------------------------------------------*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define JD_SZBUF CONFIG_JD_SZBUF
|
||||
/* Specifies size of stream input buffer */
|
||||
|
||||
#define JD_FORMAT CONFIG_JD_FORMAT
|
||||
/* Specifies output pixel format.
|
||||
/ 0: RGB888 (24-bit/pix)
|
||||
/ 1: RGB565 (16-bit/pix)
|
||||
/ 2: Grayscale (8-bit/pix)
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_JD_USE_SCALE)
|
||||
#define JD_USE_SCALE CONFIG_JD_USE_SCALE
|
||||
#else
|
||||
#define JD_USE_SCALE 0
|
||||
#endif
|
||||
/* Switches output descaling feature.
|
||||
/ 0: Disable
|
||||
/ 1: Enable
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_JD_TBLCLIP)
|
||||
#define JD_TBLCLIP CONFIG_JD_TBLCLIP
|
||||
#else
|
||||
#define JD_TBLCLIP 0
|
||||
#endif
|
||||
/* Use table conversion for saturation arithmetic. A bit faster, but increases 1 KB of code size.
|
||||
/ 0: Disable
|
||||
/ 1: Enable
|
||||
*/
|
||||
|
||||
#define JD_FASTDECODE CONFIG_JD_FASTDECODE
|
||||
/* Optimization level
|
||||
/ 0: Basic optimization. Suitable for 8/16-bit MCUs.
|
||||
/ 1: + 32-bit barrel shifter. Suitable for 32-bit MCUs.
|
||||
/ 2: + Table conversion for huffman decoding (wants 6 << HUFF_BIT bytes of RAM)
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_JD_DEFAULT_HUFFMAN)
|
||||
#define JD_DEFAULT_HUFFMAN CONFIG_JD_DEFAULT_HUFFMAN
|
||||
#else
|
||||
#define JD_DEFAULT_HUFFMAN 0
|
||||
#endif
|
||||
Reference in New Issue
Block a user