yoooooo finally the frame is dooonneee!!!

This commit is contained in:
sillysagiri 2023-12-29 10:47:03 +07:00
parent 2069bb2969
commit 589a0c94a4
4 changed files with 247 additions and 135 deletions

View File

@ -7,7 +7,7 @@ set(PROJECT_NAME "encoder")
project(${PROJECT_NAME})
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "*.cpp")
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "*.cpp" "*.c")
file(GLOB VENDOR_SOURCES CONFIGURE_DEPENDS "../vendor/FastLZ/fastlz.c")
set(PROJECT_INCLUDE

View File

@ -1,15 +1,20 @@
#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) {
unsigned short rgb15 =
((r >> 3) << 10) | // 5 bits for red
@ -30,6 +35,8 @@ int main()
std::string path_images = "../assets/out/out_";
std::string path_test = "../assets/out/out_3667.bmp";
std::vector<int> usingRLE = {177, 178, 179, 220, 231, 232, 237, 238, 239, 240, 241, 263, 264, 409, 681, 682, 735, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 770, 771, 772, 773, 774, 775, 776, 777, 779, 780, 783, 784, 785, 786, 787, 788, 789, 790, 791, 798, 799, 800, 801, 802, 803, 804, 805, 807, 808, 809, 811, 812, 813, 814, 815, 816, 817, 818, 819, 821, 822, 823, 824, 825, 826, 827, 828, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 897, 898, 899, 900, 908, 909, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 925, 926, 927, 928, 929, 930, 931, 934, 935, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1154, 1155, 1156, 1157, 1158, 1245, 1247, 1248, 1249, 1250, 1251, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1459, 1460, 1461, 1462, 1463, 1465, 1466, 1467, 1468, 1469, 1470, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1493, 1494, 1495, 1496, 1501, 1504, 1507, 1510, 1513, 1515, 1516, 1517, 1520, 1521, 1522, 1524, 1525, 1526, 1528, 1529, 1530, 1531, 1532, 1533, 1535, 1536, 1537, 1538, 1539, 1541, 1542, 1547, 1549, 1551, 1552, 1553, 1554, 1555, 1557, 1559, 1560, 1561, 1562, 1563, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1582, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1699, 1701, 1702, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1763, 1764, 1765, 1766, 1787, 1789, 1808, 1809, 1810, 1823, 1834, 1835, 1836, 1837, 1843, 1876, 1892, 1893, 1894, 1897, 1901, 1904, 1905, 1906, 1907, 1908, 1910, 1911, 1969, 2090, 2091, 2092, 2128, 2129, 2180, 2181, 2182, 2195, 2196, 2197, 2199, 2201, 2281, 2282, 2286, 2287, 2295, 2300, 2309, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2343, 2345, 2346, 2347, 2349, 2670, 2727, 2729, 2730, 2812, 2831, 2833, 2850, 2851, 3140, 3141, 3142, 3143, 3144, 3146, 3147, 3148, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3182, 3183, 3184, 3185, 3186, 3187, 3189, 3190, 3255};
int frame_total = -1;
std::stringstream ss;
@ -77,6 +84,8 @@ int main()
uint8_t batch_map[256*192*4];
int batch_counter = 0;
int batch_biggest = 0;
int batch_num = 0;
for (int frame_counter=1; frame_counter<=frame_total; frame_counter++)
{
@ -111,122 +120,60 @@ int main()
else batch_map[i+ batch_counter*256*192] = pixel_index;
}
printf("%i) frame %i/%i (%1.f%s)> done\n", batch_counter, frame_counter, frame_total, ((float)frame_counter/frame_total)*100, "%");
// printf("%i) frame %i/%i (%1.f%s)> done\n", batch_counter, frame_counter, frame_total, ((float)frame_counter/frame_total)*100, "%");
batch_counter++;
if (batch_counter > 3)
{
uint8_t batch_map_compress[256*192*4*2];
uint32_t size = fastlz_compress_level(1, batch_map, 256*192*4, batch_map_compress);
// int size;
// char *batch_map_compress = LZS_Fast(batch_map, 256*192, &size);
out.write(reinterpret_cast<const char*>(&size), sizeof(size));
out.write(reinterpret_cast<const char*>(&batch_map_compress), size);
// out.write(reinterpret_cast<const char*>(&size), sizeof(size));
// out.write(batch_map_compress, size);
if (batch_counter >= 4)
{
bool isRLE = false;
for (auto y : usingRLE)
if (batch_num == y)
isRLE = true;
uint32_t size, size2;
uint8_t *batch_map_compress = (uint8_t*)malloc(256*192*4*2);
if (isRLE)
{
char *temp = RLE_Code(batch_map, 256*192*4, (int*)&size);
size2 = (size << 1) | 0x01;
memcpy(batch_map_compress, temp, size);
free(temp);
printf("rle > ");
}
else
{
size = fastlz_compress_level(1, batch_map, 256*192*4, batch_map_compress);
size2 = (size << 1);
printf("fastlz > ");
}
out.write(reinterpret_cast<const char*>(&size2), sizeof(uint32_t));
out.write(reinterpret_cast<const char*>(batch_map_compress), size);
batch_counter = 0;
printf("write batch %i\n", size);
if ((size) > batch_biggest) batch_biggest = (size);
printf("write batch %i %i/%i\n", size, batch_num, frame_total/4);
free(batch_map_compress);
batch_num++;
}
}
out.close();
// for (int i=1; i<=frame_total/batch_size; i++)
// {
// uint8_t batch[256*192*batch_size];
// uint8_t batch_compress[256*192*batch_size*2];
// uint32_t batch_compress_len = 0;
// for (batch_current=0; batch_current<batch_size; batch_current++)
// {
// if (frame_counter > frame_total) break;
// uint8_t current_map[256*192];
// ss.str("");
// ss << path_images << frame_counter << ".bmp";
// int current_w = -1;
// int current_h = -1;
// int current_n = -1;
// unsigned char *current_data = stbi_load(ss.str().c_str(), &current_w, &current_h, &current_n, 3);
// for (int i2=0; i2<256*192; i2++)
// {
// int index = i2*3;
// unsigned char r = current_data[index];
// unsigned char g = current_data[index + 1];
// unsigned char b = current_data[index + 2];
// uint16_t current_pal = RGB15(r, g, b);
// int current_index = -1;
// for (int i3=0; i3<256; i3++)
// {
// if (palette[i3] == current_pal) {
// current_index = i3;
// break;
// }
// }
// if (current_index == -1) printf("%i> %i palette not found!!!\n", i, current_index);
// else current_map[i2] = current_index;
// }
// memcpy(current_map, &batch[batch_current*256*192], 256*192);
// printf("frame %i/%i\n", frame_counter, frame_total);
// frame_counter++;
// }
// batch_compress_len = fastlz_compress_level(1, batch, 256*192*batch_size, batch_compress);
// out.write(reinterpret_cast<const char*>(&batch_compress_len), sizeof(batch_compress_len));
// out.write(reinterpret_cast<const char*>(&batch_compress), batch_compress_len);
// printf("batch done! (%i)\n", batch_compress_len);
// }
out.close();
// uint8_t test[256*192];
// uint8_t test_compress[(256*192)*2];
// uint32_t test_compress_len = 0;
// int test_w = -1;
// int test_h = -1;
// int test_n = -1;
// unsigned char *test_data = stbi_load(path_test.c_str(), &test_w, &test_h, &test_n, 3);
// for (int i=0; i<256*192; i++)
// {
// int index = i*3;
// unsigned char r = test_data[index];
// unsigned char g = test_data[index + 1];
// unsigned char b = test_data[index + 2];
// uint16_t current_pal = RGB15(r, g, b);
// int current_index = -1;
// for (int i2=0; i2<256; i2++)
// {
// if (palette[i2] == current_pal) {
// current_index = i2;
// break;
// }
// }
// if (current_index == -1) printf("%i> %i\n", i, current_index);
// else test[i] = current_index;
// }
// test_compress_len = fastlz_compress_level(1, test, 256*192, test_compress);
// printf("len: %i\n", test_compress_len);
// out.open(path_resource + "/image.bin", std::ios::binary);
// out.write(reinterpret_cast<const char*>(&test_compress_len), sizeof(test_compress_len));
// out.write(reinterpret_cast<const char*>(test_compress), test_compress_len);
// out.close();
// Print
printf("Total Frame: %i\n", frame_total);
printf("Biggest: %i\n", batch_biggest);
}

