bad-apple/encoder/main.cpp
2023-12-30 12:27:11 +07:00

211 lines
9.5 KiB
C++

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <stdint.h>
#include <string>
#include <vector>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "fastlz.h"
extern "C" char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len);
unsigned short RGB15(int r, int g, int b);
std::string path_out = "../assets/out/";
std::string path_palette = "../assets/palette.png";
std::string path_resource = "../resource";
std::string path_images = "../assets/out/out_";
std::string path_test = "../assets/out/out_3667.bmp";
std::vector<int> usingRLE = {999999};
// std::vector<int> usingRLE = {840, 841, 842, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1041, 1459, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1626, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1664, 1666, 1719, 1720, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 3191, 3192, 3193, 3196, 3197, 3198, 3225, 3227, 3228, 3229};
constexpr int palette_size = 256;
uint16_t palette_map[palette_size];
constexpr int chunk_size = 10;
volatile int chunk_counter = 0;
volatile int chunk_current = 0;
constexpr int frame_size = 256*192;
volatile int frame_total = -1;
volatile int frame_counter = 0;
uint8_t frame_map[frame_size*chunk_size];
uint32_t compress_size, compress_flag;
volatile int compress_size_biggest;
uint8_t compress_data[frame_size*chunk_size*2];
std::ofstream file_out;
int main()
{
printf("Finding total frame...");
// Find total frame
for (const auto& entry : std::filesystem::directory_iterator(path_out)) {
if (entry.is_regular_file()) {
std::string filename = entry.path().filename().string();
if (filename.substr(0, 4) == "out_" && filename.substr(filename.size() - 4) == ".bmp") {
int number = std::stoi(filename.substr(4, filename.size() - 8));
if (number > frame_total) {
frame_total = number;
}
}
}
}
// Generate palette
printf("Generating palette map...");
int temp_w, temp_h, temp_n;
unsigned char *palette_raw = stbi_load(path_palette.c_str(), &temp_w, &temp_h, &temp_n, 3);
for (int i=0; i<palette_size; i++)
{
int index = i*3;
unsigned char r = palette_raw[index];
unsigned char g = palette_raw[index + 1];
unsigned char b = palette_raw[index + 2];
palette_map[i] = RGB15(r, g, b);
// printf("%i> %i,%i,%i (%i)\n", i, r, g, b, palette[i]);
}
printf("Writing palette map...");
file_out.open(path_resource + "/palette.bin", std::ios::binary);
file_out.write(reinterpret_cast<const char*>(palette_map), sizeof(palette_map));
file_out.close();
printf("Generating image map...");
std::stringstream ss;
int fastlz_total = 0;
int raw_total = 0;
int rle_total = 0;
file_out.open(path_resource + "/image.bin", std::ios::binary);
for (frame_counter=1; frame_counter<=frame_total; frame_counter++)
{
ss.str("");
ss << path_images << frame_counter << ".bmp";
unsigned char *frame_raw = stbi_load(ss.str().c_str(), &temp_w, &temp_h, &temp_n, 3);
for (int rgb=0; rgb<256*192; rgb++)
{
int index = rgb*3;
unsigned char r = frame_raw[index];
unsigned char g = frame_raw[index + 1];
unsigned char b = frame_raw[index + 2];
uint16_t palette_value = RGB15(r, g, b);
int palette_index = -1;
for (int i=0; i<256; i++)
{
if (palette_map[i] == palette_value) {
palette_index = i;
break;
}
}
if (palette_index == -1) printf("frame %i> palette not found!!!\n", frame_counter);
else frame_map[rgb + chunk_counter*frame_size] = palette_index;
}
printf("%i) frame %i/%i (%1.f%s)> done\n", chunk_counter, frame_counter, frame_total, ((float)frame_counter/frame_total)*100, "%");
chunk_counter++;
if (chunk_counter >= chunk_size)
{
bool isRLE = false;
for (auto y : usingRLE)
if (chunk_current == y)
isRLE = true;
if (isRLE)
{
char *temp = RLE_Code(compress_data, frame_size*chunk_size, (int*)&compress_size);
compress_flag = (compress_size << 2) | 0xfffffffd;
if (compress_size > frame_size*chunk_size)
{
free(temp);
compress_size = frame_size*chunk_size;
compress_flag = (compress_size << 2) | 0xfffffffe;
memcpy(compress_data, frame_map, compress_size);
printf("raw > ");
raw_total++;
}
else
{
memcpy(compress_data, temp, compress_size);
free(temp);
printf("rle > ");
rle_total++;
}
}
else
{
compress_size = fastlz_compress_level(1, frame_map, frame_size*chunk_size, compress_data);
compress_flag = (compress_size << 2);
if (compress_size > frame_size*chunk_size)
{
compress_size = frame_size*chunk_size;
compress_flag = (compress_size << 2) | 0xfffffffe;
memcpy(compress_data, frame_map, compress_size);
printf("raw > ");
raw_total++;
}
else
{
printf("fastlz > ");
fastlz_total++;
}
}
file_out.write(reinterpret_cast<const char*>(&compress_flag), sizeof(uint32_t));
file_out.write(reinterpret_cast<const char*>(compress_data), compress_size);
chunk_counter = 0;
if ((compress_size) > compress_size_biggest) compress_size_biggest = compress_size;
printf("write batch %i %i/%i\n", compress_size, chunk_current, frame_total/chunk_size);
chunk_current++;
}
}
file_out.close();
// Print
printf("Total Frame: %i\n", frame_total);
printf("Biggest : %i\n", compress_size_biggest);
printf("fastlz : %i\n", fastlz_total);
printf("rle : %i\n", rle_total);
printf("raw : %i\n", raw_total);
}
unsigned short RGB15(int r, int g, int b) {
unsigned short rgb15 =
((r >> 3) << 10) |
((g >> 3) << 5) |
(b >> 3);
// Set the alpha bit to 1
rgb15 |= 1 << 15;
return rgb15;
}