add some code
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# Include the components directory of the main application:
|
||||
set(EXTRA_COMPONENT_DIRS "../")
|
||||
|
||||
add_compile_options(-fdiagnostics-color=always)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(test_app)
|
||||
@@ -0,0 +1,12 @@
|
||||
set(src_dirs "./")
|
||||
|
||||
set(public_include_dirs "./")
|
||||
|
||||
set(priv_requires unity
|
||||
esp_new_jpeg
|
||||
fatfs)
|
||||
|
||||
idf_component_register(SRC_DIRS "${src_dirs}"
|
||||
INCLUDE_DIRS "${public_include_dirs}"
|
||||
PRIV_REQUIRES "${priv_requires}"
|
||||
WHOLE_ARCHIVE)
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
idf:
|
||||
version: '>=5.0'
|
||||
@@ -0,0 +1,142 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_system.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "image_io.h"
|
||||
|
||||
#define MOUNT_POINT "/sdcard"
|
||||
#define PIN_NUM_MISO 38
|
||||
#define PIN_NUM_MOSI 39
|
||||
#define PIN_NUM_CLK 40
|
||||
#define PIN_NUM_CS 41
|
||||
|
||||
static sdmmc_host_t host = SDSPI_HOST_DEFAULT();
|
||||
static sdmmc_card_t *card;
|
||||
static const char mount_point[] = MOUNT_POINT;
|
||||
|
||||
void mount_sd(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
// Options for mounting the filesystem.
|
||||
// If format_if_mount_failed is set to true, SD card will be partitioned and
|
||||
// formatted in case when mounting fails.
|
||||
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
||||
.format_if_mount_failed = false,
|
||||
.max_files = 5,
|
||||
.allocation_unit_size = 16 * 1024
|
||||
};
|
||||
printf("Initializing SD card\n");
|
||||
|
||||
// Use settings defined above to initialize SD card and mount FAT filesystem.
|
||||
// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
|
||||
// Please check its source code and implement error recovery when developing
|
||||
// production applications.
|
||||
printf("Using SPI peripheral\n");
|
||||
|
||||
// sdmmc_host_t host = SDSPI_HOST_DEFAULT();
|
||||
// host.slot = SPI3_HOST;
|
||||
spi_bus_config_t bus_cfg = {
|
||||
.mosi_io_num = PIN_NUM_MOSI,
|
||||
.miso_io_num = PIN_NUM_MISO,
|
||||
.sclk_io_num = PIN_NUM_CLK,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = 4000,
|
||||
};
|
||||
ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
|
||||
if (ret != ESP_OK) {
|
||||
printf("Failed to initialize bus.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// This initializes the slot without card detect (CD) and write protect (WP) signals.
|
||||
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
|
||||
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
|
||||
slot_config.gpio_cs = PIN_NUM_CS;
|
||||
slot_config.host_id = host.slot;
|
||||
|
||||
printf("Mounting filesystem\n");
|
||||
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
if (ret == ESP_FAIL) {
|
||||
printf("Failed to mount filesystem. "
|
||||
"If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.\n");
|
||||
} else {
|
||||
printf("Failed to initialize the card (%s). "
|
||||
"Make sure SD card lines have pull-up resistors in place.\n", esp_err_to_name(ret));
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf("Filesystem mounted\n");
|
||||
|
||||
// Card has been initialized, print its properties
|
||||
// sdmmc_card_print_info(stdout, card);
|
||||
|
||||
#if 0
|
||||
// First create a file.
|
||||
const char *file_hello = MOUNT_POINT"/hello.txt";
|
||||
|
||||
printf("Opening file %s\n", file_hello);
|
||||
FILE *f = fopen(file_hello, "w");
|
||||
if (f == NULL) {
|
||||
printf("Failed to open file for writing\n");
|
||||
return;
|
||||
}
|
||||
fprintf(f, "Hello %s!\n", card->cid.name);
|
||||
fclose(f);
|
||||
printf("File written\n");
|
||||
|
||||
const char *file_foo = MOUNT_POINT"/foo.txt";
|
||||
|
||||
// Check if destination file exists before renaming
|
||||
struct stat st;
|
||||
if (stat(file_foo, &st) == 0) {
|
||||
// Delete it if it exists
|
||||
unlink(file_foo);
|
||||
}
|
||||
|
||||
// Rename original file
|
||||
printf("Renaming file %s to %s\n", file_hello, file_foo);
|
||||
if (rename(file_hello, file_foo) != 0) {
|
||||
printf("Rename failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Open renamed file for reading
|
||||
printf("Reading file %s\n", file_foo);
|
||||
f = fopen(file_foo, "r");
|
||||
if (f == NULL) {
|
||||
printf("Failed to open file for reading\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read a line from file
|
||||
char line[64];
|
||||
fgets(line, sizeof(line), f);
|
||||
fclose(f);
|
||||
|
||||
// Strip newline
|
||||
char *pos = strchr(line, '\n');
|
||||
if (pos) {
|
||||
*pos = '\0';
|
||||
}
|
||||
printf("Read from file: '%s'\n", line);
|
||||
#endif /* 0 */
|
||||
}
|
||||
|
||||
void unmount_sd(void)
|
||||
{
|
||||
// All done, unmount partition and disable SPI peripheral
|
||||
esp_vfs_fat_sdcard_unmount(mount_point, card);
|
||||
printf("Card unmounted\n");
|
||||
|
||||
// deinitialize the bus after all devices are removed
|
||||
spi_bus_free(host.slot);
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define TEST_USE_SDCARD 0
|
||||
|
||||
#define TEST_JPEG_X 24 // width
|
||||
#define TEST_JPEG_Y 16 // height
|
||||
#define TEST_JPEG_WHITE_X 4
|
||||
#define TEST_JPEG_WHITE_Y 4
|
||||
#define TEST_JPEG_BLACK_X 12
|
||||
#define TEST_JPEG_BLACK_Y 4
|
||||
#define TEST_JPEG_CYAN_X 20
|
||||
#define TEST_JPEG_CYAN_Y 4
|
||||
#define TEST_JPEG_RED_X 4
|
||||
#define TEST_JPEG_RED_Y 12
|
||||
#define TEST_JPEG_GREEN_X 12
|
||||
#define TEST_JPEG_GREEN_Y 12
|
||||
#define TEST_JPEG_BLUE_X 20
|
||||
#define TEST_JPEG_BLUE_Y 12
|
||||
|
||||
/**
|
||||
* @brief Color array containing RGB color values
|
||||
*/
|
||||
static const uint8_t test_color_value[][3] = {
|
||||
{255, 255, 255}, // white #FFFFFF
|
||||
{0, 0, 0}, // black #000000
|
||||
{0, 255, 255}, // cyan #00FFFF
|
||||
{255, 0, 0}, // red #FF0000
|
||||
{0, 255, 0}, // green #00FF00
|
||||
{0, 0, 255}, // blue #0000FF
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Test JPEG file, resolution 24x16
|
||||
* Contain six color: white #FFFFFF, black #000000, cyan #00FFFF, red #FF0000, green #00FF00, blue #0000FF
|
||||
* │< 8px >│< 8px >│< 8px >│
|
||||
* │ │ │ │
|
||||
* ───┌───────────┬───────────┬───────────┐
|
||||
* ^ │ │ │ │
|
||||
* │ │ │ │
|
||||
* 8px │ white │ black │ cyan │
|
||||
* │ │ │ │
|
||||
* v │ │ │ │
|
||||
* ───├───────────┼───────────┼───────────┤
|
||||
* ^ │ │ │ │
|
||||
* │ │ │ │
|
||||
* 8px │ red │ green │ blue │
|
||||
* │ │ │ │
|
||||
* v │ │ │ │
|
||||
* ───└───────────┴───────────┴───────────┘
|
||||
*/
|
||||
static const uint8_t test_jpeg_data[371] = {
|
||||
0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
|
||||
0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, 0x02, 0x03,
|
||||
0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0A, 0x07,
|
||||
0x07, 0x06, 0x08, 0x0C, 0x0A, 0x0C, 0x0C, 0x0B, 0x0A, 0x0B, 0x0B, 0x0D, 0x0E, 0x12, 0x10, 0x0D,
|
||||
0x0E, 0x11, 0x0E, 0x0B, 0x0B, 0x10, 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0C, 0x0F,
|
||||
0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xFF, 0xDB, 0x00, 0x43, 0x01, 0x03, 0x04,
|
||||
0x04, 0x05, 0x04, 0x05, 0x09, 0x05, 0x05, 0x09, 0x14, 0x0D, 0x0B, 0x0D, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xFF, 0xC0,
|
||||
0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x18, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
|
||||
0x01, 0xFF, 0xC4, 0x00, 0x18, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x07, 0x0A, 0xFF, 0xC4, 0x00, 0x14, 0x10,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xC4, 0x00, 0x17, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x08, 0x09, 0xFF, 0xC4, 0x00, 0x2D, 0x11, 0x00,
|
||||
0x00, 0x03, 0x02, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
|
||||
0x12, 0x13, 0x00, 0x17, 0x01, 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x21, 0x64, 0xA3, 0x24, 0x31,
|
||||
0x41, 0x42, 0x51, 0x61, 0x62, 0x63, 0x73, 0xE2, 0xE3, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00,
|
||||
0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, 0xAA, 0x6E, 0x55, 0xCE, 0x51, 0xC6, 0x2A, 0xA5, 0x39,
|
||||
0xF5, 0x67, 0x13, 0x46, 0x31, 0x87, 0x7C, 0x35, 0x07, 0x4C, 0x3C, 0x58, 0xDA, 0x6A, 0x8B, 0x39,
|
||||
0xFB, 0x3A, 0xFA, 0xD5, 0x69, 0x5E, 0xD1, 0x52, 0x4F, 0xC8, 0x63, 0x29, 0xC8, 0x03, 0x68, 0xDD,
|
||||
0xA6, 0x84, 0x6F, 0x0D, 0x38, 0x76, 0x78, 0xCC, 0xBF, 0x76, 0x8A, 0xDC, 0xF6, 0x3F, 0x2B, 0xE8,
|
||||
0xDF, 0xFF, 0xD9,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Test RGB888 file, resolution 24x16
|
||||
* Contain six color: white #FFFFFF, black #000000, cyan #00FFFF, red #FF0000, green #00FF00, blue #0000FF
|
||||
* │< 8px >│< 8px >│< 8px >│
|
||||
* │ │ │ │
|
||||
* ───┌───────────┬───────────┬───────────┐
|
||||
* ^ │ │ │ │
|
||||
* │ │ │ │
|
||||
* 8px │ white │ black │ cyan │
|
||||
* │ │ │ │
|
||||
* v │ │ │ │
|
||||
* ───├───────────┼───────────┼───────────┤
|
||||
* ^ │ │ │ │
|
||||
* │ │ │ │
|
||||
* 8px │ red │ green │ blue │
|
||||
* │ │ │ │
|
||||
* v │ │ │ │
|
||||
* ───└───────────┴───────────┴───────────┘
|
||||
*/
|
||||
static const uint8_t test_rgb888_data[1152] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Mount the SD card
|
||||
*/
|
||||
void mount_sd(void);
|
||||
|
||||
/**
|
||||
* @brief Unmount the SD card
|
||||
*/
|
||||
void unmount_sd(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "unity_test_utils_memory.h"
|
||||
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (500)
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main()
|
||||
{
|
||||
// _____ _____ ____ _____ _ ____ _____ ____
|
||||
// |_ _| ____/ ___|_ _| | | _ \| ____/ ___|
|
||||
// | | | _| \___ \ | | _ | | |_) | _|| | _
|
||||
// | | | |___ ___) || | | |_| | __/| |__| |_| |
|
||||
// |_| |_____|____/ |_| \___/|_| |_____\____|
|
||||
|
||||
printf(" _____ _____ ____ _____ _ ____ _____ ____ \n");
|
||||
printf("|_ _| ____/ ___|_ _| | | _ \\| ____/ ___|\n");
|
||||
printf(" | | | _| \\___ \\ | | _ | | |_) | _|| | _ \n");
|
||||
printf(" | | | |___ ___) || | | |_| | __/| |__| |_| |\n");
|
||||
printf(" |_| |_____|____/ |_| \\___/|_| |_____\\____|\n");
|
||||
|
||||
unity_run_menu();
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_log.h"
|
||||
#include "unity.h"
|
||||
#include "test_decoder.h"
|
||||
#include "test_encoder.h"
|
||||
#include "image_io.h"
|
||||
|
||||
static const char *TAG = "JPEG";
|
||||
|
||||
#define JPEG_DECODER_LIMIT 16
|
||||
|
||||
TEST_CASE("test_demo", "[sys]")
|
||||
{
|
||||
ESP_LOGI(TAG, "TEST");
|
||||
}
|
||||
|
||||
TEST_CASE("test_system_heap", "[sys]")
|
||||
{
|
||||
ESP_LOGI(TAG, "Internal free heap size: %ld bytes", esp_get_free_internal_heap_size());
|
||||
ESP_LOGI(TAG, "PSRAM free heap size: %ld bytes", esp_get_free_heap_size() - esp_get_free_internal_heap_size());
|
||||
ESP_LOGI(TAG, "Total free heap size: %ld bytes", esp_get_free_heap_size());
|
||||
}
|
||||
|
||||
TEST_CASE("test_decoder_once", "[dec]")
|
||||
{
|
||||
unsigned char *input_buffer = test_jpeg_data;
|
||||
int intput_len = sizeof(test_jpeg_data);
|
||||
unsigned char *ouput_buffer = NULL;
|
||||
int output_len = 0;
|
||||
uint8_t *curpix = NULL;
|
||||
|
||||
// Test for decode process
|
||||
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_decode_one_picture(input_buffer, intput_len, &ouput_buffer, &output_len));
|
||||
|
||||
// Print output buffer
|
||||
// ESP_LOG_BUFFER_HEX(TAG, ouput_buffer, output_len);
|
||||
|
||||
// Test for while pixel
|
||||
curpix = &ouput_buffer[(TEST_JPEG_WHITE_Y * TEST_JPEG_X + TEST_JPEG_WHITE_X) * 3];
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[0][0], curpix[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[0][1], curpix[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[0][2], curpix[2]);
|
||||
|
||||
// Test for black pixel
|
||||
curpix = &ouput_buffer[(TEST_JPEG_BLACK_Y * TEST_JPEG_X + TEST_JPEG_BLACK_X) * 3];
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[1][0], curpix[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[1][1], curpix[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[1][2], curpix[2]);
|
||||
|
||||
// Test for cyan pixel
|
||||
curpix = &ouput_buffer[(TEST_JPEG_CYAN_Y * TEST_JPEG_X + TEST_JPEG_CYAN_X) * 3];
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[2][0], curpix[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[2][1], curpix[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[2][2], curpix[2]);
|
||||
|
||||
// Test for red pixel
|
||||
curpix = &ouput_buffer[(TEST_JPEG_RED_Y * TEST_JPEG_X + TEST_JPEG_RED_X) * 3];
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[3][0], curpix[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[3][1], curpix[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[3][2], curpix[2]);
|
||||
|
||||
// Test for green pixel
|
||||
curpix = &ouput_buffer[(TEST_JPEG_GREEN_Y * TEST_JPEG_X + TEST_JPEG_GREEN_X) * 3];
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[4][0], curpix[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[4][1], curpix[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[4][2], curpix[2]);
|
||||
|
||||
// Test for blue pixel
|
||||
curpix = &ouput_buffer[(TEST_JPEG_BLUE_Y * TEST_JPEG_X + TEST_JPEG_BLUE_X) * 3];
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[5][0], curpix[0]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[5][1], curpix[1]);
|
||||
TEST_ASSERT_UINT8_WITHIN(JPEG_DECODER_LIMIT, test_color_value[5][2], curpix[2]);
|
||||
|
||||
// Free output buffer
|
||||
if (ouput_buffer) {
|
||||
jpeg_free_align(ouput_buffer);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "in_buffer: %p, in_len: %d, out_buffer: %p, out_len: %d", input_buffer, intput_len, ouput_buffer, output_len);
|
||||
}
|
||||
|
||||
TEST_CASE("test_decoder_block", "[dec]")
|
||||
{
|
||||
unsigned char *input_buffer = test_jpeg_data;
|
||||
int intput_len = sizeof(test_jpeg_data);
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
mount_sd();
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
|
||||
// Test for decode process
|
||||
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_decode_one_picture_block(input_buffer, intput_len));
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
unmount_sd();
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
}
|
||||
|
||||
TEST_CASE("test_decoder_stream", "[dec]")
|
||||
{
|
||||
unsigned char *input_buffer = test_jpeg_data;
|
||||
int intput_len = sizeof(test_jpeg_data);
|
||||
unsigned char *ouput_buffer = NULL;
|
||||
int output_len = 0;
|
||||
|
||||
struct esp_jpeg_stream jpeg_handle = {0};
|
||||
|
||||
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_stream_open(&jpeg_handle));
|
||||
|
||||
for (int frame_cnt = 0; frame_cnt < 10; frame_cnt++) {
|
||||
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_stream_decode(&jpeg_handle, input_buffer, intput_len, &ouput_buffer, &output_len));
|
||||
ESP_LOGI(TAG, "frame_index: %d, in_buffer: %p, in_len: %d, out_buffer: %p, out_len: %d", frame_cnt, input_buffer, intput_len, ouput_buffer, output_len);
|
||||
|
||||
// Free output buffer
|
||||
if (ouput_buffer) {
|
||||
jpeg_free_align(ouput_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_stream_close(&jpeg_handle));
|
||||
}
|
||||
|
||||
TEST_CASE("test_encoder_once", "[enc]")
|
||||
{
|
||||
#if TEST_USE_SDCARD
|
||||
mount_sd();
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
|
||||
// Test for encode process
|
||||
TEST_ASSERT_EQUAL(JPEG_ERR_OK, esp_jpeg_encode_one_picture());
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
unmount_sd();
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
}
|
||||
|
||||
TEST_CASE("test_encoder_block", "[enc]")
|
||||
{
|
||||
#if TEST_USE_SDCARD
|
||||
mount_sd();
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
|
||||
// Test for encode process
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(JPEG_ERR_OK, esp_jpeg_encode_one_picture_block());
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
unmount_sd();
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "image_io.h"
|
||||
#include "test_decoder.h"
|
||||
|
||||
static jpeg_pixel_format_t j_type = JPEG_PIXEL_FORMAT_RGB888;
|
||||
static jpeg_rotate_t j_rotation = JPEG_ROTATE_0D;
|
||||
|
||||
jpeg_error_t esp_jpeg_decode_one_picture(uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len)
|
||||
{
|
||||
uint8_t *out_buf = NULL;
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
jpeg_dec_io_t *jpeg_io = NULL;
|
||||
jpeg_dec_header_info_t *out_info = NULL;
|
||||
|
||||
// Generate default configuration
|
||||
jpeg_dec_config_t config = DEFAULT_JPEG_DEC_CONFIG();
|
||||
config.output_type = j_type;
|
||||
config.rotate = j_rotation;
|
||||
// config.scale.width = 0;
|
||||
// config.scale.height = 0;
|
||||
// config.clipper.width = 0;
|
||||
// config.clipper.height = 0;
|
||||
|
||||
// Create jpeg_dec handle
|
||||
jpeg_dec_handle_t jpeg_dec = NULL;
|
||||
ret = jpeg_dec_open(&config, &jpeg_dec);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create io_callback handle
|
||||
jpeg_io = calloc(1, sizeof(jpeg_dec_io_t));
|
||||
if (jpeg_io == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Create out_info handle
|
||||
out_info = calloc(1, sizeof(jpeg_dec_header_info_t));
|
||||
if (out_info == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Set input buffer and buffer len to io_callback
|
||||
jpeg_io->inbuf = input_buf;
|
||||
jpeg_io->inbuf_len = len;
|
||||
|
||||
// Parse jpeg picture header and get picture for user and decoder
|
||||
ret = jpeg_dec_parse_header(jpeg_dec, jpeg_io, out_info);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
*out_len = out_info->width * out_info->height * 3;
|
||||
// Calloc out_put data buffer and update inbuf ptr and inbuf_len
|
||||
if (config.output_type == JPEG_PIXEL_FORMAT_RGB565_LE
|
||||
|| config.output_type == JPEG_PIXEL_FORMAT_RGB565_BE
|
||||
|| config.output_type == JPEG_PIXEL_FORMAT_CbYCrY) {
|
||||
*out_len = out_info->width * out_info->height * 2;
|
||||
} else if (config.output_type == JPEG_PIXEL_FORMAT_RGB888) {
|
||||
*out_len = out_info->width * out_info->height * 3;
|
||||
} else {
|
||||
ret = JPEG_ERR_INVALID_PARAM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
out_buf = jpeg_calloc_align(*out_len, 16);
|
||||
if (out_buf == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
jpeg_io->outbuf = out_buf;
|
||||
*output_buf = out_buf;
|
||||
|
||||
// Start decode jpeg
|
||||
ret = jpeg_dec_process(jpeg_dec, jpeg_io);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Decoder deinitialize
|
||||
jpeg_dec_failed:
|
||||
jpeg_dec_close(jpeg_dec);
|
||||
if (jpeg_io) {
|
||||
free(jpeg_io);
|
||||
}
|
||||
if (out_info) {
|
||||
free(out_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
jpeg_error_t esp_jpeg_decode_one_picture_block(unsigned char *input_buf, int len)
|
||||
{
|
||||
unsigned char *output_block = NULL;
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
jpeg_dec_io_t *jpeg_io = NULL;
|
||||
jpeg_dec_header_info_t *out_info = NULL;
|
||||
FILE *f_out = NULL;
|
||||
|
||||
// Generate default configuration
|
||||
jpeg_dec_config_t config = DEFAULT_JPEG_DEC_CONFIG();
|
||||
config.block_enable = true;
|
||||
|
||||
// Empty handle to jpeg_decoder
|
||||
jpeg_dec_handle_t jpeg_dec = NULL;
|
||||
ret = jpeg_dec_open(&config, &jpeg_dec);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create io_callback handle
|
||||
jpeg_io = calloc(1, sizeof(jpeg_dec_io_t));
|
||||
if (jpeg_io == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Create out_info handle
|
||||
out_info = calloc(1, sizeof(jpeg_dec_header_info_t));
|
||||
if (out_info == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Set input buffer and buffer len to io_callback
|
||||
jpeg_io->inbuf = input_buf;
|
||||
jpeg_io->inbuf_len = len;
|
||||
|
||||
// Parse jpeg picture header and get picture for user and decoder
|
||||
ret = jpeg_dec_parse_header(jpeg_dec, jpeg_io, out_info);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Calloc block output data buffer
|
||||
int output_len = 0;
|
||||
ret = jpeg_dec_get_outbuf_len(jpeg_dec, &output_len);
|
||||
if (ret != JPEG_ERR_OK || output_len == 0) {
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
output_block = jpeg_calloc_align(output_len, 16);
|
||||
if (output_block == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
jpeg_io->outbuf = output_block;
|
||||
|
||||
// get process count
|
||||
int process_count = 0;
|
||||
ret = jpeg_dec_get_process_count(jpeg_dec, &process_count);
|
||||
if (ret != JPEG_ERR_OK || process_count == 0) {
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
// Open output file on SDCard, should init SDcard first
|
||||
f_out = fopen("/sdcard/esp_jpeg_decode_one_picture_block.bin", "wb");
|
||||
if (f_out == NULL) {
|
||||
ret = JPEG_ERR_FAIL;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
|
||||
// Decode jpeg data
|
||||
for (int block_cnt = 0; block_cnt < process_count; block_cnt++) {
|
||||
ret = jpeg_dec_process(jpeg_dec, jpeg_io);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
// do something - to sdcard
|
||||
int written_data = fwrite(jpeg_io->outbuf, 1, jpeg_io->out_size, f_out);
|
||||
if (written_data != jpeg_io->out_size) {
|
||||
ret = JPEG_ERR_FAIL;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
}
|
||||
|
||||
// Decoder deinitialize
|
||||
jpeg_dec_failed:
|
||||
jpeg_dec_close(jpeg_dec);
|
||||
if (jpeg_io) {
|
||||
free(jpeg_io);
|
||||
}
|
||||
if (out_info) {
|
||||
free(out_info);
|
||||
}
|
||||
jpeg_free_align(output_block);
|
||||
#if TEST_USE_SDCARD
|
||||
if (f_out) {
|
||||
fclose(f_out);
|
||||
}
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
return ret;
|
||||
}
|
||||
|
||||
jpeg_error_t esp_jpeg_stream_open(esp_jpeg_stream_handle_t jpeg_handle)
|
||||
{
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
|
||||
// Generate default configuration
|
||||
jpeg_dec_config_t config = DEFAULT_JPEG_DEC_CONFIG();
|
||||
config.output_type = j_type;
|
||||
config.rotate = j_rotation;
|
||||
// config.scale.width = 0;
|
||||
// config.scale.height = 0;
|
||||
// config.clipper.width = 0;
|
||||
// config.clipper.height = 0;
|
||||
jpeg_handle->output_type = j_type;
|
||||
|
||||
// Create jpeg_dec handle
|
||||
ret = jpeg_dec_open(&config, &jpeg_handle->jpeg_dec);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create io_callback handle
|
||||
jpeg_handle->jpeg_io = calloc(1, sizeof(jpeg_dec_io_t));
|
||||
if (jpeg_handle->jpeg_io == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
|
||||
// Create out_info handle
|
||||
jpeg_handle->out_info = calloc(1, sizeof(jpeg_dec_header_info_t));
|
||||
if (jpeg_handle->out_info == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_dec_failed;
|
||||
}
|
||||
return JPEG_ERR_OK;
|
||||
|
||||
// Decoder deinitialize
|
||||
jpeg_dec_failed:
|
||||
jpeg_dec_close(jpeg_handle->jpeg_dec);
|
||||
if (jpeg_handle->jpeg_io) {
|
||||
free(jpeg_handle->jpeg_io);
|
||||
}
|
||||
if (jpeg_handle->out_info) {
|
||||
free(jpeg_handle->out_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
jpeg_error_t esp_jpeg_stream_decode(esp_jpeg_stream_handle_t jpeg_handle, uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len)
|
||||
{
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
unsigned char *out_buf = NULL;
|
||||
|
||||
// Set input buffer and buffer len to io_callback
|
||||
jpeg_handle->jpeg_io->inbuf = input_buf;
|
||||
jpeg_handle->jpeg_io->inbuf_len = len;
|
||||
|
||||
// Parse jpeg picture header and get picture for user and decoder
|
||||
ret = jpeg_dec_parse_header(jpeg_handle->jpeg_dec, jpeg_handle->jpeg_io, jpeg_handle->out_info);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_len = jpeg_handle->out_info->width * jpeg_handle->out_info->height * 3;
|
||||
// Calloc out_put data buffer and update inbuf ptr and inbuf_len
|
||||
if (jpeg_handle->output_type == JPEG_PIXEL_FORMAT_RGB565_LE
|
||||
|| jpeg_handle->output_type == JPEG_PIXEL_FORMAT_RGB565_BE
|
||||
|| jpeg_handle->output_type == JPEG_PIXEL_FORMAT_CbYCrY) {
|
||||
*out_len = jpeg_handle->out_info->width * jpeg_handle->out_info->height * 2;
|
||||
} else if (jpeg_handle->output_type == JPEG_PIXEL_FORMAT_RGB888) {
|
||||
*out_len = jpeg_handle->out_info->width * jpeg_handle->out_info->height * 3;
|
||||
} else {
|
||||
ret = JPEG_ERR_INVALID_PARAM;
|
||||
return ret;
|
||||
}
|
||||
out_buf = jpeg_calloc_align(*out_len, 16);
|
||||
if (out_buf == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
return ret;
|
||||
}
|
||||
jpeg_handle->jpeg_io->outbuf = out_buf;
|
||||
*output_buf = out_buf;
|
||||
|
||||
// Start decode jpeg
|
||||
ret = jpeg_dec_process(jpeg_handle->jpeg_dec, jpeg_handle->jpeg_io);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
jpeg_error_t esp_jpeg_stream_close(esp_jpeg_stream_handle_t jpeg_handle)
|
||||
{
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
|
||||
ret = jpeg_dec_close(jpeg_handle->jpeg_dec);
|
||||
if (jpeg_handle->jpeg_io) {
|
||||
free(jpeg_handle->jpeg_io);
|
||||
}
|
||||
if (jpeg_handle->out_info) {
|
||||
free(jpeg_handle->out_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_jpeg_common.h"
|
||||
#include "esp_jpeg_dec.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct esp_jpeg_stream {
|
||||
jpeg_dec_handle_t jpeg_dec;
|
||||
jpeg_dec_io_t *jpeg_io;
|
||||
jpeg_dec_header_info_t *out_info;
|
||||
jpeg_pixel_format_t output_type;
|
||||
};
|
||||
typedef struct esp_jpeg_stream *esp_jpeg_stream_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Decode a single JPEG picture
|
||||
*
|
||||
* @param input_buf Pointer to the input buffer containing JPEG data
|
||||
* @param len Length of the input buffer in bytes
|
||||
* @param output_buf Pointer to output buffer, allocated in `esp_jpeg_decoder_one_picture` but it won't to free. Please release this buffer after decoding is complete.
|
||||
* @param out_len Acturally output length in bytes
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_decode_one_picture(uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len);
|
||||
|
||||
/**
|
||||
* @brief Decode a single JPEG picture with block deocder API
|
||||
*
|
||||
* @param input_buf Pointer to the input buffer containing JPEG data
|
||||
* @param len Length of the input buffer in bytes
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_decode_one_picture_block(unsigned char *input_buf, int len);
|
||||
|
||||
/**
|
||||
* @brief Open a JPEG stream handle for decoding
|
||||
*
|
||||
* @param jpeg_handle Handle to the JPEG stream
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_stream_open(esp_jpeg_stream_handle_t jpeg_handle);
|
||||
|
||||
/**
|
||||
* @brief Decode a portion of the JPEG stream
|
||||
*
|
||||
* @param jpeg_handle Handle to the JPEG stream
|
||||
* @param input_buf Pointer to the input buffer containing JPEG data
|
||||
* @param len Length of the input buffer in bytes
|
||||
* @param output_buf Pointer to output buffer, allocated in `esp_jpeg_stream_decode` but it won't to free. Please release this buffer after decoding is complete.
|
||||
* @param out_len Acturally output length in bytes
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_stream_decode(esp_jpeg_stream_handle_t jpeg_handle, uint8_t *input_buf, int len, uint8_t **output_buf, int *out_len);
|
||||
|
||||
/**
|
||||
* @brief Close the JPEG stream
|
||||
*
|
||||
* @param jpeg_handle Handle to the JPEG stream
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_stream_close(esp_jpeg_stream_handle_t jpeg_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
@@ -0,0 +1,148 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "image_io.h"
|
||||
#include "test_encoder.h"
|
||||
|
||||
jpeg_error_t esp_jpeg_encode_one_picture(void)
|
||||
{
|
||||
// configure encoder
|
||||
jpeg_enc_config_t jpeg_enc_cfg = DEFAULT_JPEG_ENC_CONFIG();
|
||||
jpeg_enc_cfg.width = TEST_JPEG_X;
|
||||
jpeg_enc_cfg.height = TEST_JPEG_Y;
|
||||
jpeg_enc_cfg.src_type = JPEG_PIXEL_FORMAT_RGB888;
|
||||
jpeg_enc_cfg.subsampling = JPEG_SUBSAMPLE_420;
|
||||
jpeg_enc_cfg.quality = 60;
|
||||
jpeg_enc_cfg.rotate = JPEG_ROTATE_0D;
|
||||
jpeg_enc_cfg.task_enable = false;
|
||||
jpeg_enc_cfg.hfm_task_priority = 13;
|
||||
jpeg_enc_cfg.hfm_task_core = 1;
|
||||
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
uint8_t *inbuf = test_rgb888_data;
|
||||
int image_size = jpeg_enc_cfg.width * jpeg_enc_cfg.height * 3;
|
||||
uint8_t *outbuf = NULL;
|
||||
int outbuf_size = 100 * 1024;
|
||||
int out_len = 0;
|
||||
jpeg_enc_handle_t jpeg_enc = NULL;
|
||||
FILE *out = NULL;
|
||||
|
||||
// open
|
||||
ret = jpeg_enc_open(&jpeg_enc_cfg, &jpeg_enc);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// allocate output buffer to fill encoded image stream
|
||||
outbuf = (uint8_t *)calloc(1, outbuf_size);
|
||||
if (outbuf == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_example_exit;
|
||||
}
|
||||
|
||||
// process
|
||||
ret = jpeg_enc_process(jpeg_enc, inbuf, image_size, outbuf, outbuf_size, &out_len);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
goto jpeg_example_exit;
|
||||
}
|
||||
|
||||
#if TEST_USE_SDCARD
|
||||
out = fopen("/sdcard/esp_jpeg_encode_one_picture.jpg", "wb");
|
||||
if (out == NULL) {
|
||||
goto jpeg_example_exit;
|
||||
}
|
||||
fwrite(outbuf, 1, out_len, out);
|
||||
fclose(out);
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
|
||||
jpeg_example_exit:
|
||||
// close
|
||||
jpeg_enc_close(jpeg_enc);
|
||||
if (outbuf) {
|
||||
free(outbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
jpeg_error_t esp_jpeg_encode_one_picture_block(void)
|
||||
{
|
||||
// configure encoder
|
||||
jpeg_enc_config_t jpeg_enc_cfg = DEFAULT_JPEG_ENC_CONFIG();
|
||||
jpeg_enc_cfg.width = TEST_JPEG_X;
|
||||
jpeg_enc_cfg.height = TEST_JPEG_Y;
|
||||
jpeg_enc_cfg.src_type = JPEG_PIXEL_FORMAT_RGB888;
|
||||
jpeg_enc_cfg.subsampling = JPEG_SUBSAMPLE_420;
|
||||
jpeg_enc_cfg.quality = 60;
|
||||
jpeg_enc_cfg.rotate = JPEG_ROTATE_0D;
|
||||
jpeg_enc_cfg.task_enable = false;
|
||||
jpeg_enc_cfg.hfm_task_priority = 13;
|
||||
jpeg_enc_cfg.hfm_task_core = 1;
|
||||
|
||||
jpeg_error_t ret = JPEG_ERR_OK;
|
||||
uint8_t *inbuf = test_rgb888_data;
|
||||
int image_size = jpeg_enc_cfg.width * jpeg_enc_cfg.height * 3;
|
||||
int block_size = 0;
|
||||
int num_times = 0;
|
||||
uint8_t *outbuf = NULL;
|
||||
int outbuf_size = 100 * 1024;
|
||||
int out_len = 0;
|
||||
jpeg_enc_handle_t jpeg_enc = NULL;
|
||||
FILE *out = NULL;
|
||||
|
||||
// open
|
||||
ret = jpeg_enc_open(&jpeg_enc_cfg, &jpeg_enc);
|
||||
if (ret != JPEG_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// outbuf
|
||||
if ((outbuf = (uint8_t *)calloc(1, outbuf_size)) == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_example_exit;
|
||||
}
|
||||
|
||||
// inbuf
|
||||
block_size = jpeg_enc_get_block_size(jpeg_enc);
|
||||
if ((inbuf = (uint8_t *)jpeg_calloc_align(block_size, 16)) == NULL) {
|
||||
ret = JPEG_ERR_NO_MEM;
|
||||
goto jpeg_example_exit;
|
||||
}
|
||||
num_times = image_size / block_size;
|
||||
|
||||
// process
|
||||
int in_offset = 0;
|
||||
for (size_t j = 0; j < num_times; j++) {
|
||||
// copy memory or read from SDCard
|
||||
memcpy(inbuf, test_rgb888_data + in_offset, block_size);
|
||||
in_offset += block_size;
|
||||
|
||||
ret = jpeg_enc_process_with_block(jpeg_enc, inbuf, block_size, outbuf, outbuf_size, &out_len);
|
||||
if (ret < JPEG_ERR_OK) {
|
||||
goto jpeg_example_exit;
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_example_exit:
|
||||
#if TEST_USE_SDCARD
|
||||
out = fopen("/sdcard/esp_jpeg_encode_one_picture_block.jpg", "wb");
|
||||
if (out != NULL) {
|
||||
fwrite(outbuf, 1, out_len, out);
|
||||
fclose(out);
|
||||
}
|
||||
#endif /* TEST_USE_SDCARD */
|
||||
|
||||
// close
|
||||
jpeg_enc_close(jpeg_enc);
|
||||
if (inbuf) {
|
||||
jpeg_free_align(inbuf);
|
||||
}
|
||||
if (outbuf) {
|
||||
free(outbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
|
||||
// All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_jpeg_common.h"
|
||||
#include "esp_jpeg_enc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @brief Encode a single picture
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_encode_one_picture(void);
|
||||
|
||||
/**
|
||||
* @brief Encode a single picture with block encoder API
|
||||
*
|
||||
* @return
|
||||
* - JPEG_ERR_OK Succeeded
|
||||
* - Others Failed
|
||||
*/
|
||||
jpeg_error_t esp_jpeg_encode_one_picture_block(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
@@ -0,0 +1,16 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.esp32c2
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.esp32c6
|
||||
def test_esp_system(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# ESP System Settings
|
||||
#
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
|
||||
#
|
||||
# FreeRTOS
|
||||
#
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
|
||||
|
||||
#
|
||||
# SPI RAM config
|
||||
#
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_BOOT_INIT=y
|
||||
|
||||
#
|
||||
# FAT Filesystem support
|
||||
#
|
||||
CONFIG_FATFS_CODEPAGE_936=y
|
||||
CONFIG_FATFS_LFN_HEAP=y
|
||||
CONFIG_FATFS_MAX_LFN=255
|
||||
CONFIG_FATFS_FS_LOCK=5
|
||||
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# ESP32S3-Specific
|
||||
#
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240
|
||||
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||
|
||||
#
|
||||
# SPI RAM config
|
||||
#
|
||||
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_MODE_OCT=y
|
||||
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||
Reference in New Issue
Block a user