How would I got about loading and displaying a large image (1024x600) from sd card on a Riverdi 7" display which uses a BT817?
Its for a boot screen which only needs to be displayed once at startup. I don't really want to have to get the user to convert images to ASTC format first, nor do I want to store the file in external eeprom either.
All the examples I see are for small images which fit into EVEs memory nicely... but what about full screen images?
Is there a a simple "picture frame" application which supports files from SD card for larger display sizes?
Cheers
Toby
Hi Toby,
Could you advise what type of images you will use? Are they full photos or mainly logos etc.
Normally if you would like to use images directly we would suggest png or jpg and then inflate via CMD_LOADIMAGE. However, png normally decompress to a format such as RGB565 (full colour) or ARGB4 (if image has transparency) which give good quality colour images. Both of these take 2 bytes per pixel and so the image would be bigger than then RAM_G. Mono png images would be L8 (1 byte per pixel) or in some cases an indexed image may be palleted. However, if you want to allow users to use most images without too many restrictions it would likely be the 2-bytes-per-pixel formats.
1024 x 600 x 2 = 614400 x 2 = 1,228,800 and so more than the 1MBytes RAM_G
If your image is a logo then you may be able to load it as smaller one with a background colour defined by EVE, or you could consider to load and scale up a slightly smaller image.
ASTC would be ideal for this but if you want to avoid the conversion then these options above may be good.
If you could send details of the typical image style we can see what else we can advise thought too,
Best Regards, BRT Community
I've decided to go down the ASTC route, a simple application will run EAB in command line mode to generate the necessary raw data file. This will be placed on SD card. The boot screen (full colour ASTC 8x8) can be loaded into RAM_G at startup along with approx 20 small icons (60x60) in L1 format.
The final part for me, is how to get the data from the file on the sdcard to RAMG_G in small 2048 byte chunks, using Rudolph's library. I'm using Rudolph's library extensively at the moment.
There are a couple of options that I have not explored myself as my hardware usually does not have an SD card socket.
- CMD_LOADIMAGE with a MEDIA-FIO and scaling - but this probably does not look good.
- CMD_INFLATE2 with a MEDIA-FIFO for zlib compressed ASTC.
- CMD_INFLATE with some modifications.
void EVE_cmd_inflate(const uint32_t ptr, const uint8_t * const p_data, const uint32_t len)
void block_transfer(const uint8_t * const p_data, const uint32_t len)
block_transfer already cuts larger transfers into chunks of 3840 bytes as the transfer goes through the FIFO
- Write directly to RAM-G.
void EVE_memWrite_sram_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len)
You would only need a wrapper around this to count up from the base address for whatever block you are transferring.
This might be the easiest to implement, but this would be for unpacked data, so 1024x600 in ASTC 8x8 would require to write 150kiB.
Edit: personal point of curiosity - which MCU are you using?
Im running this on a Teensy 4.1 which has a builtin SD card, bang for buck these have massive perfomance and great support, only downside is no hardware debugging.
I have come up with a reasonable compromise which uses EVE_memWrite_sram_buffer, and a small 2KB buffer for streaming.
I simply read all raw data files (from EAB) into RAM_G from the SD card at startup. As the raw data does not include the data structure (width, height, format etc) I encode this into the file name and decode and store in a small asset manager data structure on startup.
I've not explored the inflate options, but I suspect that you would still need to reserve the same size uncompressed / raw image size in RAM_G? So apart from smaller image files, no real gain to be had, but I might (hopefully) be wrong!
struct AssetData
{
char name[32];
int width;
int height;
// when decoding filename, we expect the format and compression to be in the filename, e.g., "my_image_1024x600_ASTC_8X8.raw"
char format[16]; // e.g., "ASTC"
char compression[16]; // e.g., "8X8"
bool isValid;
uint32_t eveFormat; // EVE format for this asset, e.g., EVE_COMPRESSED_RGBA_ASTC_8x8_KHR
uint32_t eveAddress; // Start address in RAM_G (4-byte aligned)
uint32_t eveSize; // Total size of the asset in bytes
}; // AssetData
uint32_t GetEveFormat(const char *formatStr, const char *compressionStr)
{
if (strcmp(formatStr, "ASTC") == 0)
{
if (strcmp(compressionStr, "4x4") == 0)
return EVE_COMPRESSED_RGBA_ASTC_4x4_KHR;
if (strcmp(compressionStr, "5x4") == 0)
return EVE_COMPRESSED_RGBA_ASTC_5x4_KHR;
if (strcmp(compressionStr, "5x5") == 0)
return EVE_COMPRESSED_RGBA_ASTC_5x5_KHR;
if (strcmp(compressionStr, "6x5") == 0)
return EVE_COMPRESSED_RGBA_ASTC_6x5_KHR;
if (strcmp(compressionStr, "6x6") == 0)
return EVE_COMPRESSED_RGBA_ASTC_6x6_KHR;
if (strcmp(compressionStr, "8x5") == 0)
return EVE_COMPRESSED_RGBA_ASTC_8x5_KHR;
if (strcmp(compressionStr, "8x6") == 0)
return EVE_COMPRESSED_RGBA_ASTC_8x6_KHR;
if (strcmp(compressionStr, "8x8") == 0)
return EVE_COMPRESSED_RGBA_ASTC_8x8_KHR;
if (strcmp(compressionStr, "10x5") == 0)
return EVE_COMPRESSED_RGBA_ASTC_10x5_KHR;
if (strcmp(compressionStr, "10x6") == 0)
return EVE_COMPRESSED_RGBA_ASTC_10x6_KHR;
if (strcmp(compressionStr, "10x8") == 0)
return EVE_COMPRESSED_RGBA_ASTC_10x8_KHR;
if (strcmp(compressionStr, "10x10") == 0)
return EVE_COMPRESSED_RGBA_ASTC_10x10_KHR;
if (strcmp(compressionStr, "12x10") == 0)
return EVE_COMPRESSED_RGBA_ASTC_12x10_KHR;
if (strcmp(compressionStr, "12x12") == 0)
return EVE_COMPRESSED_RGBA_ASTC_12x12_KHR;
return EVE_COMPRESSED_RGBA_ASTC_8x8_KHR;
}
if (strcmp(formatStr, "RGB332") == 0)
return EVE_RGB332;
if (strcmp(formatStr, "RGB565") == 0)
return EVE_RGB565;
if (strcmp(formatStr, "L1") == 0)
return EVE_L1;
if (strcmp(formatStr, "L2") == 0)
return EVE_L2;
if (strcmp(formatStr, "L4") == 0)
return EVE_L4;
if (strcmp(formatStr, "L8") == 0)
return EVE_L8;
// Default fallback
return EVE_RGB565;
} // GetEveFormat
AssetData ParseAssetFilename(const char *inputFilename)
{
AssetData meta = {"", 0, 0, "", "", false};
char buffer[128];
strncpy(buffer, inputFilename, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
// 1. Get the Name
char *namePart = strtok(buffer, "_");
if (namePart)
strncpy(meta.name, namePart, 31);
// 2. Get the Resolution string (e.g., "448x456")
char *resPart = strtok(NULL, "_");
// 3. Get the Format (e.g., "ASTC")
char *formatPart = strtok(NULL, "_");
if (formatPart)
strncpy(meta.format, formatPart, 15);
// 4. Get the Compression (e.g., "8X8.raw" -> "8X8")
char *compPart = strtok(NULL, ".");
if (compPart)
strncpy(meta.compression, compPart, 15);
meta.eveFormat = GetEveFormat(meta.format, meta.compression);
// Now, safely parse the resolution string separately
if (resPart)
{
char *wStr = strtok(resPart, "x");
char *hStr = strtok(NULL, "x");
if (wStr && hStr)
{
meta.width = atoi(wStr);
meta.height = atoi(hStr);
}
}
meta.isValid = true;
return meta;
} // ParseAssetFilename
void StreamRawFileToEVE(SdFile &file, uint32_t dest_ramg_address)
{
uint8_t buffer[2048]; // 2KB buffer for streaming
int bytesRead;
while ((bytesRead = file.read(buffer, sizeof(buffer))) > 0)
{
EVE_memWrite_sram_buffer(dest_ramg_address, buffer, bytesRead);
dest_ramg_address += bytesRead;
}
} // StreamRawFileToEVE
Yes, using zlib compressed files is not about RAM-G usage.
But it would reduce the transfers from the SD card and the SPI traffic to the EVE chip.
I do have Teensy 4.0 and 4.1, but I never really found a use for them apart from implementing the library code. Total overkill. ;)
Yes agreed, the zlib compression would reduce storage on the SD card (or MCU flash) but still needs to be inflated to the original size in RAM_G to display it.
As you mentioned, it is good to encode the properties as they are not encoded. Unlike some specific formats such as png, the zlib can be used for different types of file and so does not have the full properties encoded inside.
Best Regards, BRT Community