chore(deps): managed_components 自动更新

idf.py reconfigure 触发的 idf-component-manager 版本刷新副作用:
- espressif/dl_fft, esp_jpeg, freetype 等组件的小版本更新

不影响项目功能,与 Phase 10 无直接关系。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rdzleo 2026-05-15 15:56:33 +08:00
parent 86200f5e3a
commit 0d0bc33192
835 changed files with 359109 additions and 290 deletions

View File

@ -1 +1 @@
7dadbd644c0d7ba4733cc3726ec4cff6edf27b043725e1115861dec1609a3d28
ced3cf28cc70452b7859c06f4e5059215167254a2047e34c893d6f501ccd6ea2

View File

@ -1 +1 @@
{"version": "1.0", "algorithm": "sha256", "created_at": "2025-08-22T07:02:16.273928+00:00", "files": [{"path": "CMakeLists.txt", "size": 1121, "hash": "b8db31748630321376c2a5998ea99d300a2d7f77d41b6a84d6f838ae18001632"}, {"path": "README.md", "size": 3606, "hash": "73f10b8cb40f463d4758f3c67e686105e8d6dea8f65a209219c7e2fac8c6cc81"}, {"path": "benchmark_esp32c5.md", "size": 6313, "hash": "af1c5eec587b0f7addac1e94c31a581a49f7121219826df53cbab973e6249786"}, {"path": "benchmark_esp32p4.md", "size": 5015, "hash": "b204be13020ff47f967c35dd1d60727013a83bbffbea2f0a1ca93874fe1e6226"}, {"path": "benchmark_esp32s3.md", "size": 5015, "hash": "9e9f5fa858453c853f83d63913dc974bd8c5fc7e5883400f7c1e50ffa6ef44a4"}, {"path": "dl_fft.h", "size": 4787, "hash": "f2cca68876cce36d24d5e0e1b9fe8bac3e09f65c5d065c5451b43713cada65c0"}, {"path": "dl_fft.hpp", "size": 9514, "hash": "abb72093b97832af83f5e0eb5289de0a02ead0325049d3192a39295bc166fd55"}, {"path": "dl_fft_f32.c", "size": 2231, "hash": "895ea2322a0740cf02bd6075453a247b5144aefceb8f31b6717248e6eeaf79ee"}, {"path": "dl_fft_s16.c", "size": 2737, "hash": "fb9168e0a6e2b798b88a8e06d5482610db9070a5b3c5e66f32ed8dcf514a0649"}, {"path": "dl_rfft.h", "size": 6523, "hash": "0219466a0cfc4ab218b22af3cf7954c975a0f4e05dd7fc947ab98c3bc3f76796"}, {"path": "dl_rfft_f32.c", "size": 3661, "hash": "1d87595dfe93be1e6ad63e2decd0b04c94f8414da8ccff96a4a9068a1128baaa"}, {"path": "dl_rfft_s16.c", "size": 3228, "hash": "7449d35f33c2acc30c4d4d09e9557c8a9e1ca9c7d5964047d248b35a8e756e63"}, {"path": "idf_component.yml", "size": 361, "hash": "2fa5bee9d2ede17e4724582ce74e654c2082416b060b7caf0f7d97df0eb0a596"}, {"path": "base/dl_fft2r_fc32_ansi.c", "size": 7479, "hash": "d41e48229ba05e2aeb07057ca56016525f8344cce00f2e38de4dd41305478590"}, {"path": "base/dl_fft2r_sc16_ansi.c", "size": 20141, "hash": "30e62e058832ce77cb1f94d587ceb99342824deca8c287fe931274d51d4906e4"}, {"path": "base/dl_fft4r_fc32_ansi.c", "size": 9025, "hash": "2cf9d2acbd80e4acd69601545baaef72a67924df1aacd7476530d01926ee3d7b"}, {"path": "base/dl_fft_base.c", "size": 1729, "hash": "25caaeecf1a7d6ba5387292fd448a0da0884615af1d95159f093ee93b701746f"}, {"path": "base/dl_fft_base.h", "size": 3270, "hash": "a28f0e60e4c5bdae7c3aa70e39920cef17ed6d8e3f425abc85922689b798d493"}, {"path": "base/dl_fft_dtype.h", "size": 427, "hash": "209a8da6f977565f2bbf80d8d8726afb1d3c9a6dbf1e48e342c1db6023066306"}, {"path": "base/isa/dl_fft_platform.h", "size": 1552, "hash": "f5d76981793e26cdbf549d25faaae589d8e1776519a84315da4d733cef190087"}, {"path": "base/isa/esp32/dl_fft2r_fc32_ae32.S", "size": 7019, "hash": "2aa2a8f98f05076b485c9e45056d9dc49fc17a200f1bdba609b01b1443a778df"}, {"path": "base/isa/esp32/dl_fft4r_fc32_ae32.S", "size": 12062, "hash": "e64fa52065bde43eb844b89c107ed3d33a930511c6b43e90e52de9853a1a32e3"}, {"path": "base/isa/esp32p4/dl_fft2r_fc32_arp4.S", "size": 5487, "hash": "25d706406cd3e7de3407ad8518790fb157097bad1a7e705a9d67736c4115f76b"}, {"path": "base/isa/esp32p4/dl_fft4r_fc32_arp4.S", "size": 11937, "hash": "16c9a05d68cda7e3b189d7c7290013bc7614aa879cc70b1e10e7c3ec4803b1ed"}, {"path": "base/isa/esp32s3/dl_fft2r_fc32_aes3.S", "size": 5901, "hash": "53e570f9b1d888cf4b36a07ea099ecd80905beb2e957c5f9d390e2a14b5d49b4"}, {"path": "base/isa/esp32s3/dl_fft4r_fc32_aes3.S", "size": 10950, "hash": "51840adc29034c0e0983439b366bfe2f10e697c1c9667e27cdcb1394905d3930"}]}
{"version":"1.0","algorithm":"sha256","created_at":"2026-04-28T15:16:11.629665+00:00","files":[{"path":"CMakeLists.txt","size":1305,"hash":"51f14288e06f0015fe12db090ca3a00c4d860016aa4388cd06e851f84b831bbd"},{"path":"README.md","size":4358,"hash":"4d34fc42d8b3848867e1739b6e98f2759cbb18d46007c539a9c66e3995f8dde1"},{"path":"benchmark_esp32c5.md","size":6313,"hash":"af1c5eec587b0f7addac1e94c31a581a49f7121219826df53cbab973e6249786"},{"path":"benchmark_esp32p4.md","size":5194,"hash":"da1c8cfcf6ad5dfabda18ddbf2f965d2bb565091e5f33ec8129c72877d96e26e"},{"path":"benchmark_esp32s3.md","size":5042,"hash":"4612b66a48569fa88cf3be197c3af5d28b56a8b0fd292e79ada2692af3d215c8"},{"path":"dl_fft.h","size":4787,"hash":"f2cca68876cce36d24d5e0e1b9fe8bac3e09f65c5d065c5451b43713cada65c0"},{"path":"dl_fft.hpp","size":9514,"hash":"abb72093b97832af83f5e0eb5289de0a02ead0325049d3192a39295bc166fd55"},{"path":"dl_fft_f32.c","size":2298,"hash":"7a7ccd88af830791324edd95dc0828bf8364bc7592548c2c0bbd04b544877659"},{"path":"dl_fft_s16.c","size":2877,"hash":"e15f807ba0fb0437562b592e683b4a19488e035ed601ee5cc252895b776c8bd7"},{"path":"dl_rfft.h","size":6523,"hash":"0219466a0cfc4ab218b22af3cf7954c975a0f4e05dd7fc947ab98c3bc3f76796"},{"path":"dl_rfft_f32.c","size":3728,"hash":"b8c7e4acd36ddddcbe2da564e9c91d83778aa1862e58e549ce16de37e5b8e0f3"},{"path":"dl_rfft_s16.c","size":3461,"hash":"7feb2deba9d2ec5fcdcfe5a6e1ead4174f157ea3a292eb4798a828490bb7d593"},{"path":"idf_component.yml","size":361,"hash":"86d22de015184cd4717f03d26f420388c568be3911fe98f982a261e45d079648"},{"path":"base/dl_fft2r_fc32_ansi.c","size":7479,"hash":"8ee9794462849e498ec6d7f707f3bada7723212ecf48531a8491f114a2c5a0ac"},{"path":"base/dl_fft2r_sc16_ansi.c","size":17303,"hash":"d6731bf99f42a13cd3c320ba22c19666a1093bf4a7dac859a4dadfb06ccabda1"},{"path":"base/dl_fft2r_sc16_dif_ansi.c","size":9053,"hash":"ea64cde460f5341b907fed0410c26aaa3ac9a0415990263c7cc627089fdc01f6"},{"path":"base/dl_fft4r_fc32_ansi.c","size":9025,"hash":"2cf9d2acbd80e4acd69601545baaef72a67924df1aacd7476530d01926ee3d7b"},{"path":"base/dl_fft_base.c","size":6755,"hash":"969cda8bf67f7d8769a080a0b82cc80138320f081cc2f8510ed186ba6067c217"},{"path":"base/dl_fft_base.h","size":6155,"hash":"8fce29429ad0ff8b1921007a6f2c2580869e6b26a4fd80549bbfec6e6c079e16"},{"path":"base/dl_fft_dtype.h","size":427,"hash":"209a8da6f977565f2bbf80d8d8726afb1d3c9a6dbf1e48e342c1db6023066306"},{"path":"base/isa/dl_fft_platform.h","size":2637,"hash":"8ba74ddfdcee58f76364f8a13ba363d4364b5641986413a70540d99d5140abda"},{"path":"base/isa/esp32/dl_fft2r_fc32_ae32.S","size":7019,"hash":"2aa2a8f98f05076b485c9e45056d9dc49fc17a200f1bdba609b01b1443a778df"},{"path":"base/isa/esp32/dl_fft4r_fc32_ae32.S","size":12062,"hash":"e64fa52065bde43eb844b89c107ed3d33a930511c6b43e90e52de9853a1a32e3"},{"path":"base/isa/esp32p4/dl_fft2r_fc32_arp4.S","size":5487,"hash":"25d706406cd3e7de3407ad8518790fb157097bad1a7e705a9d67736c4115f76b"},{"path":"base/isa/esp32p4/dl_fft2r_sc16_arp4.S","size":37815,"hash":"36cfb1974f18c3c54bff9afa25e7459d7e8f045cf0a6d3e566d066318dd33fdd"},{"path":"base/isa/esp32p4/dl_fft4r_fc32_arp4.S","size":11937,"hash":"16c9a05d68cda7e3b189d7c7290013bc7614aa879cc70b1e10e7c3ec4803b1ed"},{"path":"base/isa/esp32s3/dl_fft2r_fc32_aes3.S","size":5901,"hash":"53e570f9b1d888cf4b36a07ea099ecd80905beb2e957c5f9d390e2a14b5d49b4"},{"path":"base/isa/esp32s3/dl_fft2r_sc16_aes3.S","size":30280,"hash":"46867dc182ed6f85db0d6510354db1955b29be0c3e47a5968e53c7d9eb9ef05f"},{"path":"base/isa/esp32s3/dl_fft4r_fc32_aes3.S","size":10950,"hash":"51840adc29034c0e0983439b366bfe2f10e697c1c9667e27cdcb1394905d3930"}]}

View File

@ -8,6 +8,7 @@ set(srcs "dl_fft_f32.c"
"base/dl_fft2r_fc32_ansi.c"
"base/dl_fft4r_fc32_ansi.c"
"base/dl_fft2r_sc16_ansi.c"
"base/dl_fft2r_sc16_dif_ansi.c"
"base/dl_fft_base.c"
)
@ -22,11 +23,13 @@ if(CONFIG_IDF_TARGET_ESP32)
elseif(CONFIG_IDF_TARGET_ESP32S3)
list(APPEND srcs "base/isa/esp32s3/dl_fft2r_fc32_aes3.S"
"base/isa/esp32s3/dl_fft4r_fc32_aes3.S" )
"base/isa/esp32s3/dl_fft4r_fc32_aes3.S"
"base/isa/esp32s3/dl_fft2r_sc16_aes3.S" )
elseif(CONFIG_IDF_TARGET_ESP32P4)
list(APPEND srcs "base/isa/esp32p4/dl_fft2r_fc32_arp4.S"
"base/isa/esp32p4/dl_fft4r_fc32_arp4.S" )
"base/isa/esp32p4/dl_fft4r_fc32_arp4.S"
"base/isa/esp32p4/dl_fft2r_sc16_arp4.S" )
endif()

View File

@ -60,6 +60,32 @@ Please refer to [dl_fft.h](./dl_fft.h) and [dl_rfft.h](./dl_rfft.h) for more det
> Note: The input array x must be allocated with heap_caps_aligned_alloc and aligned to 16 bytes.
### C++ interface:
```
float *x1 = (float *)heap_caps_aligned_alloc(16, nfft * sizeof(float) *2, MALLOC_CAP_8BIT);
int16_t *x2= (float *)heap_caps_aligned_alloc(16, nfft * sizeof(int16_t)*2, MALLOC_CAP_8BIT);
FFT *fft = FFT::get_instance();
# float
fft->fft(x1, nfft);
fft->ifft(x1, nfft);
fft->rfft(x1, nfft);
fft->irfft(x1, nfft);
#int16_t
int in_exponent=-15;
int out_exponent;
fft->fft_hp(x2, nfft, in_exponent, &out_exponent);
fft->ifft_hp(x2, nfft, in_exponent, &out_exponent);
fft->rfft_hp(x2, nfft, in_exponent, &out_exponent);
fft->irfft_hp(x2, nfft, in_exponent, &out_exponent);
```
Please refer to [dl_fft.hpp](./dl_fft.hpp) for more details.
> Note: The input array x must be allocated with heap_caps_aligned_alloc and aligned to 16 bytes.
## FAQ:
#### 1. Why not just use esp-dsp directly?
@ -70,7 +96,7 @@ Because esp-dsp uses global variables to share FFT tables and other parameters i
1. Provides an unified and simple FFT/IFFT interface. Users no longer need to worry about their FFT results being affected by other programs. All FFT tables are allocated and released within the function scope.
2. Reimplements an int16 FFT/IFFT. Dynamic quantization is used during butterfly operations to achieve better precision.
3. [TODO] Uses built-in FFT instructions on ESP32-S3 and ESP32-P4 to further accelerate int16 FFT/IFFT.
3. Uses built-in FFT instructions on ESP32-S3 and ESP32-P4 to further accelerate int16 FFT/IFFT.
## Benchmark

View File

@ -239,7 +239,7 @@ uint16_t *dl_gen_bitrev2r_table(int N, uint32_t caps, int *bitrev_size)
return bitrev_table;
}
float *dl_gen_fftr2_table_f32(int fft_point, uint32_t caps)
float *dl_gen_fft2r_table_f32(int fft_point, uint32_t caps)
{
float *fft_table = (float *)heap_caps_aligned_alloc(16, fft_point * sizeof(float), caps);

View File

@ -367,30 +367,6 @@ static inline unsigned short reverse_sc16(unsigned short x, unsigned short N, in
return b >> (16 - order);
}
esp_err_t dl_bitrev2r_sc16_ansi(int16_t *data, int N)
{
esp_err_t result = ESP_OK;
int j, k;
uint32_t temp;
uint32_t *in_data = (uint32_t *)data;
j = 0;
for (int i = 1; i < (N - 1); i++) {
k = N >> 1;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
if (i < j) {
temp = in_data[j];
in_data[j] = in_data[i];
in_data[i] = temp;
}
}
return result;
}
esp_err_t dl_cplx2reC_sc16(int16_t *data, int N)
{
esp_err_t result = ESP_OK;
@ -429,77 +405,6 @@ esp_err_t dl_cplx2reC_sc16(int16_t *data, int N)
return result;
}
esp_err_t dl_rfft_post_proc_sc16_ansi(int16_t *data, int N, int16_t *table)
{
dl_sc16_t *result = (dl_sc16_t *)data;
// Original formula...
// result[0].re = result[0].re + result[0].im;
// result[N].re = result[0].re - result[0].im;
// result[0].im = 0;
// result[N].im = 0;
// Optimized one:
int32_t tmp_re = result[0].re + 1;
result[0].re = (tmp_re + result[0].im) >> 1;
result[0].im = (tmp_re - result[0].im) >> 1;
int round = 1 << 16;
int32_t f1k_re, f1k_im, f2k_re, f2k_im, tw_re, tw_im;
for (int k = 1; k <= N / 2; k++) {
dl_sc16_t fpk = result[k];
dl_sc16_t fpnk = result[N - k];
f1k_re = fpk.re + fpnk.re;
f1k_im = fpk.im - fpnk.im;
f2k_re = fpk.re - fpnk.re;
f2k_im = fpk.im + fpnk.im;
int16_t c = -table[k * 2 - 1];
int16_t s = -table[k * 2 - 2];
tw_re = c * f2k_re - s * f2k_im;
tw_im = s * f2k_re + c * f2k_im;
f1k_re = f1k_re << 15;
f1k_im = f1k_im << 15;
result[k].re = (f1k_re + tw_re + round) >> 17;
result[k].im = (f1k_im + tw_im + round) >> 17;
result[N - k].re = (f1k_re - tw_re + round) >> 17;
result[N - k].im = (tw_im - f1k_im + round) >> 17;
}
return ESP_OK;
}
esp_err_t dl_rfft_pre_proc_sc16_ansi(int16_t *data, int N, int16_t *table)
{
dl_sc16_t *result = (dl_sc16_t *)data;
int32_t tmp_re = result[0].re + 2;
result[0].re = (tmp_re + result[0].im) >> 2;
result[0].im = (tmp_re - result[0].im) >> 2;
int round = 1 << 16;
int32_t f1k_re, f1k_im, f2k_re, f2k_im, tw_re, tw_im;
for (int k = 1; k <= N / 2; k++) {
dl_sc16_t fpk = result[k];
dl_sc16_t fpnk = result[N - k];
f1k_re = fpk.re + fpnk.re;
f1k_im = fpk.im - fpnk.im;
f2k_re = fpk.re - fpnk.re;
f2k_im = fpk.im + fpnk.im;
int16_t c = -table[k * 2 - 1];
int16_t s = table[k * 2 - 2];
tw_re = c * f2k_re - s * f2k_im;
tw_im = s * f2k_re + c * f2k_im;
f1k_re = f1k_re << 15;
f1k_im = f1k_im << 15;
result[k].re = (f1k_re + tw_re + round) >> 17;
result[k].im = (f1k_im + tw_im + round) >> 17;
result[N - k].re = (f1k_re - tw_re + round) >> 17;
result[N - k].im = (tw_im - f1k_im + round) >> 17;
}
return ESP_OK;
}
esp_err_t dl_cplx2real_sc16_hp_ansi(int16_t *data, int N, int16_t *table, int *shift)
{
dl_sc16_t *result = (dl_sc16_t *)data;
@ -557,7 +462,7 @@ int16_t *dl_gen_fft_table_sc16(int fft_point, uint32_t caps)
fft_table[2 * i] = (int16_t)roundf(INT16_MAX * cosf(i * e));
fft_table[2 * i + 1] = (int16_t)roundf(INT16_MAX * sinf(i * e));
}
dl_bitrev2r_sc16_ansi(fft_table, fft_point >> 1);
dl_bitrev2r_sc16(fft_table, fft_point >> 1, 0);
}
return fft_table;

View File

@ -0,0 +1,239 @@
#include "dl_fft_base.h"
int16_t *dl_gen_dif_fft_table(int N, uint32_t caps)
{
int16_t *table = (int16_t *)heap_caps_aligned_alloc(16, N * 2 * sizeof(int16_t), caps);
if (!table)
return NULL;
float base_angle = (float)(M_PI * 2.0) / N;
int offset = 0;
int log2N = dl_power_of_two(N);
int scale = 1 << DL_FFT_DIF_SC16_TABLE_BITS; // scale twiddle factors to fit in int16 with some headroom for
// intermediate growth
for (int stage = 0; stage < log2N; stage++) {
int stride = 1 << stage;
int num_tw = N >> (stage + 1);
for (int k = 0; k < num_tw; k++) {
float angle = k * stride * base_angle;
table[offset * 2] = (int16_t)roundf(scale * cosf(angle));
table[offset * 2 + 1] = (int16_t)roundf(scale * sinf(angle));
offset++;
}
}
return table;
}
int16_t *dl_gen_dif_rfft_table(int N, uint32_t caps)
{
int16_t *fft_table = (int16_t *)heap_caps_aligned_alloc(16, N * sizeof(int16_t), caps);
int scale = 1 << DL_FFT_DIF_SC16_TABLE_BITS;
if (fft_table) {
for (int i = 0; i < N / 2; i++) {
double phase = -M_PI * ((i + 1.0) / N + 0.5);
fft_table[i * 2 + 0] = (int16_t)round(cos(phase) * scale);
fft_table[i * 2 + 1] = (int16_t)round(sin(phase) * scale);
}
}
return fft_table;
}
void dl_fft2r_sc16_dif_ansi(int16_t *data, int16_t *table, int shift, int num_stages, int N)
{
int half_size = N >> 1;
int num_groups = 1;
int tw_offset = 0;
int rnd = 1 << (shift - 1);
for (int stage = 0; stage < num_stages; stage++) {
for (int g = 0; g < num_groups; g++) {
int base = g * (half_size << 1);
for (int k = 0; k < half_size; k++) {
int ui = base + k;
int li = ui + half_size;
int16_t a_re = data[ui * 2];
int16_t a_im = data[ui * 2 + 1];
int16_t b_re = data[li * 2];
int16_t b_im = data[li * 2 + 1];
int32_t sum_re = (((int32_t)a_re + b_re) << 14) + rnd;
int32_t sum_im = (((int32_t)a_im + b_im) << 14) + rnd;
data[ui * 2] = (int16_t)(sum_re >> shift);
data[ui * 2 + 1] = (int16_t)(sum_im >> shift);
// int32_t sum_re = (((int32_t)a_re + b_re));
// int32_t sum_im = (((int32_t)a_im + b_im));
// data[ui * 2] = (int16_t)(sum_re >> 1);
// data[ui * 2 + 1] = (int16_t)(sum_im >> 1);
int32_t d_re = (int32_t)a_re - b_re;
int32_t d_im = (int32_t)a_im - b_im;
int16_t w_re = table[(tw_offset + k) * 2];
int16_t w_im = table[(tw_offset + k) * 2 + 1];
int32_t lo_re = d_re * w_re + d_im * w_im + rnd;
int32_t lo_im = d_im * w_re - d_re * w_im + rnd;
data[li * 2] = (int16_t)(lo_re >> shift);
data[li * 2 + 1] = (int16_t)(lo_im >> shift);
}
}
tw_offset += half_size;
half_size >>= 1;
num_groups <<= 1;
}
}
void dl_fft2r_sc16_dif(int16_t *data, int16_t *table, int shift, int num_stages, int N)
{
if (num_stages >= 3 && num_stages <= 10) {
dl_fft2r_sc16_dif_asm(data, table, shift, num_stages, N);
} else {
dl_fft2r_sc16_dif_ansi(data, table, shift, num_stages, N);
}
}
void dl_ifft2r_sc16_dif_ansi(int16_t *data, int16_t *table, int shift, int num_stages, int N)
{
int half_size = N >> 1;
int num_groups = 1;
int tw_offset = 0;
for (int stage = 0; stage < num_stages; stage++) {
for (int g = 0; g < num_groups; g++) {
int base = g * (half_size << 1);
for (int k = 0; k < half_size; k++) {
int ui = base + k;
int li = ui + half_size;
int16_t a_re = data[ui * 2];
int16_t a_im = data[ui * 2 + 1];
int16_t b_re = data[li * 2];
int16_t b_im = data[li * 2 + 1];
int32_t sum_re = (int32_t)a_re + b_re;
int32_t sum_im = (int32_t)a_im + b_im;
data[ui * 2] = (int16_t)(sum_re >> 1);
data[ui * 2 + 1] = (int16_t)(sum_im >> 1);
int32_t d_re = (int32_t)a_re - b_re;
int32_t d_im = (int32_t)a_im - b_im;
int16_t w_re = table[(tw_offset + k) * 2];
int16_t w_im = table[(tw_offset + k) * 2 + 1];
// For IFFT, multiply by W_N^{-k} = cos + i*sin
// (d_re + i*d_im) * (w_re + i*w_im) = (d_re*w_re - d_im*w_im) + i*(d_im*w_re + d_re*w_im)
int32_t lo_re = d_re * w_re - d_im * w_im;
int32_t lo_im = d_im * w_re + d_re * w_im;
data[li * 2] = (int16_t)(lo_re >> shift);
data[li * 2 + 1] = (int16_t)(lo_im >> shift);
}
}
tw_offset += half_size;
half_size >>= 1;
num_groups <<= 1;
}
}
void dl_fft2r_sc16_dif_hp_ansi(int16_t *data, int16_t *table, int num_stages, int N, int *out_shift)
{
int half_size = N >> 1;
int num_groups = 1;
int tw_offset = 0;
int loop_shift = 0;
int add_rount_mult = 0;
out_shift[0] = 0;
for (int stage = 0; stage < num_stages; stage++) {
loop_shift = dl_array_max_q_s16(data, N * 2);
add_rount_mult = 1 << (loop_shift - 1);
out_shift[0] += loop_shift - DL_FFT_DIF_SC16_TABLE_BITS;
for (int g = 0; g < num_groups; g++) {
int base = g * (half_size << 1);
for (int k = 0; k < half_size; k++) {
int ui = base + k;
int li = ui + half_size;
int32_t a_re = data[ui * 2];
int32_t a_im = data[ui * 2 + 1];
int32_t b_re = data[li * 2];
int32_t b_im = data[li * 2 + 1];
int32_t sum_re = ((a_re + b_re) << DL_FFT_DIF_SC16_TABLE_BITS) + add_rount_mult;
int32_t sum_im = ((a_im + b_im) << DL_FFT_DIF_SC16_TABLE_BITS) + add_rount_mult;
data[ui * 2] = (int16_t)(sum_re >> loop_shift);
data[ui * 2 + 1] = (int16_t)(sum_im >> loop_shift);
int32_t d_re = a_re - b_re;
int32_t d_im = a_im - b_im;
int32_t w_re = table[(tw_offset + k) * 2];
int32_t w_im = table[(tw_offset + k) * 2 + 1];
int32_t lo_re = d_re * w_re + d_im * w_im + add_rount_mult;
int32_t lo_im = d_im * w_re - d_re * w_im + add_rount_mult;
data[li * 2] = (int16_t)(lo_re >> loop_shift);
data[li * 2 + 1] = (int16_t)(lo_im >> loop_shift);
}
}
tw_offset += half_size;
half_size >>= 1;
num_groups <<= 1;
}
}
void dl_fft2r_sc16_dif_hp(int16_t *data, int16_t *table, int num_stages, int N, int *out_shift)
{
if (num_stages >= 3 && num_stages <= 10) {
dl_fft2r_sc16_dif_hp_asm(data, table, num_stages, N, out_shift);
} else {
dl_fft2r_sc16_dif_hp_ansi(data, table, num_stages, N, out_shift);
}
}
void dl_ifft2r_sc16_dif_hp_ansi(int16_t *data, int16_t *table, int num_stages, int N, int *out_shift)
{
int half_size = N >> 1;
int num_groups = 1;
int tw_offset = 0;
int loop_shift = 0;
int add_rount_mult = 0;
out_shift[0] = 0;
for (int stage = 0; stage < num_stages; stage++) {
loop_shift = dl_array_max_q_s16(data, N * 2);
add_rount_mult = 1 << (loop_shift - 1);
out_shift[0] += loop_shift - DL_FFT_DIF_SC16_TABLE_BITS;
for (int g = 0; g < num_groups; g++) {
int base = g * (half_size << 1);
for (int k = 0; k < half_size; k++) {
int ui = base + k;
int li = ui + half_size;
int32_t a_re = data[ui * 2];
int32_t a_im = data[ui * 2 + 1];
int32_t b_re = data[li * 2];
int32_t b_im = data[li * 2 + 1];
int32_t sum_re = ((a_re + b_re) << DL_FFT_DIF_SC16_TABLE_BITS) + add_rount_mult;
int32_t sum_im = ((a_im + b_im) << DL_FFT_DIF_SC16_TABLE_BITS) + add_rount_mult;
data[ui * 2] = (int16_t)(sum_re >> loop_shift);
data[ui * 2 + 1] = (int16_t)(sum_im >> loop_shift);
int32_t d_re = a_re - b_re;
int32_t d_im = a_im - b_im;
int32_t w_re = table[(tw_offset + k) * 2];
int32_t w_im = table[(tw_offset + k) * 2 + 1];
int32_t lo_re = d_re * w_re - d_im * w_im + add_rount_mult;
int32_t lo_im = d_im * w_re + d_re * w_im + add_rount_mult;
data[li * 2] = (int16_t)(lo_re >> loop_shift);
data[li * 2 + 1] = (int16_t)(lo_im >> loop_shift);
}
}
tw_offset += half_size;
half_size >>= 1;
num_groups <<= 1;
}
}

