圧縮するsharedFont

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1911 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yoshida_teruhisa 2008-07-16 08:30:56 +00:00
parent fe0fd76dbc
commit cd998bdf6f
26 changed files with 9007 additions and 146 deletions

View File

@ -18,26 +18,32 @@
TARGET_FIRM = SYSTEMMENU
SUBDIRS = compBLZ_modified \
ntrcomp
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
FONT_TIMESTAMP = 08071200
FONT_TIMESTAMP = 08061300
FONT_DIR = WW
FONTS = TBF1_l.NFTR \
TBF1_m.NFTR \
TBF1_s.NFTR
FONT_RSC = $(addprefix $(FONT_DIR)/, $(FONTS))
FONT_ORG_DIR = $(TWL_IPL_RED_ROOT)/build/systemMenu_RED/sharedFont/WW
FONT_ORG_RSC = $(addprefix $(FONT_ORG_DIR)/, $(FONTS))
ifneq ($(TWL_IPL_RED_PRIVATE_ROOT),)
FONT_TABLE = TWLFontTable.dat
endif
GEN_FONT_TABLE = $(SYSMENU_TOOLSDIR)/bin/genFontTable.plx
GEN_FONT_TABLE = ./genFontTable.plx
#----------------------------------------------------------------------------
INSTALL_TARGETS = $(FONT_TABLE)
INSTALL_DIR = $(TWL_IPL_RED_ROOT)/build/systemMenu_tools/NandInitializerRed/data
LDIRT_CLEAN =
LDIRT_CLEAN = $(FONT_TABLE) $(FONT_RSC)
#----------------------------------------------------------------------------
@ -45,7 +51,12 @@ include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules
do-build : $(FONT_TABLE)
$(FONT_TABLE): $(FONT_RSC) ./Makefile
# step1 : copy sharedFonts into local directory for work
$(FONT_RSC):
cp $(FONT_ORG_RSC) $(FONT_DIR)
# step2 : compress sharedFonts and them in local directory
$(FONT_TABLE): $(FONT_RSC)
$(GEN_FONT_TABLE) $(FONT_TIMESTAMP) $(FONT_RSC)
#===== End of Makefile =====

View File

@ -0,0 +1,73 @@
#! make -f
#---------------------------------------------------------------------------
# Project: TwlSDK - tools - compBLZ
# File: Makefile
#
# Copyright 2008 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#---------------------------------------------------------------------------
TARGET_PLATFORM = TWL NITRO
include $(TWLSDK_ROOT)/build/buildtools/commondefs
#---------------------------------------------------------------------------
TARGET_BIN = compBLZ.exe
TARGETS = $(BINDIR)/$(TARGET_BIN)
SRCS = main.c \
compress.c \
file.c \
version.c
HEADERS = common.h \
compress.h \
file.h
INCDIR += ../../../include
OBJDIR = obj
BINDIR = bin
OBJS = $(addprefix $(OBJDIR)/,$(SRCS:.c=.o))
MACROS += -DSDK_TWL $(addprefix -I,$(INCDIR))
NEWDIRS = $(OBJDIR) $(BINDIR)
LDIRT_CLEAN += $(NEWDIRS) version.c
#INSTALL_DIR = $(TWL_INSTALL_TOOLSDIR)/bin
#INSTALL_TARGETS = $(TARGETS)
#---------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/modulerules.x86
do-build: $(TARGETS)
$(TARGETS): $(OBJS) $(LIBDGT) $(MAKEFILE)
$(CC_X86) $(OBJS) $(LIBDGT) -o $@
$(OBJS):%.o:
$(COMPILE_C)
$(OBJDIR)/main.o: main.c file.h version.c
$(OBJDIR)/compress.o: compress.c compress.h
$(OBJDIR)/file.o: file.c file.h
$(OBJDIR)/version.o: version.c
version.c: $(filter-out version.c,$(SRCS)) $(HEADERS) $(MAKEFILE)
@for i in $^ ; \
do \
date -r $$i +'const unsigned long SDK_DATE_OF_LATEST_FILE=%Y%m%dUL;'; \
done | sort | tail -1 > $@
#===== End of Makefile =====

View File

@ -0,0 +1 @@
SDK_CONFIDENTIAL

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - compstatic
File: common.h
Copyright 2003 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef COMMON_H__
#define COMMON_H__
typedef enum
{
TRUE = 1,
FALSE = 0
}
BOOL;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
// macro
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ROUNDUP4(x) (((x)+3)&~3)
#define LE(a) ((((a)<<24)&0xff000000)|(((a)<<8)&0x00ff0000)|\
(((a)>>8)&0x0000ff00)|(((a)>>24)&0x000000ff))
#define FREE(x) do { if (x){ free(x); x = NULL; } } while(0)
#endif //COMMON_H__

View File

