1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-14 21:40:03 +00:00

Delete unused yaz0tool (#1959)

This commit is contained in:
cadmic 2024-06-18 17:53:19 -07:00 committed by GitHub
parent 44ca32168a
commit 7332e8ee76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 1 additions and 451 deletions

View file

@ -1,5 +1,5 @@
CFLAGS := -Wall -Wextra -pedantic -std=c99 -g -O2
PROGRAMS := elf2rom makeromfs mkdmadata mkldscript reloc_prereq vtxdis yaz0
PROGRAMS := elf2rom makeromfs mkdmadata mkldscript reloc_prereq vtxdis
ifeq ($(shell command -v clang >/dev/null 2>&1; echo $$?),0)
CC := clang
@ -36,7 +36,6 @@ mkdmadata_SOURCES := mkdmadata.c spec.c util.c
mkldscript_SOURCES := mkldscript.c spec.c util.c
reloc_prereq_SOURCES := reloc_prereq.c spec.c util.c
vtxdis_SOURCES := vtxdis.c
yaz0_SOURCES := yaz0tool.c yaz0.c util.c
define COMPILE =

View file

@ -1,238 +0,0 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "yaz0.h"
// decoder implementation by thakis of http://www.amnoid.de
// src points to the yaz0 source data (to the "real" source data, not at the header!)
// dst points to a buffer uncompressedSize bytes large (you get uncompressedSize from
// the second 4 bytes in the Yaz0 header).
void yaz0_decode(uint8_t* src, uint8_t* dst, int uncompressedSize)
{
int srcPlace = 0, dstPlace = 0; // current read/write positions
unsigned int validBitCount = 0; // number of valid bits left in "code" byte
uint8_t currCodeByte;
while (dstPlace < uncompressedSize)
{
// read new "code" byte if the current one is used up
if (validBitCount == 0)
{
currCodeByte = src[srcPlace];
++srcPlace;
validBitCount = 8;
}
if ((currCodeByte & 0x80) != 0)
{
// straight copy
dst[dstPlace] = src[srcPlace];
dstPlace++;
srcPlace++;
}
else
{
// RLE part
uint8_t byte1 = src[srcPlace];
uint8_t byte2 = src[srcPlace + 1];
srcPlace += 2;
unsigned int dist = ((byte1 & 0xF) << 8) | byte2;
unsigned int copySource = dstPlace - (dist + 1);
unsigned int numBytes = byte1 >> 4;
if (numBytes == 0)
{
numBytes = src[srcPlace] + 0x12;
srcPlace++;
}
else
{
numBytes += 2;
}
// copy run
for (unsigned int i = 0; i < numBytes; ++i)
{
dst[dstPlace] = dst[copySource];
copySource++;
dstPlace++;
}
}
// use next bit from "code" byte
currCodeByte <<= 1;
validBitCount -= 1;
}
}
// encoder implementation by shevious, with bug fixes by notwa
typedef uint32_t uint32_t;
typedef uint8_t uint8_t;
#define MAX_RUNLEN (0xFF + 0x12)
// simple and straight encoding scheme for Yaz0
static uint32_t simpleEnc(uint8_t *src, int size, int pos, uint32_t *pMatchPos)
{
int numBytes = 1;
int matchPos = 0;
int startPos = pos - 0x1000;
int end = size - pos;
if (startPos < 0)
startPos = 0;
// maximum runlength for 3 byte encoding
if (end > MAX_RUNLEN)
end = MAX_RUNLEN;
for (int i = startPos; i < pos; i++)
{
int j;
for (j = 0; j < end; j++)
{
if (src[i + j] != src[j + pos])
break;
}
if (j > numBytes)
{
numBytes = j;
matchPos = i;
}
}
*pMatchPos = matchPos;
if (numBytes == 2)
numBytes = 1;
return numBytes;
}
// a lookahead encoding scheme for ngc Yaz0
static uint32_t nintendoEnc(uint8_t *src, int size, int pos, uint32_t *pMatchPos)
{
uint32_t numBytes = 1;
static uint32_t numBytes1;
static uint32_t matchPos;
static int prevFlag = 0;
// if prevFlag is set, it means that the previous position
// was determined by look-ahead try.
// so just use it. this is not the best optimization,
// but nintendo's choice for speed.
if (prevFlag == 1)
{
*pMatchPos = matchPos;
prevFlag = 0;
return numBytes1;
}
prevFlag = 0;
numBytes = simpleEnc(src, size, pos, &matchPos);
*pMatchPos = matchPos;
// if this position is RLE encoded, then compare to copying 1 byte and next position(pos+1) encoding
if (numBytes >= 3)
{
numBytes1 = simpleEnc(src, size, pos + 1, &matchPos);
// if the next position encoding is +2 longer than current position, choose it.
// this does not guarantee the best optimization, but fairly good optimization with speed.
if (numBytes1 >= numBytes + 2)
{
numBytes = 1;
prevFlag = 1;
}
}
return numBytes;
}
int yaz0_encode(uint8_t *src, uint8_t *dst, int srcSize)
{
int srcPos = 0;
int dstPos = 0;
int bufPos = 0;
uint8_t buf[24]; // 8 codes * 3 bytes maximum
uint32_t validBitCount = 0; // number of valid bits left in "code" byte
uint8_t currCodeByte = 0; // a bitfield, set bits meaning copy, unset meaning RLE
while (srcPos < srcSize)
{
uint32_t numBytes;
uint32_t matchPos;
numBytes = nintendoEnc(src, srcSize, srcPos, &matchPos);
if (numBytes < 3)
{
// straight copy
buf[bufPos] = src[srcPos];
bufPos++;
srcPos++;
//set flag for straight copy
currCodeByte |= (0x80 >> validBitCount);
}
else
{
//RLE part
uint32_t dist = srcPos - matchPos - 1;
uint8_t byte1, byte2, byte3;
if (numBytes >= 0x12) // 3 byte encoding
{
byte1 = 0 | (dist >> 8);
byte2 = dist & 0xFF;
buf[bufPos++] = byte1;
buf[bufPos++] = byte2;
// maximum runlength for 3 byte encoding
if (numBytes > MAX_RUNLEN)
numBytes = MAX_RUNLEN;
byte3 = numBytes - 0x12;
buf[bufPos++] = byte3;
}
else // 2 byte encoding
{
byte1 = ((numBytes - 2) << 4) | (dist >> 8);
byte2 = dist & 0xFF;
buf[bufPos++] = byte1;
buf[bufPos++] = byte2;
}
srcPos += numBytes;
}
validBitCount++;
// write eight codes
if (validBitCount == 8)
{
dst[dstPos++] = currCodeByte;
for (int j = 0; j < bufPos; j++)
dst[dstPos++] = buf[j];
currCodeByte = 0;
validBitCount = 0;
bufPos = 0;
}
}
if (validBitCount > 0)
{
dst[dstPos++] = currCodeByte;
for (int j = 0; j < bufPos; j++)
dst[dstPos++] = buf[j];
currCodeByte = 0;
validBitCount = 0;
bufPos = 0;
}
return dstPos;
}

View file

@ -1,10 +0,0 @@
#ifndef _YAZ0_H_
#define _YAZ0_H_
int yaz0_encode2(uint8_t *src, uint8_t *dest, int uncompressedSize);
void yaz0_decode(uint8_t* src, uint8_t* dst, int uncompressedSize);
int yaz0_encode(uint8_t *src, uint8_t *dest, int srcSize);
#endif // _YAZ0_H_

View file

@ -1,201 +0,0 @@
#ifdef __linux__
#define _POSIX_C_SOURCE 199309L
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "yaz0.h"
#include "util.h"
// TODO: Windows support
static unsigned long int get_time_milliseconds(void)
{
#ifdef __linux__
struct timespec tspec;
clock_gettime(CLOCK_MONOTONIC, &tspec);
return (tspec.tv_sec * 1000) + tspec.tv_nsec / 1000000;
#else
// dummy
return 0;
#endif
}
static void print_report(unsigned long int time, size_t compSize, size_t uncompSize)
{
unsigned int minutes = time / (1000 * 60);
float seconds = (float)(time % (1000 * 60)) / 1000;
printf("compression ratio: %.2fKiB / %.2fKiB (%.2f%%)\n"
"time: %um %.3fs\n",
(float)compSize / 1024, (float)uncompSize / 1024,
(float)compSize * 100 / (float)uncompSize,
minutes, seconds);
}
static void compress_file(const char *inputFileName, const char *outputFileName, bool verbose)
{
size_t uncompSize;
uint8_t *input = util_read_whole_file(inputFileName, &uncompSize);
uint8_t *output = malloc(uncompSize * 2); // TODO: figure out how much space we need
unsigned long int time;
if (verbose)
{
printf("decompressing %s\n", inputFileName);
time = get_time_milliseconds();
}
// compress data
size_t compSize = yaz0_encode(input, output, uncompSize);
if (verbose)
time = get_time_milliseconds() - time;
// make Yaz0 header
uint8_t header[16] = {0};
header[0] = 'Y';
header[1] = 'a';
header[2] = 'z';
header[3] = '0';
util_write_uint32_be(header + 4, uncompSize);
// write output file
FILE *outFile = fopen(outputFileName, "wb");
if (outFile == NULL)
util_fatal_error("failed to open file '%s' for writing", outputFileName);
fwrite(header, sizeof(header), 1, outFile);
fwrite(output, compSize, 1, outFile);
fclose(outFile);
free(input);
free(output);
if (verbose)
print_report(time, compSize, uncompSize);
}
static void decompress_file(const char *inputFileName, const char *outputFileName, bool verbose)
{
size_t compSize;
uint8_t *input = util_read_whole_file(inputFileName, &compSize);
size_t uncompSize;
uint8_t *output;
unsigned long int time = 0;
// read header
if (input[0] != 'Y' || input[1] != 'a' || input[2] != 'z' || input[3] != '0')
util_fatal_error("file '%s' does not have a valid Yaz0 header", inputFileName);
uncompSize = util_read_uint32_be(input + 4);
// decompress data
output = malloc(uncompSize);
if (verbose)
{
printf("decompressing %s\n", inputFileName);
time = get_time_milliseconds();
}
yaz0_decode(input + 16, output, uncompSize);
if (verbose)
time = get_time_milliseconds() - time;
// write output file
FILE *outFile = fopen(outputFileName, "wb");
fwrite(output, uncompSize, 1, outFile);
fclose(outFile);
free(input);
free(output);
if (verbose)
print_report(time, compSize, uncompSize);
}
static void usage(const char *execName)
{
printf("Yaz0 compressor/decompressor\n"
"usage: %s [-d] [-h] [-v] INPUT_FILE OUTPUT_FILE\n"
"compresses INPUT_FILE using Yaz0 encoding and writes output to OUTPUT_FILE\n"
"Available options:\n"
"-d: decompresses INPUT_FILE, a Yaz0 compressed file, and writes decompressed\n"
" output to OUTPUT_FILE\n"
"-v: prints verbose output (compression ratio and time)\n"
"-h: shows this help message\n",
execName);
}
int main(int argc, char **argv)
{
int i;
const char *inputFileName = NULL;
const char *outputFileName = NULL;
bool decompress = false;
bool verbose = false;
// parse arguments
for (i = 1; i < argc; i++)
{
char *arg = argv[i];
if (arg[0] == '-')
{
if (strcmp(arg, "-d") == 0)
decompress = true;
else if (strcmp(arg, "-v") == 0)
verbose = true;
else if (strcmp(arg, "-h") == 0)
{
usage(argv[0]);
return 0;
}
else
{
printf("unknown option %s\n", arg);
usage(argv[0]);
return 1;
}
}
else
{
if (inputFileName == NULL)
inputFileName = arg;
else if (outputFileName == NULL)
outputFileName = arg;
else
{
puts("too many files specified");
usage(argv[0]);
return 1;
}
}
}
if (inputFileName == NULL)
{
puts("no input file specified");
usage(argv[0]);
return 1;
}
if (outputFileName == NULL)
{
puts("no output file specified");
usage(argv[0]);
return 1;
}
if (decompress)
decompress_file(inputFileName, outputFileName, verbose);
else
compress_file(inputFileName, outputFileName, verbose);
return 0;
}