View File

@ -40,25 +40,31 @@ float *dl_short_to_float(const int16_t *x, int len, int exponent, float *y)
return y;
}
int16_t dl_reduce_abs_max_ansi(const int16_t *x, int size)
{
int16_t max_val = 0;
for (int i = 0; i < size; i++) {
int32_t abs_val = x[i] < 0 ? -(int32_t)x[i] : (int32_t)x[i];
if (abs_val > INT16_MAX)
abs_val = INT16_MAX;
if ((int16_t)abs_val > max_val)
max_val = (int16_t)abs_val;
}
return max_val;
}
int16_t dl_array_max_q_s16(const int16_t *x, int size)
{
int16_t max = 0;
for (int i = 1; i < size; i++) {
if (x[i] > max) {
max = x[i];
} else if (-x[i] > max) {
max = -x[i];
}
}
int16_t max_abs = dl_reduce_abs_max(x, size);
if (max == 0) {
if (max_abs == 0) {
return 1;
}
int16_t k = 2;
while (max > 1) {
while (max_abs > 1) {
k++;
max = max >> 1;
max_abs = max_abs >> 1;
}
return k;
@ -90,3 +96,172 @@ int dl_float_to_short(const float *x, int len, int16_t *y, int out_exponent)
return -exponent;
}
esp_err_t dl_bitrev2r_sc16_ansi(int16_t *data, int N, int log2N)
{
esp_err_t result = ESP_OK;
int j, k;
uint32_t temp;
uint32_t *in_data = (uint32_t *)data;
j = 0;
for (int i = 1; i < (N - 1); i++) {
k = N >> 1;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
if (i < j) {
temp = in_data[j];
in_data[j] = in_data[i];
in_data[i] = temp;
}
}
return result;
}
esp_err_t dl_bitrev2r_sc16(int16_t *data, int N, int log2N)
{
if (N <= 1024 && N >= 8) {
dl_bitrev2r_sc16_asm(data, N, log2N);
} else {
return dl_bitrev2r_sc16_ansi(data, N, log2N);
}
return ESP_OK;
}
esp_err_t dl_rfft_post_proc_sc16_ansi(int16_t *data, int cpx_points, int16_t *win)
{
int32_t dc_val = data[0] + data[1];
int32_t nq_val = data[0] - data[1];
data[0] = dc_val;
data[1] = nq_val;
int16_t *in_f = data + 2;
int16_t *in_b = data + cpx_points * 2 - 2;
int16_t *tw = win;
int16_t *out_f = data + 2;
int16_t *out_b = data + cpx_points * 2 - 2;
int loop_points = cpx_points / 2;
for (int k = 1; k <= loop_points; k++) {
int16_t fr = in_f[0], fi = in_f[1];
int16_t br = in_b[0], bi = in_b[1];
int16_t wr = tw[0], wi = tw[1];
in_f += 2;
in_b -= 2;
tw += 2;
int32_t sum_r = fr + br;
int32_t sum_i = fi - bi;
int32_t diff_r = fr - br;
int32_t diff_i = fi + bi;
int32_t tw_r = (diff_r * wr - diff_i * wi) >> 14;
int32_t tw_i = (diff_i * wr + diff_r * wi) >> 14;
out_f[0] = (int16_t)((sum_r + tw_r) >> 1);
out_f[1] = (int16_t)((sum_i + tw_i) >> 1);
out_b[0] = (int16_t)((sum_r - tw_r) >> 1);
out_b[1] = (int16_t)((tw_i - sum_i) >> 1);
out_f += 2;
out_b -= 2;
}
return ESP_OK;
}
int dl_rfft_pre_proc_sc16(int16_t *data, int cpx_points, int16_t *table)
{
int shift = 0;
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
int max_q = dl_array_max_q_s16(data, cpx_points * 2);
if (max_q >= 15) {
for (int i = 0; i < cpx_points * 2; i++) {
data[i] = data[i] >> 1;
}
shift = 1;
}
#endif
dl_rfft_pre_proc_sc16_asm(data, cpx_points, table);
return shift;
}
/*
* Wrapper that protects dl_rfft_post_proc_sc16_asm from int16 overflow.
*
* The underlying _asm/_ansi implementations compute (sum_r + tw_r) >> 1 in
* 16-bit precision (the SIMD AMS hardware truncates the sum to 16 bits before
* the built-in `>> 1` store, dropping bit 16). When the input data uses the
* full int16 range (e.g. high-precision FFT output), |sum_r + tw_r| can exceed
* 32767 and the truncation produces a result that is 32768 off from the
* mathematically correct value.
*
* To avoid this, we pre-shift the data right by 1 whenever the abs-max
* indicates the data is in int16 range, so all intermediate (sum_r + tw_r)
* values stay within int16. The caller must compensate by adding the returned
* shift to the output exponent.
*/
int dl_rfft_post_proc_sc16(int16_t *data, int cpx_points, int16_t *table)
{
int shift = 0;
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
int max_q = dl_array_max_q_s16(data, cpx_points * 2);
if (max_q >= 15) {
for (int i = 0; i < cpx_points * 2; i++) {
data[i] = data[i] >> 1;
}
shift = 1;
}
#endif
dl_rfft_post_proc_sc16_asm(data, cpx_points, table);
return shift;
}
esp_err_t dl_rfft_pre_proc_sc16_ansi(int16_t *data, int cpx_points, int16_t *table)
{
int32_t dc_val = data[0];
int32_t nq_val = data[1];
int32_t a0 = dc_val + nq_val;
int32_t a1 = dc_val - nq_val;
data[0] = (int16_t)a0;
data[1] = (int16_t)a1;
int16_t *in_f = data + 2;
int16_t *in_b = data + cpx_points * 2 - 2;
int16_t *tw = table;
int16_t *out_f = data + 2;
int16_t *out_b = data + cpx_points * 2 - 2;
int loop_points = cpx_points / 2;
for (int k = 1; k <= loop_points; k++) {
int16_t pr = in_f[0], pi = in_f[1];
int16_t qr = in_b[0], qi = in_b[1];
int16_t wr = tw[0], wi = tw[1];
in_f += 2;
in_b -= 2;
tw += 2;
int32_t sum_r = pr + qr;
int32_t sum_i = pi - qi;
int32_t diff_r = pr - qr;
int32_t diff_i = pi + qi;
int32_t tw_r = (diff_r * wr + diff_i * wi) >> 14;
int32_t tw_i = (diff_i * wr - diff_r * wi) >> 14;
out_f[0] = (int16_t)(sum_r + tw_r);
out_f[1] = (int16_t)(sum_i + tw_i);
out_b[0] = (int16_t)(sum_r - tw_r);
out_b[1] = (int16_t)(tw_i - sum_i);
out_f += 2;
out_b -= 2;
}
return ESP_OK;
}

View File

@ -14,15 +14,18 @@ extern "C" {
#include "dl_fft_platform.h"
#define DL_FFT_DIF_SC16_TABLE_BITS 14
// common function
bool dl_is_power_of_two(int x);
int dl_power_of_two(uint32_t n);
float *dl_short_to_float(const int16_t *x, int len, int exponent, float *y);
int16_t dl_array_max_q_s16(const int16_t *x, int size);
int16_t dl_reduce_abs_max_ansi(const int16_t *x, int size);
int dl_float_to_short(const float *x, int len, int16_t *y, int out_exponent);
// float fftr2
float *dl_gen_fftr2_table_f32(int fft_point, uint32_t caps);
float *dl_gen_fft2r_table_f32(int fft_point, uint32_t caps);
uint16_t *dl_gen_bitrev2r_table(int N, uint32_t caps, int *bitrev_size);
esp_err_t dl_fft2r_fc32_ansi(float *data, int N, float *w);
@ -40,10 +43,22 @@ esp_err_t dl_ifft4r_fc32_ansi(float *data, int length, float *table, int table_s
esp_err_t dl_bitrev4r_fc32_ansi(float *data, int N, uint16_t *reverse_tab, int bitrev_size);
esp_err_t dl_rfft_post_proc_fc32_ansi(float *data, int N, float *table);
esp_err_t dl_rfft_pre_proc_fc32_ansi(float *data, int N, float *table);
int dl_rfft_pre_proc_sc16(int16_t *data, int cpx_points, int16_t *table);
// int16 fft and rfft
int16_t *dl_gen_fft_table_sc16(int fft_point, uint32_t caps);
int16_t *dl_gen_rfft_table_s16(int fft_point, uint32_t caps);
int16_t *dl_gen_dif_fft_table(int N, uint32_t caps);
int16_t *dl_gen_dif_rfft_table(int fft_point, uint32_t caps);
esp_err_t dl_bitrev2r_sc16_ansi(int16_t *data, int N, int log2N);
esp_err_t dl_bitrev2r_sc16(int16_t *data, int N, int log2N);
void dl_fft2r_sc16_dif_ansi(int16_t *data, int16_t *table, int shift, int num_stages, int N);
void dl_fft2r_sc16_dif(int16_t *data, int16_t *table, int shift, int num_stages, int N);
void dl_ifft2r_sc16_dif_ansi(int16_t *data, int16_t *table, int shift, int num_stages, int N);
void dl_fft2r_sc16_dif_hp_ansi(int16_t *data, int16_t *table, int num_stages, int N, int *out_shift);
void dl_fft2r_sc16_dif_hp(int16_t *data, int16_t *table, int num_stages, int N, int *out_shift);
void dl_ifft2r_sc16_dif_hp_ansi(int16_t *data, int16_t *table, int num_stages, int N, int *out_shift);
esp_err_t dl_fft2r_sc16_hp_ansi(int16_t *data, int N, int16_t *table, int *shift);
esp_err_t dl_fft2r_sc16_ansi(int16_t *data, int N, int16_t *table);
@ -51,11 +66,19 @@ esp_err_t dl_fft2r_sc16_ansi(int16_t *data, int N, int16_t *table);
esp_err_t dl_ifft2r_sc16_hp_ansi(int16_t *data, int N, int16_t *table, int *shift);
esp_err_t dl_ifft2r_sc16_ansi(int16_t *data, int N, int16_t *table);
esp_err_t dl_bitrev2r_sc16_ansi(int16_t *data, int N);
esp_err_t dl_rfft_post_proc_sc16_ansi(int16_t *data, int N, int16_t *table);
esp_err_t dl_rfft_pre_proc_sc16_ansi(int16_t *data, int N, int16_t *table);
esp_err_t dl_cplx2real_sc16_hp_ansi(int16_t *data, int N, int16_t *table, int *shift);
/* Pre-shifts input by 1 if needed (to avoid int16 overflow in
* dl_rfft_post_proc_sc16_asm), then runs the post-processing.
* Returns the number of right shifts applied (0 or 1) so the caller can
* adjust the output exponent. */
int dl_rfft_post_proc_sc16(int16_t *data, int cpx_points, int16_t *table);
// int16_t *dl_gen_dif_rfft_table(int N, uint32_t caps);
// int16_t *dl_gen_dif_rfft_table2(int N, uint32_t caps);
#if CONFIG_IDF_TARGET_ESP32
#define dl_fft2r_fc32 dl_fft2r_fc32_ae32_
#define dl_ifft2r_fc32 dl_ifft2r_fc32_ae32_
@ -78,6 +101,36 @@ esp_err_t dl_cplx2real_sc16_hp_ansi(int16_t *data, int N, int16_t *table, int *s
#define dl_ifft4r_fc32 dl_ifft4r_fc32_ansi
#endif
#if CONFIG_IDF_TARGET_ESP32S3
#define dl_reduce_abs_max dl_reduce_abs_max_aes3_
#define dl_fft2r_sc16_dif_asm dl_fft2r_sc16_dif_aes3_
#define dl_fft2r_sc16_dif_hp_asm dl_fft2r_sc16_dif_hp_aes3_
#define dl_bitrev2r_sc16_asm dl_bitrev2r_sc16_aes3_
#define dl_ifft2r_sc16_dif_hp dl_ifft2r_sc16_dif_hp_aes3_
#define dl_ifft2r_sc16_dif dl_ifft2r_sc16_dif_aes3_
#define dl_rfft_post_proc_sc16_asm dl_rfft_post_proc_sc16_aes3_
#define dl_rfft_pre_proc_sc16_asm dl_rfft_pre_proc_sc16_aes3_
#elif !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 && \
((IDF_VERSION_MAJOR == 5 && IDF_VERSION_MINOR == 5) || IDF_VERSION_MAJOR > 5)
#define dl_reduce_abs_max dl_reduce_abs_max_arp4_
#define dl_fft2r_sc16_dif_asm dl_fft2r_sc16_dif_arp4_
#define dl_fft2r_sc16_dif_hp_asm dl_fft2r_sc16_dif_hp_arp4_
#define dl_bitrev2r_sc16_asm dl_bitrev2r_sc16_arp4_
#define dl_ifft2r_sc16_dif_hp dl_ifft2r_sc16_dif_hp_arp4_
#define dl_ifft2r_sc16_dif dl_ifft2r_sc16_dif_arp4_
#define dl_rfft_post_proc_sc16_asm dl_rfft_post_proc_sc16_ansi
#define dl_rfft_pre_proc_sc16_asm dl_rfft_pre_proc_sc16_ansi
#else
#define dl_reduce_abs_max dl_reduce_abs_max_ansi
#define dl_fft2r_sc16_dif_asm dl_fft2r_sc16_dif_ansi
#define dl_fft2r_sc16_dif_hp_asm dl_fft2r_sc16_dif_hp_ansi
#define dl_bitrev2r_sc16_asm dl_bitrev2r_sc16_ansi
#define dl_ifft2r_sc16_dif_hp dl_ifft2r_sc16_dif_hp_ansi
#define dl_ifft2r_sc16_dif dl_ifft2r_sc16_dif_ansi
#define dl_rfft_post_proc_sc16_asm dl_rfft_post_proc_sc16_ansi
#define dl_rfft_pre_proc_sc16_asm dl_rfft_pre_proc_sc16_ansi
#endif
#define dl_fft2r_sc16 dl_fft2r_sc16_ansi
#define dl_fft2r_sc16_hp dl_fft2r_sc16_hp_ansi
#define dl_ifft2r_sc16 dl_ifft2r_sc16_ansi

View File

@ -15,20 +15,30 @@ void dl_fft2r_fc32_aes3_(float *data, int N, float *table);
void dl_ifft2r_fc32_aes3_(float *data, int N, float *table);
void dl_fft4r_fc32_aes3_(float *data, int N, float *table, int table_size);
void dl_ifft4r_fc32_aes3_(float *data, int N, float *table, int table_size);
// void test_radix2_fft_bf_s16(int16_t *data, int16_t *table, int16_t fft_point, int16_t log2n, int16_t);
// int test_radix2_fft_bf_s16_hp(int16_t *, int16_t *, int16_t, int16_t, int16_t);
// void test_radix2_bit_reverse(int16_t *data, int16_t cpx_point, int16_t log2n);
// void test_fftr_s16(int16_t *, int16_t *, int16_t);
// void test_ffti_s16(int16_t *, int16_t *, int16_t);
// void test_radix2_ifft_bf_s16(int16_t *, int16_t *, int16_t, int16_t, int16_t);
// int test_radix2_ifft_bf_s16_hp(int16_t *, int16_t *, int16_t, int16_t, int16_t);
int16_t dl_fft_reduce_max_aes3_(const int16_t *inputs, int len);
int16_t dl_reduce_abs_max_aes3_(const int16_t *inputs, int len);
void dl_bitrev2r_sc16_aes3_(int16_t *data, int cpx_points, int log2N);
esp_err_t dl_rfft_post_proc_sc16_aes3_(int16_t *data, int N, int16_t *table);
esp_err_t dl_rfft_pre_proc_sc16_aes3_(int16_t *data, int N, int16_t *table);
void test_fftr_s16(int16_t *, int16_t *, int16_t);
void test_ffti_s16(int16_t *, int16_t *, int16_t);
void dl_fft2r_sc16_dif_aes3_(int16_t *data, int16_t *table, int shift, int num_stages, int cpx_points);
void dl_ifft2r_sc16_dif_aes3_(int16_t *data, int16_t *table, int shift, int num_stages, int cpx_points);
void dl_fft2r_sc16_dif_hp_aes3_(int16_t *data, int16_t *table, int num_stages, int cpx_points, int *out_shift);
void dl_ifft2r_sc16_dif_hp_aes3_(int16_t *data, int16_t *table, int num_stages, int cpx_points, int *out_shift);
int test_radix2_fft_bf_s16_hp(int16_t *data, int16_t *table, int shift, int num_stages, int cpx_points);
#elif CONFIG_IDF_TARGET_ESP32P4
void dl_fft2r_fc32_arp4_(float *data, int N, float *table);
void dl_ifft2r_fc32_arp4_(float *data, int N, float *table);
void dl_fft4r_fc32_arp4_(float *data, int N, float *table, int table_size);
void dl_ifft4r_fc32_arp4_(float *data, int N, float *table, int table_size);
int16_t dl_fft_reduce_max_arp4_(const int16_t *inputs, int len);
int16_t dl_reduce_abs_max_arp4_(const int16_t *inputs, int len);
void dl_bitrev2r_sc16_arp4_(int16_t *data, int cpx_points, int log2N);
void dl_fft2r_sc16_dif_arp4_(int16_t *data, int16_t *table, int shift, int num_stages, int cpx_points);
void dl_ifft2r_sc16_dif_arp4_(int16_t *data, int16_t *table, int shift, int num_stages, int cpx_points);
void dl_fft2r_sc16_dif_hp_arp4_(int16_t *data, int16_t *table, int num_stages, int cpx_points, int *out_shift);
void dl_ifft2r_sc16_dif_hp_arp4_(int16_t *data, int16_t *table, int num_stages, int cpx_points, int *out_shift);
#endif
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,64 +2,68 @@
| Test Name | Size | SNR (dB) | RMSE | Time (μs) |
|-----------------------|----------|--------------|------------|---------------|
| 1. test dl fft | 128 | 104.868538 | 0.000316 | 38 |
| | 256 | 107.637619 | 0.000316 | 85 |
| | 512 | 110.548630 | 0.000316 | 188 |
| | 1024 | 113.582832 | 0.000316 | 415 |
| | 2048 | 116.905914 | 0.000316 | 904 |
| 2. test dl ifft | 128 | 85.701355 | 0.000316 | 46 |
| | 256 | 85.375244 | 0.000316 | 99 |
| | 512 | 85.372276 | 0.000316 | 217 |
| | 1024 | 85.351921 | 0.000316 | 471 |
| | 2048 | 85.206238 | 0.000316 | 1017 |
| 3. test dl rfft | 128 | 101.360046 | 0.000316 | 18 |
| | 256 | 105.289742 | 0.000316 | 44 |
| | 512 | 107.978775 | 0.000316 | 88 |
| | 1024 | 110.488144 | 0.000316 | 212 |
| | 2048 | 113.904335 | 0.000316 | 416 |
| 4. test dl irfft | 128 | 85.467148 | 0.000316 | 22 |
| | 256 | 85.928154 | 0.000316 | 52 |
| | 512 | 84.540436 | 0.000316 | 102 |
| | 1024 | 85.282562 | 0.000316 | 244 |
| | 2048 | 85.383667 | 0.000316 | 465 |
| 5. test dl fft s16 | 128 | 65.917183 | 0.001719 | 60 |
| | 256 | 61.950771 | 0.003524 | 135 |
| | 512 | 59.240242 | 0.006614 | 299 |
| | 1024 | 56.814144 | 0.013190 | 654 |
| | 2048 | 53.681591 | 0.026223 | 1422 |
| 6. test dl ifft s16 | 128 | 59.837440 | 0.000527 | 61 |
| | 256 | 52.158340 | 0.000902 | 137 |
| | 512 | 51.414349 | 0.000917 | 303 |
| | 1024 | 51.119301 | 0.000960 | 663 |
| | 2048 | 45.654255 | 0.001737 | 1439 |
| 7. test dl fft hp s16 | 128 | 76.132126 | 0.000621 | 79 |
| | 256 | 73.598412 | 0.000975 | 177 |
| | 512 | 72.596603 | 0.001546 | 384 |
| | 1024 | 73.045952 | 0.002084 | 853 |
| | 2048 | 69.902023 | 0.004387 | 1826 |
| 8. test dl ifft hp s16 | 128 | 72.633217 | 0.000327 | 80 |
| | 256 | 71.462891 | 0.000328 | 180 |
| | 512 | 68.908401 | 0.000334 | 389 |
| | 1024 | 68.920097 | 0.000335 | 862 |
| | 2048 | 67.777245 | 0.000345 | 1842 |
| 9. test dl rfft s16 | 128 | 63.782593 | 0.001403 | 32 |
| | 256 | 60.652668 | 0.002885 | 70 |
| | 512 | 58.204708 | 0.005433 | 154 |
| | 1024 | 54.490803 | 0.011284 | 337 |
| | 2048 | 51.854618 | 0.022304 | 730 |
| 10. test dl irfft s16 | 128 | 57.822262 | 0.000596 | 32 |
| | 256 | 52.207390 | 0.000937 | 71 |
| | 512 | 50.153603 | 0.000984 | 155 |
| | 1024 | 45.564911 | 0.001740 | 338 |
| | 2048 | 40.217754 | 0.003298 | 733 |
| 11. test dl rfft hp s16 | 128 | 75.728333 | 0.000464 | 41 |
| | 256 | 74.201035 | 0.000730 | 88 |
| | 512 | 72.743904 | 0.001103 | 196 |
| | 1024 | 72.959915 | 0.001432 | 422 |
| | 2048 | 70.298073 | 0.002952 | 928 |
| 12. test dl irfft hp s16 | 128 | 72.830231 | 0.000324 | 41 |
| | 256 | 71.144485 | 0.000330 | 89 |
| | 512 | 67.758896 | 0.000338 | 198 |
| | 1024 | 69.508110 | 0.000335 | 424 |
| | 2048 | 67.428802 | 0.000346 | 933 |
| 1. test dl fft | 128 | 104.9 | 0.000316 | 34 |
| | 256 | 107.6 | 0.000316 | 76 |
| | 512 | 110.5 | 0.000316 | 169 |
| | 1024 | 113.6 | 0.000316 | 372 |
| | 2048 | 116.9 | 0.000316 | 811 |
| 2. test dl ifft | 128 | 85.7 | 0.000316 | 40 |
| | 256 | 85.4 | 0.000316 | 89 |
| | 512 | 85.4 | 0.000316 | 194 |
| | 1024 | 85.4 | 0.000316 | 423 |
| | 2048 | 85.2 | 0.000316 | 913 |
| 3. test dl rfft | 128 | 101.4 | 0.000316 | 16 |
| | 256 | 105.3 | 0.000316 | 39 |
| | 512 | 108.0 | 0.000316 | 79 |
| | 1024 | 110.5 | 0.000316 | 191 |
| | 2048 | 113.9 | 0.000316 | 376 |
| 4. test dl irfft | 128 | 85.5 | 0.000316 | 20 |
| | 256 | 85.9 | 0.000316 | 47 |
| | 512 | 84.5 | 0.000316 | 91 |
| | 1024 | 85.3 | 0.000316 | 217 |
| | 2048 | 85.4 | 0.000316 | 418 |
| 5. test dl fft s16 | 128 | 58.8 | 0.003591 | 4 |
| | 256 | 54.4 | 0.007583 | 8 |
| | 512 | 51.2 | 0.015255 | 16 |
| | 1024 | 48.5 | 0.030612 | 34 |
| | 2048 | 46.6 | 0.051513 | 1083 |
| 6. test dl ifft s16 | 128 | 50.4 | 0.001103 | 4 |
| | 256 | 42.5 | 0.002179 | 8 |
| | 512 | 43.1 | 0.002135 | 16 |
| | 1024 | 43.4 | 0.002261 | 34 |
| | 2048 | 37.9 | 0.003895 | 141 |
| 7. test dl fft hp s16 | 128 | 67.5 | 0.001742 | 13 |
| | 256 | 65.8 | 0.003011 | 26 |
| | 512 | 63.6 | 0.005801 | 55 |
| | 1024 | 63.7 | 0.009429 | 115 |
| | 2048 | 67.1 | 0.007992 | 1182 |
| 8. test dl ifft hp s16 | 128 | 69.0 | 0.000391 | 9 |
| | 256 | 65.0 | 0.000466 | 18 |
| | 512 | 64.5 | 0.000505 | 38 |
| | 1024 | 64.9 | 0.000526 | 80 |
| | 2048 | 64.4 | 0.000422 | 241 |
| 9. test dl rfft s16 | 128 | 62.5 | 0.001746 | 5 |
| | 256 | 61.0 | 0.003415 | 10 |
| | 512 | 57.9 | 0.006776 | 20 |
| | 1024 | 54.5 | 0.013945 | 42 |
| | 2048 | 51.9 | 0.027488 | 84 |
| 10. test dl irfft s16 | 128 | 60.4 | 0.000535 | 5 |
| | 256 | 54.5 | 0.000897 | 11 |
| | 512 | 51.5 | 0.000990 | 22 |
| | 1024 | 46.7 | 0.001790 | 44 |
| | 2048 | 41.7 | 0.003164 | 89 |
| 11. test dl rfft hp s16 | 128 | 68.7 | 0.000965 | 8 |
| | 256 | 67.4 | 0.001988 | 17 |
| | 512 | 67.9 | 0.002471 | 32 |
| | 1024 | 64.8 | 0.004735 | 68 |
| | 2048 | 66.2 | 0.007309 | 141 |
| 12. test dl irfft hp s16 | 128 | 67.4 | 0.000372 | 9 |
| | 256 | 67.4 | 0.000407 | 17 |
| | 512 | 66.2 | 0.000399 | 32 |
| | 1024 | 66.2 | 0.000439 | 70 |
| | 2048 | 64.4 | 0.000499 | 138 |
*Note: Only ESP32-P4 revisions greater than 3.0 support acceleration using PIE instructions. The above data was measured on the ESP32-P4 at 400 MHz.*
Generation Time: 2026-05-07

View File

@ -2,64 +2,65 @@
| Test Name | Size | SNR (dB) | RMSE | Time (μs) |
|-----------------------|----------|--------------|------------|---------------|
| 1. test dl fft | 128 | 105 | 0.000316 | 61 |
| | 256 | 108 | 0.000316 | 136 |
| | 512 | 111 | 0.000316 | 299 |
| | 1024 | 114 | 0.000316 | 653 |
| | 2048 | 117 | 0.000316 | 1413 |
| 2. test dl ifft | 128 | 85.7 | 0.000316 | 80 |
| | 256 | 85.4 | 0.000316 | 175 |
| | 512 | 85.4 | 0.000316 | 375 |
| | 1024 | 85.4 | 0.000316 | 807 |
| | 2048 | 85.2 | 0.000316 | 1721 |
| 3. test dl rfft | 128 | 101 | 0.000316 | 34 |
| | 256 | 105 | 0.000316 | 73 |
| | 512 | 108 | 0.000316 | 156 |
| | 1024 | 110 | 0.000316 | 347 |
| | 2048 | 114 | 0.000316 | 714 |
| 4. test dl irfft | 128 | 85.5 | 0.000316 | 47 |
| | 256 | 85.9 | 0.000316 | 97 |
| | 512 | 84.5 | 0.000316 | 197 |
| | 1024 | 85.3 | 0.000316 | 432 |
| | 2048 | 85.4 | 0.000316 | 868 |
| 5. test dl fft s16 | 128 | 65.9 | 0.001719 | 131 |
| | 256 | 62.0 | 0.003524 | 289 |
| | 512 | 59.2 | 0.006614 | 633 |
| | 1024 | 56.8 | 0.013190 | 1374 |
| | 2048 | 53.7 | 0.026223 | 2966 |
| 6. test dl ifft s16 | 128 | 59.8 | 0.000527 | 133 |
| | 256 | 52.2 | 0.000902 | 293 |
| | 512 | 51.4 | 0.000917 | 640 |
| | 1024 | 51.1 | 0.000960 | 1387 |
| | 2048 | 45.7 | 0.001737 | 2992 |
| 7. test dl fft hp s16 | 128 | 76.1 | 0.000621 | 189 |
| | 256 | 73.6 | 0.000975 | 424 |
| | 512 | 72.6 | 0.001546 | 914 |
| | 1024 | 73.0 | 0.002084 | 2023 |
| | 2048 | 69.9 | 0.004387 | 4322 |
| 8. test dl ifft hp s16 | 128 | 72.6 | 0.000327 | 190 |
| | 256 | 71.5 | 0.000328 | 427 |
| | 512 | 68.9 | 0.000334 | 920 |
| | 1024 | 68.9 | 0.000335 | 2036 |
| | 2048 | 67.8 | 0.000345 | 4349 |
| 9. test dl rfft s16 | 128 | 63.8 | 0.001403 | 70 |
| | 256 | 60.7 | 0.002885 | 152 |
| | 512 | 58.2 | 0.005433 | 331 |
| | 1024 | 54.5 | 0.011284 | 717 |
| | 2048 | 51.9 | 0.022304 | 1542 |
| 10. test dl irfft s16 | 128 | 57.8 | 0.000596 | 70 |
| | 256 | 52.2 | 0.000937 | 153 |
| | 512 | 50.2 | 0.000984 | 334 |
| | 1024 | 45.6 | 0.001740 | 720 |
| | 2048 | 40.2 | 0.003298 | 1547 |
| 11. test dl rfft hp s16 | 128 | 75.7 | 0.000464 | 98 |
| | 256 | 74.2 | 0.000730 | 210 |
| | 512 | 72.7 | 0.001103 | 466 |
| | 1024 | 73.0 | 0.001432 | 998 |
| | 2048 | 70.3 | 0.002952 | 2190 |
| 12. test dl irfft hp s16 | 128 | 72.8 | 0.000324 | 98 |
| | 256 | 71.1 | 0.000330 | 210 |
| | 512 | 67.8 | 0.000338 | 468 |
| | 1024 | 69.5 | 0.000335 | 1001 |
| | 2048 | 67.4 | 0.000346 | 2196 |
| 1. test dl fft | 128 | 104.9 | 0.000316 | 62 |
| | 256 | 107.6 | 0.000316 | 138 |
| | 512 | 110.5 | 0.000316 | 302 |
| | 1024 | 113.6 | 0.000316 | 658 |
| | 2048 | 116.9 | 0.000316 | 1427 |
| 2. test dl ifft | 128 | 85.7 | 0.000316 | 82 |
| | 256 | 85.4 | 0.000316 | 176 |
| | 512 | 85.4 | 0.000316 | 380 |
| | 1024 | 85.4 | 0.000316 | 813 |
| | 2048 | 85.2 | 0.000316 | 1734 |
| 3. test dl rfft | 128 | 101.4 | 0.000316 | 34 |
| | 256 | 105.3 | 0.000316 | 75 |
| | 512 | 108.0 | 0.000316 | 157 |
| | 1024 | 110.5 | 0.000316 | 352 |
| | 2048 | 113.9 | 0.000316 | 716 |
| 4. test dl irfft | 128 | 85.5 | 0.000316 | 46 |
| | 256 | 85.9 | 0.000316 | 99 |
| | 512 | 84.5 | 0.000316 | 196 |
| | 1024 | 85.3 | 0.000316 | 434 |
| | 2048 | 85.4 | 0.000316 | 864 |
| 5. test dl fft s16 | 128 | 58.8 | 0.003591 | 8 |
| | 256 | 54.4 | 0.007583 | 16 |
| | 512 | 51.2 | 0.015255 | 33 |
| | 1024 | 48.5 | 0.030612 | 70 |
| | 2048 | 46.6 | 0.051513 | 3353 |
| 6. test dl ifft s16 | 128 | 50.4 | 0.001103 | 8 |
| | 256 | 42.5 | 0.002179 | 16 |
| | 512 | 43.1 | 0.002135 | 33 |
| | 1024 | 43.4 | 0.002261 | 70 |
| | 2048 | 37.9 | 0.003895 | 344 |
| 7. test dl fft hp s16 | 128 | 67.5 | 0.001742 | 30 |
| | 256 | 65.8 | 0.003011 | 60 |
| | 512 | 63.6 | 0.005801 | 122 |
| | 1024 | 63.7 | 0.009429 | 252 |
| | 2048 | 67.1 | 0.007992 | 3302 |
| 8. test dl ifft hp s16 | 128 | 69.0 | 0.000391 | 17 |
| | 256 | 65.0 | 0.000466 | 34 |
| | 512 | 64.5 | 0.000505 | 73 |
| | 1024 | 64.9 | 0.000526 | 153 |
| | 2048 | 64.4 | 0.000422 | 522 |
| 9. test dl rfft s16 | 128 | 62.5 | 0.001746 | 6 |
| | 256 | 61.0 | 0.003415 | 11 |
| | 512 | 57.9 | 0.006776 | 21 |
| | 1024 | 54.5 | 0.013945 | 41 |
| | 2048 | 51.9 | 0.027488 | 84 |
| 10. test dl irfft s16 | 128 | 60.4 | 0.000535 | 6 |
| | 256 | 54.5 | 0.000897 | 10 |
| | 512 | 51.5 | 0.000990 | 20 |
| | 1024 | 46.7 | 0.001790 | 41 |
| | 2048 | 41.7 | 0.003164 | 83 |
| 11. test dl rfft hp s16 | 128 | 68.7 | 0.000965 | 16 |
| | 256 | 67.4 | 0.001988 | 31 |
| | 512 | 67.9 | 0.002471 | 47 |
| | 1024 | 64.8 | 0.004735 | 106 |
| | 2048 | 66.2 | 0.007309 | 220 |
| 12. test dl irfft hp s16 | 128 | 67.4 | 0.000372 | 14 |
| | 256 | 67.4 | 0.000407 | 30 |
| | 512 | 66.2 | 0.000399 | 40 |
| | 1024 | 66.2 | 0.000439 | 109 |
| | 2048 | 64.4 | 0.000499 | 225 |
Generation Time: 2026-05-07

View File

@ -1,4 +1,5 @@
#include "dl_fft.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include <math.h>
#include <string.h>
@ -25,7 +26,7 @@ dl_fft_f32_t *dl_fft_f32_init(int fft_point, uint32_t caps)
handle->log2n = dl_power_of_two(fft_point);
// Allocate and generate FFT table
handle->fft_table = dl_gen_fftr2_table_f32(fft_point, caps);
handle->fft_table = dl_gen_fft2r_table_f32(fft_point, caps);
if (!handle->fft_table) {
ESP_LOGE(TAG, "Failed to generate FFT table");
dl_fft_f32_deinit(handle);
@ -41,15 +42,15 @@ void dl_fft_f32_deinit(dl_fft_f32_t *handle)
{
if (handle) {
if (handle->fft_table) {
free(handle->fft_table);
heap_caps_free(handle->fft_table);
}
if (handle->rfft_table) {
free(handle->rfft_table);
heap_caps_free(handle->rfft_table);
}
if (handle->bitrev_table) {
free(handle->bitrev_table);
heap_caps_free(handle->bitrev_table);
}
free(handle);
heap_caps_free(handle);
}
}

View File

@ -1,4 +1,5 @@
#include "dl_fft.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include <math.h>
#include <string.h>
@ -23,10 +24,9 @@ dl_fft_s16_t *dl_fft_s16_init(int fft_point, uint32_t caps)
handle->fft_point = fft_point;
handle->log2n = dl_power_of_two(fft_point);
// Allocate and generate FFT table
handle->fft_table = dl_gen_fft_table_sc16(fft_point, caps);
handle->fft_table = dl_gen_dif_fft_table(fft_point, caps);
if (!handle->fft_table) {
ESP_LOGE(TAG, "Failed to generate FFT table");
ESP_LOGE(TAG, "Failed to generate DIF FFT table");
dl_fft_s16_deinit(handle);
return NULL;
}
@ -39,9 +39,9 @@ void dl_fft_s16_deinit(dl_fft_s16_t *handle)
{
if (handle) {
if (handle->fft_table) {
free(handle->fft_table);
heap_caps_free(handle->fft_table);
}
free(handle);
heap_caps_free(handle);
}
}
@ -53,8 +53,8 @@ esp_err_t dl_fft_s16_run(dl_fft_s16_t *handle, int16_t *data, int in_exponent, i
}
int fft_point = handle->fft_point;
dl_fft2r_sc16(data, fft_point, handle->fft_table);
dl_bitrev2r_sc16_ansi(data, fft_point);
dl_fft2r_sc16_dif(data, handle->fft_table, 15, handle->log2n, fft_point);
dl_bitrev2r_sc16(data, fft_point, handle->log2n);
out_exponent[0] = in_exponent + handle->log2n;
return ESP_OK;
@ -67,8 +67,8 @@ esp_err_t dl_ifft_s16_run(dl_fft_s16_t *handle, int16_t *data, int in_exponent,
}
int fft_point = handle->fft_point;
dl_ifft2r_sc16(data, fft_point, handle->fft_table);
dl_bitrev2r_sc16_ansi(data, fft_point);
dl_ifft2r_sc16_dif(data, handle->fft_table, 15, handle->log2n, fft_point);
dl_bitrev2r_sc16(data, fft_point, handle->log2n);
out_exponent[0] = in_exponent;
@ -83,8 +83,8 @@ esp_err_t dl_fft_s16_hp_run(dl_fft_s16_t *handle, int16_t *data, int in_exponent
int fft_point = handle->fft_point;
out_exponent[0] = 0;
dl_fft2r_sc16_hp(data, fft_point, handle->fft_table, out_exponent);
dl_bitrev2r_sc16_ansi(data, fft_point);
dl_fft2r_sc16_dif_hp(data, handle->fft_table, handle->log2n, fft_point, out_exponent);
dl_bitrev2r_sc16_ansi(data, fft_point, handle->log2n);
out_exponent[0] = in_exponent + out_exponent[0];
return ESP_OK;
@ -98,8 +98,8 @@ esp_err_t dl_ifft_s16_hp_run(dl_fft_s16_t *handle, int16_t *data, int in_exponen
int fft_point = handle->fft_point;
out_exponent[0] = 0;
dl_ifft2r_sc16_hp(data, fft_point, handle->fft_table, out_exponent);
dl_bitrev2r_sc16_ansi(data, fft_point);
dl_ifft2r_sc16_dif_hp(data, handle->fft_table, handle->log2n, fft_point, out_exponent);
dl_bitrev2r_sc16(data, fft_point, handle->log2n);
out_exponent[0] = in_exponent + out_exponent[0] - handle->log2n;
return ESP_OK;

View File

@ -1,5 +1,6 @@
#include "dl_rfft.h"
#include "esp_attr.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include <math.h>
#include <string.h>
@ -42,7 +43,7 @@ dl_fft_f32_t *dl_rfft_f32_init(int fft_point, uint32_t caps)
}
} else {
handle->bitrev_table = dl_gen_bitrev2r_table(fft_point >> 1, caps, &handle->bitrev_size);
handle->fft_table = dl_gen_fftr2_table_f32(fft_point >> 1, caps);
handle->fft_table = dl_gen_fft2r_table_f32(fft_point >> 1, caps);
if (!handle->fft_table) {
ESP_LOGE(TAG, "Failed to generate FFT table");
dl_rfft_f32_deinit(handle);
@ -57,15 +58,15 @@ void dl_rfft_f32_deinit(dl_fft_f32_t *handle)
{
if (handle) {
if (handle->fft_table) {
free(handle->fft_table);
heap_caps_free(handle->fft_table);
}
if (handle->rfft_table) {
free(handle->rfft_table);
heap_caps_free(handle->rfft_table);
}
if (handle->bitrev_table) {
free(handle->bitrev_table);
heap_caps_free(handle->bitrev_table);
}
free(handle);
heap_caps_free(handle);
}
}
esp_err_t dl_rfft_f32_run(dl_fft_f32_t *handle, float *data)

View File

@ -15,10 +15,10 @@ dl_fft_s16_t *dl_rfft_s16_init(int fft_point, uint32_t caps)
handle->fft_table = NULL;
handle->rfft_table = NULL;
handle->fft_point = fft_point;
handle->log2n = dl_power_of_two(fft_point);
handle->log2n = dl_power_of_two(fft_point) - 1; // rfft point is half of fft point
// rfft table
handle->rfft_table = dl_gen_rfft_table_s16(fft_point, caps);
handle->rfft_table = dl_gen_dif_rfft_table(fft_point >> 1, caps);
if (!handle->rfft_table) {
ESP_LOGE(TAG, "Failed to generate FFT table");
dl_rfft_s16_deinit(handle);
@ -26,7 +26,7 @@ dl_fft_s16_t *dl_rfft_s16_init(int fft_point, uint32_t caps)
}
// fft table
handle->fft_table = dl_gen_fft_table_sc16(fft_point >> 1, caps);
handle->fft_table = dl_gen_dif_fft_table(fft_point >> 1, caps);
if (!handle->fft_table) {
ESP_LOGE(TAG, "Failed to generate FFT table");
dl_rfft_s16_deinit(handle);
@ -58,10 +58,10 @@ esp_err_t dl_rfft_s16_run(dl_fft_s16_t *handle, int16_t *data, int in_exponent,
}
int cpx_point = handle->fft_point >> 1;
dl_fft2r_sc16(data, cpx_point, handle->fft_table);
dl_bitrev2r_sc16_ansi(data, cpx_point);
dl_rfft_post_proc_sc16_ansi(data, cpx_point, handle->rfft_table);
out_exponent[0] = in_exponent + handle->log2n;
dl_fft2r_sc16_dif(data, handle->fft_table, 15, handle->log2n, cpx_point);
dl_bitrev2r_sc16(data, cpx_point, handle->log2n);
int post_shift = dl_rfft_post_proc_sc16(data, cpx_point, handle->rfft_table);
out_exponent[0] = in_exponent + handle->log2n + post_shift;
return ESP_OK;
}
@ -74,10 +74,10 @@ esp_err_t dl_rfft_s16_hp_run(dl_fft_s16_t *handle, int16_t *data, int in_exponen
int cpx_point = handle->fft_point >> 1;
out_exponent[0] = 0;
dl_fft2r_sc16_hp(data, cpx_point, handle->fft_table, out_exponent);
dl_bitrev2r_sc16_ansi(data, cpx_point);
dl_rfft_post_proc_sc16_ansi(data, cpx_point, handle->rfft_table);
out_exponent[0] = in_exponent + out_exponent[0] + 1;
dl_fft2r_sc16_dif_hp(data, handle->fft_table, handle->log2n, cpx_point, out_exponent);
dl_bitrev2r_sc16(data, cpx_point, handle->log2n);
int post_shift = dl_rfft_post_proc_sc16(data, cpx_point, handle->rfft_table);
out_exponent[0] = in_exponent + out_exponent[0] + post_shift;
return ESP_OK;
}
@ -89,13 +89,11 @@ esp_err_t dl_irfft_s16_run(dl_fft_s16_t *handle, int16_t *data, int in_exponent,
}
int cpx_point = handle->fft_point >> 1;
out_exponent[0] = 0;
dl_rfft_pre_proc_sc16_ansi(data, cpx_point, handle->rfft_table);
dl_ifft2r_sc16(data, cpx_point, handle->fft_table);
dl_bitrev2r_sc16_ansi(data, cpx_point);
out_exponent[0] = in_exponent + 1;
int pre_shift = dl_rfft_pre_proc_sc16(data, cpx_point, handle->rfft_table);
dl_ifft2r_sc16_dif(data, handle->fft_table, 15, handle->log2n, cpx_point);
dl_bitrev2r_sc16(data, cpx_point, handle->log2n);
out_exponent[0] = in_exponent + pre_shift - 1;
return ESP_OK;
}
@ -109,11 +107,11 @@ esp_err_t dl_irfft_s16_hp_run(dl_fft_s16_t *handle, int16_t *data, int in_expone
int cpx_point = handle->fft_point >> 1;
out_exponent[0] = 0;
dl_rfft_pre_proc_sc16_ansi(data, cpx_point, handle->rfft_table);
dl_ifft2r_sc16_hp(data, cpx_point, handle->fft_table, out_exponent);
dl_bitrev2r_sc16_ansi(data, cpx_point);
int pre_shift = dl_rfft_pre_proc_sc16(data, cpx_point, handle->rfft_table);
dl_ifft2r_sc16_dif_hp(data, handle->fft_table, handle->log2n, cpx_point, out_exponent);
dl_bitrev2r_sc16(data, cpx_point, handle->log2n);
out_exponent[0] = in_exponent + out_exponent[0] + 2 - handle->log2n;
out_exponent[0] = in_exponent + out_exponent[0] - handle->log2n + pre_shift - 1;
return ESP_OK;
}

View File

@ -4,7 +4,7 @@ description: dl_fft is a lightweight and efficient fft library for all espressif
license: MIT
repository: git://github.com/espressif/esp-dl.git
repository_info:
commit_sha: 48f53066553a3483d6c710998609aedff0ea20bc
commit_sha: c63ab059bb745b5b071f8e3b71521d983363d9f6
path: tools/dl_fft
url: https://github.com/espressif/esp-dl/tree/master/esp-dl/tools/dl_fft
version: 0.3.1
version: 0.4.0

View File

@ -0,0 +1 @@
98823384f51ca298e2c9bebacd1c629148e528ed0902d18b16556df151519e68

View File

@ -0,0 +1,63 @@
# Changelog
## v1.0.1
### Features
- Supported IDF6.0
- Supported ESP32-S31, ESP32-H4, ESP32-C61
### Bug Fixes
- Fixed build error in test_app
## v1.0.0
### Features
- Added support for RGB565(big endian), RGB565(little endian), and CbYCrY pixel format in the encoder
- Aligned pixel format with esp-fourcc
### Bug Fixes
- Fixed encoding error with large gray images
- Fixed missing assignment of the `out_size` member in the `jpeg_dec_io_t` structure when scale is enabled during decoding
## v0.6.1
### Features
- Optimize error handling logic of the decoder
- Improve example of encoder block mode in test_app
### Bug Fixes
- Fix decoding error for some images containing restart markers
## v0.6.0
### Features
- Support IDF5.4
- Support SD power supply comes from internal LDO IO in test_app
- Add 16-byte alignment check for encoder input buffer when using ESP32-S3
- Add 16-byte alignment check for decoder output buffer when using ESP32-S3
### Bug Fixes
- Fix inaccurate `inbuf_remain` member in `jpeg_dec_io_t` structure after decoding is finished
- Fix spelling errors in test_app
## v0.5.1
### Bug Fixes
- Fix memory leakage on jpeg_enc_open fail
- Fix memory allocation fail when dram is insufficient
## v0.5.0
### Features
- Initial version of `esp_new_jpeg`
- Add JPEG encoder and decoder library

View File

@ -0,0 +1 @@
{"version":"1.0","algorithm":"sha256","created_at":"2026-04-28T15:16:08.467184+00:00","files":[{"path":"CHANGELOG.md","size":1335,"hash":"c130cf686b0e8ab3ba0933360088ee15a2900284d5ef4c83bf0eb7ca5427d789"},{"path":"CMakeLists.txt","size":310,"hash":"742e44bed0ef8fc9d323759e70afbee8e037d4404855e467e202b0b7987a8e42"},{"path":"LICENSE","size":1186,"hash":"0bf7f2018fffa1caff5ecbf10d79707b218eea4e26b8c705d744de4556552815"},{"path":"README.md","size":12598,"hash":"2815ab7dfbf5b851ba9726df36f80921f81b223f23048ff51ec34dc88900de26"},{"path":"idf_component.yml","size":481,"hash":"8f1fed78ab54830170190359a62d1591a91b72bac2c7110d909d6a72890aff29"},{"path":"include/esp_jpeg_common.h","size":6227,"hash":"c0852f3a5322af939c8f59fe7ba1ab231a143b6397def11847a7d955bfdb39c6"},{"path":"include/esp_jpeg_dec.h","size":7067,"hash":"136aa1cb155444fb460292b86c6e6ee1c6cc644681c647d268a56bec6aa67d47"},{"path":"include/esp_jpeg_enc.h","size":5487,"hash":"a73eeee202e52b9285bcfa6cbf2d8d803c2f96e2b3dd6338d26736c3e6eb5deb"},{"path":"include/esp_jpeg_version.h","size":1758,"hash":"6643796e0add19b4be6bc5f662c6519ead2adddedcb7a0b0210e557eeec9b973"},{"path":"test_app/CMakeLists.txt","size":313,"hash":"711b7d7d02dfba1a742bae8891c22bd7fc2d6a415c1223eb52bb35a750efac3d"},{"path":"test_app/pytest_esp_new_jpeg.py","size":397,"hash":"a55268d59c15700b575acfadbb53656935e107aba1bdb79aaa9313ccb2399927"},{"path":"test_app/sdkconfig.defaults","size":333,"hash":"a2de67417c4b9d838abacfd076725a85293d96a1dad780fbf4d03bded2beeddb"},{"path":"test_app/sdkconfig.defaults.esp32s3","size":238,"hash":"3288c88412caf5a00e3aecb5300444f01764cd64de20a18a852b6697839cc75d"},{"path":"test_app/main/CMakeLists.txt","size":382,"hash":"b001bc4b6d2e711ee0be17c264ae059aa479a5ccad07c1454442f7c05ff31467"},{"path":"test_app/main/idf_component.yml","size":42,"hash":"43d0de6527c82c1b474b1bf719968c68a1368863e653b60cafb51e689194a61e"},{"path":"test_app/main/image_io.c","size":5318,"hash":"ac8753a7cc791adf73f26b5896341b6583b38451c03ecbc9135679b9e367ac54"},{"path":"test_app/main/image_io.h","size":13338,"hash":"afde00c6d4f8edb19693fe6cd6f3eb52f7158c03977b9a19739564cacea8889d"},{"path":"test_app/main/test_app_main.c","size":1035,"hash":"92d80a8f04ef1700dfaec6d3742b8ae24d87a60ca655a4a461eb8ef44653b317"},{"path":"test_app/main/test_case.c","size":5672,"hash":"f20263cb35914494ce4e20c2018812fc56bc29460c55e83e4f454851a5fcc609"},{"path":"test_app/main/test_decoder.c","size":9141,"hash":"e34d4bad45243f209b277da008af44742a281ac5691f74ae5eda17d42aeae61a"},{"path":"test_app/main/test_decoder.h","size":2675,"hash":"c55a83399a13d6e7b9bef97647881eb7bd40bece0e701ce129952636434e04f8"},{"path":"test_app/main/test_encoder.c","size":4048,"hash":"d41b15624279802d1e8386344135671450720a7e828efb4b38f34779b2c131f0"},{"path":"test_app/main/test_encoder.h","size":629,"hash":"eddfaf1fea0907e98af877e53967b6535d466fdf83aa90076007d9dff8ce72de"},{"path":"lib/esp32/libesp_new_jpeg.a","size":2397506,"hash":"42f226866a13580988d9eed2f907da92955ec40f107f47f64460c72310c65d6f"},{"path":"lib/esp32c2/libesp_new_jpeg.a","size":4306308,"hash":"685a76686e85139d564f59aeee5d58222426cda7cf19e41cf2689e19b02152ea"},{"path":"lib/esp32c3/libesp_new_jpeg.a","size":4306308,"hash":"0e0df75e680dde492b05a11cd4a952cca5466d89d9b65065a6dd96e33286d643"},{"path":"lib/esp32c5/libesp_new_jpeg.a","size":3121412,"hash":"f2641ae9717d91da3f4c4ae434c53dc354bcbc7ddeedd0e3873372f8c2f73e68"},{"path":"lib/esp32c6/libesp_new_jpeg.a","size":4302396,"hash":"26af101018cb0d5d78465bdfac1684f87130011ace4f790b04d2d35999c64d86"},{"path":"lib/esp32c61/libesp_new_jpeg.a","size":4307260,"hash":"d5805e3a5b02f44e8cf1cf133da3b03df0bcc7ee388dfd962c74cff760ad9539"},{"path":"lib/esp32h4/libesp_new_jpeg.a","size":4211176,"hash":"0938c03e1bc2a290a4f9001f7151b79bc0f129403996e7870e2b77abb2cd2104"},{"path":"lib/esp32p4/libesp_new_jpeg.a","size":4313876,"hash":"79d92c036c18f9f8a51631ab3bfe17f1b7eef3f22395d0241b28a7a5876ead64"},{"path":"lib/esp32s2/libesp_new_jpeg.a","size":2253458,"hash":"f70370dda264c6b6c24acd9aba59c29d63a27a257ebed3b968687c7ff201ffda"},{"path":"lib/esp32s3/libesp_new_jpeg.a","size":1714940,"hash":"50464c893a2c0e06bdd75b1fef68ecbcef40db79b9e5b8da8ce32a8e10ad9465"},{"path":"lib/esp32s31/libesp_new_jpeg.a","size":4313876,"hash":"79d92c036c18f9f8a51631ab3bfe17f1b7eef3f22395d0241b28a7a5876ead64"}]}

View File

@ -0,0 +1,6 @@
set(public_include_dirs "./include")
idf_component_register(INCLUDE_DIRS "${public_include_dirs}")
add_prebuilt_library(esp_new_jpeg "${CMAKE_CURRENT_SOURCE_DIR}/lib/${CONFIG_IDF_TARGET}/libesp_new_jpeg.a")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--start-group" esp_new_jpeg "-Wl,--end-group")

View File

@ -0,0 +1,20 @@
ESPRESSIF MIT License
Copyright (c) 2024 <ESPRESSIF SYSTEMS (SHANGHAI) CO.LTD>
Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
it is free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,205 @@
# ESP_NEW_JPEG
ESP_NEW_JPEG is Espressif's lightweight JPEG encoder and decoder library. The memory and CPU loading are optimized to make better use of Espressif chips.
## Features
### Encoder
- Support variety of width and height to encoder
- Support RGB888 RGBA RGB565(big endian) RGB565(little endian) YCbYCr YCbY2YCrY2 CbYCrY GRAY pixel format
- Support YUV444 YUV422 YUV420 subsampling
- Support quality(1-100)
- Support 0 90 180 270 degree clockwise rotation, under the follow cases
1. src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_420 and width and height are multiply of 16
2. src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_GRAY and width and height are multiply of 8
- Support mono-task and dual-task
- Support two mode encoder, respectively one image encoder and block encoder
### Decoder
- Support variety of width and height to decoder
- Support one and three channels decoder
- Support RGB888 RGB565(big endian) RGB565(little endian) CbYCrY pixel format output
- Support 0 90 180 270 degree clockwise rotation, under width and height are multiply of 8
- Support clipper and scale, under width and height are multiply of 8
- Support two mode decoder, respectively one image decoder and block decoder
## Performance
### Test on chip ESP32-S3
#### Encoder
For **mono task** encoder, the consume memory(10 kByte DRAM) is constant.
| Resolution | Source Pixel Format | Output Quality | Output Subsampling | Frames Per Second(fps) |
|-------------|--------------------------|----------------|--------------------|------------------------|
| 1920 * 1080 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 1.59 |
| 1920 * 1080 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 1.33 |
| 1280 * 720 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 4.84 |
| 1280 * 720 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 2.92 |
| 800 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 10.82 |
| 800 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 6.74 |
| 640 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 13.24 |
| 640 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 8.32 |
| 480 * 320 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 24.35 |
| 480 * 320 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 15.84 |
| 320 * 240 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 45.30 |
| 320 * 240 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 30.37 |
When **dual task** encoder in enabled, the wider the image, the more memory is consumed.
| Resolution | Source Pixel Format | Output Quality | Output Subsampling | Frames Per Second(fps) |
|------------|--------------------------|----------------|--------------------|------------------------|
| 1280 * 720 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 4.62 |
| 800 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 10.46 |
| 640 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 12.89 |
| 480 * 320 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 23.57 |
| 320 * 240 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 43.97 |
#### Decoder
The consume memory(10 kByte DRAM) is constant.
Rotate JPEG_ROTATE_0D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|-------------|--------------------|----------------|-----------------------------|------------------------|
| 1920 * 1080 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 3.27 |
| 1920 * 1080 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 3.78 |
| 1280 * 720 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 6.77 |
| 1280 * 720 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 7.82 |
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 14.73 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 16.87 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 17.90 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 20.46 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 32.27 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 36.29 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 58.95 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 66.28 |
Rotate JPEG_ROTATE_90D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|-------------|--------------------|----------------|-----------------------------|------------------------|
| 1920 * 1080 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 2.23 |
| 1920 * 1080 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 3.11 |
| 1280 * 720 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.02 |
| 1280 * 720 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 7.13 |
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 14.09 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 16.85 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 17.16 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 20.45 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 30.87 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 36.15 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 59.17 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 70.78 |
### Test on chip ESP32-S2
#### Encoder
Only support mono task. The consume memory(10 kByte DRAM) is constant.
| Resolution | Source Pixel Format | Output Quality | Output Subsampling | Frames Per Second(fps) |
|------------|--------------------------|----------------|--------------------|------------------------|
| 800 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 3.60 |
| 800 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 2.76 |
| 640 * 480 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 4.47 |
| 640 * 480 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 3.43 |
| 480 * 320 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 8.64 |
| 480 * 320 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 6.69 |
| 320 * 240 | JPEG_PIXEL_FORMAT_YCbYCr | 60 | JPEG_SUBSAMPLE_420 | 16.30 |
| 320 * 240 | JPEG_PIXEL_FORMAT_RGB888 | 60 | JPEG_SUBSAMPLE_420 | 13.05 |
#### Decoder
The consume memory(10 kByte DRAM) is constant.
Rotate JPEG_ROTATE_0D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|------------|--------------------|----------------|-----------------------------|------------------------|
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.44 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.76 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 6.70 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 7.09 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 12.71 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 13.42 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 24.18 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 25.60 |
Rotate JPEG_ROTATE_90D cases:
| Resolution | Source Subsampling | Source Quality | Output Pixel Format | Frames Per Second(fps) |
|------------|--------------------|----------------|-----------------------------|------------------------|
| 800 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 4.53 |
| 800 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 4.81 |
| 640 * 480 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.59 |
| 640 * 480 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 5.94 |
| 480 * 320 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 10.69 |
| 480 * 320 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 11.33 |
| 320 * 240 | JPEG_SUBSAMPLE_422 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 22.40 |
| 320 * 240 | JPEG_SUBSAMPLE_420 | 60 | JPEG_PIXEL_FORMAT_RGB565_LE | 21.77 |
## Usage
Please refer to the `test_app` folder for more details on API usage.
- `test_app/main/test_encoder.c` for encoder
- Encode a single picture
- Encode a single picture with block encoder API
- `test_app/main/test_decoder.c` for decoder
- Decode a single JPEG picture
- Decode a single JPEG picture with block deocder API
- Decode JPEG stream of the same size
For more information, please refer to [Introducing ESP_NEW_JPEG: An Efficient JPEG Encoder and Decoder](https://developer.espressif.com/blog/2025/09/esp-new-jpeg-introduction/). The article provides detailed information on the features and configuration options of esp_new_jpeg.
## FAQ
1. Does ESP_NEW_JPEG support decoding progressive JPEG?
No, ESP_NEW_JPEG only support decoding baseline JPEG.
You can use the following code to check if the image is progressive JPEG. Output 1 means progressive JPEG, 0 means baseline JPEG.
```bash
python
>>> from PIL import Image
>>> Image.open("file_name.jpg").info.get('progressive', 0)
```
2. Why does the output image appear misaligned?
The issue typically occurs when a few columns of the image on the far left or right side appear on the opposite side. If you are using the ESP32-S3, a possible cause is that the output buffer of decoder or the input buffer of encoder is not 16-byte aligned. Please use the `jpeg_calloc_align` function to allocate buffer.
3. How can I use a simpler method to check if the encoder's output is correct?
You can use the following code to directly print the output JPEG data. Copy the output data, paste it into a hex editor, and save it as a .jpg file.
```c
for (int i = 0; i < out_len; i++) {
printf("%02x", outbuf[i]);
}
printf("\n");
```
## Supported chip
The following table shows the support of ESP_NEW_JPEG for Espressif SoCs. The "&#10004;" means supported, and the "&#10006;" means not supported.
| Chip | v1.0.1 |
|-----------|----------|
| ESP32 | &#10004; |
| ESP32-S2 | &#10004; |
| ESP32-S3 | &#10004; |
| ESP32-S31 | &#10004; |
| ESP32-P4 | &#10004; |
| ESP32-C2 | &#10004; |
| ESP32-C3 | &#10004; |
| ESP32-C5 | &#10004; |
| ESP32-C6 | &#10004; |
| ESP32-C61 | &#10004; |
| ESP32-H4 | &#10004; |

View File

@ -0,0 +1,23 @@
description: Espressif JPEG encoder and decoder
issues: https://github.com/espressif/esp-adf/issues
repository: git://github.com/espressif/esp-adf-libs.git
repository_info:
commit_sha: fdfb85fcfa732a01eae6bc4c83178bac332fc444
path: esp_new_jpeg
tags:
- multimedia
- jpeg
targets:
- esp32
- esp32s2
- esp32s3
- esp32s31
- esp32p4
- esp32c2
- esp32c3
- esp32c5
- esp32c6
- esp32c61
- esp32h4
url: https://github.com/espressif/esp-adf-libs/tree/master/esp_new_jpeg
version: 1.0.1

View File

@ -0,0 +1,127 @@
// Copyright 2025 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @brief Convert four characters to FOURCC
*/
#define JPEG_FOURCC_TO_INT(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
/**
* @brief Convert 32-bit FOURCC to string
*/
static inline void jpeg_fourcc_to_str(uint32_t fourcc, char out[5])
{
for (int i = 0; i < 4; i++) {
out[i] = (char)((fourcc >> (i * 8)) & 0xFF);
}
out[4] = '\0';
}
/**
* @brief Macro to convert an FOURCC to a string
*/
#define JPEG_FOURCC_TO_STR(fourcc) ({ \
static char fourcc_str[5]; \
fourcc_str[0] = fourcc_str[1] = fourcc_str[2] = fourcc_str[3] = fourcc_str[4] = '\0'; \
jpeg_fourcc_to_str(fourcc, fourcc_str); \
fourcc_str; \
})
/**
* @brief JPEG pixel format
*
* @note Aligned with GMF FourCC definition for audio video codecs and formats
* Detailed info refer to `https://github.com/espressif/esp-gmf/blob/main/gmf_core/helpers/include/esp_fourcc.h`
*/
typedef enum {
JPEG_PIXEL_FORMAT_GRAY = JPEG_FOURCC_TO_INT('G', 'R', 'E', 'Y'), /*!< Grayscale. 1-byte luminance component stored in memory for each pixel.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_RGB888 = JPEG_FOURCC_TO_INT('R', 'G', 'B', '3'), /*!< RGB888. 3-bytes red, green and blue components stored in memory from low to high address for each pixel.
Encoder supported. Decoder supported. */
JPEG_PIXEL_FORMAT_RGBA = JPEG_FOURCC_TO_INT('R', 'A', '2', '4'), /*!< RGBA. 4-bytes red, green, blue and alpha components stored in memory from low to high address for each pixel.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_YCbYCr = JPEG_FOURCC_TO_INT('Y', 'U', 'Y', 'V'), /*!< YCbYCr (belongs to packed yuv422). 4-bytes Y, Cb, Y and Cr components stored in memory from low to high address for each 2 pixels.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_YCbY2YCrY2 = JPEG_FOURCC_TO_INT('Y', 'U', 'Y', '2'), /*!< YCbY2YCrY2 (belongs to packed yuv420). 12-bytes Y, Cb, Y, Y, Cb, Y, Y, Cr, Y, Y, Cr and Y components stored in memory from low to high address for each 8 pixels.
Encoder supported. Decoder un-supported. */
JPEG_PIXEL_FORMAT_RGB565_BE = JPEG_FOURCC_TO_INT('R', 'G', 'B', 'B'), /*!< RGB565. 2-bytes RGB565 big-endian data stored in memory for each pixel.
Encoder supported. Decoder supported. */
JPEG_PIXEL_FORMAT_RGB565_LE = JPEG_FOURCC_TO_INT('R', 'G', 'B', 'L'), /*!< RGB565. 2-bytes RGB565 little-endian data stored in memory for each pixel.
Encoder supported. Decoder supported. */
JPEG_PIXEL_FORMAT_CbYCrY = JPEG_FOURCC_TO_INT('U', 'Y', 'V', 'Y'), /*!< CbYCrY (belongs to packed yuv422). 4-bytes Cb, Y, Cr and Y components stored in memory from low to high address for each 2 pixels.
Encoder supported. Decoder supported. */
} jpeg_pixel_format_t;
/**
* @brief JPEG error code
*/
typedef enum {
JPEG_ERR_OK = 0, /*!< Succeeded */
JPEG_ERR_FAIL = -1, /*!< Device error or wrong termination of input stream */
JPEG_ERR_NO_MEM = -2, /*!< Insufficient memory for the image */
JPEG_ERR_NO_MORE_DATA = -3, /*!< Input data is not enough */
JPEG_ERR_INVALID_PARAM = -4, /*!< Parameter error */
JPEG_ERR_BAD_DATA = -5, /*!< Data format error (may be damaged data) */
JPEG_ERR_UNSUPPORT_FMT = -6, /*!< Right format but not supported */
JPEG_ERR_UNSUPPORT_STD = -7, /*!< Not supported JPEG standard */
} jpeg_error_t;
/**
* @brief JPEG chrominance subsampling type
*/
typedef enum {
JPEG_SUBSAMPLE_GRAY = 0, /*!< Grayscale, no chrominance components */
JPEG_SUBSAMPLE_444 = 1, /*!< 4:4:4 chrominance subsampling, one chroma component for every pixel in the source image */
JPEG_SUBSAMPLE_422 = 2, /*!< 4:2:2 chrominance subsampling, one chroma component for every 2x1 block of pixels in the source image */
JPEG_SUBSAMPLE_420 = 3, /*!< 4:2:0 chrominance subsampling, one chroma component for every 2x2 block of pixels in the source image */
} jpeg_subsampling_t;
/**
* @brief JPEG rotation type
*/
typedef enum {
JPEG_ROTATE_0D = 0, /*!< Source image rotates clockwise 0 degree before encoding */
JPEG_ROTATE_90D = 1, /*!< Source image rotates clockwise 90 degree before encoding */
JPEG_ROTATE_180D = 2, /*!< Source image rotates clockwise 180 degree before encoding */
JPEG_ROTATE_270D = 3, /*!< Source image rotates clockwise 270 degree before encoding */
} jpeg_rotate_t;
/**
* @brief JPEG resize resolution parameter
*/
typedef struct {
uint16_t width; /*!< Image width */
uint16_t height; /*!< Image height */
} jpeg_resolution_t;
/**
* @brief Allocate buffer. The buffer address will be aligned.
*
* @param[in] size Allocate buffer size
* @param[in] aligned Aligned byte
*
* @return
* - NULL Failed
* - Others Allocated buffer address
*/
void *jpeg_calloc_align(size_t size, int aligned);
/**
* @brief Free buffer. The buffer address come from `jpeg_calloc_align`
*
* @param[in] buf Buffer address
*/
void jpeg_free_align(void *data);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -0,0 +1,165 @@
// Copyright 2026 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_jpeg_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DEFAULT_JPEG_DEC_CONFIG() { \
.output_type = JPEG_PIXEL_FORMAT_RGB888, \
.scale = {.width = 0, .height = 0}, \
.clipper = {.width = 0, .height = 0}, \
.rotate = JPEG_ROTATE_0D, \
.block_enable = false, \
}
/**
* @brief JPEG decoder handle
*/
typedef void *jpeg_dec_handle_t;
/**
* @brief Configuration for JPEG decoder
*
* @note Feature supported and limitations
* - support scale. Maximum scale ratio is 1/8. Scale.height and scale.width require integer multiples of 8.
* - support clipper. Clipper.height and clipper.width require integer multiples of 8.
* - support 0, 90, 180 and 270 clockwise rotation. Width and height require integer multiples of 8.
* - support block decoder mode.
*
* The general flow of decoder
* image data ----> decoding (required) ----> scale (optional) ----> clipper (optional) ----> rotation (optional)
*
* Each case of general flow:
* image -> decoding: The variety of width and height supported.
* image -> decoding -> scale: The scale.height and scale.width require integer multiples of 8.
* image -> decoding -> clipper: The clipper.height and clipper.width require integer multiples of 8.
* image -> decoding -> rotation: The height and width of image require integer multiples of 8.
* image -> decoding -> scale -> clipper: The scale.height, scale.width, clipper.height and clipper.width require integer multiples of 8. The resolution of clipper should be less or equal than scale.
* image -> decoding -> scale -> rotation: The scale.height and scale.width require integer multiples of 8.
* image -> decoding -> clipper -> rotation: The clipper.height and clipper.width require integer multiples of 8.
* image -> decoding -> scale -> clipper -> rotation: The scale.height, scale.width, clipper.height and clipper.width require integer multiples of 8. The resolution of clipper should be less or equal than scale.
*
* Flow of block decoder mode
* image data ----> decoding
*/
typedef struct {
jpeg_pixel_format_t output_type; /*!< Output pixel format. Support RGB888 RGB565_BE RGB565_LE CbYCrY, see jpeg_pixel_format_t enumeration. */
jpeg_resolution_t scale; /*!< Resolution of scale. scale.width = 0 means disable the width scale. scale.height = 0 means disable the height scale.
If enable this mode, scale.width and scale.height require integer multiples of 8. */
jpeg_resolution_t clipper; /*!< Resolution of clipper. clipper.width = 0 means disable the width clipper. clipper.height = 0 means disable the height clipper.
If enable this mode, clipper.width and clipper.height require integer multiples of 8. */
jpeg_rotate_t rotate; /*!< Support 0 90 180 270 degree clockwise rotation.
Only support when both width and height are multiples of 8. Otherwise unsupported. */
bool block_enable; /*!< Configured to true to enable block mode, each time output 8 or 16 line data depending on the height of MCU(Minimum Coded Unit).
If enabled this mode, scale and clipper are not supported, the width and height require integer multiples of 8 and rotate require JPEG_ROTATE_0D.
Configured to false to disable block mode. */
} jpeg_dec_config_t;
/**
* @brief JPEG decoder output infomation
*/
typedef struct {
uint16_t width; /*!< Image width */
uint16_t height; /*!< Image height */
} jpeg_dec_header_info_t;
/**
* @brief JPEG decoder io control
*/
typedef struct {
uint8_t *inbuf; /*!< The input buffer pointer */
int inbuf_len; /*!< The length of the input buffer in bytes */
int inbuf_remain; /*!< Not used length of the input buffer */
uint8_t *outbuf; /*!< The buffer to store decoded data. The buffer must be aligned 16 byte. */
int out_size; /*!< Output size of current block when block mode is enabled.
Size of entire image when block mode is disabled. */
} jpeg_dec_io_t;
/**
* @brief Create a JPEG decoder handle, set user configuration infomation to decoder handle
*
* @param[in] config Pointer to configuration information
* @param[out] jpeg_dec Pointer to JPEG decoder handle
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to create handle
*/
jpeg_error_t jpeg_dec_open(jpeg_dec_config_t *config, jpeg_dec_handle_t *jpeg_dec);
/**
* @brief Parse JPEG header, and output infomation to user
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[in] io Pointer to io control struct
* @param[out] out_info Pointer to output infomation struct
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to parse JPEG header
*/
jpeg_error_t jpeg_dec_parse_header(jpeg_dec_handle_t jpeg_dec, jpeg_dec_io_t *io, jpeg_dec_header_info_t *out_info);
/**
* @brief Get image buffer size
*
* @note User buffer must align to 16 bytes, user can malloc it through helper function `jpeg_calloc_align`.
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[out] outbuf_len Image buffer size
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to get output buffer size
*/
jpeg_error_t jpeg_dec_get_outbuf_len(jpeg_dec_handle_t jpeg_dec, int *outbuf_len);
/**
* @brief Get the number of times to call `jpeg_dec_process`
*
* @note If disable block decoder mode, the process_count always be 1.
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[out] process_count Number of times
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to get process times
*/
jpeg_error_t jpeg_dec_get_process_count(jpeg_dec_handle_t jpeg_dec, int *process_count);
/**
* @brief Decode JPEG picture
*
* @note For ESP32-S3, please use `jpeg_calloc_align` to allocate a 16-byte aligned output buffer.
*
* @param[in] jpeg_dec JPEG decoder handle
* @param[in] io Pointer to io control struct
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to decode JPEG picture
*/
jpeg_error_t jpeg_dec_process(jpeg_dec_handle_t jpeg_dec, jpeg_dec_io_t *io);
/**
* @brief Close JPEG decoder
*
* @param[in] jpeg_dec JPEG decoder handle
*
* @return
* - JPEG_ERR_OK On success
* - Others Fail to close JPEG decoder
*/
jpeg_error_t jpeg_dec_close(jpeg_dec_handle_t jpeg_dec);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -0,0 +1,131 @@
// Copyright 2024 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_jpeg_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DEFAULT_JPEG_ENC_CONFIG() { \
.width = 320, \
.height = 240, \
.src_type = JPEG_PIXEL_FORMAT_YCbYCr, \
.subsampling = JPEG_SUBSAMPLE_420, \
.quality = 40, \
.rotate = JPEG_ROTATE_0D, \
.task_enable = false, \
.hfm_task_priority = 13, \
.hfm_task_core = 1, \
}
/**
* @brief JPEG encoder handle
*/
typedef void *jpeg_enc_handle_t;
/* JPEG configure Configuration */
typedef struct jpeg_info {
int width; /*!< Image width */
int height; /*!< Image height */
jpeg_pixel_format_t src_type; /*!< Input image type */
jpeg_subsampling_t subsampling; /*!< JPEG chroma subsampling factors. If `src_type` is JPEG_PIXEL_FORMAT_YCbY2YCrY2, this must be `JPEG_SUBSAMPLE_GRAY` or `JPEG_SUBSAMPLE_420`. Others is un-support */
uint8_t quality; /*!< Quality: 1-100, higher is better. Typical values are around 40 - 100. */
jpeg_rotate_t rotate; /*!< Supports 0, 90 180 270 degree clockwise rotation.
Under src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_420, width % 16 == 0. height % 16 = 0 conditions, rotation enabled.
Otherwise unsupported */
bool task_enable; /*!< True: `jpeg_enc_open` would create task to finish part of encoding work. false: no task help the encoder encode */
uint8_t hfm_task_priority; /*!< Task priority. If task_enable is true, this must be set */
uint8_t hfm_task_core; /*!< Task core. If task_enable is true, this must be set */
} jpeg_enc_config_t;
/**
* @brief Open JPEG encoder
*
* @param[in] info The configuration information
* @param[out] jpeg_enc The JPEG encoder handle
*
* @return
* - positive value JPEG encoder handle
* - NULL refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_open(jpeg_enc_config_t *info, jpeg_enc_handle_t *jpeg_enc);
/**
* @brief Encode one image
*
* @note For ESP32-S3, please use `jpeg_calloc_align` to allocate a 16-byte aligned input buffer.
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
* @param[in] in_buf The input buffer, It needs a completed image. The buffer must be aligned 16 byte.
* @param[in] inbuf_size The size of `in_buf`. The value must be size of a completed image.
* @param[out] out_buf The output buffer
* @param[out] outbuf_size The size of output buffer
* @param[out] out_size The size of JPEG image
*
* @return
* - JPEG_ERR_OK It has finished to encode one image.
* - other values refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_process(const jpeg_enc_handle_t jpeg_enc, const uint8_t *in_buf, int inbuf_size, uint8_t *out_buf, int outbuf_size, int *out_size);
/**
* @brief Get block size. Block size is minimum process unit.
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
*
* @return
* - positive value block size
* - other values not valid data
*/
int jpeg_enc_get_block_size(const jpeg_enc_handle_t jpeg_enc);
/**
* @brief Encode block size image. Get block size from `jpeg_enc_get_block_size`
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
* @param[in] in_buf The input buffer, It needs a completed image.
* @param[in] inbuf_size The size of `in_buf`. Get block size from `jpeg_enc_get_block_size`
* @param[out] out_buf The output buffer, it saves a completed JPEG image.
* @param[out] outbuf_size The size of output buffer
* @param[out] out_size The size of JPEG image
*
* @return
* - block size It has finished to encode current block size image.
* - JPEG_ERR_OK It has finished to encode one image.
* - JPEG_ERR_FAIL Encoder failed.
*/
jpeg_error_t jpeg_enc_process_with_block(const jpeg_enc_handle_t jpeg_enc, const uint8_t *in_buf, int inbuf_size, uint8_t *out_buf, int outbuf_size, int *out_size);
/**
* @brief Reset quality.
*
* @note After encoding an entire image, user can call this function to change the quality value.
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
* @param[in] q Quality: 1-100, higher is better. Typical values are around 40 - 100.
*
* @return
* - JPEG_ERR_OK succeed
* - others values refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_set_quality(const jpeg_enc_handle_t jpeg_enc, uint8_t q);
/**
* @brief Close JPEG encoder
*
* @param[in] jpeg_enc The JPEG encoder handle. It gained from `jpeg_enc_open`
*
* @return
* - JPEG_ERR_OK It has finished to deinit.
* - other values refer to `jpeg_error_t`
*/
jpeg_error_t jpeg_enc_close(jpeg_enc_handle_t jpeg_enc);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -0,0 +1,46 @@
// Copyright 2026 Espressif Systems (Shanghai) CO., LTD.
// All rights reserved.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define ESP_JPEG_VERION "1.0.1"
/**
* @version 1.0.1:
* Features:
* Encoder:
* - Support variety of width and height to encoder
* - Support RGB888 RGBA RGB565(big endian) RGB565(little endian) YCbYCr YCbY2YCrY2 CbYCrY GRAY pixel format
* - Support YUV444 YUV422 YUV420 subsampling
* - Support quality(1-100)
* - Support 0 90 180 270 degree clockwise rotation, under src_type = JPEG_PIXEL_FORMAT_YCbYCr,
* subsampling = JPEG_SUBSAMPLE_420, width and height are multiply of 16 and
* src_type = JPEG_PIXEL_FORMAT_YCbYCr, subsampling = JPEG_SUBSAMPLE_GRAY, width and height are multiply of 8
* - Support mono-task and dual-task
* - Support two mode encoder, respectively one image encoder and block encoder
* Decoder:
* - Support variety of width and height to decoder
* - Support one and three channels decoder
* - Support RGB888 RGB565(big endian) RGB565(little endian) CbYCrY pixel format output
* - Support 0 90 180 270 degree clockwise rotation, under width and height are multiply of 8
* - Support clipper and scale, under width and height are multiply of 8
* - Support two mode decoder, respectively one image decoder and block decoder
*
* @note The encoder/decoder do ASM optimization in ESP32S3. Frame rate performs better than the others chips.
*/
/**
* @brief Get JPEG version string
*
* @return
* - JPEG codec version
*/
const char *esp_jpeg_get_version();
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -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)

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,170 @@
// Copyright 2026 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"
#if SOC_SDMMC_IO_POWER_EXTERNAL
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
#endif /* SOC_SDMMC_IO_POWER_EXTERNAL */
#define SD_PWR_CTRL_LDO_INTERNAL_ENABLE 0
#define SD_PWR_CTRL_LDO_IO_ID 4
#define MOUNT_POINT "/sdcard"
#define PIN_NUM_MISO 39
#define PIN_NUM_MOSI 44
#define PIN_NUM_CLK 43
#define PIN_NUM_CS 42
static sdmmc_host_t host = SDSPI_HOST_DEFAULT();
static sdmmc_card_t *card;
static const char mount_point[] = MOUNT_POINT;
#if SD_PWR_CTRL_LDO_INTERNAL_ENABLE
static sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
#endif /* SD_PWR_CTRL_LDO_INTERNAL_ENABLE */
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");
#if SD_PWR_CTRL_LDO_INTERNAL_ENABLE
sd_pwr_ctrl_ldo_config_t ldo_config = {
.ldo_chan_id = SD_PWR_CTRL_LDO_IO_ID,
};
ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle);
if (ret != ESP_OK) {
printf("Failed to create a new on-chip LDO power control driver\n");
return;
}
host.pwr_ctrl_handle = pwr_ctrl_handle;
#endif /* SD_PWR_CTRL_LDO_INTERNAL_ENABLE */
// 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.\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);
// Deinitialize the power control driver if it was used
#if SD_PWR_CTRL_LDO_INTERNAL_ENABLE
esp_err_t ret = sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle);
if (ret != ESP_OK) {
printf("Failed to delete the on-chip LDO power control driver");
return;
}
#endif /* SD_PWR_CTRL_LDO_INTERNAL_ENABLE */
}

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] __attribute__((aligned(16))) = {
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,159 @@
// Copyright 2026 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 = (unsigned char *)test_jpeg_data;
int input_len = sizeof(test_jpeg_data);
unsigned char *output_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, input_len, &output_buffer, &output_len));
// Print output buffer
// ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
// Test for white pixel
curpix = &output_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 = &output_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 = &output_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 = &output_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 = &output_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 = &output_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 (output_buffer) {
jpeg_free_align(output_buffer);
}
ESP_LOGI(TAG, "in_buffer: %p, in_len: %d, out_buffer: %p, out_len: %d", input_buffer, input_len, output_buffer, output_len);
}
TEST_CASE("test_decoder_block", "[dec]")
{
unsigned char *input_buffer = (unsigned char *)test_jpeg_data;
int input_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, input_len));
#if TEST_USE_SDCARD
unmount_sd();
#endif /* TEST_USE_SDCARD */
}
TEST_CASE("test_decoder_stream", "[dec]")
{
unsigned char *input_buffer = (unsigned char *)test_jpeg_data;
int input_len = sizeof(test_jpeg_data);
unsigned char *output_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, input_len, &output_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, input_len, output_buffer, output_len);
// Free output buffer
if (output_buffer) {
jpeg_free_align(output_buffer);
output_buffer = NULL;
}
}
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,312 @@
// Copyright 2026 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;
#if TEST_USE_SDCARD
FILE *f_out = NULL;
#endif /* TEST_USE_SDCARD */
// 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 2026 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;
const 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;
// 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
FILE *out = NULL;
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 = NULL;
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;
// 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
FILE *out = NULL;
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 */

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
a4169cdd22b3572342b2d640d7082405b8895e3214539283601c03412589b65d

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
idf_component_register()
# Override options defined in freetype/CMakeLists.txt.
# We could have used normal set(...) here if freetype enabled CMake policy CMP0077.
option(FT_DISABLE_HARFBUZZ "" ON)
option(FT_DISABLE_BZIP2 "" ON)
option(FT_DISABLE_BROTLI "" ON)
option(FT_DISABLE_PNG "" ON)
option(FT_DISABLE_ZLIB "" ON)
# These are regular CMake variables, so we can set them directly.
set(SKIP_INSTALL_ALL TRUE)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(freetype output)
# https://gitlab.freedesktop.org/freetype/freetype/-/issues/1299
target_compile_options(freetype PRIVATE "-Wno-dangling-pointer")
target_link_libraries(${COMPONENT_LIB} INTERFACE freetype)

