Инициализация времени компиляции массива uint8_t строковым литералом base64C++

Программы на C++. Форум разработчиков
Anonymous
 Инициализация времени компиляции массива uint8_t строковым литералом base64

Сообщение Anonymous »

У меня есть исходный файл с большим массивом байтов, представляющим изображение.
Ниже пример (на самом деле это могут быть любые случайные данные):

Код: Выделить всё

const uint8_t image_test_image[] ={
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
...
);
У меня есть несколько таких исходных файлов, и они занимают много места на моем диске.
Я мог бы удалить пробелы, но это сэкономит лишь немного места.
Я хочу попробовать два разных способа инициализации этого массива во время компиляции, чтобы уменьшить размер исходного файла.
Один из способов — использовать строки base64:

Код: Выделить всё

const uint8_t image_test_image[] =
base64decode(
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OT"
"o7PD0+P0BBQkNERUZH"...
);
Я думаю, что должно быть возможно создать C++ декодер constexpr base64 только для заголовков, который принимает строковые литералы. Пример здесь: https://stackoverflow.com/a/59604914/15307950. Но для этого требуется явно добавить размер в качестве параметра. Я не хочу этого. Можно ли вывести значение параметра шаблона из значения аргумента?
Другой способ — вместо этого использовать массив uint64_t или список инициализаторов uint64_t в качестве входных данных. Выбор определенного порядка байтов и учет массива байтов не могут быть кратны 8 байтам.
Сейчас я использую C++14, но возможен и C++17. Даже C++20 может стать возможным в будущем этого проекта. Можно использовать std::array.
Edit2:
массив uint64 работает в C++14:

Код: Выделить всё

#include 
#include 
#include 

//#define LITTLE_ENDIAN

template 
constexpr std::array u64_array_to_u8_array(T&&... t)
{
std::array out{};
std::array in = {t...};

for (size_t i = 0; i < sizeof...(T)*8; ++ i) {
#ifdef LITTLE_ENDIAN
out[i] = uint64_t(in[i/8]) >> ((i%8)*8);//little endian
#else
out[i] = uint64_t(in[i/8]) >> ((7-i%8)*8);//big endian
#endif
}
return out;
}

#ifdef LITTLE_ENDIAN
//little little
const auto image_test_image = u64_array_to_u8_array(
0x0706050403020100,0x0F0E0D0C0B0A0908,
0x1716151413121110,0x1F1E1D1C1B1A1918);
#else
//big endian
const auto image_test_image = u64_array_to_u8_array(
0x0001020304050607,0x08090A0B0C0D0E0F,
0x1011121314151617,0x18191A1B1C1D1E1F
);
#endif

int main() {
for (size_t i = 0; i < sizeof(image_test_image); ++i)
{
printf("0x%02X, ", image_test_image[i]);
if ((i%16==15) && i != sizeof(image_test_image))
{
puts("");
}
}

return 0;
}
Теперь мне просто нужно знать, как реализовать декодирование constexpr base64 с помощью строкового литерала.

Подробнее здесь: https://stackoverflow.com/questions/790 ... ng-literal

Вернуться в «C++»