@ -0,0 +1,374 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - compstatic
File: compress.c
Copyright 2003 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "file.h"
#include "compress.h"
static int LZCompressRV(u8 *src_buffer, int src_size, u8 *dst_buffer, int dst_size);
static int FindMatched(u8 *src_buffer, int src_size, u8 *dic_buffer, int dic_size, int *index);
static int HowManyMatched(u8 *src_buffer, u8 *dic_buffer, int max_len);
static int CheckOverwrite(int orig_size, u8 *cmprs_buffer, int cmprs_buffer_size,
int *orig_safe, int *cmprs_safe);
/*---------------------------------------------------------------------------*
Name: Compress
Description: Buffer
調
buffer :
buffer_size :
Return: >=0:
< 0:
*---------------------------------------------------------------------------*/
int Compress(u8 *buffer_original, int buffer_original_size)
{
u8 *buffer;
int buffer_size;
int buffer_start;
u8 *temp_buffer_original;
u8 *temp_buffer;
int temp_buffer_size;
int temp_buffer_start;
int compressed_size;
int aligned_size;
int total_size;
int reduced;
int i;
CompFooter *footer;
// 前準備
if (NULL == (temp_buffer_original = (u8 *)malloc(buffer_original_size)))
{
ErrorPrintf("Cannot allocate memory size=%d\n", buffer_original_size);
return COMPRESS_FATAL_ERROR;
}
if ((u32)buffer_original % 4 != 0)
{
ErrorPrintf("Top of buffer is not aligned by 4.\n");
return COMPRESS_FATAL_ERROR;
}
buffer = buffer_original;
buffer_size = buffer_original_size;
temp_buffer = temp_buffer_original;
temp_buffer_size = buffer_original_size;
// 圧縮を行なう
reduced = LZCompressRV(buffer, buffer_size, temp_buffer, temp_buffer_size);
if (reduced < 0)
{
DebugPrintf("Compressed buffer size exceeds original data size.\n");
free(temp_buffer_original);
return COMPRESS_LARGER_ORIGINAL;
}
temp_buffer_size -= reduced;
temp_buffer += reduced;
DebugPrintf("1: source size = %d compressed = %d\n", buffer_size, temp_buffer_size);
// 展開不能な上書きが発生するか確認
if (!CheckOverwrite
(buffer_size, temp_buffer, temp_buffer_size, &buffer_start, &temp_buffer_start))
{
// 上書きが発生するなら圧縮範囲を変更する
buffer += buffer_start;
buffer_size -= buffer_start;
temp_buffer += temp_buffer_start;
temp_buffer_size -= temp_buffer_start;
DebugPrintf(" !! Shrink back Compressed region to avoid overwriting.\n"
" !! Expand non-compressed region = +%d\n"
"2: source size = %d compressed = %d\n",
buffer_start, buffer_size, temp_buffer_size);
}
// PADDING とパラメータ領域を加えても超えないかどうか判定
compressed_size = buffer_start + temp_buffer_size; // header+body
aligned_size = ROUNDUP4(compressed_size); // +padding
total_size = aligned_size + sizeof(CompFooter); // +footer
if (buffer_original_size <= total_size)
{
DebugPrintf("Compressed buffer size exceeds or equals original data size.\n");
free(temp_buffer_original);
return COMPRESS_LARGER_ORIGINAL;
}
// データをテンポラリバッファから元データへ上書きする
CopyBuffer(temp_buffer, buffer, temp_buffer_size);
free(temp_buffer_original);
// サイズが 4 の倍数になるように PADDING
// LZ の実装上圧縮領域の最初のバイト値は 0xff にならない(最初は圧縮
// フラグであり、最初のデータは圧縮なしで格納されるから)ので 0xff で
// 埋める
for (i = compressed_size; i < aligned_size; i++)
{
buffer_original[i] = 0xff;
}
// サイズ設定
// compressBottom は sizeof(PAD)+sizeof(footer) なので 1バイトで十分
footer = (CompFooter *) (buffer_original + aligned_size);
footer->bufferTop = total_size - buffer_start; // 正の値
footer->compressBottom = total_size - compressed_size; // 正の値
footer->originalBottom = buffer_original_size - total_size; // 正の値
return total_size;
}
/*---------------------------------------------------------------------------*
Name: LZCompressRV
Description: LZ
Returns: index
dst_buffer+index dst_buffer+dst_size-1
-1: ()
*---------------------------------------------------------------------------*/
static int LZCompressRV(u8 *src_buffer, int src_size, u8 *dst_buffer, int dst_size)
{
int src_index = src_size;
int dst_index = dst_size;
int compflag;
int compflag_index;
int i;
while (src_index > 0)
{
if (dst_index < 1)
return -1; // Buffer Overflow
// 8bit の圧縮フラグの挿入位置を予約
compflag = 0x00;
compflag_index = --dst_index;
// フラグ系列が8ビットデータとして格納されるため、8回ループ
for (i = 0; i < 8; i++)
{
compflag <<= 1;
if (src_index > 0) // src が残っているか判定
{
u8 *dic_buffer;
int dic_size;
u8 *ref_buffer;
int ref_size;
int index;
int len;
dic_buffer = src_buffer + src_index;
dic_size = src_size - src_index;
ref_size = MIN(src_index, LZ_MAX_COPY);
ref_buffer = dic_buffer - ref_size;
len = FindMatched(ref_buffer, ref_size,
dic_buffer, MIN(dic_size, LZ_MAX_DIC_LENGTH), &index);
if (len >= LZ_MIN_COPY)
{
u16 half;
// Offset/Len の記録が可能かどうか確認
if (dst_index < 2)
return -1; // Buffer Overflow
// src index 進める
src_index -= len;
// len >= LZ_MIN_COPY なのでその分減算し値域を節約する
index -= (LZ_MIN_COPY - 1);
len -= (LZ_MIN_COPY - 0);
// 16bit データとしてたたむ
half = (u16)((index & (LZ_MAX_INDEX - 1)) | (len << LZ_BIT_INDEX));
dst_buffer[--dst_index] = (half >> 8) & 0xff;
dst_buffer[--dst_index] = (half >> 0) & 0xff;
// flag セット
compflag |= 0x01;
}
else
{
// 値そのままを記録する & src index 進める
if (dst_index < 1)
return -1; // Buffer Overflow
dst_buffer[--dst_index] = src_buffer[--src_index];
}
}
}
// 圧縮フラグの保存
dst_buffer[compflag_index] = compflag;
}
return dst_index;
}
/*---------------------------------------------------------------------------*
Name: FindMatched
Description:
src_buffer[0...src_size-1] src_buffer
dic_buffer[0...dic_size-1]
Returns:
*index
*---------------------------------------------------------------------------*/
static int FindMatched(u8 *src_buffer, int src_size, u8 *dic_buffer, int dic_size, int *index)
{
u8 *src_bottom = src_buffer + src_size - 1;
u8 char_src_bottom = *src_bottom;
int n, len, max_len;
// 返値初期化
max_len = 0;
for (n = 0; n < dic_size; n++)
{
// 高速化のためのキャッシュ
if (char_src_bottom == dic_buffer[n])
{
len = HowManyMatched(src_bottom, dic_buffer + n, MIN(n + 1, src_size));
if (max_len < len)
{
max_len = len;
*index = n;
}
}
}
// 最小サイズ以上なら成功
return max_len;
}
/*---------------------------------------------------------------------------*
Name: HowManyMatched
Description: 2調
src_buffer, dic_buffer
()
max_len 調
Returns:
*---------------------------------------------------------------------------*/
static int HowManyMatched(u8 *src_buffer, u8 *dic_buffer, int max_len)
{
int i;
// パターン一致検索(逆順)
for (i = 0; i < max_len; i++)
{
if (*src_buffer != *dic_buffer)
{
break;
}
src_buffer--;
dic_buffer--;
}
return i;
}
/*---------------------------------------------------------------------------*
Name: CheckOverwrite
Description: LZ
Returns: TRUE FALSE
*---------------------------------------------------------------------------*/
static int CheckOverwrite(int orig_size, u8 *cmprs_buffer, int cmprs_buffer_size,
int *orig_safe, int *cmprs_safe)
{
int src = cmprs_buffer_size;
int dst = orig_size;
int flag;
int i;
//#define DETAIL
while (dst > 0)
{
flag = cmprs_buffer[--src]; // 圧縮非圧縮フラグ 8 ループ分
#ifdef DETAIL
DebugPrintf("%08x %08x FLG=0x%02x\n", src, dst, flag);
#endif
for (i = 0; i < 8; i++)
{
if (dst > 0)
{
if (flag & 0x80) // 圧縮データか?
{
u16 half;
int len;
// 展開長を計算
src -= 2;
half = (u16)(cmprs_buffer[src] | (cmprs_buffer[src + 1] << 8));
len = ((half >> LZ_BIT_INDEX) & (LZ_MAX_LENGTH - 1)) + LZ_MIN_COPY;
#ifdef DETAIL
DebugPrintf("%08x %08x-%08x LEN=%d\n", src, dst - 1, dst - len, len);
#endif
// ソースデータを上書きしてしまうかチェック
dst -= len;
if (dst < 0)
{
ErrorPrintf("System error in CheckOverwrite???\n");
exit(-1); // Panic!!
}
if (dst < src)
{
// 上書きしてしまうなら圧縮は現在のところまでで止める
*orig_safe = dst;
*cmprs_safe = src;
return FALSE;
}
}
else
{
// 非圧縮データならそのままコピーなので
// 破壊を伴なう上書きは起こらない
src--;
dst--;
#ifdef DETAIL
DebugPrintf("%08x %08x CHR=0x%02x\n", src, dst, cmprs_buffer[src]);
#endif
}
flag <<= 1;
}
}
}
*orig_safe = 0;
*cmprs_safe = 0;
return TRUE;
}

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - compstatic
File: compress.h
Copyright 2003 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef COMPRESS_H__
#define COMPRESS_H__
#include "common.h"
//---------------------------------------------------------
typedef struct
{
u32 bufferTop:24; // 圧縮領域終端 - 先頭
u32 compressBottom:8; // 圧縮領域終端 - データ終端
u32 originalBottom; // 展開領域終端 - 圧縮領域終端
}
CompFooter;
//---------------------------------------------------------
int Compress(u8 *buffer, int buffer_size);
#define COMPRESS_LARGER_ORIGINAL (-1)
#define COMPRESS_FATAL_ERROR (-2)
// loader area
#define LOADER_SIZE_ARM9 (16*1024)
#define LOADER_SIZE_ARM7 ( 1*1024)
// LZ compress parameters
#define LZ_BIT_INDEX 12 // 12bit offset
#define LZ_BIT_LENGTH 4 // 4bit length
#define LZ_MAX_INDEX (1 << LZ_BIT_INDEX)
#define LZ_MAX_LENGTH (1 << LZ_BIT_LENGTH)
#define LZ_MIN_COPY 3
#define LZ_MAX_COPY (LZ_MIN_COPY+LZ_MAX_LENGTH-1)
#define LZ_MAX_DIC_LENGTH (LZ_MIN_COPY+LZ_MAX_INDEX-1)
// macro
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ROUNDUP4(x) (((x)+3)&~3)
#endif

View File