View File

@ -0,0 +1,46 @@
FREETYPE LICENSES
-----------------
The FreeType 2 font engine is copyrighted work and cannot be used
legally without a software license. In order to make this project
usable to a vast majority of developers, we distribute it under two
mutually exclusive open-source licenses.
This means that *you* must choose *one* of the two licenses described
below, then obey all its terms and conditions when using FreeType 2 in
any of your projects or products.
- The FreeType License, found in the file `docs/FTL.TXT`, which is
similar to the original BSD license *with* an advertising clause
that forces you to explicitly cite the FreeType project in your
product's documentation. All details are in the license file.
This license is suited to products which don't use the GNU General
Public License.
Note that this license is compatible to the GNU General Public
License version 3, but not version 2.
- The GNU General Public License version 2, found in
`docs/GPLv2.TXT` (any later version can be used also), for
programs which already use the GPL. Note that the FTL is
incompatible with GPLv2 due to its advertisement clause.
The contributed BDF and PCF drivers come with a license similar to
that of the X Window System. It is compatible to the above two
licenses (see files `src/bdf/README` and `src/pcf/README`). The same
holds for the source code files `src/base/fthash.c` and
`include/freetype/internal/fthash.h`; they were part of the BDF driver
in earlier FreeType versions.
The gzip module uses the zlib license (see `src/gzip/zlib.h`) which
too is compatible to the above two licenses.
The files `src/autofit/ft-hb.c` and `src/autofit/ft-hb.h` contain code
taken almost verbatim from the HarfBuzz file `hb-ft.cc`, which uses
the 'Old MIT' license, compatible to the above two licenses.
The MD5 checksum support (only used for debugging in development
builds) is in the public domain.
--- end of LICENSE.TXT ---

