add some code

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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