@ -0,0 +1,314 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - compstatic
File: file.c
Copyright 2003 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <malloc.h> // calloc()
#include <stdlib.h> // free(), exit()
#include <sys/stat.h> // stat()
#include <string.h> // strlen/strdup/strcpy
#include <stdarg.h> // va_start(),va_end()
#include <unistd.h> // unlink()
#include "file.h"
/*---------------------------------------------------------------------------*
Name: ReadFile
Description:
*---------------------------------------------------------------------------*/
int ReadFile(const char *filename, u8 **buffer)
{
FILE *fp;
struct stat filestat;
int filesize;
fp = NULL;
*buffer = NULL;
if (filename == NULL)
{
ErrorPrintf("Not specified filename\n");
goto error;
}
/* Open file */
if (stat(filename, &filestat) || !S_ISREG(filestat.st_mode) ||
NULL == (fp = fopen(filename, "rb")))
{
ErrorPrintf("Cannot open file '%s'\n", filename);
goto error;
}
/* Read file */
filesize = filestat.st_size;
if (NULL == (*buffer = malloc(filesize)))
{
ErrorPrintf("Cannot allocate memory size=%d\n", filesize);
goto error;
}
if (filesize != fread(*buffer, sizeof(u8), filesize, fp))
{
ErrorPrintf("Cannot read file '%s'\n", filename);
goto error;
}
DebugPrintf("%p %8d bytes ReadFile \'%s\'\n", *buffer, filesize, filename);
/* Close file */
fclose(fp);
return filesize;
error:
if (*buffer)
free(*buffer);
if (fp)
fclose(fp);
return -1;
}
/*---------------------------------------------------------------------------*
Name: WriteFile
Description:
*---------------------------------------------------------------------------*/
int WriteFile(const char *filename, u8 *buffer, int size)
{
FILE *fp;
DebugPrintf("%p %8d bytes WriteFile \'%s\'\n", buffer, size, filename);
/* Open file */
if (NULL == (fp = fopen(filename, "wb")))
{
ErrorPrintf("Cannot open file '%s'\n", filename);
return -1;
}
/* Write file */
if (size != fwrite(buffer, sizeof(u8), size, fp))
{
ErrorPrintf("Cannot write file '%s'\n", filename);
(void)fclose(fp);
(void)unlink(filename);
return -1;
}
/* Close file */
if (0 > fclose(fp))
{
ErrorPrintf("Cannot close file '%s'\n", filename);
(void)unlink(filename);
return -1;
}
return size;
}
/*---------------------------------------------------------------------------*
Name: CopyBuffer
Description:
*---------------------------------------------------------------------------*/
void CopyBuffer(const u8 *src, u8 *dst, int size)
{
int i;
if ((unsigned int)src > (unsigned int)dst)
{
for (i = 0; i < size; i++)
{
dst[i] = src[i];
}
}
else
{
for (i = size - 1; i >= 0; i--)
{
dst[i] = src[i];
}
}
return;
}
/*---------------------------------------------------------------------------*
Name: GetDirName
Description:
*---------------------------------------------------------------------------*/
char *GetDirName(const char *path)
{
int i;
char *new_path;
for (i = strlen(path) - 1; i >= 0; i--)
{
if (path[i] == '/' || path[i] == '\\')
{
if (NULL != (new_path = strdup(path)))
{
new_path[i] = '\0';
}
return new_path;
}
if (path[i] == ':')
{
if (NULL != (new_path = malloc(i + 3)))
{
strncpy(new_path, path, i);
strcpy(new_path + i, ":.");
}
return new_path;
}
}
return strdup(".");
}
/*---------------------------------------------------------------------------*
Name: DebugPrintf
Description: Debug Printf
*---------------------------------------------------------------------------*/
BOOL bDebugMode = FALSE;
void DebugPrintf(const char *fmt, ...)
{
va_list va;
if (bDebugMode)
{
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
}
/*---------------------------------------------------------------------------*
Name: ConsolePrintf
Description: Printf
*---------------------------------------------------------------------------*/
void ConsolePrintf(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vfprintf(stdout, fmt, va);
va_end(va);
}
/*---------------------------------------------------------------------------*
Name: ErrorPrintf
Description: Error Printf
*---------------------------------------------------------------------------*/
void ErrorPrintf(const char *fmt, ...)
{
va_list va;
fprintf(stderr, "Error: ");
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
/*---------------------------------------------------------------------------*
Name: StrDup
Description: free strdup
*---------------------------------------------------------------------------*/
char *StrDup(char *old, char *new)
{
if (old)
{
free(old);
}
if (new && NULL == (new = strdup(new)))
{
ErrorPrintf("Cannot allocate memory\n");
exit(1);
}
return new;
}
/*---------------------------------------------------------------------------*
Name: StrCat
Description:
*---------------------------------------------------------------------------*/
char *StrCat(int num, ...)
{
va_list va;
int i;
int size;
char *result;
va_start(va, num);
size = 0;
for (i = 0; i < num; i++)
{
size += strlen(va_arg(va, char *));
}
va_end(va);
if (NULL == (result = malloc(size + 1)))
{
ErrorPrintf("Cannot allocate memory\n");
exit(1);
}
va_start(va, num);
result[0] = '\0';
for (i = 0; i < num; i++)
{
(void)strcat(result, va_arg(va, char *));
}
va_end(va);
return result;
}
//---------------------------------------------------------------------------
// パス文字列からファイル名部分のポインタを取得し、拡張子を削る
// @param path パス
// @return ファイル名のポインタ
//---------------------------------------------------------------------------
char *StrCutFname(char *path)
{
char *search_tmp;
if (path == NULL)
{
return NULL;
}
if ((search_tmp = strrchr(path, '/')) != NULL)
{
path = (search_tmp + 1);
}
if ((search_tmp = strrchr(path, '\\')) != NULL)
{
path = (search_tmp + 1);
}
if ((search_tmp = strrchr(path, '.')) != NULL)
{
*search_tmp = '\0';
}
return path;
}

View File

@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - compstatic
File: file.h
Copyright 2003 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef FILE_H__
#define FILE_H__
#include "common.h"
int ReadFile(const char *filename, u8 **buffer);
int WriteFile(const char *filename, u8 *buffer, int size);
void CopyBuffer(const u8 *src, u8 *dst, int size);
char *GetDirName(const char *filename);
void DebugPrintf(const char *fmt, ...);
void ErrorPrintf(const char *fmt, ...);
void ConsolePrintf(const char *fmt, ...);
char *StrDup(char *old, char *new);
char *StrCat(int num, ...);
char *StrCutFname(char *path);
extern BOOL bDebugMode;
#endif //FILE_H__

View File

@ -0,0 +1,171 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - compBLZ
File: main.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // getopt()
#include "file.h"
#include "compress.h"
extern const unsigned long SDK_DATE_OF_LATEST_FILE;
static void usage(void);
/*---------------------------------------------------------------------------*
Name: main
Description:
*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
int n;
int result;
int iptfilesize;
char* optfilename;
char* suffix;
u8* filebuf;
BOOL optfname_flag = FALSE; // if optfilename input, this flag is true.
optfilename = suffix = NULL;
while ((n = getopt(argc, argv, "o:e:dhv")) != -1)
{
switch (n)
{
case 'o': // output file name
optfilename = optarg;
optfname_flag = TRUE;
break;
case 'e':
suffix = optarg;
break;
case 'd': // Show debug message
bDebugMode = TRUE;
break;
case 'h':
case 'v':
default:
usage(); // Never returns
break;
}
DebugPrintf("option -%c: %s\n", n, optarg ? optarg : "No ARG");
}
argc -= optind;
argv += optind;
if (bDebugMode)
{
int i;
DebugPrintf("argc=%d optind=%d\n", argc, optind);
for (i = 0; i < argc; i++)
{
DebugPrintf("argv[%d] = [%s]\n", i, argv[i]);
}
}
if (argc == 1)
{
if (optfilename == NULL)
{
optfilename = argv[0];
}
iptfilesize = ReadFile(argv[0], &filebuf);
}
else
{
usage(); // Never returns
}
if (iptfilesize < 0)
{
ConsolePrintf("exit...\n");
return 1;
}
if ((result = Compress(filebuf, iptfilesize)) < 0)
{
switch (result)
{
case COMPRESS_LARGER_ORIGINAL:
ConsolePrintf("Inputdata ..... Not compressed (enlarged or same size as before)\n");
break;
case COMPRESS_FATAL_ERROR:
ConsolePrintf("Fatal error occured\n");
break;
}
ConsolePrintf("exit...\n");
return 1;
}
// cut file path and suffix of input file
if (!optfname_flag)
{
optfilename = StrCutFname(optfilename);
}
// create output filename
if (suffix == NULL)
{
optfilename = StrCat(2, optfilename, "_BLZ.bin");
}
else
{
optfilename = StrCat(2, optfilename, suffix);
}
// output file
if (WriteFile(optfilename, filebuf, result) < 0)
{
ConsolePrintf("exit...\n\n");
return 1;
}
ConsolePrintf("Inputdata ..... Compressed ... %9d -> %9d\n", iptfilesize, result);
return 0;
}
/*---------------------------------------------------------------------------*
Name: usage
Description:
*---------------------------------------------------------------------------*/
static void usage(void)
{
fprintf(stderr,
"TWL-SDK Development Tool - compBLZ - Compress data\n"
"Build %lu\n"
"\n"
"Usage: compBLZ [-d] [-o outputFile] [-e suffix] inputFile\n"
"\n"
" Compress data (backward LZ)\n"
"\n"
" -o outputFile FILENAME for output file (default:input filename)\n"
" -e suffix SUFFIX for output file (default:\"_BLZ\")\n"
" -d Show debug messages (for test purpose)\n"
" -h Show this message\n" "\n", SDK_DATE_OF_LATEST_FILE);
exit(1);
}

View File

@ -0,0 +1,18 @@
rem
rem ***** SD起動ファイル作成ツール *****
rem
rem sdmc_launcher_writer.gcd が起動ファイルとして menu.srl しか受け付けないので
rem 引数として与えたファイルを menu.srl としてコピーする
rem
if "%1" equ "" (
echo 失敗しました。
echo ディレクトリごとドラッグアンドドロップしてください。
echo:
goto end
)
set progdir=%~dp0
del %progdir%\menu.srl
copy %1 %progdir%\menu.srl

View File

@ -0,0 +1 @@
NINTENDO PRIVATE

View File

@ -0,0 +1,27 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - build - tools - ntrcomp
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
TARGET_PLATFORM = NITRO
export TWLSDK_PLATFORM = NITRO
include $(TWLSDK_ROOT)/build/buildtools/commondefs
SUBDIRS += gcc
include $(TWLSDK_ROOT)/build/buildtools/modulerules.x86

View File

@ -0,0 +1,59 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - build - tools - ntrcomp - gcc
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
TARGET_PLATFORM = NITRO
include $(TWLSDK_ROOT)/build/buildtools/commondefs
OBJECTS = ntcompress_main.o ntcompress_test.o nitroCompLib.o multipleCompLib.o rangeCoder.o
WIN32 ?= 1
ifneq ($(WIN32),0)
TARGETS = ntrcomp.exe
CC_X86 := gcc -mno-cygwin
else
TARGETS = ntrcomp
CC_X86 := gcc
endif
LDIRT_CLEAN = $(OBJECTS) $(TARGETS)
#INSTALL_DIR = $(NITRO_INSTALL_TOOLSDIR)/bin
#INSTALL_TARGETS = $(TARGETS)
#----------------------------------------------------------------------------
# build
#----------------------------------------------------------------------------
do-build: $(TARGETS)
$(TARGETS): $(OBJECTS)
$(CC_X86) $+ -o $@
ntcompress_main.o: ../src/ntcompress_main.c ../src/nitroCompLib.h
$(CC_X86) -c $< -o $@
ntcompress_test.o: ../src/ntcompress_test.c ../src/nitroCompLib.h
$(CC_X86) -c $< -o $@
nitroCompLib.o: ../src/nitroCompLib.c ../src/nitroCompLib.h
$(CC_X86) -c $< -o $@
multipleCompLib.o: ../src/multipleCompLib.c ../src/multipleCompLib.h
$(CC_X86) -c $< -o $@
rangeCoder.o: ../src/rangeCoder.c ../src/rangeCoder.h
$(CC_X86) -c $< -o $@
include $(TWLSDK_ROOT)/build/buildtools/modulerules.x86

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: multipleCompLib.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
// nitroCompLib.h : nitroCompLib.DLL のメイン ヘッダー ファイル
//
#ifndef __MULTIPLE_COMPLIB_H__
#define __MULTIPLE_COMPLIB_H__
//===========================================================================================
// インクルード
//===========================================================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "types.h"
//===========================================================================================
// プロトタイプ宣言
//===========================================================================================
// C++用
#ifdef __cplusplus
extern "C"
{
#endif
s32 LHCompRead( const u8* srcp, u32 srcSize, u8* dstp );
u32 LHCompWrite( const u8* srcp, s32 size, u8* dstp );
s32 LRCCompRead( const u8* srcp, u32 srcSize, u8* dstp );
u32 LRCCompWrite( const u8* srcp, u32 size, u8* dstp );
#ifdef __cplusplus
}
#endif
#endif // __MULTIPLEX_COMPLIB_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,127 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: nitroCompLib.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
// nitroCompLib.h : nitroCompLib.DLL のメイン ヘッダー ファイル
//
#ifndef __NITROCOMPLIB_H__
#define __NITROCOMPLIB_H__
//===========================================================================================
// インクルード
//===========================================================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "types.h"
#ifdef WIN32
#define STDCALL __stdcall
#else
#define STDCALL
#endif
//===========================================================================================
// プロトタイプ宣言
//===========================================================================================
// C++用
#ifdef __cplusplus
extern "C"
{
#endif
//BOOL WINAPI DllMain( HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved);
u8* STDCALL nitroCompMalloc( u32 size );
void STDCALL nitroCompFree( u8 *p );
u32 STDCALL nitroCompress ( const u8 *srcp, u32 srcSize, u8 *dstp, char *compList, u8 rawHeader );
s32 STDCALL nitroDecompress( const u8 *srcp, u32 srcSize, u8 *dstp, s8 depth );
void STDCALL debugMemPrint ( FILE * fp, u8 *str, u32 size );
void STDCALL debugMemBitPrint( FILE * fp, u8 *str, u32 size );
int STDCALL matchingCheck( u8 *srcp, u32 srcSize, u8 *dstp, u32 dstSize );
u32 STDCALL nitroGetDecompFileSize( const void* srcp );
#ifdef __cplusplus
}
#endif
//===========================================================================================
// 関数の使用法
//===========================================================================================
//----------------------------------------------------------------------------------
// 圧縮後のデータを置くためのメモリ領域を確保
// 圧縮前のデータの2倍の領域を確保する
// 引数
// u32 size 圧縮前のデータサイズ
// u32 は符号無し整数型でたいていは、
// unsigned int (処理系依存)
// 返り値
// u8 * 圧縮後のデータ領域を指すポインタ
// (汎用ポインタなので、好きな型にキャスト)
// ではない
//----------------------------------------------------------------------------------
//u8 *nitroCompMalloc(u32 size);
//----------------------------------------------------------------------------------
// 圧縮後のデータを置いていたメモリ領域を解放
// 引数
// u8 *p 圧縮後のデータ領域を指すポインタ
//----------------------------------------------------------------------------------
//void nitroCompFree(u8 *p);
//----------------------------------------------------------------------------------
// データを圧縮する
// 圧縮方式、圧縮順序は引数compListを用いて指示する
// 引数
// u8 *srcp 圧縮対象データを指すポインタ
// u32 size 圧縮対象データのサイズ(単位はバイト)
// u8 *dstp 圧縮後のデータを保持するデータ領域を指すポインタ
// 十分な領域を確保しておく必要あり
// nitroCompMallocの返り値でよい
// char *compList 圧縮方式、圧縮順序を格納したリスト (C言語のヌル文字列)
// d8 : 8ビット差分フィルタ
// d16 : 16ビット差分フィルタ
// r : ランレングス符号化
// lx : LZ77xには同一データ検索の開始点を示すオフセット
// : 2以上でなければならない上限は255.
// h4 : 4ビット・ハフマン圧縮
// h8 : 8ビット・ハフマン圧縮
// u8 rawHeaderFlag 圧縮前のデータであることを示すヘッダ情報を付加するかどうかを
// 指示するフラグ0であれば付加せず、1であれば、展開しきった
// データにもヘッダが付加される.
// 返り値
// 圧縮後のデータサイズ
//----------------------------------------------------------------------------------
//u32 nitroCompress(u8 *srcp, u32 size, u8 *dstp, char *compList, u8 rawHeader);
//----------------------------------------------------------------------------------
// データを展開する
// 展開方式、展開順序はデータのヘッダを見て判断する
// 引数
// u8 *srcp 展開対象データを指すポインタ
// u32 size 展開対象データのサイズ(単位はバイト)
// u8 *dstp 展開後のデータを保持するデータ領域を指すポインタ
// 十分な領域を確保しておく必要あり
// nitroCompMallocの返り値でよい
// u8 depth 展開する深さ(回数)
// 0未満の場合は、圧縮前データを示すヘッダ情報が得られるまで展開し続ける
// 返り値
// 展開後のデータサイズ
//----------------------------------------------------------------------------------
//u32 nitroDecompress(u8 *srcp, u32 size, u8 *dstp, s8 depth);
#endif // __NITROCOMPLIB_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,661 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: ntcompress_test.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#if defined( _DEBUG )
#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#include "nitroCompLib.h"
#include "multipleCompLib.h"
#define MAX_DATA_SIZE_EX 0x02000000 // 32MB
#define MAX_DATA_SIZE 0x00100000 // 1MB
//#define MAX_DATA_SIZE 0x100 // 256B
#define LOOP_CNT 100
#define LOOP_CNT_EX 4
#if 0
#define TestReport(...) (void)0
#else
#define TestReport printf
#endif
#define ASSERT assert
static u8* s_original;
static int TestInit( void );
static void TestLZ8( void );
static void TestRL8( void );
static void TestHuffman( void );
static struct
{
u64 x; // 乱数値
u64 mul; // 乗数
u64 add; // 加算する数
}
sRandContext;
static void InitRand32_(u64 seed)
{
sRandContext.x = seed;
sRandContext.mul = (1566083941LL << 32) + 1812433253LL;
sRandContext.add = 2531011;
}
static u32 Rand32_(u32 max)
{
sRandContext.x = sRandContext.mul * sRandContext.x + sRandContext.add;
// 引数maxが定数ならばコンパイラにより最適化される。
if (max == 0)
{
return (u32)(sRandContext.x >> 32);
}
else
{
return (u32)((((sRandContext.x >> 32) * (max >> 1)) >> 32) + (max >> 1));
}
}
static int compare( const u8 a[], const u8 b[], int size )
{
int i;
int equivalent_flag = 1;
for ( i = 0; i < size; ++i )
{
if ( a[i] != b[i] )
{
equivalent_flag = 0;
break;
}
}
return equivalent_flag;
}
//--------------------------------------------------
// 元データ生成用関数
//--------------------------------------------------
// LZ,Huffmanで圧縮されやすい元データを作成する。
static u32 makeOriginalDataForLZHuff( u32 seed )
{
u32 fsize;
u32 i;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
(void)Rand32_( 0 );
fsize = Rand32_( MAX_DATA_SIZE );
if ( fsize <= 4 )
{
fsize += 5;
}
for ( i = 0; i < fsize; ++i )
{
s_original[ i ] = (u8)(Rand32_(0x100) & 0xF0);
}
return fsize;
}
// RL圧縮されやすい元データを作成する。
static u32 makeOriginalDataForRL( u32 seed )
{
u8 val;
u32 i;
u32 fsize;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
(void)Rand32_( 0 );
fsize = Rand32_( MAX_DATA_SIZE );
if ( fsize <= 4 )
{
fsize += 5;
}
for ( i = 0; i < fsize; ++i )
{
if ( (i % 4) == 0 )
{
val = (u8)Rand32_(0x100);
}
s_original[ i ] = val;
}
return fsize;
}
// 圧縮されにくい元データを作成する。
static u32 makeOriginalDataRand( u32 seed )
{
u32 i;
u32 fsize;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
(void)Rand32_( 0 );
fsize = Rand32_( MAX_DATA_SIZE );
if ( fsize <= 4 )
{
fsize += 5;
}
for ( i = 0; i < fsize; ++i )
{
s_original[ i ] = (u8)Rand32_(0x100);
}
return fsize;
}
// すべてが単一値の元データを作成する。
static u32 makeOriginalDataMonoValue( u32 seed )
{
u32 i;
u32 fsize;
u8 val;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
(void)Rand32_( 0 );
fsize = Rand32_( MAX_DATA_SIZE );
if ( fsize <= 4 )
{
fsize += 5;
}
val = (u8)Rand32_(0x100);
for ( i = 0; i < fsize; ++i )
{
s_original[ i ] = val;
}
return fsize;
}
// LZ,Huffmanで圧縮されやすい元データを作成する。
static u32 makeOriginalDataForLZHuffEx( u32 seed )
{
u32 i;
u32 fsize;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
fsize = Rand32_(MAX_DATA_SIZE_EX / 2) + (MAX_DATA_SIZE_EX / 2);
if ( fsize <= 4 )
{
fsize += 5;
}
for ( i = 0; i < fsize; ++i )
{
s_original[ i ] = (u8)(Rand32_(0x100) & 0xF0);
}
return fsize;
}
// RL圧縮されやすい元データを作成する。
static u32 makeOriginalDataForRLEx( u32 seed )
{
u32 i;
u32 fsize;
u8 val;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
fsize = Rand32_(MAX_DATA_SIZE_EX / 2) + (MAX_DATA_SIZE_EX / 2);
if ( fsize <= 4 )
{
fsize += 5;
}
val;
for ( i = 0; i < fsize; ++i )
{
if ( (i % 4) == 0 )
{
val = (u8)Rand32_(0x100);
}
s_original[ i ] = val;
}
return fsize;
}
// 圧縮されにくい元データを作成する。
static u32 makeOriginalDataRandEx( u32 seed )
{
u32 fsize;
u32 i;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
fsize = Rand32_(MAX_DATA_SIZE_EX / 2) + (MAX_DATA_SIZE_EX / 2);
if ( fsize <= 4 )
{
fsize += 5;
}
for ( i = 0; i < fsize; ++i )
{
s_original[ i ] = (u8)Rand32_(0x100);
}
return fsize;
}
// すべてが単一値の元データを作成する。
static u32 makeOriginalDataMonoValueEx( u32 seed )
{
u32 fsize;
u32 i;
u8 val;
TestReport("seed: %u\n", seed);
InitRand32_( seed );
fsize = Rand32_(MAX_DATA_SIZE_EX / 2) + (MAX_DATA_SIZE_EX / 2);
if ( fsize <= 4 )
{
fsize += 5;
}
val = (u8)Rand32_(0x100);
for ( i = 0; i < fsize; ++i )
{
s_original[ i ] = val;
}
return fsize;
}
typedef u32 (*MakeDataFunc)( u32 seed );
#define WATER_MARK 0xDeadBeaf
static void TestLZ8_template( MakeDataFunc makeDataFunc, u32 exFmt, u32 loop_cnt )
{
u32 i;
for ( i = 0; i < loop_cnt; ++i )
{
u32 fsize = makeDataFunc( i );
u8* s_compressed = nitroCompMalloc( fsize );
u8* s_uncompressed = (u8*)malloc( fsize + 4 );
u32 sz;
TestReport("size = %d\n", fsize);
if ( ! exFmt )
{
sz = nitroCompress( s_original, fsize, s_compressed, "l2", 0 );
}
else
{
sz = nitroCompress( s_original, fsize, s_compressed, "L2", 0 );
}
if ( sz == 0 )
{
TestReport( "compress LZ fail size %d\n", fsize );
}
else
{
TestReport("compress LZ %d -> %d\n", fsize, sz );
*(u32*)(&s_uncompressed[ fsize ]) = WATER_MARK;
nitroDecompress( s_compressed, sz, s_uncompressed, 1 );
ASSERT( compare( s_original, s_uncompressed, (int)fsize ) );
// 展開時のオーバーアクセスをチェック
ASSERT( *(u32*)(&s_uncompressed[ fsize ]) == WATER_MARK );
}
nitroCompFree( s_compressed );
free( s_uncompressed );
}
}
static void TestRL8_template( MakeDataFunc makeDataFunc, u32 loop_cnt )
{
u32 i;
for ( i = 0; i < loop_cnt; ++i )
{
u32 fsize = makeDataFunc( i );
u8* s_compressed = nitroCompMalloc( fsize );
u8* s_uncompressed = (u8*)malloc( fsize + 4 );
u32 sz;
TestReport("size = %d\n", fsize);
sz = nitroCompress( s_original, fsize, s_compressed, "r", 0 );
if ( sz == 0 )
{
TestReport( "compress RL fail size %d\n", fsize );
}
else
{
TestReport("compress RL %d -> %d\n", fsize, sz );
*(u32*)(&s_uncompressed[ fsize ]) = WATER_MARK;
nitroDecompress( s_compressed, sz, s_uncompressed, 1 );
ASSERT( compare(s_original, s_uncompressed, (int)fsize) );
// 展開時のオーバーアクセスをチェック
ASSERT( *(u32*)(&s_uncompressed[ fsize ]) == WATER_MARK );
}
nitroCompFree( s_compressed );
free( s_uncompressed );
}
}
static void TestHuffman_template( MakeDataFunc makeDataFunc, u8 encBit, u32 loop_cnt )
{
u32 i;
for (i = 0; i < loop_cnt; ++i )
{
u32 fsize = makeDataFunc( i );
u8* s_compressed = nitroCompMalloc( fsize );
u8* s_uncompressed = (u8*)malloc( ((fsize + 0x3) & ~0x3) + 4 );
u32 sz;
TestReport("size = %d\n", fsize);
sz = nitroCompress( s_original, fsize, s_compressed, (encBit == 4 )? "h4" : "h8", 0 );
if ( sz == 0 )
{
TestReport( "compress Huff fail size %d\n", fsize );
}
else
{
TestReport("compress Huff %d -> %d\n", fsize, sz );
// ハフマン展開では末尾の4バイトアラインまではオーバーアクセスされ得る
// コードになっている
*(u32*)(&s_uncompressed[ (fsize + 0x3) & ~0x3 ]) = WATER_MARK;
nitroDecompress( s_compressed, sz, s_uncompressed, 1 );
ASSERT( compare(s_original, s_uncompressed, (int)fsize) );
// 展開時のオーバーアクセスをチェック
ASSERT( *(u32*)(&s_uncompressed[ (fsize + 0x3) & ~0x3 ]) == WATER_MARK );
}
nitroCompFree( s_compressed );
free( s_uncompressed );
}
}
static void TestLH8_template( MakeDataFunc makeDataFunc, u32 exFmt, u32 loop_cnt )
{
u32 i;
for ( i = 0; i < loop_cnt; ++i )
{
u32 fsize = makeDataFunc( i );
u8* s_compressed = nitroCompMalloc( fsize );
u8* s_uncompressed = (u8*)malloc( fsize + 4 );
u32 sz;
TestReport("size = %d\n", fsize);
sz = LHCompWrite( s_original, fsize, s_compressed );
if ( sz == 0 )
{
TestReport( "compress LH fail size %d\n", fsize );
}
else
{
TestReport("compress LH %d -> %d\n", fsize, sz );
*(u32*)(&s_uncompressed[ fsize ]) = WATER_MARK;
LHCompRead( s_compressed, sz, s_uncompressed );
ASSERT( compare(s_original, s_uncompressed, (int)fsize) );
// 展開時のオーバーアクセスをチェック
ASSERT( *(u32*)(&s_uncompressed[ fsize ]) == WATER_MARK );
}
nitroCompFree( s_compressed );
free( s_uncompressed );
}
}
static void TestLRC8_template( MakeDataFunc makeDataFunc, u32 exFmt, u32 loop_cnt )
{
u32 i;
for ( i = 0; i < loop_cnt; ++i )
{
u32 fsize = makeDataFunc( i );
u8* s_compressed = nitroCompMalloc( fsize );
u8* s_uncompressed = (u8*)malloc( fsize + 4 );
u32 sz;
TestReport("size = %d\n", fsize);
sz = LRCCompWrite( s_original, fsize, s_compressed );
if ( sz == 0 )
{
TestReport( "compress LRC fail size %d\n", fsize );
}
else
{
TestReport("compress LRC %d -> %d\n", fsize, sz );
*(u32*)(&s_uncompressed[ fsize ]) = WATER_MARK;
LRCCompRead( s_compressed, sz, s_uncompressed );
ASSERT( compare(s_original, s_uncompressed, (int)fsize) );
// 展開時のオーバーアクセスをチェック
ASSERT( *(u32*)(&s_uncompressed[ fsize ]) == WATER_MARK );
}
nitroCompFree( s_compressed );
free( s_uncompressed );
}
}
//--------------------------------------------------
// テストメイン
//--------------------------------------------------
static int TestInit( void )
{
time_t t;
s_original = (u8*)malloc( MAX_DATA_SIZE_EX + 4 );
makeOriginalDataRand( (u32)time( &t ) );
return 0;
}
static void TestLZ8_normal( void )
{
TestLZ8_template( makeOriginalDataForLZHuff, 0, LOOP_CNT );
}
static void TestLZ8_random( void )
{
TestLZ8_template( makeOriginalDataRand, 0, LOOP_CNT );
}
static void TestLZ8_mono( void )
{
TestLZ8_template( makeOriginalDataMonoValue, 0, LOOP_CNT );
}
static void TestLZ8EX_normal( void )
{
TestLZ8_template( makeOriginalDataForLZHuff, 1, LOOP_CNT );
}
static void TestLZ8EX_random( void )
{
TestLZ8_template( makeOriginalDataRand, 1, LOOP_CNT );
}
static void TestLZ8EX_mono( void )
{
TestLZ8_template( makeOriginalDataMonoValue, 1, LOOP_CNT );
}
static void TestRL8_normal( void )
{
TestRL8_template( makeOriginalDataForRL, LOOP_CNT );
}
static void TestRL8_random( void )
{
TestRL8_template( makeOriginalDataRand, LOOP_CNT );
}
static void TestRL8_mono( void )
{
TestRL8_template( makeOriginalDataMonoValue, LOOP_CNT );
}
static void TestHuffman8_normal( void )
{
TestHuffman_template( makeOriginalDataForLZHuff, 8, LOOP_CNT );
}
static void TestHuffman8_random( void )
{
TestHuffman_template( makeOriginalDataRand, 8, LOOP_CNT );
}
static void TestHuffman8_mono( void )
{
TestHuffman_template( makeOriginalDataMonoValue, 8, LOOP_CNT );
}
static void TestHuffman4_normal( void )
{
TestHuffman_template( makeOriginalDataForLZHuff, 4, LOOP_CNT );
}
static void TestHuffman4_random( void )
{
TestHuffman_template( makeOriginalDataRand, 4, LOOP_CNT );
}
static void TestHuffman4_mono( void )
{
TestHuffman_template( makeOriginalDataMonoValue, 4, LOOP_CNT );
}
static void TestLZ_ex(void)
{
TestLZ8_template( makeOriginalDataForLZHuffEx, 0, LOOP_CNT_EX );
}
static void TestLZEX_ex(void)
{
TestLZ8_template( makeOriginalDataForLZHuffEx, 1, LOOP_CNT_EX );
}
static void TestRL_ex(void)
{
TestRL8_template( makeOriginalDataForRLEx, LOOP_CNT_EX );
}
static void TestHuffman8_ex(void)
{
TestHuffman_template( makeOriginalDataForLZHuffEx, 8, LOOP_CNT_EX );
}
static void TestHuffman4_ex(void)
{
TestHuffman_template( makeOriginalDataForLZHuffEx, 4, LOOP_CNT_EX );
}
static void TestLH_normal(void)
{
TestLH8_template( makeOriginalDataForLZHuff, 0, LOOP_CNT );
}
static void TestLH_random(void)
{
TestLH8_template( makeOriginalDataRand, 0, LOOP_CNT );
}
static void TestLH_mono(void)
{
TestLH8_template( makeOriginalDataMonoValue, 0, LOOP_CNT );
}
static void TestLRC_normal(void)
{
TestLRC8_template( makeOriginalDataForLZHuff, 0, LOOP_CNT );
}
static void TestLRC_random(void)
{
TestLRC8_template( makeOriginalDataRand, 0, LOOP_CNT );
}
static void TestLRC_mono(void)
{
TestLRC8_template( makeOriginalDataMonoValue, 0, LOOP_CNT );
}
#endif /* defined( _DEBUG ) */
/*---------------------------------------------------------------------------*
Name: ntcompress_test
Description:
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
void ntcompress_test( void )
{
#if defined( _DEBUG )
TestInit();
TestLH_normal();
TestLH_random();
TestLH_mono ();
TestLRC_normal();
TestLRC_random();
TestLRC_mono ();
TestLZ8EX_normal();
TestLZ8EX_random();
TestLZ8EX_mono ();
TestLZ8_normal();
TestLZ8_random();
TestLZ8_mono ();
TestRL8_normal();
TestRL8_random();
TestRL8_mono ();
TestHuffman8_normal();
TestHuffman8_random();
TestHuffman8_mono ();
TestHuffman4_normal();
TestHuffman4_random();
TestHuffman4_mono ();
TestLZ_ex();
TestLZEX_ex();
TestRL_ex();
TestHuffman8_ex();
TestHuffman4_ex();
#endif
}

View File

@ -0,0 +1,23 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: ntcompress_test.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef NTCOMPRESS_TEST_H__
#define NTCOMPRESS_TEST_H__
void ntcompress_test( void );
#endif // NTCOMPRESS_TEST_H__

View File

@ -0,0 +1,539 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: rangeCoder.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include "rangeCoder.h"
typedef struct
{
u32 freq[ 0x100 ];
u32 low_cnt[ 0x100 ];
u32 total;
}
RCCompressionInfo;
// レンジコーダ状態構造体
typedef struct
{
u32 low;
u32 range;
u32 code; // 展開時のみ使用
u8 carry; // 圧縮時のみ使用
u32 carry_cnt; // 圧縮時のみ使用
}
RCState;
#define MAX_RANGE 0x80000000
/*---------------------------------------------------------------------------*
Name: RCInitInfo_
Description:
Arguments: info
Returns: None.
*---------------------------------------------------------------------------*/
static void
RCInitInfo_( RCCompressionInfo* info, BOOL adaptive )
{
u32 i;
if ( adaptive )
// 適応型レンジコーダ
{
for ( i = 0; i < 0x100; i++ )
{
info->freq[ i ] = 1;
info->low_cnt[ i ] = i;
}
info->total = 0x100;
}
else
// 静的レンジコーダ
{
for ( i = 0; i < 0x100; i++ )
{
info->freq[ i ] = 0;
info->low_cnt[ i ] = 0;
}
info->total = 0;
}
}
/*---------------------------------------------------------------------------*
Name: RCCount_
Description:
Arguments: info
srcp
size
Returns: None.
*---------------------------------------------------------------------------*/
static void
RCCount_( RCCompressionInfo* info, const u8* srcp, u32 size )
{
u32 srcCnt = 0;
u32 i;
while ( srcCnt < size )
{
info->freq[ srcp[ srcCnt ] ]++;
info->total++;
srcCnt++;
}
// 0x10000へ正規化
#define NORMAL_FREQ 0x10000
{
f32 rate = (f32)NORMAL_FREQ / info->total;
u32 max_i = 0;
u32 max_freq = 0;
info->total = 0;
for ( i = 0; i < 0x100; i++ )
{
u32 orig = info->freq[ i ];
info->freq[ i ] = (u32)(rate * info->freq[ i ] + 0.5f);
if ( orig != 0 && info->freq[ i ] == 0 )
{
info->freq[ i ] = 1;
}
info->total += info->freq[ i ];
if ( info->freq[ i ] >= max_freq )
{
max_i = i;
max_freq = info->freq[ i ];
}
}
if ( info->total > NORMAL_FREQ )
{
info->freq[ max_i ] -= (info->total - NORMAL_FREQ);
}
else
{
info->freq[ max_i ] += (NORMAL_FREQ - info->total);
}
info->total = NORMAL_FREQ;
}
#undef NORMAL_FREQ
info->low_cnt[ 0 ] = 0;
for ( i = 1; i < 0x100; i++ )
{
info->low_cnt[ i ] = info->low_cnt[ i - 1 ] + info->freq[ i - 1 ];
}
}
/*---------------------------------------------------------------------------*
Name: RCAAddCount_
Description:
Arguments: info
val
Returns: None.
*---------------------------------------------------------------------------*/
static void
RCAAddCount_( RCCompressionInfo* info, u8 val )
{
u32 i;
info->freq[ val ]++;
info->total++;
for ( i = val + 1; i < 0x100; i++ )
{
info->low_cnt[ i ]++;
}
// トータルが最大値を越えた場合には、再構成する。
if ( info->total >= 0x00010000 )
{
if ( info->freq[ 0 ] > 1 )
{
info->freq[ 0 ] = info->freq[ 0 ] / 2;
}
info->low_cnt[ 0 ] = 0;
info->total = info->freq[ 0 ];
for ( i = 1; i < 0x100; i++ )
{
if ( info->freq[ i ] > 1 )
{
info->freq[ i ] >>= 1;
}
info->low_cnt[ i ] = info->low_cnt[ i - 1 ] + info->freq[ i - 1 ];
info->total += info->freq[ i ];
}
}
}
/*---------------------------------------------------------------------------*
Name: RCCompWrite
Description: ()
Arguments: srcp
size
dstp
Returns:
*---------------------------------------------------------------------------*/
s32
RCCompWrite_( const u8* srcp, u32 size, u8* dstp, BOOL adaptive )
{
#define MIN_RANGE 0x01000000
static RCCompressionInfo sInfo;
u32 srcCnt = 0;
u32 dstCnt = 0;
u32 low, range;
u8 carry;
u32 carry_cnt;
u32 i;
// ワークの初期化
RCInitInfo_( &sInfo, adaptive );
if ( ! adaptive )
{
// 出現頻度を計算
RCCount_( &sInfo, srcp, size );
}
// 開始Rangeが0x80000000なので、初回いきなり桁上げが発生することはない
low = 0;
range = MAX_RANGE;
carry = 0;
carry_cnt = 0;
// ヘッダ出力
dstp[ dstCnt++ ] = LRC_CODE_HEADER;
if ( size > 0x1000000 )
{
dstp[ dstCnt++ ] = 0;
dstp[ dstCnt++ ] = 0;
dstp[ dstCnt++ ] = 0;
}
dstp[ dstCnt++ ] = (u8)( size );
dstp[ dstCnt++ ] = (u8)( size >> 8 );
dstp[ dstCnt++ ] = (u8)( size >> 16 );
if ( size > 0x1000000 )
{
dstp[ dstCnt++ ] = (u8)( size >> 24 );
}
if ( ! adaptive )
{
// 頻度テーブルの出力(16bitリトルエンディアン)
for ( i = 0; i < 0x100; i++ )
{
dstp[ dstCnt++ ] = (u8)( sInfo.freq[ i ] );
dstp[ dstCnt++ ] = (u8)( sInfo.freq[ i ] >> 8 );
}
}
// コードの出力
while ( srcCnt < size )
{
u8 val = srcp[ srcCnt++ ];
u32 temp = range / sInfo.total;
u32 prevLow = low;
low = low + sInfo.low_cnt[ val ] * temp;
range = sInfo.freq[ val ] * temp;
if ( adaptive )
{
// 出現頻度テーブルを更新
RCAAddCount_( &sInfo, val );
}
// 桁上がりが発生する場合の処理
if ( prevLow > low )
{
// キャリーを1繰上げ
++carry;
// キャリーと(キャリーカウンタ - 1)分の0x00を出力します。
if ( carry_cnt > 1 )
{
dstp[ dstCnt++ ] = carry;
--carry_cnt;
carry = 0x00;
}
while ( carry_cnt > 1 )
{
dstp[ dstCnt++ ] = 0x00;
--carry_cnt;
}
}
// Rangeの上位1バイトが空になったら桁上げ
while ( range < MIN_RANGE )
{
u8 candidate = (u8)( low >> 24 );
// 次のキャリーが0xFFの場合は更に桁上げがあり得るのでcarryを出力せずにcarry_cntだけ増やす
if ( candidate == 0xFF )
{
++carry_cnt;
}
else
// 次のキャリーが0xFFではない場合はcarryを出力する
{
// carryと(carry_cnt - 1)分の0xFFを出力する
if ( carry_cnt > 0 )
{
dstp[ dstCnt++ ] = carry;
--carry_cnt;
}
while ( carry_cnt > 0 )
{
dstp[ dstCnt++ ] = 0xFF;
--carry_cnt;
}
// 新しいcarryに置き換え
carry = candidate;
carry_cnt = 1;
}
low <<= 8;
range <<= 8;
}
}
if ( carry_cnt > 0 )
{
dstp[ dstCnt++ ] = carry;
--carry_cnt;
}
while ( carry_cnt > 0 )
{
dstp[ dstCnt++ ] = 0xFF;
--carry_cnt;
}
dstp[ dstCnt++ ] = (u8)( (low >> 24) & 0xFF );
dstp[ dstCnt++ ] = (u8)( (low >> 16) & 0xFF );
dstp[ dstCnt++ ] = (u8)( (low >> 8 ) & 0xFF );
dstp[ dstCnt++ ] = (u8)( (low >> 0 ) & 0xFF );
return dstCnt;
#undef MIN_RANGE
}
/*---------------------------------------------------------------------------*
Name: RCACompWrite
Description: ()
Arguments: srcp
size
dstp
Returns:
*---------------------------------------------------------------------------*/
s32
RCCompWrite( const u8* srcp, u32 size, u8* dstp )
{
return RCCompWrite_( srcp, size, dstp, FALSE );
}
s32
RCACompWrite( const u8* srcp, u32 size, u8* dstp )
{
return RCCompWrite_( srcp, size, dstp, TRUE );
}
static u8
SearchRC_( RCCompressionInfo* info, u32 code, u32 range, u32 low )
{
#define TABLE_SIZE 0x100
u32 codeVal = code - low;
u32 i;
u32 temp = range / info->total;
u32 tempVal = codeVal / temp;
#if 0
// TODO: とりあえず線形探索、二分探索にするべき
for ( i = 0; i < TABLE_SIZE - 1; i++ )
{
if ( info->low_cnt[ i + 1 ] > tempVal )
{
while ( info->freq[ i ] == 0 )
{
--i;
}
return (u8)i;
}
}
return TABLE_SIZE - 1;
#else
// 二分探索
u32 left = 0;
u32 right = TABLE_SIZE - 1;
while ( left < right )
{
i = (left + right) / 2;
if ( info->low_cnt[ i ] > tempVal )
{
right = i;
}
else
{
left = i + 1;
}
}
i = left;
while ( info->low_cnt[ i ] > tempVal )
{
--i;
}
return (u8)i;
#endif
}
/*---------------------------------------------------------------------------*
Name: RCCompRead
Description: ()
Arguments: srcp
size
dstp
Returns:
*---------------------------------------------------------------------------*/
s32
RCCompRead_( const u8* srcp, u32 srcSize, u8* dstp, BOOL adaptive )
{
#define MIN_RANGE 0x01000000
static RCCompressionInfo sInfo;
u32 dstSize = *(u32*)srcp >> 8;
u32 dstCnt = 0;
u32 srcCnt = 0;
u32 i;
u32 code, range, low;
if ( srcSize < 4 )
{
return -1;
}
srcCnt = 4;
if ( dstSize == 0 )
{
dstSize = *(u32*)&srcp[ srcCnt ];
srcCnt += 4;
if ( srcSize < 8 )
{
return -1;
}
}
if ( srcSize < sizeof(u16) * 0x100 + srcCnt )
{
return -1;
}
// ワークの初期化
if ( adaptive )
{
RCInitInfo_( &sInfo, TRUE );
}
else
{
sInfo.total = 0;
for ( i = 0; i < 0x100; i++ )
{
sInfo.freq[ i ] = *(u16*)&srcp[ srcCnt ];
srcCnt += 2;
sInfo.total += sInfo.freq[ i ];
}
sInfo.low_cnt[ 0 ] = 0;
for ( i = 1; i < 0x100; i++ )
{
sInfo.low_cnt[ i ] = sInfo.low_cnt[ i - 1 ] + sInfo.freq[ i - 1 ];
}
}
code = (u32)((srcp[ srcCnt ] << 24) | (srcp[ srcCnt + 1 ] << 16) |
(srcp[ srcCnt + 2 ] << 8) | (srcp[ srcCnt + 3 ]));
range = MAX_RANGE;
low = 0;
srcCnt += 4;
while ( dstCnt < dstSize )
{
u8 val = SearchRC_( &sInfo, code, range, low );
dstp[ dstCnt++ ] = val;
{
u32 tmp;
tmp = range / sInfo.total;
low = low + sInfo.low_cnt[ val ] * tmp;
range = sInfo.freq[ val ] * tmp;
}
if ( adaptive )
{
// 出現頻度テーブルを更新
RCAAddCount_( &sInfo, val );
}
while ( range < MIN_RANGE )
{
code <<= 8;
code += srcp[ srcCnt++ ];
range <<= 8;
low <<= 8;
}
}
return dstSize;
#undef MIN_RANGE
}
/*---------------------------------------------------------------------------*
Name: RCACompRead
Description: ()
Arguments: srcp
size
dstp
Returns:
*---------------------------------------------------------------------------*/
s32
RCCompRead( const u8* srcp, u32 srcSize, u8* dstp )
{
return RCCompRead_( srcp, srcSize, dstp, FALSE );
}
s32
RCACompRead( const u8* srcp, u32 srcSize, u8* dstp )
{
return RCCompRead_( srcp, srcSize, dstp, TRUE );
}

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: rangeCoder.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include "types.h"
#ifndef __NTCOMPRESS_RANGE_CODER_H__
#define __NTCOMPRESS_RANGE_CODER_H__
/*---------------------------------------------------------------------------*
Name: RCCompWrite
Description: ƒŒƒƒWƒR<EFBFBD>[ƒ_̈³<EFBFBD>k
Arguments: srcp
size
dstp
Returns:
*---------------------------------------------------------------------------*/
s32
RCCompWrite( const u8* srcp, u32 size, u8* dstp );
s32
RCCompRead( const u8* srcp, u32 srcSize, u8* dstp );
s32
RCACompWrite( const u8* srcp, u32 size, u8* dstp );
s32
RCACompRead( const u8* srcp, u32 srcSize, u8* dstp );
#endif // __NTCOMPRESS_RANGE_CODER_H__

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*
Project: NinTendo Compress tool
File: types.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef __NTCOMPRESS_TYPES_H__
#define __NTCOMPRESS_TYPES_H__
//===========================================================================================
// Œ^’è‹`
//===========================================================================================
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
typedef float f32;
typedef unsigned long BOOL;
#define FALSE 0
#define TRUE 1
#define DIFF_CODE_HEADER (0x80)
#define LZ_CODE_HEADER (0x10)
#define HUFF_CODE_HEADER (0x20)
#define RL_CODE_HEADER (0x30)
#define LH_CODE_HEADER (0x40)
#define LRC_CODE_HEADER (0x50)
#define CODE_HEADER_MASK (0xF0)
#if defined( __GNUC__ )
typedef unsigned long long int u64;
typedef signed long long int s64;
#define INLINE inline
#define ASSERT(x) (void)0
#else
#include <assert.h>
#define INLINE __inline
#define ASSERT assert
typedef unsigned __int64 u64;
typedef signed __int64 s64;
#endif
#endif // __NTCOMPRESS_TYPES_H__

View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntcompress", "ntcompress.vcproj", "{FA042C1E-4CB1-4B8A-87A6-B46B4222605E}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{FA042C1E-4CB1-4B8A-87A6-B46B4222605E}.Debug.ActiveCfg = Debug|Win32
{FA042C1E-4CB1-4B8A-87A6-B46B4222605E}.Debug.Build.0 = Debug|Win32
{FA042C1E-4CB1-4B8A-87A6-B46B4222605E}.Release.ActiveCfg = Release|Win32
{FA042C1E-4CB1-4B8A-87A6-B46B4222605E}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="shift_jis"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="ntcompress"
ProjectGUID="{FA042C1E-4CB1-4B8A-87A6-B46B4222605E}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/ntrcomp.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/ntrcomp.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/ntrcomp.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/ntrcomp.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1041"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/ntrcomp.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/ntrcomp.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/ntrcomp.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/ntrcomp.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1041"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\src\multipleCompLib.c">
</File>
<File
RelativePath="..\src\multipleCompLib.h">
</File>
<File
RelativePath="..\src\nitroCompLib.c">
</File>
<File
RelativePath="..\src\nitroCompLib.h">
</File>
<File
RelativePath="..\src\ntcompress_main.c">
</File>
<File
RelativePath="..\src\ntcompress_test.c">
</File>
<File
RelativePath="..\src\ntcompress_test.h">
</File>
<File
RelativePath="..\src\rangeCoder.c">
</File>
<File
RelativePath="..\src\rangeCoder.h">
</File>
<File
RelativePath="..\src\types.h">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,9 +1,9 @@
#!/usr/bin/perl
######################################################################
# genFontTable.pl
# genFontTable.pl
#
# generate Secure Shared Font Data Table
# generate Secure Shared Font Data Table
#
# [[ HEADER FORMAT ]]
# security code (128 bytes) : RSA signature of Header
@ -16,7 +16,7 @@
#
# Font info table ( 64 bytes * number)
# fileName ( 32 bytes) : font file name
# padding ( 4 bytes) :
# comp_length ( 4 bytes) : length of the compression file
# file offset ( 4 bytes) : file offset of Font data
# length ( 4 bytes) : length of file (bytes)
# digest ( 20 bytes) : SHA1 digest of Font data
@ -39,16 +39,28 @@ my $headerFile = "header.bin";
my $digestFile = "sha1.bin";
my $signFile = "sign.bin";
my $tempFile = "temp.bin";
my $compprog = "./compBLZ_modified/bin/compBLZ.exe"; # 圧縮プログラム
my $compoption = "-e \"\"";
#my $compprog = "./ntrcomp/gcc/ntrcomp.exe";
#my $compoption = "-h8 -A32 -s";
# 後始末
sub deleteTemp {
system ("rm -f $infoFile");
system ("rm -f $headerFile");
system ("rm -f $digestFile");
system ("rm -f $signFile");
system ("rm -f $tempFile");
system ("rm -f $infoFile");
system ("rm -f $headerFile");
system ("rm -f $digestFile");
system ("rm -f $signFile");
system ("rm -f $tempFile");
}
# 環境変数からSDKのルートをサーチして(ntrcompの場所特定に必要)
#foreach ( sort keys ( %ENV ) ){
# if ($_ =~ m/TWLSDK_ROOT/s) {
# $SDKROOT = $ENV{$_};
# }
#}
#printf "TWLSDK_ROOT is ${SDKROOT}\n";
my $signSize = 0x80;
my $headerSize = 0x20;
my @files;
@ -56,113 +68,127 @@ my @files;
# 要素数算出
my $num = 0;
foreach ( @ARGV ) {
next if( $_ eq $ARGV[0] );
$files[ $num ] = $_;
$num++;
next if( $_ eq $ARGV[0] );
$files[ $num ] = $_;
$num++;
}
# 情報テーブルの出力
{
my $elementSize = 0x40;
my $fileNameMax = 0x20;
my $padLen = 0x04;
# offset length = 0x04;
# file length = 0x04;
my $sha1Len = 0x14;
open INFO, ">$infoFile" or die;
binmode INFO;
# オフセット算出
my $offset = $signSize + $headerSize + $num * $elementSize;
if( ( $offset % 32 ) > 0 ) { $offset += 32 - ( $offset % 32 ); }
foreach ( @files ) {
# NULL指定時は、NULL出力
if( "NULL" eq basename( $_ ) ) {
syswrite( INFO, pack( "x$elementSize") );
next;
}
# ファイルネームの出力
if( !( -e $_ ) ) {
close( INFO );
deleteTemp();
die "file not exist. : $_\n";
}
my $name = basename( $_ );
if( length $name >= $fileNameMax ) {
close( INFO );
deleteTemp();
die "file name length must be smaller than $fileNameMax. : $_\n";
}
my $data = pack( "a$fileNameMax", $name );
syswrite( INFO, $data, $fileNameMax );
# パディングの出力
syswrite( INFO, pack( "x$padLen") );
# ファイルオフセットの出力
$data = pack( "L", $offset );
syswrite( INFO, $data, 4 );
# ファイル長の出力
$data = pack( "L", -s $_ );
syswrite( INFO, $data, 4 );
# ファイルのSHA1ハッシュの出力
{
my $digest;
system ("openssl dgst -sha1 -binary -out $digestFile $_");
open DIGEST, $digestFile or die;
binmode DIGEST;
sysread( DIGEST, $digest, $sha1Len );
close DIGEST;
syswrite( INFO, $digest, $sha1Len );
}
printf "%s\t0x%08x\t0x%08x\n", $_, $offset, -s $_;
# オフセット加算
$offset += -s $_;
if( ( $offset % 32 ) > 0 ) { $offset += 32 - ( $offset % 32 ); }
}
close INFO;
my $elementSize = 0x40;
my $fileNameMax = 0x20;
my $padLen = 0x04;
# offset length = 0x04;
# file length = 0x04;
my $sha1Len = 0x14;
open INFO, ">$infoFile" or die;
binmode INFO;
# オフセット算出
my $offset = $signSize + $headerSize + $num * $elementSize;
if( ( $offset % 32 ) > 0 ) { $offset += 32 - ( $offset % 32 ); }
printf "---------------------------------------------------------------\n";
printf "filename\toffset \torig_size\tcompressed_size\n";
foreach ( @files ) {
# NULL指定時は、NULL出力
if( "NULL" eq basename( $_ ) ) {
syswrite( INFO, pack( "x$elementSize") );
next;
}
# ファイルネームの出力
if( !( -e $_ ) ) {
close( INFO );
deleteTemp();
die "file not exist. : $_\n";
}
my $name = basename( $_ );
if( length $name >= $fileNameMax ) {
close( INFO );
deleteTemp();
die "file name length must be smaller than $fileNameMax. : $_\n";
}
my $data = pack( "a$fileNameMax", $name );
syswrite( INFO, $data, $fileNameMax );
# 圧縮
# SDKのcompBLZ.exeは引数バグがあるためローカルに修正版を入れておく
my $compfile = "$_.comp";
system ("${compprog} $compoption $_ -o $compfile");
# パディングの出力
#syswrite( INFO, pack( "x$padLen") );
# 圧縮ファイル長を出力(もともとはpadding)
$data = pack( "L", -s $compfile );
syswrite( INFO, $data, 4 );
# ファイルオフセットの出力
$data = pack( "L", $offset );
syswrite( INFO, $data, 4 );
# ファイル長の出力
$data = pack( "L", -s $_ );
syswrite( INFO, $data, 4 );
# ファイルのSHA1ハッシュの出力
{
my $digest;
#system ("openssl dgst -sha1 -binary -out $digestFile $_");
system ("openssl dgst -sha1 -binary -out $digestFile $compfile"); # 圧縮後のファイルにハッシュをつける
open DIGEST, $digestFile or die;
binmode DIGEST;
sysread( DIGEST, $digest, $sha1Len );
close DIGEST;
syswrite( INFO, $digest, $sha1Len );
}
printf "%s\t0x%08x\t0x%08x\t0x%08x\n", $_, $offset, -s $_, -s $compfile;
# オフセット加算
#$offset += -s $_;
$offset += -s $compfile;
if( ( $offset % 32 ) > 0 ) { $offset += 32 - ( $offset % 32 ); }
}
close INFO;
printf "---------------------------------------------------------------\n";
}
# ヘッダの出力
{
# timestampLen = 0x08;
# elementNumLen = 0x02;
my $padLen = 0x06;
my $sha1Len = 0x14;
open HEADER, ">$headerFile" or die;
binmode HEADER;
# タイムスタンプの出力
# my $timestamp = strftime "%y%m%d%H", localtime;
my $timestamp = $ARGV[ 0 ];
printf "timestamp = %s\n", $timestamp;
syswrite( HEADER, pack( "N", unpack( "L", pack( "H8", $timestamp ) ) ) );
# 要素数の出力
syswrite( HEADER, pack( "S", $num ) );
# パディングの出力
syswrite( HEADER, pack( "x$padLen") );
# 情報テーブルのSHA1ハッシュの出力
{
my $digest;
system ("openssl dgst -sha1 -binary -out $digestFile $infoFile");
open DIGEST, $digestFile or die;
binmode DIGEST;
sysread( DIGEST, $digest, $sha1Len );
close DIGEST;
syswrite( HEADER, $digest, $sha1Len );
}
close HEADER;
# timestampLen = 0x08;
# elementNumLen = 0x02;
my $padLen = 0x06;
my $sha1Len = 0x14;
open HEADER, ">$headerFile" or die;
binmode HEADER;
# タイムスタンプの出力
# my $timestamp = strftime "%y%m%d%H", localtime;
my $timestamp = $ARGV[ 0 ];
printf "timestamp = %s\n", $timestamp;
syswrite( HEADER, pack( "N", unpack( "L", pack( "H8", $timestamp ) ) ) );
# 要素数の出力
syswrite( HEADER, pack( "S", $num ) );
# パディングの出力
syswrite( HEADER, pack( "x$padLen") );
# 情報テーブルのSHA1ハッシュの出力
{
my $digest;
system ("openssl dgst -sha1 -binary -out $digestFile $infoFile");
open DIGEST, $digestFile or die;
binmode DIGEST;
sysread( DIGEST, $digest, $sha1Len );
close DIGEST;
syswrite( HEADER, $digest, $sha1Len );
}
close HEADER;
}
# 環境変数サーチ
@ -172,51 +198,57 @@ foreach ( sort keys ( %ENV ) ){
}
}
if (!$KEYROOT) {
deleteTemp();
die "No TWL_IPL_RED_PRIVATE_ROOT is found.\n";
deleteTemp();
die "No TWL_IPL_RED_PRIVATE_ROOT is found.\n";
}
# ヘッダへの署名付加
{
system ( "openssl dgst -sha1 -binary -out $digestFile $headerFile" );
system ( "openssl rsautl -sign -in $digestFile -inkey $KEYROOT/keys/rsa/private_sharedFont.der -keyform DER -out $signFile" );
system ( "cat $signFile $headerFile >$tempFile" );
system ( "cat $tempFile $infoFile >$outFile" );
deleteTemp();
system ( "cat $signFile $headerFile >$tempFile" );
system ( "cat $tempFile $infoFile >$outFile" );
deleteTemp();
}
# フォントの出力
{
open FONTTABLE, ">>$outFile" or die;
binmode FONTTABLE;
{
# パディング出力
my $fileLen = -s $outFile;
my $padNum = ( $fileLen % 32 ) ? ( 32 - ( $fileLen % 32 ) ) : 0;
my $padding = pack( "x$padNum" );
syswrite( FONTTABLE, $padding, $padNum );
}
open FONTTABLE, ">>$outFile" or die;
binmode FONTTABLE;
{
# パディング出力
my $fileLen = -s $outFile;
my $padNum = ( $fileLen % 32 ) ? ( 32 - ( $fileLen % 32 ) ) : 0;
my $padding = pack( "x$padNum" );
syswrite( FONTTABLE, $padding, $padNum );
}
foreach ( @files ) {
# NULL指定時はスキップ
if( "NULL" eq basename( $_ ) ) {
next;
}
# フォント出力
my $fileLen = -s $_;
open TEST, $_ or die;
binmode TEST;
sysread ( TEST, $buffer, $fileLen );
close TEST;
syswrite( FONTTABLE, $buffer, $fileLen );
# パディング出力
my $padNum = ( $fileLen % 32 ) ? ( 32 - ( $fileLen % 32 ) ) : 0;
my $padding = pack( "x$padNum" );
syswrite( FONTTABLE, $padding, $padNum );
}
close FONTTABLE;
foreach ( @files ) {
# NULL指定時はスキップ
if( "NULL" eq basename( $_ ) ) {
next;
}
# フォント出力
#my $fileLen = -s $_;
#open TEST, $_ or die;
my $compfile = "$_.comp"; # 圧縮ファイルを出力
$fileLen = -s $compfile;
open TEST, $compfile or die;
binmode TEST;
sysread ( TEST, $buffer, $fileLen );
close TEST;
syswrite( FONTTABLE, $buffer, $fileLen );
# パディング出力
my $padNum = ( $fileLen % 32 ) ? ( 32 - ( $fileLen % 32 ) ) : 0;
my $padding = pack( "x$padNum" );
syswrite( FONTTABLE, $padding, $padNum );
# 圧縮ファイルを削除
system ("rm -rf $compfile");
}
close FONTTABLE;
}