View File

@ -0,0 +1,7 @@
# freetype compression and decompression Library
[![Component Registry](https://components.espressif.com/components/espressif/freetype/badge.svg)](https://components.espressif.com/components/espressif/freetype)
This is an IDF component for freetype library.
For usage instructions, please refer to the official documentation: https://freetype.org/freetype2/docs/documentation.html

View File

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.17)
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(freetype-example)

View File

@ -0,0 +1,51 @@
# FreeType Example
This is a simple example of initializing FreeType library, loading a font from a filesystem, and rendering a line of text.
The font file (DejaVu Sans) is downloaded at compile time and is added into a SPIFFS filesystem image. The filesystem is flashed to the board together with the application. The example loads the font file and renders "FreeType" text into the console as ASCII art.
This example doesn't require any special hardware and can run on any development board.
## Building and running
Run the application as usual for an ESP-IDF project. For example, for ESP32:
```
idf.py set-target esp32
idf.py -p PORT flash monitor
```
## Example output
The example should output the following:
```
I (468) main_task: Calling app_main()
I (538) example: FreeType library initialized
I (1258) example: Font loaded
I (1268) example: Rendering char: 'F'
I (1388) example: Rendering char: 'r'
I (1528) example: Rendering char: 'e'
I (1658) example: Rendering char: 'e'
I (1798) example: Rendering char: 'T'
I (1938) example: Rendering char: 'y'
I (2078) example: Rendering char: 'p'
I (2208) example: Rendering char: 'e'
######. #########
## +#
## ##### +###+ +###+ +# +# ######## +###+
## ##+ +#. .#+ +#. .#+ +# #+ #+##+ .#+ +#. .#+
###### ## #+ +# #+ +# +# ## +# ## +# #+ +#
## ## .####### .####### +# .# ## ## .# .#######
## ## .#. .#. +# #+.#. ## .# .#.
## ## #+ #+ +# +### ## +# #+
## ## ##+ ++ ##+ ++ +# ##+ ##+ .#+ ##+ ++
## ## +#### +#### +# ## ###### +####
## ##
+#. ##
##+ ##
```

View File

@ -0,0 +1,13 @@
idf_component_register(SRCS "freetype-example.c"
INCLUDE_DIRS "."
PRIV_REQUIRES spiffs)
# Download the example font into a directory "spiffs" in the build directory
set(URL "https://github.com/espressif/esp-docs/raw/f036a337d8bee5d1a93b2264ecd29255baec4260/src/esp_docs/fonts/DejaVuSans.ttf")
set(FILE "DejaVuSans.ttf")
set(SPIFFS_DIR "${CMAKE_BINARY_DIR}/spiffs")
file(MAKE_DIRECTORY ${SPIFFS_DIR})
file(DOWNLOAD ${URL} ${SPIFFS_DIR}/${FILE} SHOW_PROGRESS)
# Create a partition named "fonts" with the example font
spiffs_create_partition_image(fonts ${SPIFFS_DIR} FLASH_IN_PROJECT)

View File

@ -0,0 +1,150 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdlib.h>
#include "esp_log.h"
#include "esp_err.h"
#include "esp_spiffs.h"
#include "ft2build.h"
#include FT_FREETYPE_H
static const char *TAG = "example";
static void init_filesystem(void);
static void init_freetype(void);
static void load_font(void);
static void render_text(void);
#define BITMAP_WIDTH 80
#define BITMAP_HEIGHT 18
static FT_Library s_library;
static FT_Face s_face;
static uint8_t s_bitmap[BITMAP_HEIGHT][BITMAP_WIDTH];
void app_main(void)
{
init_filesystem();
init_freetype();
load_font();
render_text();
}
static void init_filesystem(void)
{
esp_vfs_spiffs_conf_t conf = {
.base_path = "/fonts",
.partition_label = "fonts",
.max_files = 1,
};
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&conf));
}
static void init_freetype(void)
{
FT_Error error = FT_Init_FreeType( &s_library );
if (error) {
ESP_LOGE(TAG, "Error initializing FreeType library: %d", error);
abort();
}
ESP_LOGI(TAG, "FreeType library initialized");
}
static void load_font(void)
{
FT_Error error = FT_New_Face( s_library,
"/fonts/DejaVuSans.ttf",
0,
&s_face );
if (error) {
ESP_LOGE(TAG, "Error loading font: %d", error);
abort();
}
ESP_LOGI(TAG, "Font loaded");
}
static void render_text(void)
{
/* Configure character size. */
const int font_size = 14;
const int freetype_scale = 64;
FT_Error error = FT_Set_Char_Size(s_face, 0, font_size * freetype_scale, 0, 0 );
if (error) {
ESP_LOGE(TAG, "Error setting font size: %d", error);
abort();
}
const char *text = "FreeType";
int num_chars = strlen(text);
/* current drawing position */
int x = 0;
int y = 12;
for (int n = 0; n < num_chars; n++) {
ESP_LOGI(TAG, "Rendering char: '%c'", text[n]);
/* retrieve glyph index from character code */
FT_UInt glyph_index = FT_Get_Char_Index( s_face, text[n] );
/* load glyph image into the slot (erase previous one) */
error = FT_Load_Glyph( s_face, glyph_index, FT_LOAD_DEFAULT );
if (error) {
ESP_LOGE(TAG, "Error loading glyph: %d", error);
abort();
}
/* convert to a bitmap */
error = FT_Render_Glyph( s_face->glyph, FT_RENDER_MODE_NORMAL );
if (error) {
ESP_LOGE(TAG, "Error rendering glyph: %d", error);
abort();
}
/* copy the glyph bitmap into the overall bitmap */
FT_GlyphSlot slot = s_face->glyph;
for (int iy = 0; iy < slot->bitmap.rows; iy++) {
for (int ix = 0; ix < slot->bitmap.width; ix++) {
/* bounds check */
int res_x = ix + x;
int res_y = y + iy - slot->bitmap_top;
if (res_x >= BITMAP_WIDTH || res_y >= BITMAP_HEIGHT) {
continue;
}
s_bitmap[res_y][res_x] = slot->bitmap.buffer[ix + iy * slot->bitmap.width];
}
}
/* increment horizontal position */
x += slot->advance.x / 64;
if (x >= BITMAP_WIDTH) {
break;
}
}
/* output the resulting bitmap to console */
for (int iy = 0; iy < BITMAP_HEIGHT; iy++) {
for (int ix = 0; ix < x; ix++) {
int val = s_bitmap[iy][ix];
if (val > 127) {
putchar('#');
} else if (val > 64) {
putchar('+');
} else if (val > 32) {
putchar('.');
} else {
putchar(' ');
}
}
putchar('\n');
}
}