121
encoder/rle.c Normal file
View File

@ -0,0 +1,121 @@
/*----------------------------------------------------------------------------*/
/*-- rle.c - RLE coding for Nintendo GBA/DS --*/
/*-- Copyright (C) 2011 CUE --*/
/*-- --*/
/*-- This program is free software: you can redistribute it and/or modify --*/
/*-- it under the terms of the GNU General Public License as published by --*/
/*-- the Free Software Foundation, either version 3 of the License, or --*/
/*-- (at your option) any later version. --*/
/*-- --*/
/*-- This program is distributed in the hope that it will be useful, --*/
/*-- but WITHOUT ANY WARRANTY; without even the implied warranty of --*/
/*-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --*/
/*-- GNU General Public License for more details. --*/
/*-- --*/
/*-- You should have received a copy of the GNU General Public License --*/
/*-- along with this program. If not, see <http://www.gnu.org/licenses/>. --*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*----------------------------------------------------------------------------*/
#define CMD_DECODE 0x00 // decode
#define CMD_CODE_30 0x30 // RLE magic number
#define RLE_CHECK 1 // bits to check
#define RLE_MASK 0x80 // bits position:
// ((((1 << RLE_CHECK) - 1) << (8 - RLE_CHECK)
#define RLE_LENGTH 0x7F // length, (0xFF & ~RLE_MASK)
#define RLE_THRESHOLD 2 // max number of bytes to not encode
#define RLE_N 0x80 // max store, (RLE_LENGTH + 1)
#define RLE_F 0x82 // max coded, (RLE_LENGTH + RLE_THRESHOLD + 1)
#define RAW_MINIM 0x00000000 // empty file, 0 bytes
#define RAW_MAXIM 0x00FFFFFF // 3-bytes length, 16MB - 1
#define RLE_MINIM 0x00000004 // header only (empty RAW file)
#define RLE_MAXIM 0x01400000 // 0x01020003, padded to 20MB:
// * header, 4
// * length, RAW_MAXIM
// * flags, (RAW_MAXIM + RLE_N - 1) / RLE_N
// 4 + 0x00FFFFFF + 0x00020000 + padding
/*----------------------------------------------------------------------------*/
#define BREAK(text) { printf(text); return; }
#define EXIT(text) { printf(text); exit(-1); }
/*----------------------------------------------------------------------------*/
void Title(void);
void Usage(void);
char *Load(char *filename, int *length, int min, int max);
void Save(char *filename, char *buffer, int length);
char *Memory(int length, int size);
void RLE_Decode(char *filename);
void RLE_Encode(char *filename);
char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len);
/*----------------------------------------------------------------------------*/
char *Memory(int length, int size) {
char *fb;
fb = (char *) calloc(length, size);
if (fb == NULL) EXIT("\nMemory error\n");
return(fb);
}
/*----------------------------------------------------------------------------*/
char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len) {
unsigned char *pak_buffer, *pak, *raw, *raw_end, store[RLE_N];
unsigned int pak_len, len, store_len, count;
pak_len = 4 + raw_len + ((raw_len + RLE_N - 1) / RLE_N);
pak_buffer = (unsigned char *) Memory(pak_len, sizeof(char));
*(unsigned int *)pak_buffer = CMD_CODE_30 | (raw_len << 8);
pak = pak_buffer + 4;
raw = raw_buffer;
raw_end = raw_buffer + raw_len;
store_len = 0;
while (raw < raw_end) {
for (len = 1; len < RLE_F; len++) {
if (raw + len == raw_end) break;
if (*(raw + len) != *raw) break;
}
if (len <= RLE_THRESHOLD) store[store_len++] = *raw++;
if ((store_len == RLE_N) || (store_len && (len > RLE_THRESHOLD))) {
*pak++ = store_len - 1;
for (count = 0; count < store_len; count++) *pak++ = store[count];
store_len = 0;
}
if (len > RLE_THRESHOLD) {
*pak++ = RLE_MASK | (len - (RLE_THRESHOLD + 1));
*pak++ = *raw;
raw += len;
}
}
if (store_len) {
*pak++ = store_len - 1;
for (count = 0; count < store_len; count++) *pak++ = store[count];
}
*new_len = pak - pak_buffer;
return(pak_buffer);
}
/*----------------------------------------------------------------------------*/
/*-- EOF Copyright (C) 2011 CUE --*/
/*----------------------------------------------------------------------------*/

