#include #include #include #include #include #include #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); extern "C" unsigned char *LZS_Fast(unsigned char *raw_buffer, size_t raw_len, size_t *new_len); extern "C" unsigned char *LZS_Code(unsigned char *raw_buffer, size_t raw_len, size_t *new_len, size_t best); #define LZS_WRAM 0x00 // VRAM not compatible (LZS_WRAM | LZS_NORMAL) #define LZS_VRAM 0x01 // VRAM compatible (LZS_VRAM | LZS_NORMAL) #define RGBtoRGB15(r,g,b) (((r >> 3) & 0x1F) | (((g >> 3) & 0x1F) << 5) | (((b >> 3) & 0x1F) << 10)) #define ASSETS_PATH "../assets/" #define PALETTE_SIZE 256 #define FRAME_SIZE 256*192 #define CHUNK_SIZE 8 void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest, uint16_t *palette_buffer); int Compress(uint8_t type, uint8_t *frame_buffer, uint32_t frame_buffer_len, uint8_t *compress_buffer) { switch (type) { case 1: // fastlz return fastlz_compress_level(1, frame_buffer, frame_buffer_len, compress_buffer); break; case 2: // rle { int compress_len; char *compress = RLE_Code(frame_buffer, frame_buffer_len, &compress_len); memcpy(compress_buffer, compress, compress_len); return compress_len; break; } case 3: // lzss { size_t compress_len; unsigned char *compress = LZS_Fast(frame_buffer, frame_buffer_len, &compress_len); // int mode = LZS_VRAM; // unsigned char *compress = LZS_Code(frame_buffer, frame_buffer_len, &compress_len, mode); memcpy(compress_buffer, compress, compress_len); return compress_len; break; } } return 0; } void Convert(std::string frame_path, std::string palette_path, std::string output_path, std::string output_basename, uint8_t type) { uint16_t palette_buffer[PALETTE_SIZE]; size_t frame_total = 0; uint8_t frame_buffer[FRAME_SIZE*CHUNK_SIZE]; uint32_t compress_size = 0; uint32_t compress_size_total = 0; size_t compress_size_biggest = 0; uint8_t compress_buffer[162000]; std::ofstream file_out; printf("Finding total frame..."); // Find total frame for (const auto& entry : std::filesystem::directory_iterator(frame_path)) { if (entry.is_regular_file()) { std::string filename = entry.path().filename().string(); int extpos = filename.find(".bmp", 4); if (extpos != std::string::npos) { int number = std::stoi(filename.substr(4, extpos-4)); if (number > frame_total) frame_total = number; } } } // Generate palette printf("Generating palette map...\n"); int pal_w, pal_h, pal_n; unsigned char *palette_raw = stbi_load(palette_path.c_str(), &pal_w, &pal_h, &pal_n, 3); for (int i=0; i(palette_buffer), sizeof(palette_buffer)); file_out.close(); printf("Generating image map...\n"); std::stringstream ss; file_out.open(output_path + output_basename + "_img.bin", std::ios::binary); // ########## PER FRAME ENCODER ########## // for (int i=0; i compress_size_biggest) compress_size_biggest = compress_size; // compress_size_total += compress_size; // file_out.write(reinterpret_cast(&compress_size), sizeof(uint32_t)); // file_out.write(reinterpret_cast(compress_buffer), compress_size); // printf("write %i bytes (%i/%i)\n", compress_size, i+1, frame_total); // } // ######################################## // Calculate the number of complete iterations needed int numIterations = frame_total / CHUNK_SIZE; // Calculate the number of remaining items int remainingItems = frame_total % CHUNK_SIZE; for (int i=0; i compress_size_biggest) compress_size_biggest = compress_size; compress_size_total += compress_size; file_out.write(reinterpret_cast(&compress_size), sizeof(uint32_t)); file_out.write(reinterpret_cast(compress_buffer), compress_size); // file_out.put('\0'); printf("write chunk %i bytes %i/%i\n", compress_size, i, numIterations-1); } // Handle remaining frame if (remainingItems > 0) { memset(frame_buffer, 0, FRAME_SIZE*CHUNK_SIZE); int i_chunk = 0; for (int k = frame_total-remainingItems; k compress_size_biggest) compress_size_biggest = compress_size; compress_size_total += compress_size; file_out.write(reinterpret_cast(&compress_size), sizeof(uint32_t)); file_out.write(reinterpret_cast(compress_buffer), compress_size); // file_out.put('\0'); printf("write remaining chunk %i bytes\n", compress_size); } file_out.close(); // Print printf("Total Frame: %i\n", frame_total); printf("Biggest : %i\n", compress_size_biggest); printf("Total Size : %1.fmb\n", static_cast(compress_size_total) / (1024*1024)); } int main() { // Convert(ASSETS_PATH "out1/", ASSETS_PATH "palette1.png", "../nitrofs/", "data_fastlz", 1); // Convert(ASSETS_PATH "out1/", ASSETS_PATH "palette1.png", "../nitrofs/", "data_rle", 2); Convert(ASSETS_PATH "out/", ASSETS_PATH "palette1.png", "../nitrofs/", "main", 3); // Convert(ASSETS_PATH "out2/", ASSETS_PATH "palette2.png", "../nitrofs/", "sub"); } void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest, uint16_t *palette_buffer) { for (int rgb=0; rgb