View File

@ -0,0 +1,3 @@
dependencies:
espressif/freetype:
version: '*'

View File

@ -0,0 +1,4 @@
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
fonts, data, spiffs, , 0xF0000,
1 nvs data nvs 0x9000 0x6000
2 phy_init data phy 0xf000 0x1000
3 factory app factory 0x10000 1M
4 fonts data spiffs 0xF0000

View File

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
from __future__ import unicode_literals
import textwrap
import pytest
from pytest_embedded import Dut
@pytest.mark.generic
def test_freetype_example(dut: Dut) -> None:
dut.expect_exact('FreeType library initialized')
dut.expect_exact('Font loaded')
for c in 'FreeType':
dut.expect_exact(f'Rendering char: \'{c}\'')

View File

@ -0,0 +1,5 @@
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_ESP_MAIN_TASK_STACK_SIZE=20000
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y

View File

@ -0,0 +1,16 @@
BasedOnStyle: Chromium
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignConsecutiveMacros: true
AlignEscapedNewlines: true
# AlignOperands: Align
AlignTrailingComments: true
AlwaysBreakAfterReturnType: AllDefinitions
BreakBeforeBraces: Allman
ColumnLimit: 80
DerivePointerAlignment: false
IndentCaseLabels: false
PointerAlignment: Left
SpaceBeforeParens: ControlStatements
SpacesInParentheses: true

View File