View File

@ -1,17 +1,19 @@
#include "fastlz.h"
#include <cstddef>
#include <cstdlib>
#include <malloc.h>
#include <nds.h>
#include <filesystem.h>
#include <nds/arm9/console.h>
#include <nds/arm9/video.h>
#include <nds/debug.h>
#include <nds/ndstypes.h>
#include <nds/arm9/decompress.h>
#include <nds/bios.h>
#include <nds/dma.h>
#include <nds/system.h>
#include <nds/timers.h>
#include <stdio.h>
#include <cstdarg>
#include <sys/_stdint.h>
void wait_forever(const char* msg, ...);
#define TIMER_SPEED (BUS_CLOCK/1024)
void wait_forever(const char* msg);
size_t LoadFile(const char* file, unsigned char **buffer);
void readNextBatch(FILE *input, void *output);
void vbl_handler();
@ -64,9 +66,9 @@ public:
}
};
static uint8_t chunk[256*192*4*16];
static uint8_t chunk[256*192*4*7];
static int chunk_counter = 0;
static CircularQueue queue(16);
static CircularQueue queue(7);
static FILE *in = NULL;
static int bgp;
@ -85,7 +87,7 @@ int main(void) {
nitroFSInit(NULL);
in = fopen("nitro:/image.bin", "rb");
if (in == NULL) wait_forever("cannot load %s", "nitro:/image.bin");
if (in == NULL) wait_forever("cannot load nitro:/image.bin");
// unsigned char* bmp = NULL;
// unsigned char* bmp_decompress = (unsigned char*)malloc(256*192);
@ -108,14 +110,37 @@ int main(void) {
// dmaCopy(bmp_decompress, bgGetGfxPtr(bgp), 256*192);
// nocashMessage("done\n");
// fprintf(stderr, "start debug\n");
// int cframe = 0;
// int hframe = 0;
// int ticks = 0;
// while(!feof(in))
// {
// timerStart(0, ClockDivider_1024, 0, NULL);
// readNextBatch(in , chunk);
// ticks = timerStop(0);
// int milis = ((ticks%TIMER_SPEED)*1000) /TIMER_SPEED;
// if (milis > 60) fprintf(stderr, "%i\n", cframe);
// cframe++;
// }
// fprintf(stderr, "%i\n", hframe);
fseek(in, 0, SEEK_SET);
fprintf(stderr, "read\n");
while(!queue.isFull()) {
queue.push();
readNextBatch(in, &chunk[256*192*4 * queue.rear]);
fprintf(stderr, "read %i\n", queue.rear);
// if (queue.rear == 1) break;
}
fprintf(stderr, "done read\n");
while(1) {
irqSet(IRQ_VBLANK, vbl_handler);
@ -132,15 +157,23 @@ int main(void) {
void vbl_handler()
{
if (queue.isEmpty()) return;
// if (queue.isEmpty() && chunk_counter == 0) {
// return;
// fprintf(stderr, "NO QUEUE!!!!!");
// }
dmaCopy(&chunk[256*192*4 * queue.front + 256*192*chunk_counter], bgGetGfxPtr(bgp), 256*192);
fprintf(stderr, "count: %i, %i\n ", chunk_counter, queue.current);
chunk_counter++;
if (chunk_counter >= 3) {
queue.pop();
chunk_counter = 0;
if (chunk_counter >= 4) {
if (!queue.isEmpty()) {
queue.pop();
chunk_counter = 0;
} else {
chunk_counter = 4;
fprintf(stderr, "NO QUEUE!!!!!");
}
}
}
@ -149,42 +182,53 @@ void readNextBatch(FILE *input, void *output)
uint32_t chunk_len;
fread(&chunk_len, sizeof(uint32_t), 1, input);
unsigned char *buffer = (unsigned char*)malloc(chunk_len);
bool isRLE = chunk_len & 0x01;
chunk_len = chunk_len >> 1;
uint8_t buffer[chunk_len];
// uint8_t *buffer2 = (uint8_t*)malloc(256*192*4);
fread(buffer, 1, chunk_len, input);
fastlz_decompress(buffer, chunk_len, output, 256*192*4);
free(buffer);
// DC_FlushRange(output, 256*192*4);
if (isRLE)
{
// fprintf(stderr, "rle\n");
decompress(buffer, output, RLE);
// dmaCopy(buffer2, output, 256*192*4);
}
else
{
// fprintf(stderr, "fastlz\n");
fastlz_decompress(buffer, chunk_len, output, 256*192*4);
}
}
size_t LoadFile(const char* file, unsigned char **buffer)
{
FILE *in = fopen(file, "rb");
if (in == NULL) wait_forever("cannot load %s", file);
if (in == NULL) wait_forever("cannot load file!");
fseek(in, 0, SEEK_END);
long file_size = ftell(in);
rewind(in);
*buffer = (unsigned char*)malloc(file_size);
if (*buffer == NULL) wait_forever("Failed to malloc %s", file);
if (*buffer == NULL) wait_forever("Failed to malloc!");
size_t bytes_read = fread(*buffer, 1, file_size, in);
if (bytes_read != file_size)
{
fclose(in);
free(*buffer);
wait_forever("Failed to read %s", file);
wait_forever("Failed to read");
}
return bytes_read;
}
void wait_forever(const char* msg, ...)
void wait_forever(const char* msg)
{
va_list args;
va_start(args, msg);
fprintf(stdout, msg, args);
fprintf(stderr, msg, args);
va_end(args);
fprintf(stdout, "%s", msg);
fprintf(stderr, "%s", msg);
while (1) swiWaitForVBlank();
}