@ -0,0 +1,7 @@
/build/
/config.mk
include/dlg/
src/dlg/dlg.c
subprojects/*
!subprojects/*.wrap
/tests/data/*

View File

@ -0,0 +1,3 @@
[submodule "dlg"]
path = subprojects/dlg
url = https://github.com/nyorain/dlg.git

View File

@ -0,0 +1,25 @@
Alexander Borsuk <me@alex.bio> <alexander.borsuk@qnective.com>
Behdad Esfahbod (بهداد اسفهبد) <behdad@behdad.org> <behdad.esfahbod@gmail.com>
Behdad Esfahbod (بهداد اسفهبد) <behdad@behdad.org> <behdad@google.com>
Behdad Esfahbod (بهداد اسفهبد) <behdad@behdad.org>
Ewald Hew (Hew Yih Shiuan 丘毅宣) <ewaldhew@gmail.com>
Moazin Khatti (موؤذن کھٹی) <moazinkhatri@gmail.com>
Priyesh Kumar (प्रियेश कुमार) <priyeshkkumar@gmail.com>
Alexei Podtelezhnikov (Алексей Подтележников) <apodtele@gmail.com>
Nikhil Ramakrishnan (निखिल रामकृष्णन) <ramakrishnan.nikhil@gmail.com>
Dominik Röttsches <drott@chromium.org> <drott@google.com>
Kostya Serebryany <kcc@google.com> <konstantin.s.serebryany@gmail.com>
Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> <sssa@flavor1.ipc.hiroshima-u.ac.jp>
Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> sssa <sssa@IPA2004-mps.local>
Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> sssa <sssa@sssas-powerbook-g4-12.local>
Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
Bram Tassyns <bramt@enfocus.be> bram tassyns <BramT@enfocus.be>
Bram Tassyns <bramt@enfocus.be> <BramT@enfocus.com>
Anurag Thakur (अनुराग ठाकुर) <anuthadev@gmail.com>
David Turner <david@freetype.org> <david.turner.dev@gmail.com>
David Turner <david@freetype.org> <digit@google.com>
Anuj Verma (अनुज वर्मा) <anujv@iitbhilai.ac.in>
Ben Wagner <bungeman@gmail.com>
Ben Wagner <bungeman@gmail.com> <bungeman@google.com>
Ben Wagner <bungeman@gmail.com> <bungeman@chromium.org>
Nikolaus Waxweiler <madigens@gmail.com> <nikolaus.waxweiler@daltonmaag.com>

View File

@ -0,0 +1,711 @@
# CMakeLists.txt
#
# Copyright (C) 2013-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# Written originally by John Cary <cary@txcorp.com>
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
#
#
# The following will (1) create a build directory, and (2) change into it and
# call cmake to configure the build with default parameters as a static
# library. See
#
# https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
#
# for information about debug or release builds, for example
#
# cmake -B build -D CMAKE_BUILD_TYPE=Release
#
#
# For a dynamic library, use
#
# cmake -B build -D BUILD_SHARED_LIBS=true -D CMAKE_BUILD_TYPE=Release
#
# For a framework on OS X, use
#
# cmake -E chdir build cmake -G Xcode -D BUILD_FRAMEWORK:BOOL=true ..
#
# For an iOS static library, use
#
# cmake -E chdir build cmake -G Xcode -D IOS_PLATFORM=OS ..
#
# or
#
# cmake -E chdir build cmake -G Xcode -D IOS_PLATFORM=SIMULATOR ..
#
# or
#
# cmake -E chdir build cmake -G Xcode -D IOS_PLATFORM=SIMULATOR64 ..
#
#
# Finally, build the project with
#
# cmake --build build
#
# Install it with
#
# (sudo) cmake --build build --target install
#
# A binary distribution can be made with
#
# cmake --build build --config Release --target package
#
# Please refer to the cmake manual for further options, in particular, how
# to modify compilation and linking parameters.
#
# Some notes.
#
# - Say `cmake -LAH` to see all configuration options.
#
# - `cmake' creates configuration files in
#
# <build-directory>/include/freetype/config
#
# which should be further modified if necessary.
#
# - You can use `cmake' directly on a freshly cloned FreeType git
# repository.
#
# - `CMakeLists.txt' is provided as-is since it is normally not used by the
# developer team.
#
# - Set the `FT_REQUIRE_ZLIB', `FT_REQUIRE_BZIP2', `FT_REQUIRE_PNG',
# `FT_REQUIRE_HARFBUZZ', and `FT_REQUIRE_BROTLI' CMake variables to `ON'
# or `TRUE' to force using a dependency. Leave a variable undefined
# (which is the default) to use the dependency only if it is available.
# Example:
#
# cmake -B build -D FT_REQUIRE_ZLIB=TRUE \
# -D FT_REQUIRE_BZIP2=TRUE \
# -D FT_REQUIRE_PNG=TRUE \
# -D FT_REQUIRE_HARFBUZZ=TRUE \
# -D FT_REQUIRE_BROTLI=TRUE [...]
#
# - Set the `FT_DYNAMIC_HARFBUZZ' CMake variable to `ON' or `TRUE' to load
# the HarfBuzz library dynamically at runtime, if possible. Example:
#
# cmake -B build -D FT_DYNAMIC_HARFBUZZ=TRUE [...]
#
# - Set `FT_DISABLE_XXX=TRUE' to disable a dependency completely (where
# `XXX' is a CMake package name like `BZip2'). Example for disabling all
# dependencies:
#
# cmake -B build -D FT_DISABLE_ZLIB=TRUE \
# -D FT_DISABLE_BZIP2=TRUE \
# -D FT_DISABLE_PNG=TRUE \
# -D FT_DISABLE_HARFBUZZ=TRUE \
# -D FT_DISABLE_BROTLI=TRUE [...]
#
# - NOTE: If a package is set as DISABLED, it cannot be set as REQUIRED
# without unsetting the DISABLED value first. For example, if
# `FT_DISABLE_HARFBUZZ=TRUE' has been set (Cache is present), you need to
# call `FT_DISABLE_HARFBUZZ=FALSE' before calling
# `FT_REQUIRE_HARFBUZZ=TRUE'.
#
# - Installation of FreeType can be controlled with the CMake variables
# `SKIP_INSTALL_HEADERS', `SKIP_INSTALL_LIBRARIES', and `SKIP_INSTALL_ALL'
# (this is compatible with the same CMake variables in zlib's CMake
# support).
# CMake 3.12 provides for IMPORTED targets for common libraries like zlib, libpng and bzip2
cmake_minimum_required(VERSION 3.12...3.31.0)
include(CheckIncludeFile)
include(CMakeDependentOption)
# CMAKE_TOOLCHAIN_FILE must be set before `project' is called, which
# configures the base build environment and references the toolchain file
if (APPLE)
if (DEFINED IOS_PLATFORM)
if (NOT "${IOS_PLATFORM}" STREQUAL "OS"
AND NOT "${IOS_PLATFORM}" STREQUAL "SIMULATOR"
AND NOT "${IOS_PLATFORM}" STREQUAL "SIMULATOR64")
message(FATAL_ERROR
"IOS_PLATFORM must be set to either OS, SIMULATOR, or SIMULATOR64")
endif ()
if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
message(AUTHOR_WARNING
"You should use Xcode generator with IOS_PLATFORM enabled to get Universal builds.")
endif ()
if (BUILD_SHARED_LIBS)
message(FATAL_ERROR
"BUILD_SHARED_LIBS can not be on with IOS_PLATFORM enabled")
endif ()
if (BUILD_FRAMEWORK)
message(FATAL_ERROR
"BUILD_FRAMEWORK can not be on with IOS_PLATFORM enabled")
endif ()
# iOS only uses static libraries
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_TOOLCHAIN_FILE
${CMAKE_SOURCE_DIR}/builds/cmake/iOS.cmake)
endif ()
else ()
if (DEFINED IOS_PLATFORM)
message(FATAL_ERROR "IOS_PLATFORM is not supported on this platform")
endif ()
endif ()
project(freetype C)
set(VERSION_MAJOR "2")
set(VERSION_MINOR "14")
set(VERSION_PATCH "2")
# Generate LIBRARY_VERSION and LIBRARY_SOVERSION.
set(LIBTOOL_REGEX "version_info='([0-9]+):([0-9]+):([0-9]+)'")
file(STRINGS "${PROJECT_SOURCE_DIR}/builds/unix/configure.raw"
VERSION_INFO
REGEX ${LIBTOOL_REGEX})
string(REGEX REPLACE
${LIBTOOL_REGEX} "\\1"
LIBTOOL_CURRENT "${VERSION_INFO}")
string(REGEX REPLACE
${LIBTOOL_REGEX} "\\2"
LIBTOOL_REVISION "${VERSION_INFO}")
string(REGEX REPLACE
${LIBTOOL_REGEX} "\\3"
LIBTOOL_AGE "${VERSION_INFO}")
# This is what libtool does internally on Unix platforms.
math(EXPR LIBRARY_SOVERSION "${LIBTOOL_CURRENT} - ${LIBTOOL_AGE}")
set(LIBRARY_VERSION "${LIBRARY_SOVERSION}.${LIBTOOL_AGE}.${LIBTOOL_REVISION}")
# External dependency library detection is automatic. See the notes at the
# top of this file, for how to force or disable dependencies completely.
option(FT_DISABLE_ZLIB
"Disable use of system zlib and use internal zlib library instead." OFF)
cmake_dependent_option(FT_REQUIRE_ZLIB
"Require system zlib instead of internal zlib library." OFF
"NOT FT_DISABLE_ZLIB" OFF)
option(FT_DISABLE_BZIP2
"Disable support of bzip2 compressed fonts." OFF)
cmake_dependent_option(FT_REQUIRE_BZIP2
"Require support of bzip2 compressed fonts." OFF
"NOT FT_DISABLE_BZIP2" OFF)
option(FT_DISABLE_PNG
"Disable support of PNG compressed OpenType embedded bitmaps." OFF)
cmake_dependent_option(FT_REQUIRE_PNG
"Require support of PNG compressed OpenType embedded bitmaps." OFF
"NOT FT_DISABLE_PNG" OFF)
option(FT_DISABLE_HARFBUZZ
"Disable HarfBuzz (used for improving auto-hinting of OpenType fonts)." OFF)
cmake_dependent_option(FT_DYNAMIC_HARFBUZZ
"Load HarfBuzz library dynamically at runtime, if possible." ON
"NOT FT_DISABLE_HARFBUZZ" OFF)
cmake_dependent_option(FT_REQUIRE_HARFBUZZ
"Require HarfBuzz for improving auto-hinting of OpenType fonts." OFF
"NOT FT_DISABLE_HARFBUZZ" OFF)
option(FT_DISABLE_BROTLI
"Disable support of compressed WOFF2 fonts." OFF)
cmake_dependent_option(FT_REQUIRE_BROTLI
"Require support of compressed WOFF2 fonts." OFF
"NOT FT_DISABLE_BROTLI" OFF)
option(FT_ENABLE_ERROR_STRINGS
"Enable support for meaningful error descriptions." OFF)
# Disallow in-source builds
if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
message(FATAL_ERROR
"In-source builds are not permitted! Make a separate folder for"
" building, e.g.,\n"
" cmake -E make_directory build\n"
" cmake -E chdir build cmake ..\n"
"Before that, remove the files created by this failed run with\n"
" cmake -E remove CMakeCache.txt\n"
" cmake -E remove_directory CMakeFiles")
endif ()
# Add local cmake modules
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/builds/cmake)
if (BUILD_FRAMEWORK)
if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
message(FATAL_ERROR
"You should use Xcode generator with BUILD_FRAMEWORK enabled")
endif ()
set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)")
set(BUILD_SHARED_LIBS ON)
endif ()
# Find dependencies
include(FindPkgConfig)
include(CMakePushCheckState)
include(CheckSymbolExists)
if (NOT FT_DISABLE_HARFBUZZ)
set(HARFBUZZ_MIN_VERSION "2.0.0")
if (FT_DYNAMIC_HARFBUZZ)
if (WIN32) # Windows uses its own LoadLibrary()
set(FT_DYNAMIC_HARFBUZZ_ENABLED TRUE)
else()
cmake_push_check_state(RESET)
check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN_IN_LIBC)
if (NOT HAVE_DLOPEN_IN_LIBC)
set(CMAKE_REQUIRED_LIBRARIES dl)
check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN_IN_LIBDL)
endif()
cmake_pop_check_state()
if (HAVE_DLOPEN_IN_LIBC OR HAVE_DLOPEN_IN_LIBDL)
set(FT_DYNAMIC_HARFBUZZ_ENABLED TRUE)
if (HAVE_DLOPEN_IN_LIBDL)
set(FT_NEED_LIBDL TRUE)
endif()
endif()
endif()
endif()
if (FT_DYNAMIC_HARFBUZZ_ENABLED)
message(STATUS "Enabled dynamic loading of HarfBuzz library at runtime.")
elseif (FT_REQUIRE_HARFBUZZ)
find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION} REQUIRED)
else ()
find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION})
endif ()
endif ()
if (NOT FT_DISABLE_PNG)
if (FT_REQUIRE_PNG)
find_package(PNG REQUIRED)
else ()
find_package(PNG)
endif ()
# FreePNG calls FindZLIB so unset ZLIB_FOUND to respect FT_DISABLE_ZLIB
unset(ZLIB_FOUND)
endif ()
if (NOT FT_DISABLE_ZLIB)
if (FT_REQUIRE_ZLIB)
find_package(ZLIB REQUIRED)
else ()
find_package(ZLIB)
endif ()
endif ()
if (NOT FT_DISABLE_BZIP2)
# Genuine BZip2 does not provide bzip2.pc, but some platforms have it.
# For better dependency in freetype2.pc, bzip2.pc is searched
# regardless of the availability of libbz2. If bzip2.pc is found,
# Requires.private is used instead of Libs.private.
if (FT_REQUIRE_BZIP2)
find_package(BZip2 REQUIRED)
else ()
find_package(BZip2)
endif ()
pkg_check_modules(PC_BZIP2 bzip2)
endif ()
if (NOT FT_DISABLE_BROTLI)
if (FT_REQUIRE_BROTLI)
find_package(BrotliDec REQUIRED)
else ()
find_package(BrotliDec)
endif ()
endif ()
# Create the configuration file
if (UNIX AND NOT WIN32)
check_include_file("unistd.h" HAVE_UNISTD_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
file(READ "${PROJECT_SOURCE_DIR}/builds/unix/ftconfig.h.in"
FTCONFIG_H)
if (HAVE_UNISTD_H)
string(REGEX REPLACE
"#undef +(HAVE_UNISTD_H)" "#define \\1 1"
FTCONFIG_H "${FTCONFIG_H}")
endif ()
if (HAVE_FCNTL_H)
string(REGEX REPLACE
"#undef +(HAVE_FCNTL_H)" "#define \\1 1"
FTCONFIG_H "${FTCONFIG_H}")
endif ()
else ()
file(READ "${PROJECT_SOURCE_DIR}/include/freetype/config/ftconfig.h"
FTCONFIG_H)
endif ()
set(FTCONFIG_H_NAME "${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h")
if (EXISTS "${FTCONFIG_H_NAME}")
file(READ "${FTCONFIG_H_NAME}" ORIGINAL_FTCONFIG_H)
else ()
set(ORIGINAL_FTCONFIG_H "")
endif ()
if (NOT (ORIGINAL_FTCONFIG_H STREQUAL FTCONFIG_H))
file(WRITE "${FTCONFIG_H_NAME}" "${FTCONFIG_H}")
endif ()
# Create the options file
file(READ "${PROJECT_SOURCE_DIR}/include/freetype/config/ftoption.h"
FTOPTION_H)
if (ZLIB_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_SYSTEM_ZLIB) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (BZIP2_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_BZIP2) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (PNG_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_PNG) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (HARFBUZZ_FOUND OR FT_DYNAMIC_HARFBUZZ_ENABLED)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_HARFBUZZ) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
if (FT_DYNAMIC_HARFBUZZ_ENABLED)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
endif ()
if (BROTLIDEC_FOUND)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_USE_BROTLI) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
if (FT_ENABLE_ERROR_STRINGS)
string(REGEX REPLACE
"/\\* +(#define +FT_CONFIG_OPTION_ERROR_STRINGS) +\\*/" "\\1"
FTOPTION_H "${FTOPTION_H}")
endif ()
set(FTOPTION_H_NAME "${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h")
if (EXISTS "${FTOPTION_H_NAME}")
file(READ "${FTOPTION_H_NAME}" ORIGINAL_FTOPTION_H)
else ()
set(ORIGINAL_FTOPTION_H "")
endif ()
if (NOT (ORIGINAL_FTOPTION_H STREQUAL FTOPTION_H))
file(WRITE "${FTOPTION_H_NAME}" "${FTOPTION_H}")
endif ()
file(GLOB PUBLIC_HEADERS "include/ft2build.h" "include/freetype/*.h")
file(GLOB PUBLIC_CONFIG_HEADERS "include/freetype/config/*.h")
file(GLOB PRIVATE_HEADERS "include/freetype/internal/*.h")
set(BASE_SRCS
src/autofit/autofit.c
src/base/ftbase.c
src/base/ftbbox.c
src/base/ftbdf.c
src/base/ftbitmap.c
src/base/ftcid.c
src/base/ftfstype.c
src/base/ftgasp.c
src/base/ftglyph.c
src/base/ftgxval.c
src/base/ftinit.c
src/base/ftmm.c
src/base/ftotval.c
src/base/ftpatent.c
src/base/ftpfr.c
src/base/ftstroke.c
src/base/ftsynth.c
src/base/fttype1.c
src/base/ftwinfnt.c
src/bdf/bdf.c
src/bzip2/ftbzip2.c
src/cache/ftcache.c
src/cff/cff.c
src/cid/type1cid.c
src/gzip/ftgzip.c
src/lzw/ftlzw.c
src/pcf/pcf.c
src/pfr/pfr.c
src/psaux/psaux.c
src/pshinter/pshinter.c
src/psnames/psnames.c
src/raster/raster.c
src/sdf/sdf.c
src/sfnt/sfnt.c
src/smooth/smooth.c
src/svg/svg.c
src/truetype/truetype.c
src/type1/type1.c
src/type42/type42.c
src/winfonts/winfnt.c
)
if (WIN32)
list(APPEND BASE_SRCS "builds/windows/ftsystem.c")
elseif (UNIX)
list(APPEND BASE_SRCS "builds/unix/ftsystem.c")
else ()
list(APPEND BASE_SRCS "src/base/ftsystem.c")
endif ()
if (WIN32)
enable_language(RC)
list(APPEND BASE_SRCS builds/windows/ftdebug.c
src/base/ftver.rc)
elseif (WINCE)
list(APPEND BASE_SRCS builds/wince/ftdebug.c)
else ()
list(APPEND BASE_SRCS src/base/ftdebug.c)
endif ()
if (BUILD_FRAMEWORK)
list(APPEND BASE_SRCS builds/mac/freetype-Info.plist)
endif ()
if (NOT DISABLE_FORCE_DEBUG_POSTFIX)
set(CMAKE_DEBUG_POSTFIX d)
endif ()
add_library(freetype
${PUBLIC_HEADERS}
${PUBLIC_CONFIG_HEADERS}
${PRIVATE_HEADERS}
${BASE_SRCS}
)
target_compile_definitions(
freetype PRIVATE FT2_BUILD_LIBRARY)
if (WIN32)
target_compile_definitions(
freetype PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS)
if (BUILD_SHARED_LIBS)
target_compile_definitions(
freetype PRIVATE DLL_EXPORT)
endif ()
else ()
# Windows handles exports with DLL_EXPORT defined above.
set_target_properties(freetype PROPERTIES
C_VISIBILITY_PRESET hidden)
endif ()
if (BUILD_SHARED_LIBS)
set_target_properties(freetype PROPERTIES
VERSION ${LIBRARY_VERSION}
SOVERSION ${LIBRARY_SOVERSION})
endif ()
# Pick up ftconfig.h and ftoption.h generated above, first.
target_include_directories(
freetype
PUBLIC
$<INSTALL_INTERFACE:include/freetype2>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/include
# Make <ftconfig.h> available for builds/unix/ftsystem.c.
${CMAKE_CURRENT_BINARY_DIR}/include/freetype/config
)
if (BUILD_FRAMEWORK)
set_property(SOURCE ${PUBLIC_CONFIG_HEADERS}
PROPERTY MACOSX_PACKAGE_LOCATION Headers/config
)
set_target_properties(freetype PROPERTIES
FRAMEWORK TRUE
MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/builds/mac/freetype-Info.plist
PUBLIC_HEADER "${PUBLIC_HEADERS}"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
)
endif ()
# 'freetype-interface' is an interface library, to be accessed with
# `EXPORT_NAME Freetype::Freetype`. This is the target name provided by
# CMake's `FindFreetype.cmake`, so we provide it for compatibility.
add_library(freetype-interface INTERFACE)
set_target_properties(freetype-interface PROPERTIES
EXPORT_NAME Freetype::Freetype
INTERFACE_LINK_LIBRARIES freetype)
set(PKGCONFIG_REQUIRES "")
set(PKGCONFIG_REQUIRES_PRIVATE "")
set(PKGCONFIG_LIBS "-L\${libdir} -lfreetype")
set(PKGCONFIG_LIBS_PRIVATE "")
if (ZLIB_FOUND)
target_link_libraries(freetype PRIVATE ZLIB::ZLIB)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "zlib")
endif ()
if (BZIP2_FOUND)
target_link_libraries(freetype PRIVATE BZip2::BZip2)
if (PC_BZIP2_FOUND)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "bzip2")
else ()
list(APPEND PKGCONFIG_LIBS_PRIVATE "-lbz2")
endif ()
endif ()
if (PNG_FOUND)
target_link_libraries(freetype PRIVATE PNG::PNG)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "libpng")
endif ()
if (FT_DYNAMIC_HARFBUZZ_ENABLED AND FT_NEED_LIBDL)
target_link_libraries(freetype PRIVATE dl)
list(APPEND PKGCONFIG_LIBS_PRIVATE " -ldl")
endif ()
if (HarfBuzz_FOUND AND (NOT FT_DYNAMIC_HARFBUZZ_ENABLED))
target_link_libraries(freetype PRIVATE HarfBuzz::HarfBuzz)
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "harfbuzz >= ${HARFBUZZ_MIN_VERSION}")
endif ()
if (BROTLIDEC_FOUND)
target_link_libraries(freetype PRIVATE ${BROTLIDEC_LIBRARIES})
target_compile_definitions(freetype PRIVATE ${BROTLIDEC_DEFINITIONS})
target_include_directories(freetype PRIVATE ${BROTLIDEC_INCLUDE_DIRS})
list(APPEND PKGCONFIG_REQUIRES_PRIVATE "libbrotlidec")
endif ()
# Installation
include(GNUInstallDirs)
if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
install(
# Note the trailing slash in the argument to `DIRECTORY'!
DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/freetype2
COMPONENT headers
PATTERN "internal" EXCLUDE
PATTERN "ftconfig.h" EXCLUDE
PATTERN "ftoption.h" EXCLUDE)
install(
FILES ${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h
${PROJECT_BINARY_DIR}/include/freetype/config/ftoption.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/freetype2/freetype/config
COMPONENT headers)
endif ()
if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
# Generate the pkg-config file
file(READ "${PROJECT_SOURCE_DIR}/builds/unix/freetype2.in" FREETYPE2_PC_IN)
string(REPLACE ";" ", " PKGCONFIG_REQUIRES_PRIVATE "${PKGCONFIG_REQUIRES_PRIVATE}")
string(REPLACE "%prefix%" ${CMAKE_INSTALL_PREFIX}
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%exec_prefix%" "\${prefix}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%ft_version%" "${LIBTOOL_CURRENT}.${LIBTOOL_REVISION}.${LIBTOOL_AGE}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
if (BUILD_SHARED_LIBS)
string(REPLACE "%PKGCONFIG_REQUIRES%" "${PKGCONFIG_REQUIRES}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%PKGCONFIG_REQUIRES_PRIVATE%" "${PKGCONFIG_REQUIRES_PRIVATE}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%PKGCONFIG_LIBS%" "${PKGCONFIG_LIBS}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%PKGCONFIG_LIBS_PRIVATE%" "${PKGCONFIG_LIBS_PRIVATE}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
else ()
string(REPLACE "%PKGCONFIG_REQUIRES%" "${PKGCONFIG_REQUIRES} ${PKGCONFIG_REQUIRES_PRIVATE}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%PKGCONFIG_REQUIRES_PRIVATE%" ""
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%PKGCONFIG_LIBS%" "${PKGCONFIG_LIBS} ${PKGCONFIG_LIBS_PRIVATE}"
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
string(REPLACE "%PKGCONFIG_LIBS_PRIVATE%" ""
FREETYPE2_PC_IN ${FREETYPE2_PC_IN})
endif ()
set(FREETYPE2_PC_IN_NAME "${PROJECT_BINARY_DIR}/freetype2.pc")
if (EXISTS "${FREETYPE2_PC_IN_NAME}")
file(READ "${FREETYPE2_PC_IN_NAME}" ORIGINAL_FREETYPE2_PC_IN)
else ()
set(ORIGINAL_FREETYPE2_PC_IN "")
endif ()
if (NOT (ORIGINAL_FREETYPE2_PC_IN STREQUAL FREETYPE2_PC_IN))
file(WRITE "${FREETYPE2_PC_IN_NAME}" ${FREETYPE2_PC_IN})
endif ()
install(
FILES ${PROJECT_BINARY_DIR}/freetype2.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
COMPONENT pkgconfig)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${PROJECT_BINARY_DIR}/freetype-config-version.cmake
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
COMPATIBILITY SameMajorVersion)
install(
TARGETS freetype freetype-interface
EXPORT freetype-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION Library/Frameworks
COMPONENT libraries)
install(
EXPORT freetype-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype
FILE freetype-config.cmake
COMPONENT headers)
install(
FILES ${PROJECT_BINARY_DIR}/freetype-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/freetype
COMPONENT headers)
endif ()
# Packaging
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The FreeType font rendering library.")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT")
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
if (WIN32)
set(CPACK_GENERATOR ZIP)
else ()
set(CPACK_GENERATOR TGZ)
endif ()
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers")
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
"Library used to build programs which use FreeType")
set(CPACK_COMPONENT_HEADERS_DESCRIPTION
"C/C++ header files for use with FreeType")
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
set(CPACK_COMPONENT_HEADERS_GROUP "Development")
include(CPack)

View File

@ -0,0 +1,47 @@
FREETYPE LICENSES
-----------------
The FreeType 2 font engine is copyrighted work and cannot be used
legally without a software license. In order to make this project
usable to a vast majority of developers, we distribute it under two
mutually exclusive open-source licenses.
This means that *you* must choose *one* of the two licenses described
below, then obey all its terms and conditions when using FreeType 2 in
any of your projects or products.
- The FreeType License, found in the file `docs/FTL.TXT`, which is
similar to the original BSD license *with* an advertising clause
that forces you to explicitly cite the FreeType project in your
product's documentation. All details are in the license file.
This license is suited to products which don't use the GNU General
Public License.
Note that this license is compatible to the GNU General Public
License version 3, but not version 2.
- The GNU General Public License version 2, found in
`docs/GPLv2.TXT` (any later version can be used also), for
programs which already use the GPL. Note that the FTL is
incompatible with GPLv2 due to its advertisement clause.
The contributed BDF and PCF drivers come with a license similar to
that of the X Window System. It is compatible to the above two
licenses (see files `src/bdf/README` and `src/pcf/README`). The same
holds for the source code files `src/base/fthash.c` and
`include/freetype/internal/fthash.h`; they were part of the BDF driver
in earlier FreeType versions.
The gzip module uses the zlib license (see `src/gzip/zlib.h`) which
too is compatible to the above two licenses.
The files `src/autofit/ft-hb-ft.c`, `src/autofit/ft-hb-decls.h`,
`src/autofit/ft-hb-types.h`, and `src/autofit/hb-script-list.h`
contain code taken (almost) verbatim from the HarfBuzz library, which
uses the 'Old MIT' license compatible to the above two licenses.
The MD5 checksum support (only used for debugging in development
builds) is in the public domain.
--- end of LICENSE.TXT ---

View File

@ -0,0 +1,4 @@
# MSBuild.rsp with default command-line switches
/clp:ForceConsoleColor
/p:Configuration=Release
#/p:WindowsTargetPlatformVersion=10.0.16299.0

View File

@ -0,0 +1,66 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 or later
#
# You can build FreeType with MSBuild as follows
#
# MSBuild.exe -t:Rebuild
# -p:Configuration=Debug
# -p:Platform=x64
# -p:UserDefines=FT_DEBUG_LOGGING
# MSBuild.sln
#
# or with different appropriate switches. The library file
# freetype.dll and/or freetype.lib should appear in the objs/
# folder. A copy should be sent to ../freetype-demos/bin/
# to be used with the demo programs.
#
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "builds\windows\vc2010\freetype.vcxproj", "{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|ARM64 = Debug|ARM64
Debug|Win32 = Debug|Win32
Debug Static|x64 = Debug Static|x64
Debug Static|ARM64 = Debug Static|ARM64
Debug Static|Win32 = Debug Static|Win32
Release|x64 = Release|x64
Release|ARM64 = Release|ARM64
Release|Win32 = Release|Win32
Release Static|x64 = Release Static|x64
Release Static|ARM64 = Release Static|ARM64
Release Static|Win32 = Release Static|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.ActiveCfg = Debug|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|x64.Build.0 = Debug|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|ARM64.Build.0 = Debug|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.ActiveCfg = Debug|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug|Win32.Build.0 = Debug|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|x64.ActiveCfg = Debug Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|x64.Build.0 = Debug Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|ARM64.ActiveCfg = Debug Static|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|ARM64.Build.0 = Debug Static|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.ActiveCfg = Debug Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Debug Static|Win32.Build.0 = Debug Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.ActiveCfg = Release|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|x64.Build.0 = Release|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|ARM64.ActiveCfg = Release|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|ARM64.Build.0 = Release|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.ActiveCfg = Release|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release|Win32.Build.0 = Release|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|x64.ActiveCfg = Release Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|x64.Build.0 = Release Static|x64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|ARM64.ActiveCfg = Release Static|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|ARM64.Build.0 = Release Static|ARM64
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.ActiveCfg = Release Static|Win32
{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}.Release Static|Win32.Build.0 = Release Static|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {90811697-0889-4381-80BC-C3FE8FA4931F}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,34 @@
#
# FreeType 2 build system -- top-level Makefile
#
# Copyright (C) 1996-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# Project names
#
PROJECT := freetype
PROJECT_TITLE := FreeType
# The variable TOP_DIR holds the path to the topmost directory in the project
# engine source hierarchy. If it is not defined, default it to `.'.
#
TOP_DIR ?= .
# The variable OBJ_DIR gives the location where object files and the
# FreeType library are built.
#
OBJ_DIR ?= $(TOP_DIR)/objs
include $(TOP_DIR)/builds/toplevel.mk
# EOF

View File

@ -0,0 +1,107 @@
FreeType 2.14.2
===============
Homepage: https://freetype.org
FreeType is a freely available software library to render fonts.
It is written in C, designed to be small, efficient, highly
customizable, and portable while capable of producing high-quality
output (glyph images) of most vector and bitmap font formats.
Please read the `docs/CHANGES` file, it contains IMPORTANT
INFORMATION.
Read the files `docs/INSTALL*` for installation instructions; see the
file `LICENSE.TXT` for the available licenses.
For using FreeType's git repository instead of a distribution bundle,
please read file `README.git`. Note that you have to actually clone
the repository; using a snapshot will not work (in other words, don't
use gitlab's 'Download' button).
The FreeType 2 API reference is located in directory `docs/reference`;
use the file `index.html` as the top entry point. [Please note that
currently the search function for locally installed documentation
doesn't work due to cross-site scripting issues.]
Additional documentation is available as a separate package from our
sites. Go to
https://download.savannah.gnu.org/releases/freetype/
and download one of the following files.
freetype-doc-2.14.2.tar.xz
freetype-doc-2.14.2.tar.gz
ftdoc2142.zip
To view the documentation online, go to
https://freetype.org/freetype2/docs/
Mailing Lists
-------------
The preferred way of communication with the FreeType team is using
e-mail lists.
general use and discussion: freetype@nongnu.org
engine internals, porting, etc.: freetype-devel@nongnu.org
announcements: freetype-announce@nongnu.org
git repository tracker: freetype-commit@nongnu.org
The lists are moderated; see
https://freetype.org/contact.html
how to subscribe.
Bugs
----
Please submit bug reports at
https://gitlab.freedesktop.org/freetype/freetype/-/issues
Alternatively, you might report bugs by e-mail to
`freetype-devel@nongnu.org`. Don't forget to send a detailed
explanation of the problem -- there is nothing worse than receiving a
terse message that only says 'it doesn't work'.
Patches
-------
For larger changes please provide merge requests at
https://gitlab.freedesktop.org/freetype/freetype/-/merge_requests
Alternatively, you can send patches to the `freetype-devel@nongnu.org`
mailing list -- and thank you in advance for your work on improving
FreeType!
Details on the process can be found here:
https://freetype.org/developer.html#patches
Enjoy!
The FreeType Team
----------------------------------------------------------------------
Copyright (C) 2006-2025 by
David Turner, Robert Wilhelm, and Werner Lemberg.
This file is part of the FreeType project, and may only be used,
modified, and distributed under the terms of the FreeType project
license, LICENSE.TXT. By continuing to use, modify, or distribute
this file you indicate that you have read the license and understand
and accept it fully.
--- end of README ---

View File

@ -0,0 +1,102 @@
README.git
==========
repository issues
-----------------
FreeType's official repository site is
https://gitlab.freedesktop.org/freetype ,
from which the 'freetype.git' and 'freetype-demos.git' repositories
can be cloned in the usual way.
git clone https://gitlab.freedesktop.org/freetype/freetype.git
git clone https://gitlab.freedesktop.org/freetype/freetype-demos.git
If you want to use the Savannah mirror instead, you have to do a
slightly different incantation because the repository names contain
digit '2' for historical reasons.
git clone \
https://git.savannah.nongnu.org/git/freetype/freetype2.git \
freetype
git clone \
https://git.savannah.nongnu.org/git/freetype/freetype2-demos.git \
freetype-demos
standard builds with `configure`
--------------------------------
The git repository doesn't contain pre-built configuration scripts for
UNIXish platforms. To generate them say
sh autogen.sh
which in turn depends on the following packages:
automake (1.10.1)
libtool (2.2.4)
autoconf (2.62)
The versions given in parentheses are known to work. Newer versions
should work too, of course. Note that `autogen.sh` also sets up
proper file permissions for the `configure` and auxiliary scripts.
The `autogen.sh` script checks whether the versions of the above three
tools match the numbers above. Otherwise it will complain and suggest
either upgrading or using environment variables to point to more
recent versions of the required tools.
Note that `aclocal` is provided by the 'automake' package on Linux,
and that `libtoolize` is called `glibtoolize` on Darwin (OS X).
alternative build methods
-------------------------
For static builds that don't use platform-specific optimizations, no
configure script is necessary at all; saying
make setup ansi
make
should work on all platforms that have GNU `make` (or `makepp`).
A build with `cmake` or `meson` can be done directly from the git
repository. However, if you want to use the `FT_DEBUG_LOGGING` macro
(see file `docs/DEBUG` for more information) it is currently mandatory
to execute `autogen.sh` in advance; this script clones the 'dlg' git
submodule and copies some files into FreeType's source tree.
Code of Conduct
---------------
Please note that this project is released with a Contributor Code of
Conduct (CoC). By participating in this project you agree to abide by
its terms, which you can find in the following link:
https://www.freedesktop.org/wiki/CodeOfConduct
CoC issues may be raised to the project maintainers at the following
address:
wl@gnu.org
apodtele@gmail.com
----------------------------------------------------------------------
Copyright (C) 2005-2025 by
David Turner, Robert Wilhelm, and Werner Lemberg.
This file is part of the FreeType project, and may only be used,
modified, and distributed under the terms of the FreeType project
license, LICENSE.TXT. By continuing to use, modify, or distribute
this file you indicate that you have read the license and understand
and accept it fully.
--- end of README.git ---

View File

@ -0,0 +1,199 @@
#!/bin/sh
# Copyright (C) 2005-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
run ()
{
echo "running \`$*'"
eval $*
if test $? != 0 ; then
echo "error while running \`$*'"
exit 1
fi
}
get_major_version ()
{
echo $1 | sed -e 's/\([0-9][0-9]*\)\..*/\1/g'
}
get_minor_version ()
{
echo $1 | sed -e 's/[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'
}
get_patch_version ()
{
# tricky: some version numbers don't include a patch
# separated with a point, but something like 1.4-p6
patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/g'`
if test "$patch" = "$1"; then
patch=`echo $1 | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\-p\([0-9][0-9]*\).*/\1/g'`
# if there isn't any patch number, default to 0
if test "$patch" = "$1"; then
patch=0
fi
fi
echo $patch
}
# $1: version to check
# $2: minimum version
compare_to_minimum_version ()
{
MAJOR1=`get_major_version $1`
MAJOR2=`get_major_version $2`
if test $MAJOR1 -lt $MAJOR2; then
echo 0
return
else
if test $MAJOR1 -gt $MAJOR2; then
echo 1
return
fi
fi
MINOR1=`get_minor_version $1`
MINOR2=`get_minor_version $2`
if test $MINOR1 -lt $MINOR2; then
echo 0
return
else
if test $MINOR1 -gt $MINOR2; then
echo 1
return
fi
fi
PATCH1=`get_patch_version $1`
PATCH2=`get_patch_version $2`
if test $PATCH1 -lt $PATCH2; then
echo 0
else
echo 1
fi
}
# check the version of a given tool against a minimum version number
#
# $1: tool path
# $2: tool usual name (e.g. `aclocal')
# $3: tool variable (e.g. `ACLOCAL')
# $4: minimum version to check against
# $5: option field index used to extract the tool version from the
# output of --version
check_tool_version ()
{
field=$5
# assume the output of "[TOOL] --version" is "toolname (GNU toolname foo bar) version"
if test "$field"x = x; then
field=3 # default to 3 for all GNU autotools, after filtering enclosed string
fi
version=`$1 --version | sed -n '1s/([^)]*)/()/gp' | cut -d ' ' -f $field`
version_check=`compare_to_minimum_version $version $4`
if test "$version_check"x = 0x; then
echo "ERROR: Your version of the \`$2' tool is too old."
echo " Minimum version $4 is required (yours is version $version)."
echo " Please upgrade or use the $3 variable to point to a more recent one."
echo ""
exit 1
fi
}
# Solaris 10's shell doesn't like the `!` operator to negate the exit status.
if test -f ./builds/unix/configure.raw; then
:
else
echo "You must be in the same directory as \`autogen.sh'."
echo "Bootstrapping doesn't work if srcdir != builddir."
exit 1
fi
# On MacOS X, the GNU libtool is named `glibtool'.
HOSTOS=`uname`
if test "$LIBTOOLIZE"x != x; then
:
elif test "$HOSTOS"x = Darwinx; then
LIBTOOLIZE=glibtoolize
else
LIBTOOLIZE=libtoolize
fi
if test "$ACLOCAL"x = x; then
ACLOCAL=aclocal
fi
if test "$AUTOCONF"x = x; then
AUTOCONF=autoconf
fi
check_tool_version $ACLOCAL aclocal ACLOCAL 1.10.1
check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4
check_tool_version $AUTOCONF autoconf AUTOCONF 2.62
# This sets FREETYPE version.
eval `sed -n \
-e 's/^#define *\(FREETYPE_MAJOR\) *\([0-9][0-9]*\).*/\1=\2/p' \
-e 's/^#define *\(FREETYPE_MINOR\) *\([0-9][0-9]*\).*/\1=\2/p' \
-e 's/^#define *\(FREETYPE_PATCH\) *\([0-9][0-9]*\).*/\1=\2/p' \
include/freetype/freetype.h`
if test "$FREETYPE_PATCH" = "0"; then
FREETYPE=$FREETYPE_MAJOR.$FREETYPE_MINOR
else
FREETYPE=$FREETYPE_MAJOR.$FREETYPE_MINOR.$FREETYPE_PATCH
fi
echo "FreeType $FREETYPE:"
cd builds/unix
echo "generating \`configure.ac'"
sed -e "s;@VERSION@;$FREETYPE;" \
< configure.raw > configure.ac
run aclocal -I . --force
run $LIBTOOLIZE --force --copy --install
run autoconf --force
chmod +x install-sh
cd ../..
chmod +x ./configure
# Copy all necessary 'dlg' files.
copy_submodule_files ()
{
echo "Copying files from \`subprojects/dlg' to \`src/dlg' and \`include/dlg'"
mkdir include/dlg 2> /dev/null
cp $DLG_INC_DIR/output.h include/dlg
cp $DLG_INC_DIR/dlg.h include/dlg
cp $DLG_SRC_DIR/* src/dlg
}
if test -d ".git" -o -h ".git"; then
DLG_INC_DIR=subprojects/dlg/include/dlg
DLG_SRC_DIR=subprojects/dlg/src/dlg
if test -d "$DLG_INC_DIR"; then
:
else
echo "Checking out submodule in \`subprojects/dlg':"
git submodule update --init
fi
copy_submodule_files
fi
# EOF

View File

@ -0,0 +1,110 @@
README for the builds/amiga subdirectory.
Copyright (C) 2005-2025 by
Werner Lemberg and Detlef Würkner.
This file is part of the FreeType project, and may only be used, modified,
and distributed under the terms of the FreeType project license,
LICENSE.TXT. By continuing to use, modify, or distribute this file you
indicate that you have read the license and understand and accept it
fully.
The makefile.os4 is for the AmigaOS4 SDK. To use it, type
"make -f makefile.os4", it produces a link library libft2_ppc.a.
The makefile is for ppc-morphos-gcc-2.95.3-bin.tgz (gcc 2.95.3 hosted on
68k-Amiga producing MorphOS-PPC-binaries from http://www.morphos.de).
To use it, type "make assign", then "make"; it produces a link library
libft2_ppc.a.
The smakefile is a makefile for Amiga SAS/C 6.58 (no longer available,
latest sold version was 6.50, updates can be found in Aminet). It is
based on the version found in the sourcecode of ttf.library 0.83b for
FreeType 1.3.1 from Richard Griffith (ragriffi@sprynet.com,
http://ragriffi.home.sprynet.com).
You will also need the latest include files and amiga.lib from the
Amiga web site (https://os.amigaworld.de/download.php?id=3) for
AmigaOS 3.9; the generated code should work under AmigaOS 2.04 and up.
To use it, call "smake assign" and then "smake" from the builds/amiga
directory. The results are:
- A link library "ft2_680x0.lib" (where x depends on the setting of
the CPU entry in the smakefile) containing all FreeType2 parts
except of the init code, debugging code, and the system interface
code.
- ftsystem.o, an object module containing the standard version of the
system interface code which uses fopen() fclose() fread() fseek()
ftell() malloc() realloc() and free() from lib:sc.lib (not pure).
- ftsystempure.o, an object module containing the pure version of the
system interface code which uses Open() Close() Read() Seek()
ExamineFH() AsmAllocPooled() AsmFreePooled() etc. This version can
be used in both normal programs and in Amiga run-time shared system
librarys (can be linked with lib:libinit.o, no copying of DATA and
BSS hunks for each OpenLibrary() necessary). Source code is in
src/base/ftsystem.c.
- ftdebug.o, an object module containing the standard version of the
debugging code which uses vprintf() and exit() (not pure).
Debugging can be turned on in FT:include/freetype/config/ftoption.h
and with FT_SetTraceLevel().
- ftdebugpure.o, an object module containing the pure version of the
debugging code which uses KVPrintf() from lib:debug.lib and no
exit(). For debugging of Amiga run-time shared system libraries.
Source code is in src/base/ftdebug.c.
- NO ftinit.o. Because linking with a link library should result in
linking only the needed object modules in it, but standard
ftsystem.o would force ALL FreeType2 modules to be linked to your
program, I decided to use a different scheme: You must #include
FT:src/base/ftinit.c in your sourcecode and specify with #define
statements which modules you need. See
include/freetype/config/ftmodule.h.
To use in your own programs:
- Insert the #define and #include statements from top of
include/freetype/config/ftmodule.h in your source code and
uncomment the #define statements for the FreeType2 modules you need.
- You can use either PARAMETERS=REGISTER or PARAMETERS=STACK for
calling the FreeType2 functions, because the link library and the
object files are compiled with PARAMETERS=BOTH.
- "smake assign" (assign "FT:" to the FreeType2 main directory).
- Compile your program.
- Link with either ftsystem.o or ftsystempure.o, if debugging enabled
with either ftdebug.o or (ftdebugpure.o and lib:debug.lib), and with
ft2_680x0.lib as link library.
To adapt to other compilers:
- The standard ANSI C maximum length of 31 significant characters in
identifiers is not enough for FreeType2. Check if your compiler has
a minimum length of 40 significant characters or can be switched to
it. "idlen=40" is the option for SAS/C. Setting #define
HAVE_LIMIT_ON_IDENTS in an include file may also work (not tested).
- Make sure that the include directory in builds/amiga is searched
before the normal FreeType2 include directory, so you are able to
replace problematic include files with your own version (same may be
useful for the src directory).
- An example of how to replace/workaround a problematic include file
is include/freetype/config/ftconfig.h; it changes a #define that
would prevent SAS/C from generating XDEF's where it should do that and
then includes the standard FreeType2 include file.
Local Variables:
coding: latin-1
End:

View File

@ -0,0 +1,55 @@
/***************************************************************************/
/* */
/* ftconfig.h */
/* */
/* Amiga-specific configuration file (specification only). */
/* */
/* Copyright (C) 2005-2025 by */
/* Werner Lemberg and Detlef Würkner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*
* This is an example how to override the default FreeType2 header files
* with Amiga-specific changes. When the compiler searches this directory
* before the default directory, we can do some modifications.
*
* Here we must change FT_EXPORT_DEF so that SAS/C does
* generate the needed XDEFs.
*/
#if 0
#define FT_EXPORT_DEF( x ) extern x
#endif
#undef FT_EXPORT_DEF
#define FT_EXPORT_DEF( x ) x
/* Now include the original file */
#ifndef __MORPHOS__
#ifdef __SASC
#include "FT:include/freetype/config/ftconfig.h"
#else
#include "/FT/include/freetype/config/ftconfig.h"
#endif
#else
/* We must define that, it seems that
* lib/gcc-lib/ppc-morphos/2.95.3/include/syslimits.h is missing in
* ppc-morphos-gcc-2.95.3-bin.tgz (gcc for 68k producing MorphOS PPC elf
* binaries from http://www.morphos.de)
*/
#define _LIBC_LIMITS_H_
#include "/FT/include/freetype/config/ftconfig.h"
#endif
/*
Local Variables:
coding: latin-1
End:
*/

View File

@ -0,0 +1,158 @@
/***************************************************************************/
/* */
/* ftmodule.h */
/* */
/* Amiga-specific FreeType module selection. */
/* */
/* Copyright (C) 2005-2025 by */
/* Werner Lemberg and Detlef Würkner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*
* To avoid that all your programs include all FreeType modules,
* you copy the following piece of source code into your own
* source file and specify which modules you really need in your
* application by uncommenting the appropriate lines.
*/
/*
//#define FT_USE_AUTOFIT // autofitter
//#define FT_USE_RASTER // monochrome rasterizer
//#define FT_USE_SMOOTH // anti-aliasing rasterizer
//#define FT_USE_TT // truetype font driver
//#define FT_USE_T1 // type1 font driver
//#define FT_USE_T42 // type42 font driver
//#define FT_USE_T1CID // cid-keyed type1 font driver // no cmap support
//#define FT_USE_CFF // opentype font driver
//#define FT_USE_BDF // bdf bitmap font driver
//#define FT_USE_PCF // pcf bitmap font driver
//#define FT_USE_PFR // pfr font driver
//#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver
//#define FT_USE_OTV // opentype validator
//#define FT_USE_GXV // truetype gx validator
#include "FT:src/base/ftinit.c"
*/
/* Make sure that the needed support modules are built in.
* Dependencies can be found by searching for FT_Get_Module.
*/
#ifdef FT_USE_T42
#define FT_USE_TT
#endif
#ifdef FT_USE_TT
#define FT_USE_SFNT
#endif
#ifdef FT_USE_CFF
#define FT_USE_SFNT
#define FT_USE_PSHINT
#define FT_USE_PSNAMES
#endif
#ifdef FT_USE_T1
#define FT_USE_PSAUX
#define FT_USE_PSHINT
#define FT_USE_PSNAMES
#endif
#ifdef FT_USE_T1CID
#define FT_USE_PSAUX
#define FT_USE_PSHINT
#define FT_USE_PSNAMES
#endif
#ifdef FT_USE_PSAUX
#define FT_USE_PSNAMES
#endif
#ifdef FT_USE_SFNT
#define FT_USE_PSNAMES
#endif
/* Now include the modules */
#ifdef FT_USE_AUTOFIT
FT_USE_MODULE( FT_Module_Class, autofit_module_class )
#endif
#ifdef FT_USE_TT
FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
#endif
#ifdef FT_USE_T1
FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
#endif
#ifdef FT_USE_CFF
FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
#endif
#ifdef FT_USE_T1CID
FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
#endif
#ifdef FT_USE_PFR
FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
#endif
#ifdef FT_USE_T42
FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
#endif
#ifdef FT_USE_WINFNT
FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
#endif
#ifdef FT_USE_PCF
FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
#endif
#ifdef FT_USE_PSAUX
FT_USE_MODULE( FT_Module_Class, psaux_module_class )
#endif
#ifdef FT_USE_PSNAMES
FT_USE_MODULE( FT_Module_Class, psnames_module_class )
#endif
#ifdef FT_USE_PSHINT
FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
#endif
#ifdef FT_USE_RASTER
FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
#endif
#ifdef FT_USE_SFNT
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
#endif
#ifdef FT_USE_SMOOTH
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
#endif
#ifdef FT_USE_OTV
FT_USE_MODULE( FT_Module_Class, otv_module_class )
#endif
#ifdef FT_USE_BDF
FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
#endif
#ifdef FT_USE_GXV
FT_USE_MODULE( FT_Module_Class, gxv_module_class )
#endif
/*
Local Variables:
coding: latin-1
End:
*/

View File

@ -0,0 +1,293 @@
#
# Makefile for FreeType2 link library using ppc-morphos-gcc-2.95.3-bin.tgz
# (gcc 2.95.3 hosted on 68k-Amiga producing MorphOS-PPC-binaries from
# http://www.morphos.de)
#
# Copyright (C) 2005-2025 by
# Werner Lemberg and Detlef Würkner.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
#
# to build from the builds/amiga directory call
#
# make assign
# make
#
# Your programs source code should start with this
# (uncomment the parts you do not need to keep the program small):
# ---8<---
#define FT_USE_AUTOFIT // autofitter
#define FT_USE_RASTER // monochrome rasterizer
#define FT_USE_SMOOTH // anti-aliasing rasterizer
#define FT_USE_TT // truetype font driver
#define FT_USE_T1 // type1 font driver
#define FT_USE_T42 // type42 font driver
#define FT_USE_T1CID // cid-keyed type1 font driver
#define FT_USE_CFF // opentype font driver
#define FT_USE_BDF // bdf bitmap font driver
#define FT_USE_PCF // pcf bitmap font driver
#define FT_USE_PFR // pfr font driver
#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver
#define FT_USE_OTV // opentype validator
#define FT_USE_GXV // truetype gx validator
#include "FT:src/base/ftinit.c"
# ---8<---
#
# link your programs with libft2_ppc.a and either ftsystem.ppc.o or ftsystempure.ppc.o
# (and either ftdebug.ppc.o or ftdebugpure.ppc.o if you enabled FT_DEBUG_LEVEL_ERROR or
# FT_DEBUG_LEVEL_TRACE in include/freetype/config/ftoption.h).
all: libft2_ppc.a ftsystem.ppc.o ftsystempure.ppc.o
assign:
assign FT: //
FTSRC = /FT/src
CC = ppc-morphos-gcc
AR = ppc-morphos-ar rc
RANLIB = ppc-morphos-ranlib
LD = ppc-morphos-ld
CFLAGS = -DFT2_BUILD_LIBRARY -O2 -I/emu/emulinclude/includegcc -I/emu/include -Iinclude -I$(FTSRC) -I/FT/include
#
# FreeType2 library base
#
ftbase.ppc.o: $(FTSRC)/base/ftbase.c
$(CC) -c $(CFLAGS) -o $@ $<
ftinit.ppc.o: $(FTSRC)/base/ftinit.c
$(CC) -c $(CFLAGS) -o $@ $<
ftsystem.ppc.o: $(FTSRC)/base/ftsystem.c
$(CC) -c $(CFLAGS) -o $@ $<
# pure version for use in run-time library etc
ftsystempure.ppc.o: src/base/ftsystem.c
$(CC) -c $(CFLAGS) -o $@ $<
ftdebug.ppc.o: $(FTSRC)/base/ftdebug.c
$(CC) -c $(CFLAGS) -o $@ $<
# pure version for use in run-time library etc
ftdebugpure.ppc.o: src/base/ftdebug.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library base extensions
#
ftbbox.ppc.o: $(FTSRC)/base/ftbbox.c
$(CC) -c $(CFLAGS) -o $@ $<
ftbdf.ppc.o: $(FTSRC)/base/ftbdf.c
$(CC) -c $(CFLAGS) -o $@ $<
ftbitmap.ppc.o: $(FTSRC)/base/ftbitmap.c
$(CC) -c $(CFLAGS) -o $@ $<
ftcid.ppc.o: $(FTSRC)/base/ftcid.c
$(CC) -c $(CFLAGS) -o $@ $<
ftfstype.ppc.o: $(FTSRC)/base/ftfstype.c
$(CC) -c $(CFLAGS) -o $@ $<
ftgasp.ppc.o: $(FTSRC)/base/ftgasp.c
$(CC) -c $(CFLAGS) -o $@ $<
ftglyph.ppc.o: $(FTSRC)/base/ftglyph.c
$(CC) -c $(CFLAGS) -o $@ $<
ftgxval.ppc.o: $(FTSRC)/base/ftgxval.c
$(CC) -c $(CFLAGS) -o $@ $<
ftmm.ppc.o: $(FTSRC)/base/ftmm.c
$(CC) -c $(CFLAGS) -o $@ $<
ftotval.ppc.o: $(FTSRC)/base/ftotval.c
$(CC) -c $(CFLAGS) -o $@ $<
ftpatent.ppc.o: $(FTSRC)/base/ftpatent.c
$(CC) -c $(CFLAGS) -o $@ $<
ftpfr.ppc.o: $(FTSRC)/base/ftpfr.c
$(CC) -c $(CFLAGS) -o $@ $<
ftstroke.ppc.o: $(FTSRC)/base/ftstroke.c
$(CC) -c $(CFLAGS) -o $@ $<
ftsynth.ppc.o: $(FTSRC)/base/ftsynth.c
$(CC) -c $(CFLAGS) -o $@ $<
fttype1.ppc.o: $(FTSRC)/base/fttype1.c
$(CC) -c $(CFLAGS) -o $@ $<
ftwinfnt.ppc.o: $(FTSRC)/base/ftwinfnt.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library autofitting module
#
autofit.ppc.o: $(FTSRC)/autofit/autofit.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library postscript hinting module
#
pshinter.ppc.o: $(FTSRC)/pshinter/pshinter.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library PS support module
#
psaux.ppc.o: $(FTSRC)/psaux/psaux.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library PS glyph names module
#
psnames.ppc.o: $(FTSRC)/psnames/psnames.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library monochrome raster module
#
raster.ppc.o: $(FTSRC)/raster/raster.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library anti-aliasing raster module
#
smooth.ppc.o: $(FTSRC)/smooth/smooth.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library 'sfnt' module
#
sfnt.ppc.o: $(FTSRC)/sfnt/sfnt.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library glyph and image caching system
#
ftcache.ppc.o: $(FTSRC)/cache/ftcache.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library OpenType font driver
#
cff.ppc.o: $(FTSRC)/cff/cff.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library TrueType font driver
#
truetype.ppc.o: $(FTSRC)/truetype/truetype.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library Type1 font driver
#
type1.ppc.o: $(FTSRC)/type1/type1.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library Type42 font driver
#
type42.ppc.o: $(FTSRC)/type42/type42.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library CID-keyed Type1 font driver
#
type1cid.ppc.o: $(FTSRC)/cid/type1cid.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library BDF bitmap font driver
#
bdf.ppc.o: $(FTSRC)/bdf/bdf.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library PCF bitmap font driver
#
pcf.ppc.o: $(FTSRC)/pcf/pcf.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library gzip support for compressed PCF bitmap fonts
#
gzip.ppc.o: $(FTSRC)/gzip/ftgzip.c
$(CC) -c $(CFLAGS) -o $@ $<
# FreeType2 library bzip2 support for compressed PCF bitmap fonts
#
bzip2.ppc.o: $(FTSRC)/bzip2/ftbzip2.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library compress support for compressed PCF bitmap fonts
#
lzw.ppc.o: $(FTSRC)/lzw/ftlzw.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library PFR font driver
#
pfr.ppc.o: $(FTSRC)/pfr/pfr.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library Windows FNT/FON bitmap font driver
#
winfnt.ppc.o: $(FTSRC)/winfonts/winfnt.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library TrueTypeGX Validator
#
gxvalid.ppc.o: $(FTSRC)/gxvalid/gxvalid.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library OpenType validator
#
otvalid.ppc.o: $(FTSRC)/otvalid/otvalid.c
$(CC) -c $(CFLAGS) -o $@ $<
BASEPPC = ftbase.ppc.o ftbbox.ppc.o ftbdf.ppc.o ftbitmap.ppc.o ftcid.ppc.o \
oftfstype.ppc.o ftgasp.ppc.o ftglyph.ppc.o \
ftgxval.ppc.o ftmm.ppc.o ftotval.ppc.o \
ftpatent.ppc.o ftpfr.ppc.o ftstroke.ppc.o ftsynth.ppc.o \
fttype1.ppc.o ftwinfnt.ppc.o
DEBUGPPC = ftdebug.ppc.o ftdebugpure.ppc.o
AFITPPC = autofit.ppc.o
GXVPPC = gxvalid.ppc.o
OTVPPC = otvalid.ppc.o
PSPPC = psaux.ppc.o psnames.ppc.o pshinter.ppc.o
RASTERPPC = raster.ppc.o smooth.ppc.o
FONTDPPC = cff.ppc.o type1.ppc.o type42.ppc.o type1cid.ppc.o truetype.ppc.o\
bdf.ppc.o pcf.ppc.o pfr.ppc.o winfnt.ppc.o
libft2_ppc.a: $(BASEPPC) $(AFITPPC) $(GXVPPC) $(OTVPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) gzip.ppc.o bzip2.ppc.o lzw.ppc.o
$(AR) $@ $(BASEPPC) $(AFITPPC) $(GXVPPC) $(OTVPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) gzip.ppc.o bzip2.ppc.o lzw.ppc.o
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
#Local Variables:
#coding: latin-1
#End:

View File

@ -0,0 +1,297 @@
#
# Makefile for FreeType2 link library using gcc 4.0.3 from the
# AmigaOS4 SDK
#
# Copyright (C) 2005-2025 by
# Werner Lemberg and Detlef Würkner.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# to build from the builds/amiga directory call
#
# make -f makefile.os4
#
# Your programs source code should start with this
# (uncomment the parts you do not need to keep the program small):
# ---8<---
#define FT_USE_AUTOFIT // autofitter
#define FT_USE_RASTER // monochrome rasterizer
#define FT_USE_SMOOTH // anti-aliasing rasterizer
#define FT_USE_TT // truetype font driver
#define FT_USE_T1 // type1 font driver
#define FT_USE_T42 // type42 font driver
#define FT_USE_T1CID // cid-keyed type1 font driver
#define FT_USE_CFF // opentype font driver
#define FT_USE_BDF // bdf bitmap font driver
#define FT_USE_PCF // pcf bitmap font driver
#define FT_USE_PFR // pfr font driver
#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver
#define FT_USE_OTV // opentype validator
#define FT_USE_GXV // truetype gx validator
#include "FT:src/base/ftinit.c"
# ---8<---
#
# link your programs with libft2_ppc.a and either ftsystem.ppc.o or ftsystempure.ppc.o
# (and either ftdebug.ppc.o or ftdebugpure.ppc.o if you enabled FT_DEBUG_LEVEL_ERROR or
# FT_DEBUG_LEVEL_TRACE in include/freetype/config/ftoption.h).
all: assign libft2_ppc.a ftsystem.ppc.o ftsystempure.ppc.o
assign:
assign FT: //
CC = ppc-amigaos-gcc
AR = ppc-amigaos-ar
RANLIB = ppc-amigaos-ranlib
DIRFLAGS = -Iinclude -I/FT/src -I/FT/include -I/SDK/include
WARNINGS = -Wall -W -Wundef -Wpointer-arith -Wbad-function-cast \
-Waggregate-return -Wwrite-strings -Wshadow
OPTIONS = -DFT2_BUILD_LIBRARY -DNDEBUG -fno-builtin
OPTIMIZE = -O2 -fomit-frame-pointer -fstrength-reduce -finline-functions
CFLAGS = -mcrt=clib2 $(DIRFLAGS) $(WARNINGS) $(FT2FLAGS) $(OPTIONS) $(OPTIMIZE)
#
# FreeType2 library base
#
ftbase.ppc.o: FT:src/base/ftbase.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftbase.c
ftinit.ppc.o: FT:src/base/ftinit.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftinit.c
ftsystem.ppc.o: FT:src/base/ftsystem.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftsystem.c
# pure version for use in run-time library etc
ftsystempure.ppc.o: src/base/ftsystem.c
$(CC) -c $(CFLAGS) -o $@ src/base/ftsystem.c
#
# FreeType2 library base extensions
#
ftbbox.ppc.o: FT:src/base/ftbbox.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftbbox.c
ftbdf.ppc.o: FT:src/base/ftbdf.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftbdf.c
ftbitmap.ppc.o: FT:src/base/ftbitmap.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftbitmap.c
ftcid.ppc.o: FT:src/base/ftcid.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftcid.c
ftdebug.ppc.o: FT:src/base/ftdebug.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftdebug.c
# pure version for use in run-time library etc
ftdebugpure.ppc.o: src/base/ftdebug.c
$(CC) -c $(CFLAGS) -o $@ src/base/ftdebug.c
ftfstype.ppc.o: FT:src/base/ftfstype.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftfstype.c
ftgasp.ppc.o: FT:src/base/ftgasp.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftgasp.c
ftglyph.ppc.o: FT:src/base/ftglyph.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftglyph.c
ftgxval.ppc.o: FT:src/base/ftgxval.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftgxval.c
ftmm.ppc.o: FT:src/base/ftmm.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftmm.c
ftotval.ppc.o: FT:src/base/ftotval.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftotval.c
ftpatent.ppc.o: FT:src/base/ftpatent.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftpatent.c
ftpfr.ppc.o: FT:src/base/ftpfr.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftpfr.c
ftstroke.ppc.o: FT:src/base/ftstroke.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftstroke.c
ftsynth.ppc.o: FT:src/base/ftsynth.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftsynth.c
fttype1.ppc.o: FT:src/base/fttype1.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/fttype1.c
ftwinfnt.ppc.o: FT:src/base/ftwinfnt.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/base/ftwinfnt.c
#
# FreeType2 library autofitting module
#
autofit.ppc.o: FT:src/autofit/autofit.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/autofit/autofit.c
#
# FreeType2 library postscript hinting module
#
pshinter.ppc.o: FT:src/pshinter/pshinter.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/pshinter/pshinter.c
#
# FreeType2 library PS support module
#
psaux.ppc.o: FT:src/psaux/psaux.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/psaux/psaux.c
#
# FreeType2 library PS glyph names module
#
psnames.ppc.o: FT:src/psnames/psnames.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/psnames/psnames.c
#
# FreeType2 library monochrome raster module
#
raster.ppc.o: FT:src/raster/raster.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/raster/raster.c
#
# FreeType2 library anti-aliasing raster module
#
smooth.ppc.o: FT:src/smooth/smooth.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/smooth/smooth.c
#
# FreeType2 library 'sfnt' module
#
sfnt.ppc.o: FT:src/sfnt/sfnt.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/sfnt/sfnt.c
#
# FreeType2 library glyph and image caching system
#
ftcache.ppc.o: FT:src/cache/ftcache.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/cache/ftcache.c
#
# FreeType2 library OpenType font driver
#
cff.ppc.o: FT:src/cff/cff.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/cff/cff.c
#
# FreeType2 library TrueType font driver
#
truetype.ppc.o: FT:src/truetype/truetype.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/truetype/truetype.c
#
# FreeType2 library Type1 font driver
#
type1.ppc.o: FT:src/type1/type1.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/type1/type1.c
#
# FreeType2 library Type42 font driver
#
type42.ppc.o: FT:src/type42/type42.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/type42/type42.c
#
# FreeType2 library CID-keyed Type1 font driver
#
type1cid.ppc.o: FT:src/cid/type1cid.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/cid/type1cid.c
#
# FreeType2 library BDF bitmap font driver
#
bdf.ppc.o: FT:src/bdf/bdf.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/bdf/bdf.c
#
# FreeType2 library PCF bitmap font driver
#
pcf.ppc.o: FT:src/pcf/pcf.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/pcf/pcf.c
#
# FreeType2 library gzip support for compressed PCF bitmap fonts
#
gzip.ppc.o: FT:src/gzip/ftgzip.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/gzip/ftgzip.c
#
# FreeType2 library bzip2 support for compressed PCF bitmap fonts
#
bzip2.ppc.o: FT:src/bzip2/ftbzip2.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/bzip2/ftbzip2.c
#
# FreeType2 library compress support for compressed PCF bitmap fonts
#
lzw.ppc.o: FT:src/lzw/ftlzw.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/lzw/ftlzw.c
#
# FreeType2 library PFR font driver
#
pfr.ppc.o: FT:src/pfr/pfr.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/pfr/pfr.c
#
# FreeType2 library Windows FNT/FON bitmap font driver
#
winfnt.ppc.o: FT:src/winfonts/winfnt.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/winfonts/winfnt.c
#
# FreeType2 library TrueTypeGX Validator
#
gxvalid.ppc.o: FT:src/gxvalid/gxvalid.c
$(CC) -c $(CFLAGS) -Wno-aggregate-return -o $@ /FT/src/gxvalid/gxvalid.c
#
# FreeType2 library OpenType validator
#
otvalid.ppc.o: FT:src/otvalid/otvalid.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/otvalid/otvalid.c
BASE = ftbase.ppc.o ftbbox.ppc.o ftbdf.ppc.o ftbitmap.ppc.o ftcid.ppc.o \
ftfstype.ppc.o ftgasp.ppc.o ftglyph.ppc.o \
ftgxval.ppc.o ftmm.ppc.o ftotval.ppc.o \
ftpatent.ppc.o ftpfr.ppc.o ftstroke.ppc.o ftsynth.ppc.o \
fttype1.ppc.o ftwinfnt.ppc.o
DEBUG = ftdebug.ppc.o ftdebugpure.ppc.o
AFIT = autofit.ppc.o
GXV = gxvalid.ppc.o
OTV = otvalid.ppc.o
PS = psaux.ppc.o psnames.ppc.o pshinter.ppc.o
RASTER = raster.ppc.o smooth.ppc.o
FONTD = cff.ppc.o type1.ppc.o type42.ppc.o type1cid.ppc.o truetype.ppc.o\
bdf.ppc.o pcf.ppc.o pfr.ppc.o winfnt.ppc.o
libft2_ppc.a: $(BASE) $(AFIT) $(GXV) $(OTV) $(PS) $(RASTER) sfnt.ppc.o ftcache.ppc.o $(FONTD) gzip.ppc.o lzw.ppc.o
$(AR) r $@ $(BASE) $(AFIT) $(GXV) $(OTV) $(PS) $(RASTER) sfnt.ppc.o ftcache.ppc.o $(FONTD) gzip.ppc.o lzw.ppc.o
$(RANLIB) $@
#Local Variables:
#coding: latin-1
#End:

View File

@ -0,0 +1,299 @@
#
# Makefile for FreeType2 link library using Amiga SAS/C 6.58
#
# Copyright (C) 2005-2025 by
# Werner Lemberg and Detlef Würkner.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
# to build from the builds/amiga directory call
#
# smake assign
# smake
#
# Your programs source code should start with this
# (uncomment the parts you do not need to keep the program small):
# ---8<---
#define FT_USE_AUTOFIT // autofitter
#define FT_USE_RASTER // monochrome rasterizer
#define FT_USE_SMOOTH // anti-aliasing rasterizer
#define FT_USE_TT // truetype font driver
#define FT_USE_T1 // type1 font driver
#define FT_USE_T42 // type42 font driver
#define FT_USE_T1CID // cid-keyed type1 font driver
#define FT_USE_CFF // opentype font driver
#define FT_USE_BDF // bdf bitmap font driver
#define FT_USE_PCF // pcf bitmap font driver
#define FT_USE_PFR // pfr font driver
#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver
#define FT_USE_OTV // opentype validator
#define FT_USE_GXV // truetype gx validator
#include "FT:src/base/ftinit.c"
# ---8<---
#
# link your programs with ft2_680x0.lib and either ftsystem.o or ftsystempure.o
# (and either ftdebug.o or ftdebugpure.o if you enabled FT_DEBUG_LEVEL_ERROR or
# FT_DEBUG_LEVEL_TRACE in include/freetype/config/ftoption.h).
OBJBASE = ftbase.o ftbbox.o ftbdf.o ftbitmap.o ftcid.o ftfstype.o \
ftgasp.o ftglyph.o ftgxval.o ftmm.o ftotval.o \
ftpatent.o ftpfr.o ftstroke.o ftsynth.o fttype1.o ftwinfnt.o
OBJSYSTEM = ftsystem.o ftsystempure.o
OBJDEBUG = ftdebug.o ftdebugpure.o
OBJAFIT = autofit.o
OBJGXV = gxvalid.o
OBJOTV = otvalid.o
OBJPS = psaux.o psnames.o pshinter.o
OBJRASTER = raster.o smooth.o
OBJSFNT = sfnt.o
OBJCACHE = ftcache.o
OBJFONTD = cff.o type1.o type42.o type1cid.o\
truetype.o winfnt.o bdf.o pcf.o pfr.o
CORE = FT:src/
CPU = 68000
#CPU = 68020
#CPU = 68030
#CPU = 68040
#CPU = 68060
OPTIMIZER = optinlocal
SCFLAGS = optimize opttime optsched strmerge data=faronly idlen=50 cpu=$(CPU)\
idir=include/ idir=$(CORE) idir=FT:include/ nostackcheck nochkabort\
noicons ignore=79,85,110,306 parameters=both define=FT2_BUILD_LIBRARY
LIB = ft2_$(CPU).lib
# sample linker options
OPTS = link lib=$(LIB),lib:sc.lib,lib:amiga.lib,lib:debug.lib\
smallcode smalldata noicons utillib
# sample program entry
#myprog: myprog.c ftsystem.o $(LIB)
# sc $< programname=$@ ftsystem.o $(SCFLAGS) $(OPTS)
all: $(LIB) $(OBJSYSTEM) $(OBJDEBUG)
assign:
assign FT: //
# uses separate object modules in lib to make for easier debugging
# also, can make smaller programs if entire engine is not used
ft2_$(CPU).lib: $(OBJBASE) $(OBJAFIT) $(OBJOTV) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) lzw.o gzip.o bzip2.o
oml $@ r $(OBJBASE) $(OBJAFIT) $(OBJOTV) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) lzw.o gzip.o bzip2.o
clean:
-delete \#?.o
realclean: clean
-delete ft2$(CPU).lib
#
# freetype library base
#
ftbase.o: $(CORE)base/ftbase.c
sc $(SCFLAGS) objname=$@ $<
ftinit.o: $(CORE)base/ftinit.c
sc $(SCFLAGS) objname=$@ $<
ftsystem.o: $(CORE)base/ftsystem.c
sc $(SCFLAGS) objname=$@ $<
ftsystempure.o: src/base/ftsystem.c ## pure version for use in run-time library etc
sc $(SCFLAGS) objname=$@ $<
ftdebug.o: $(CORE)base/ftdebug.c
sc $(SCFLAGS) objname=$@ $<
ftdebugpure.o: src/base/ftdebug.c ## pure version for use in run-time library etc
sc $(SCFLAGS) objname=$@ $<
#
# freetype library base extensions
#
ftbbox.o: $(CORE)base/ftbbox.c
sc $(SCFLAGS) objname=$@ $<
ftbdf.o: $(CORE)base/ftbdf.c
sc $(SCFLAGS) objname=$@ $<
ftbitmap.o: $(CORE)base/ftbitmap.c
sc $(SCFLAGS) objname=$@ $<
ftcid.o: $(CORE)base/ftcid.c
sc $(SCFLAGS) objname=$@ $<
ftfstype.o: $(CORE)base/ftfstype.c
sc $(SCFLAGS) objname=$@ $<
ftgasp.o: $(CORE)base/ftgasp.c
sc $(SCFLAGS) objname=$@ $<
ftglyph.o: $(CORE)base/ftglyph.c
sc $(SCFLAGS) objname=$@ $<
ftgxval.o: $(CORE)base/ftgxval.c
sc $(SCFLAGS) objname=$@ $<
ftmm.o: $(CORE)base/ftmm.c
sc $(SCFLAGS) objname=$@ $<
ftotval.o: $(CORE)base/ftotval.c
sc $(SCFLAGS) objname=$@ $<
ftpatent.o: $(CORE)base/ftpatent.c
sc $(SCFLAGS) objname=$@ $<
ftpfr.o: $(CORE)base/ftpfr.c
sc $(SCFLAGS) objname=$@ $<
ftstroke.o: $(CORE)base/ftstroke.c
sc $(SCFLAGS) objname=$@ $<
ftsynth.o: $(CORE)base/ftsynth.c
sc $(SCFLAGS) objname=$@ $<
fttype1.o: $(CORE)base/fttype1.c
sc $(SCFLAGS) objname=$@ $<
ftwinfnt.o: $(CORE)base/ftwinfnt.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library autofitter module
#
autofit.o: $(CORE)autofit/autofit.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library PS hinting module
#
pshinter.o: $(CORE)pshinter/pshinter.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library PS support module
#
psaux.o: $(CORE)psaux/psaux.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library PS glyph names module
#
psnames.o: $(CORE)psnames/psnames.c
sc $(SCFLAGS) code=far objname=$@ $<
#
# freetype library monochrome raster module
#
raster.o: $(CORE)raster/raster.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library anti-aliasing raster module
#
smooth.o: $(CORE)smooth/smooth.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library 'sfnt' module
#
sfnt.o: $(CORE)sfnt/sfnt.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library glyph and image caching system (still experimental)
#
ftcache.o: $(CORE)cache/ftcache.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library OpenType font driver
#
cff.o: $(CORE)cff/cff.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library TrueType font driver
#
truetype.o: $(CORE)truetype/truetype.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library Type1 font driver
#
type1.o: $(CORE)type1/type1.c
sc $(SCFLAGS) objname=$@ $<
#
# FreeType2 library Type42 font driver
#
type42.o: $(CORE)type42/type42.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library CID-keyed Type1 font driver
#
type1cid.o: $(CORE)cid/type1cid.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library CID-keyed Type1 font driver extensions
#
#cidafm.o: $(CORE)cid/cidafm.c
# sc $(SCFLAGS) objname=$@ $<
#
# freetype library BDF bitmap font driver
#
bdf.o: $(CORE)bdf/bdf.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library PCF bitmap font driver
#
pcf.o: $(CORE)pcf/pcf.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library gzip support for compressed PCF bitmap fonts
#
gzip.o: $(CORE)gzip/ftgzip.c
sc $(SCFLAGS) define FAR objname=$@ $<
#
# freetype library bzip2 support for compressed PCF bitmap fonts
#
bzip2.o: $(CORE)bzip2/ftbzip2.c
sc $(SCFLAGS) define FAR objname=$@ $<
#
# freetype library compress support for compressed PCF bitmap fonts
#
lzw.o: $(CORE)lzw/ftlzw.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library PFR font driver
#
pfr.o: $(CORE)pfr/pfr.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library Windows FNT/FON bitmap font driver
#
winfnt.o: $(CORE)winfonts/winfnt.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library TrueTypeGX validator
#
gxvalid.o: $(CORE)gxvalid/gxvalid.c
sc $(SCFLAGS) objname=$@ $<
#
# freetype library OpenType validator
#
otvalid.o: $(CORE)otvalid/otvalid.c
sc $(SCFLAGS) objname=$@ $<
#Local Variables:
#coding: latin-1
#End:

View File

@ -0,0 +1,348 @@
/****************************************************************************
*
* ftdebug.c
*
* Debugging and logging component for amiga (body).
*
* Copyright (C) 1996-2025 by
* David Turner, Robert Wilhelm, Werner Lemberg, and Detlef Wuerkner.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This component contains various macros and functions used to ease the
* debugging of the FreeType engine. Its main purpose is in assertion
* checking, tracing, and error detection.
*
* There are now three debugging modes:
*
* - trace mode
*
* Error and trace messages are sent to the log file (which can be the
* standard error output).
*
* - error mode
*
* Only error messages are generated.
*
* - release mode:
*
* No error message is sent or generated. The code is free from any
* debugging parts.
*
*/
/*
* Based on the default `ftdebug.c' file,
* replaced `vprintf' with `KVPrintF',
* commented out `exit',
* replaced `getenv' with `GetVar'.
*/
#include <exec/types.h>
#include <utility/tagitem.h>
#include <dos/exall.h>
#include <dos/var.h>
#define __NOLIBBASE__
#define __NOLOBALIFACE__
#define __USE_INLINE__
#include <proto/dos.h>
#include <clib/debug_protos.h>
#ifndef __amigaos4__
extern struct Library* DOSBase;
#else
extern struct DOSIFace* IDOS;
#endif
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/internal/ftdebug.h>
#ifdef FT_DEBUG_LEVEL_ERROR
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Message( const char* fmt,
... )
{
va_list ap;
va_start( ap, fmt );
KVPrintF( fmt, ap );
va_end( ap );
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Panic( const char* fmt,
... )
{
va_list ap;
va_start( ap, fmt );
KVPrintF( fmt, ap );
va_end( ap );
/* exit( EXIT_FAILURE ); */
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( int )
FT_Throw( FT_Error error,
int line,
const char* file )
{
#if 0
/* activating the code in this block makes FreeType very chatty */
fprintf( stderr,
"%s:%d: error 0x%02x: %s\n",
file,
line,
error,
FT_Error_String( error ) );
#else
FT_UNUSED( error );
FT_UNUSED( line );
FT_UNUSED( file );
#endif
return 0;
}
#endif /* FT_DEBUG_LEVEL_ERROR */
#ifdef FT_DEBUG_LEVEL_TRACE
/* array of trace levels, initialized to 0; */
/* this gets adjusted at run-time */
static int ft_trace_levels_enabled[trace_count];
/* array of trace levels, always initialized to 0 */
static int ft_trace_levels_disabled[trace_count];
/* a pointer to either `ft_trace_levels_enabled' */
/* or `ft_trace_levels_disabled' */
int* ft_trace_levels;
/* define array of trace toggle names */
#define FT_TRACE_DEF( x ) #x ,
static const char* ft_trace_toggles[trace_count + 1] =
{
#include <freetype/internal/fttrace.h>
NULL
};
#undef FT_TRACE_DEF
/* documentation is in ftdebug.h */
FT_BASE_DEF( FT_Int )
FT_Trace_Get_Count( void )
{
return trace_count;
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( const char * )
FT_Trace_Get_Name( FT_Int idx )
{
int max = FT_Trace_Get_Count();
if ( idx < max )
return ft_trace_toggles[idx];
else
return NULL;
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Trace_Disable( void )
{
ft_trace_levels = ft_trace_levels_disabled;
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Trace_Enable( void )
{
ft_trace_levels = ft_trace_levels_enabled;
}
/**************************************************************************
*
* Initialize the tracing sub-system. This is done by retrieving the
* value of the `FT2_DEBUG' environment variable. It must be a list of
* toggles, separated by spaces, `;', or `,'. Example:
*
* export FT2_DEBUG="any:3 memory:7 stream:5"
*
* This requests that all levels be set to 3, except the trace level for
* the memory and stream components which are set to 7 and 5,
* respectively.
*
* See the file `include/freetype/internal/fttrace.h' for details of
* the available toggle names.
*
* The level must be between 0 and 7; 0 means quiet (except for serious
* runtime errors), and 7 means _very_ verbose.
*/
FT_BASE_DEF( void )
ft_debug_init( void )
{
/* const char* ft2_debug = ft_getenv( "FT2_DEBUG" ); */
char buf[256];
const char* ft2_debug = &buf[0];
/* if ( ft2_debug ) */
if ( GetVar( "FT2_DEBUG", (STRPTR)ft2_debug, 256, LV_VAR ) > 0 )
{
const char* p = ft2_debug;
const char* q;
for ( ; *p; p++ )
{
/* skip leading whitespace and separators */
if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
continue;
/* read toggle name, followed by ':' */
q = p;
while ( *p && *p != ':' )
p++;
if ( !*p )
break;
if ( *p == ':' && p > q )
{
FT_Int n, i, len = (FT_Int)( p - q );
FT_Int level = -1, found = -1;
for ( n = 0; n < trace_count; n++ )
{
const char* toggle = ft_trace_toggles[n];
for ( i = 0; i < len; i++ )
{
if ( toggle[i] != q[i] )
break;
}
if ( i == len && toggle[i] == 0 )
{
found = n;
break;
}
}
/* read level */
p++;
if ( *p )
{
level = *p - '0';
if ( level < 0 || level > 7 )
level = -1;
}
if ( found >= 0 && level >= 0 )
{
if ( found == trace_any )
{
/* special case for `any' */
for ( n = 0; n < trace_count; n++ )
ft_trace_levels_enabled[n] = level;
}
else
ft_trace_levels_enabled[found] = level;
}
}
}
}
ft_trace_levels = ft_trace_levels_enabled;
}
#else /* !FT_DEBUG_LEVEL_TRACE */
FT_BASE_DEF( void )
ft_debug_init( void )
{
/* nothing */
}
FT_BASE_DEF( FT_Int )
FT_Trace_Get_Count( void )
{
return 0;
}
FT_BASE_DEF( const char * )
FT_Trace_Get_Name( FT_Int idx )
{
FT_UNUSED( idx );
return NULL;
}
FT_BASE_DEF( void )
FT_Trace_Disable( void )
{
/* nothing */
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Trace_Enable( void )
{
/* nothing */
}
#endif /* !FT_DEBUG_LEVEL_TRACE */
/* END */

View File

@ -0,0 +1,530 @@
/***************************************************************************/
/* */
/* ftsystem.c */
/* */
/* Amiga-specific FreeType low-level system interface (body). */
/* */
/* Copyright (C) 1996-2025 by */
/* David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This file contains the Amiga interface used by FreeType to access */
/* low-level, i.e. memory management, i/o access as well as thread */
/* synchronisation. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* Maintained by Detlef Würkner <TetiSoft@apg.lahn.de> */
/* */
/* Based on the original ftsystem.c, */
/* modified to avoid fopen(), fclose(), fread(), fseek(), ftell(), */
/* malloc(), realloc(), and free(). */
/* */
/* Those C library functions are often not thread-safe or cant be */
/* used in a shared Amiga library. If that's not a problem for you, */
/* you can of course use the default ftsystem.c with C library calls */
/* instead. */
/* */
/* This implementation needs exec V39+ because it uses AllocPooled() etc */
/* */
/*************************************************************************/
#define __NOLIBBASE__
#define __NOGLOBALIFACE__
#define __USE_INLINE__
#include <proto/exec.h>
#include <dos/stdio.h>
#include <proto/dos.h>
#ifdef __amigaos4__
extern struct ExecIFace *IExec;
extern struct DOSIFace *IDOS;
#else
extern struct Library *SysBase;
extern struct Library *DOSBase;
#endif
#define IOBUF_SIZE 512
/* structure that helps us to avoid
* useless calls of Seek() and Read()
*/
struct SysFile
{
BPTR file;
ULONG iobuf_start;
ULONG iobuf_end;
UBYTE iobuf[IOBUF_SIZE];
};
#ifndef __amigaos4__
/* C implementation of AllocVecPooled (see autodoc exec/AllocPooled) */
APTR
Alloc_VecPooled( APTR poolHeader,
ULONG memSize )
{
ULONG newSize = memSize + sizeof ( ULONG );
ULONG *mem = AllocPooled( poolHeader, newSize );
if ( !mem )
return NULL;
*mem = newSize;
return mem + 1;
}
/* C implementation of FreeVecPooled (see autodoc exec/AllocPooled) */
void
Free_VecPooled( APTR poolHeader,
APTR memory )
{
ULONG *realmem = (ULONG *)memory - 1;
FreePooled( poolHeader, realmem, *realmem );
}
#endif
#include <ft2build.h>
#include FT_CONFIG_CONFIG_H
#include <freetype/internal/ftdebug.h>
#include <freetype/ftsystem.h>
#include <freetype/fterrors.h>
#include <freetype/fttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*************************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* It is not necessary to do any error checking for the */
/* allocation-related functions. This is done by the higher level */
/* routines like ft_mem_alloc() or ft_mem_realloc(). */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* ft_alloc */
/* */
/* <Description> */
/* The memory allocation function. */
/* */
/* <Input> */
/* memory :: A pointer to the memory object. */
/* */
/* size :: The requested size in bytes. */
/* */
/* <Return> */
/* The address of newly allocated block. */
/* */
FT_CALLBACK_DEF( void* )
ft_alloc( FT_Memory memory,
long size )
{
#ifdef __amigaos4__
return AllocVecPooled( memory->user, size );
#else
return Alloc_VecPooled( memory->user, size );
#endif
}
/*************************************************************************/
/* */
/* <Function> */
/* ft_realloc */
/* */
/* <Description> */
/* The memory reallocation function. */
/* */
/* <Input> */
/* memory :: A pointer to the memory object. */
/* */
/* cur_size :: The current size of the allocated memory block. */
/* */
/* new_size :: The newly requested size in bytes. */
/* */
/* block :: The current address of the block in memory. */
/* */
/* <Return> */
/* The address of the reallocated memory block. */
/* */
FT_CALLBACK_DEF( void* )
ft_realloc( FT_Memory memory,
long cur_size,
long new_size,
void* block )
{
void* new_block;
#ifdef __amigaos4__
new_block = AllocVecPooled ( memory->user, new_size );
#else
new_block = Alloc_VecPooled ( memory->user, new_size );
#endif
if ( new_block != NULL )
{
CopyMem ( block, new_block,
( new_size > cur_size ) ? cur_size : new_size );
#ifdef __amigaos4__
FreeVecPooled ( memory->user, block );
#else
Free_VecPooled ( memory->user, block );
#endif
}
return new_block;
}
/*************************************************************************/
/* */
/* <Function> */
/* ft_free */
/* */
/* <Description> */
/* The memory release function. */
/* */
/* <Input> */
/* memory :: A pointer to the memory object. */
/* */
/* block :: The address of block in memory to be freed. */
/* */
FT_CALLBACK_DEF( void )
ft_free( FT_Memory memory,
void* block )
{
#ifdef __amigaos4__
FreeVecPooled( memory->user, block );
#else
Free_VecPooled( memory->user, block );
#endif
}
/*************************************************************************/
/* */
/* RESOURCE MANAGEMENT INTERFACE */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT io
/* We use the macro STREAM_FILE for convenience to extract the */
/* system-specific stream handle from a given FreeType stream object */
#define STREAM_FILE( stream ) ( (struct SysFile *)stream->descriptor.pointer )
/*************************************************************************/
/* */
/* <Function> */
/* ft_amiga_stream_close */
/* */
/* <Description> */
/* The function to close a stream. */
/* */
/* <Input> */
/* stream :: A pointer to the stream object. */
/* */
FT_CALLBACK_DEF( void )
ft_amiga_stream_close( FT_Stream stream )
{
struct SysFile* sysfile;
sysfile = STREAM_FILE( stream );
Close ( sysfile->file );
FreeMem ( sysfile, sizeof ( struct SysFile ));
stream->descriptor.pointer = NULL;
stream->size = 0;
stream->base = NULL;
}
/*************************************************************************/
/* */
/* <Function> */
/* ft_amiga_stream_io */
/* */
/* <Description> */
/* The function to open a stream. */
/* */
/* <Input> */
/* stream :: A pointer to the stream object. */
/* */
/* offset :: The position in the data stream to start reading. */
/* */
/* buffer :: The address of buffer to store the read data. */
/* */
/* count :: The number of bytes to read from the stream. */
/* */
/* <Return> */
/* The number of bytes actually read. */
/* */
FT_CALLBACK_DEF( unsigned long )
ft_amiga_stream_io( FT_Stream stream,
unsigned long offset,
unsigned char* buffer,
unsigned long count )
{
struct SysFile* sysfile;
unsigned long read_bytes;
if ( count != 0 )
{
sysfile = STREAM_FILE( stream );
/* handle the seek */
if ( (offset < sysfile->iobuf_start) || (offset + count > sysfile->iobuf_end) )
{
/* requested offset implies we need a buffer refill */
if ( !sysfile->iobuf_end || offset != sysfile->iobuf_end )
{
/* a physical seek is necessary */
Seek( sysfile->file, offset, OFFSET_BEGINNING );
}
sysfile->iobuf_start = offset;
sysfile->iobuf_end = 0; /* trigger a buffer refill */
}
/* handle the read */
if ( offset + count <= sysfile->iobuf_end )
{
/* we have buffer and requested bytes are all inside our buffer */
CopyMem( &sysfile->iobuf[offset - sysfile->iobuf_start], buffer, count );
read_bytes = count;
}
else
{
/* (re)fill buffer */
if ( count <= IOBUF_SIZE )
{
/* requested bytes is a subset of the buffer */
read_bytes = Read( sysfile->file, sysfile->iobuf, IOBUF_SIZE );
if ( read_bytes == -1UL )
{
/* error */
read_bytes = 0;
}
else
{
sysfile->iobuf_end = offset + read_bytes;
CopyMem( sysfile->iobuf, buffer, count );
if ( read_bytes > count )
{
read_bytes = count;
}
}
}
else
{
/* we actually need more than our buffer can hold, so we decide
** to do a single big read, and then copy the last IOBUF_SIZE
** bytes of that to our internal buffer for later use */
read_bytes = Read( sysfile->file, buffer, count );
if ( read_bytes == -1UL )
{
/* error */
read_bytes = 0;
}
else
{
ULONG bufsize;
bufsize = ( read_bytes > IOBUF_SIZE ) ? IOBUF_SIZE : read_bytes;
sysfile->iobuf_end = offset + read_bytes;
sysfile->iobuf_start = sysfile->iobuf_end - bufsize;
CopyMem( &buffer[read_bytes - bufsize] , sysfile->iobuf, bufsize );
}
}
}
}
else
{
read_bytes = 0;
}
return read_bytes;
}
/* documentation is in ftobjs.h */
FT_BASE_DEF( FT_Error )
FT_Stream_Open( FT_Stream stream,
const char* filepathname )
{
struct FileInfoBlock* fib;
struct SysFile* sysfile;
if ( !stream )
return FT_THROW( Invalid_Stream_Handle );
#ifdef __amigaos4__
sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_SHARED );
#else
sysfile = AllocMem ( sizeof (struct SysFile ), MEMF_PUBLIC );
#endif
if ( !sysfile )
{
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_THROW( Cannot_Open_Resource );
}
sysfile->file = Open( (STRPTR)filepathname, MODE_OLDFILE );
if ( !sysfile->file )
{
FreeMem ( sysfile, sizeof ( struct SysFile ));
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_THROW( Cannot_Open_Resource );
}
fib = AllocDosObject( DOS_FIB, NULL );
if ( !fib )
{
Close ( sysfile->file );
FreeMem ( sysfile, sizeof ( struct SysFile ));
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_THROW( Cannot_Open_Resource );
}
if ( !( ExamineFH( sysfile->file, fib ) ) )
{
FreeDosObject( DOS_FIB, fib );
Close ( sysfile->file );
FreeMem ( sysfile, sizeof ( struct SysFile ));
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_THROW( Cannot_Open_Resource );
}
stream->size = fib->fib_Size;
FreeDosObject( DOS_FIB, fib );
stream->descriptor.pointer = (void *)sysfile;
stream->pathname.pointer = (char*)filepathname;
sysfile->iobuf_start = 0;
sysfile->iobuf_end = 0;
stream->pos = 0;
stream->read = ft_amiga_stream_io;
stream->close = ft_amiga_stream_close;
if ( !stream->size )
{
ft_amiga_stream_close( stream );
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
return FT_THROW( Cannot_Open_Stream );
}
FT_TRACE1(( "FT_Stream_Open:" ));
FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
filepathname, stream->size ));
return FT_Err_Ok;
}
#ifdef FT_DEBUG_MEMORY
extern FT_Int
ft_mem_debug_init( FT_Memory memory );
extern void
ft_mem_debug_done( FT_Memory memory );
#endif
/* documentation is in ftobjs.h */
FT_BASE_DEF( FT_Memory )
FT_New_Memory( void )
{
FT_Memory memory;
#ifdef __amigaos4__
memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_SHARED );
#else
memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_PUBLIC );
#endif
if ( memory )
{
#ifdef __amigaos4__
memory->user = CreatePool( MEMF_SHARED, 16384, 16384 );
#else
memory->user = CreatePool( MEMF_PUBLIC, 16384, 16384 );
#endif
if ( memory->user == NULL )
{
FreeVec( memory );
memory = NULL;
}
else
{
memory->alloc = ft_alloc;
memory->realloc = ft_realloc;
memory->free = ft_free;
#ifdef FT_DEBUG_MEMORY
ft_mem_debug_init( memory );
#endif
}
}
return memory;
}
/* documentation is in ftobjs.h */
FT_BASE_DEF( void )
FT_Done_Memory( FT_Memory memory )
{
#ifdef FT_DEBUG_MEMORY
ft_mem_debug_done( memory );
#endif
DeletePool( memory->user );
FreeVec( memory );
}
/*
Local Variables:
coding: latin-1
End:
*/
/* END */

View File

@ -0,0 +1,77 @@
#
# FreeType 2 configuration rules for a `normal' ANSI system
#
# Copyright (C) 1996-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
DELETE := rm -f
CAT := cat
SEP := /
PLATFORM_DIR := $(TOP_DIR)/builds/ansi
PLATFORM := ansi
# This is used for `make refdoc' and `make refdoc-venv'
#
BIN := bin
# The directory where all library files are placed.
#
# By default, this is the same as $(OBJ_DIR); however, this can be changed
# to suit particular needs.
#
LIB_DIR := $(OBJ_DIR)
# The name of the final library file. Note that the DOS-specific Makefile
# uses a shorter (8.3) name.
#
LIBRARY := lib$(PROJECT)
# Path inclusion flag. Some compilers use a different flag than `-I' to
# specify an additional include path. Examples are `/i=' or `-J'.
#
I := -I
# C flag used to define a macro before the compilation of a given source
# object. Usually it is `-D' like in `-DDEBUG'.
#
D := -D
# The link flag used to specify a given library file on link. Note that
# this is only used to compile the demo programs, not the library itself.
#
L := -l
# Target flag.
#
T := -o$(space)
# C flags
#
# These should concern: debug output, optimization & warnings.
#
# Use the ANSIFLAGS variable to define the compiler flags used to enforce
# ANSI compliance.
#
CFLAGS ?= -c
# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
#
ANSIFLAGS ?=
# EOF

View File

@ -0,0 +1,21 @@
#
# FreeType 2 configuration rules for a `normal' pseudo ANSI compiler/system
#
# Copyright (C) 1996-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
include $(TOP_DIR)/builds/ansi/ansi-def.mk
include $(TOP_DIR)/builds/compiler/ansi-cc.mk
include $(TOP_DIR)/builds/link_std.mk
# EOF

View File

@ -0,0 +1,20 @@
#if defined( GXVALID_H_ )
#pragma warn -aus /* too many unevaluated variables in gxvalid */
#endif
#ifndef ATARI_H
#define ATARI_H
#pragma warn -stu
/* PureC doesn't like 32bit enumerations */
#ifndef FT_IMAGE_TAG
#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value
#endif /* FT_IMAGE_TAG */
#ifndef FT_ENC_TAG
#define FT_ENC_TAG( value, a, b, c, d ) value
#endif /* FT_ENC_TAG */
#endif /* ATARI_H */

View File

@ -0,0 +1,37 @@
/* the following changes file names for PureC projects */
if (argc > 0)
{
ordner = argv[0];
if (basename(ordner) == "") /* ist Ordner */
{
ChangeFilenames(ordner);
}
}
proc ChangeFilenames(folder)
local i,entries,directory,file;
{
entries = filelist(directory,folder);
for (i = 0; i < entries; ++i)
{
file = directory[i,0];
if ((directory[i,3]&16) > 0) /* subdirectory */
{
ChangeFilenames(folder+file+"\\");
}
else
{
if ((stricmp(suffix(file),".h")==0)|(stricmp(suffix(file),".c")==0))
ChangeFilename(folder,file);
}
}
}
proc ChangeFilename(path,datei)
local newfile,err;
{
newfile=datei;
newfile[0]=(newfile[0] | 32) ^ 32;
err=files.rename("-q",path+datei,newfile);
}

View File

@ -0,0 +1,32 @@
;FreeType project file
FREETYPE.LIB
.C [-K -P -R -A]
.L [-J -V]
.S
=
..\..\src\base\ftsystem.c
..\..\src\base\ftdebug.c
..\..\src\base\ftinit.c
..\..\src\base\ftglyph.c
..\..\src\base\ftmm
..\..\src\base\ftbbox
..\..\src\base\ftbase.c
..\..\src\autohint\autohint.c
;..\..\src\cache\ftcache.c
..\..\src\cff\cff.c
..\..\src\cid\type1cid.c
..\..\src\psaux\psaux.c
..\..\src\pshinter\pshinter.c
..\..\src\psnames\psnames.c
..\..\src\raster\raster.c
..\..\src\sfnt\sfnt.c
..\..\src\smooth\smooth.c
..\..\src\truetype\truetype.c
..\..\src\type1\type1.c
..\..\src\type42\type42.c

View File

@ -0,0 +1,51 @@
Compiling FreeType 2 with PureC compiler
========================================
[See below for a German version.]
To compile FreeType 2 as a library the following changes must be applied:
- All *.c files must start with an uppercase letter.
(In case GEMSCRIPT is available:
Simply drag the whole FreeType 2 directory to the file `FNames.SIC'.)
- You have to change the INCLUDE directory in PureC's compiler options
to contain both the `INCLUDE' and `freetype2\include' directory.
Example:
INCLUDE;E:\freetype2\include
- The file `freetype/include/Ft2build.h' must be patched as follows to
include ATARI.H:
#ifndef FT2_BUILD_GENERIC_H_
#define FT2_BUILD_GENERIC_H_
#include "ATARI.H"
Compilieren von FreeType 2 mit PureC
====================================
Um FreeType 2 als eine Bibliothek (library) zu compilieren, muss folgendes
ge„ndert werden:
- Alle *.c-files m<>ssen mit einem GROSSBUCHSTABEN beginnen.
(Falls GEMSCRIPT zur Verf<72>gung steht:
Den kompletten Ordner freetype2 auf die Datei `FNames.SIC' draggen.)
- In den Compiler-Optionen von PureC muss das INCLUDE directory auf INCLUDE
und freetype2\include verweisen. Z.B.:
INCLUDE;E:\freetype2\include
- In der Datei freetype/include/Ft2build.h muss zu Beginn
ein #include "ATARI.H" wie folgt eingef<65>gt werden:
#ifndef FT2_BUILD_GENERIC_H_
#define FT2_BUILD_GENERIC_H_
#include "ATARI.H"
--- end of README.TXT ---

View File

@ -0,0 +1,181 @@
#!/usr/bin/env awk
function shift( array, \
junk, elm0, l )
{
elm0 = array[0]
for ( l = 0; l < asorti( array, junk ) - 1; l++ )
array[l] = array[l+1];
delete array[l]
return elm0
}
function init_cpp_src_line()
{
logical_line = ""
delete break_pos
}
function shift_valid_bp( array, \
junk, elm )
{
elm = -1
if ( 0 < asorti( array, junk ) )
do {
elm = shift( array )
} while ( 0 > elm );
return elm
}
function check_cpp_src_line_break_pos( \
i, junk )
{
printf( "break_pos:" )
for ( i = 0; i < asorti( break_pos, junk ); i++ )
printf( " %d", break_pos[i] );
printf( "\n" )
}
function check_cpp_src_line()
{
printf( "logical_line[%s]\n", logical_line )
check_cpp_src_line_break_pos()
}
function append_line( phys_line, \
filt_line, bp_len )
{
filt_line = phys_line
sub( /\\$/, " ", filt_line )
logical_line = logical_line filt_line
bp_len = asorti( break_pos, junk )
break_pos[bp_len] = length( logical_line ) - 1
}
function print_line( \
c0, c1, i, junk, part_str )
{
c0 = 0
while( asorti( break_pos, junk ) > 1 )
{
if ( ( c1 = shift_valid_bp( break_pos ) ) < 1 )
{
part_str = substr( logical_line, c0 + 1 )
printf( "%s\n", part_str )
return
}
part_str = substr( logical_line, c0 + 1, c1 - c0 + 1 )
gsub( / $/, "\\", part_str )
printf( "%s\n", part_str )
c0 = c1 + 1
}
part_str = substr( logical_line, c0 + 1 )
printf( "%s\n", part_str )
}
function shrink_spaces( pos, \
tail, removed_length, k )
{
tail = substr( logical_line, pos )
sub( /^[ \t]+/, " ", tail )
removed_length = length( logical_line ) - pos - length( tail ) + 1
logical_line = substr( logical_line, 0, pos - 1 ) tail
for ( k = 0; k < asorti( break_pos, junk ); k++ )
if ( ( pos + removed_length ) <= break_pos[k] )
break_pos[k] = break_pos[k] - removed_length;
else if ( pos <= break_pos[k] )
break_pos[k] = -1;
return removed_length
}
function shrink_spaces_to_linebreak( pos, \
junk, part_str, removed_length, i )
{
for ( i = 0; i < asorti( break_pos, junk ) && break_pos[i] < pos ; i++ )
;
if ( break_pos[i] < 1 )
return;
part_str = substr( logical_line, pos, break_pos[i] - pos + 1 )
sub( /^[ \t]+/, " ", part_str )
removed_length = ( break_pos[i] - pos + 1 ) - length( part_str )
tail = substr( logical_line, pos + removed_length )
logical_line = substr( logical_line, 0, pos - 1 ) tail
for ( ; i < asorti( break_pos, junk ); i++ )
break_pos[i] -= removed_length;
return removed_length
}
function delete_linebreaks_in_2nd_token( \
tail, paren_depth, junk, i, j, k, l )
{
if ( logical_line ~ /^[ \t]*#[ \t]*define[ \t]+[0-9A-Za-z_]+\(/ )
{
tail = logical_line
sub( /^[ \t]*#[ \t]*define[ \t]+[0-9A-Za-z_]+/, "", tail )
paren_depth = 0
l = 0
i = length( logical_line ) - length( tail ) + 1 # seek to the 1st op paren
j = i
do {
if ( substr( logical_line, j, 2 ) ~ /[ \t][ \t]/ )
l = shrink_spaces( j );
else if ( substr( logical_line, j, 1 ) == "(" )
paren_depth += 1;
else if ( substr( logical_line, j, 1 ) == ")" )
paren_depth -= 1;
j += 1
} while ( j < length( logical_line ) && paren_depth != 0 )
for ( k = 0; k < asorti( break_pos, junk ); k++ )
if ( i <= break_pos[k] && break_pos[k] < j )
break_pos[k] = -1;
if ( l > 0 )
shrink_spaces_to_linebreak( j );
}
}
BEGIN{
init_cpp_src_line()
}
{
append_line( $0 )
if ( $0 !~ /\\$/ )
{
delete_linebreaks_in_2nd_token()
print_line()
init_cpp_src_line()
}
}
END{
if ( 0 < length( logical_line ) )
{
delete_linebreaks_in_2nd_token()
print_line()
}
}

View File

@ -0,0 +1,40 @@
#!/bin/sh
TOP_DIR=.
OBJ_DIR=.
for x in "$@"
do
case x"$x" in
x--srcdir=* | x--topdir=* )
TOP_DIR=`echo $x | sed 's/^--[a-z]*dir=//'`
;;
x--builddir=* | x--objdir=* )
OBJ_DIR=`echo $x | sed 's/^--[a-z]*dir=//'`
;;
esac
done
mkdir -p ${OBJ_DIR}/builds/atari/tmp/orig
( cd ${TOP_DIR} && find . -name '*.[CHch]' -type f | fgrep -v builds/atari/tmp | cpio -o ) | \
( cd ${OBJ_DIR}/builds/atari/tmp/orig && cpio -idum )
cp ${TOP_DIR}/builds/atari/deflinejoiner.awk ${OBJ_DIR}/builds/atari/tmp
pushd ${OBJ_DIR}/builds/atari/tmp
cp -pr orig purec
for f in `cd orig && find . -type f`
do
echo filter $f
env LANG=C awk -f deflinejoiner.awk < orig/$f > purec/$f
done
echo '#define FT2_BUILD_LIBRARY' > purec/include/ft2build.h
echo '#include "ATARI.H"' >> purec/include/ft2build.h
env LANG=C awk -f deflinejoiner.awk < orig/include/ft2build.h >> purec/include/ft2build.h
env LANG=C diff -ur orig purec > ../purec.diff
popd
rm -rf ${OBJ_DIR}/builds/atari/tmp

View File

@ -0,0 +1,79 @@
#
# FreeType 2 configuration rules for a BeOS system
#
# this is similar to the "ansi-def.mk" file, except for BUILD and PLATFORM
#
# Copyright (C) 1996-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
DELETE := rm -f
CAT := cat
SEP := /
PLATFORM_DIR := $(TOP_DIR)/builds/beos
PLATFORM := beos
# This is used for `make refdoc' and `make refdoc-venv'
#
BIN := bin
# The directory where all library files are placed.
#
# By default, this is the same as $(OBJ_DIR); however, this can be changed
# to suit particular needs.
#
LIB_DIR := $(OBJ_DIR)
# The name of the final library file. Note that the DOS-specific Makefile
# uses a shorter (8.3) name.
#
LIBRARY := lib$(PROJECT)
# Path inclusion flag. Some compilers use a different flag than `-I' to
# specify an additional include path. Examples are `/i=' or `-J'.
#
I := -I
# C flag used to define a macro before the compilation of a given source
# object. Usually it is `-D' like in `-DDEBUG'.
#
D := -D
# The link flag used to specify a given library file on link. Note that
# this is only used to compile the demo programs, not the library itself.
#
L := -l
# Target flag.
#
T := -o$(space)
# C flags
#
# These should concern: debug output, optimization & warnings.
#
# Use the ANSIFLAGS variable to define the compiler flags used to enforce
# ANSI compliance.
#
CFLAGS ?= -c
# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant.
#
ANSIFLAGS ?=
# EOF

View File

@ -0,0 +1,19 @@
#
# FreeType 2 configuration rules for a BeOS system
#
# Copyright (C) 1996-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
include $(TOP_DIR)/builds/beos/beos-def.mk
include $(TOP_DIR)/builds/compiler/ansi-cc.mk
include $(TOP_DIR)/builds/link_std.mk
# EOF

View File

@ -0,0 +1,41 @@
#
# FreeType 2 configuration file to detect an BeOS host platform.
#
# Copyright (C) 1996-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
.PHONY: setup
ifeq ($(PLATFORM),ansi)
ifdef BE_HOST_CPU
PLATFORM := beos
endif # test MACHTYPE beos
endif
ifeq ($(PLATFORM),beos)
DELETE := rm -f
CAT := cat
SEP := /
PLATFORM_DIR := $(TOP_DIR)/builds/beos
CONFIG_FILE := beos.mk
setup: std_setup
endif # test PLATFORM beos
# EOF

View File

@ -0,0 +1,52 @@
# FindBrotliDec.cmake
#
# Copyright (C) 2019-2025 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# Written by Werner Lemberg <wl@gnu.org>
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.
#
#
# Try to find libbrotlidec include and library directories.
#
# If found, the following variables are set.
#
# BROTLIDEC_INCLUDE_DIRS
# BROTLIDEC_LIBRARIES
find_package(PkgConfig QUIET)
pkg_check_modules(PC_BROTLIDEC QUIET libbrotlidec)
if (PC_BROTLIDEC_VERSION)
set(BROTLIDEC_VERSION "${PC_BROTLIDEC_VERSION}")
endif ()
find_path(BROTLIDEC_INCLUDE_DIRS
NAMES brotli/decode.h
HINTS ${PC_BROTLIDEC_INCLUDEDIR}
${PC_BROTLIDEC_INCLUDE_DIRS}
PATH_SUFFIXES brotli)
find_library(BROTLIDEC_LIBRARIES
NAMES brotlidec
HINTS ${PC_BROTLIDEC_LIBDIR}
${PC_BROTLIDEC_LIBRARY_DIRS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
BrotliDec
REQUIRED_VARS BROTLIDEC_INCLUDE_DIRS BROTLIDEC_LIBRARIES
FOUND_VAR BROTLIDEC_FOUND
VERSION_VAR BROTLIDEC_VERSION)
mark_as_advanced(
BROTLIDEC_INCLUDE_DIRS
BROTLIDEC_LIBRARIES)

Some files were not shown because too many files have changed in this diff Show More