mirror of
https://github.com/simtactics/niotso.git
synced 2025-03-15 08:11:22 +00:00
Added Propeng's tsoscan, and removed old files from libpng and zlib
This commit is contained in:
parent
1f7061d98a
commit
67fa76c747
10 changed files with 985 additions and 1 deletions
241
Libraries/FileHandler/iff/spr.c
Normal file
241
Libraries/FileHandler/iff/spr.c
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iff.h"
|
||||
|
||||
typedef struct {
|
||||
const uint8_t * StartPos;
|
||||
const uint8_t * Buffer;
|
||||
size_t TotalSize;
|
||||
size_t Size;
|
||||
uint8_t Endian; /* 0 = little, 1 = big */
|
||||
} bytestream;
|
||||
|
||||
static unsigned read_uint32xe(bytestream * b){
|
||||
if(b->Size >= 4){
|
||||
unsigned value = (b->Endian == 0) ? read_uint32le(b->Buffer) : read_uint32be(b->Buffer);
|
||||
b->Buffer += 4;
|
||||
b->Size -= 4;
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned read_uint16xe(bytestream * b){
|
||||
if(b->Size >= 2){
|
||||
unsigned value = (b->Endian == 0) ? read_uint16le(b->Buffer) : read_uint16be(b->Buffer);
|
||||
b->Buffer += 2;
|
||||
b->Size -= 2;
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skipbytes(bytestream * b, uint32_t bytes){
|
||||
if(b->Size < bytes) return 0;
|
||||
b->Buffer += bytes; b->Size -= bytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int seekto(bytestream * b, uint32_t Position){
|
||||
if(Position > b->TotalSize) return 0;
|
||||
b->Buffer = b->StartPos + Position;
|
||||
b->Size = b->TotalSize - Position;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iff_parse_spr(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
unsigned ChunkSize = ChunkInfo->Size - 76;
|
||||
bytestream b;
|
||||
unsigned i;
|
||||
|
||||
b.StartPos = Buffer;
|
||||
b.Buffer = Buffer;
|
||||
b.TotalSize = ChunkSize;
|
||||
b.Size = ChunkSize;
|
||||
b.Endian = 0;
|
||||
|
||||
if(ChunkSize < 12)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
SpriteList->Version = read_uint32xe(&b);
|
||||
SpriteList->SpriteCount = read_uint32xe(&b);
|
||||
SpriteList->PaletteID = read_uint32xe(&b);
|
||||
if(SpriteList->Version < 502 || (SpriteList->Version > 505 && SpriteList->Version != 1001))
|
||||
return 0;
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
/* Skip past the offset table */
|
||||
if(SpriteList->SpriteCount > UINT_MAX/4 || !skipbytes(&b, SpriteList->SpriteCount*4))
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize = 0;
|
||||
unsigned row = 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32xe(&b)))
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else
|
||||
seekto(&b, b.Buffer - b.StartPos); /* Update b.Size */
|
||||
|
||||
if(b.Size < ((SpriteList->Version == 1001) ? 18 : 10))
|
||||
return 0;
|
||||
if(SpriteList->Version == 1001){
|
||||
if(read_uint32xe(&b) != 1001)
|
||||
return 0;
|
||||
SpriteSize = read_uint32xe(&b);
|
||||
if(SpriteSize > b.Size || SpriteSize < 10)
|
||||
return 0;
|
||||
}
|
||||
Sprite->Reserved = read_uint32xe(&b);
|
||||
Sprite->Height = read_uint16xe(&b);
|
||||
Sprite->Width = read_uint16xe(&b);
|
||||
if(Sprite->Reserved != 0 || Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/Sprite->Width/2)
|
||||
return 0;
|
||||
Sprite->IndexData = calloc(Sprite->Height*Sprite->Width, 2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
|
||||
while(1){
|
||||
/* Row command: valid commands are 0, 4, 5, and 9 */
|
||||
uint8_t Command, Count;
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
|
||||
Command = *(b.Buffer++);
|
||||
Count = *(b.Buffer++);
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(Command == 0){
|
||||
/* Do nothing */
|
||||
}else if(Command == 4){
|
||||
/* Pixel command: valid commands are 1, 2, and 3 */
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || Count < 2 || (Count -= 2) > SpriteSize || Count%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= Count;
|
||||
while(Count){
|
||||
uint8_t PixelCommand, PixelCount;
|
||||
if(Count < 2)
|
||||
return 0;
|
||||
|
||||
PixelCommand = *(b.Buffer++);
|
||||
PixelCount = *(b.Buffer++);
|
||||
Count -= 2;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* Leave pixels as transparent */
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
pixel += PixelCount;
|
||||
}else if(PixelCommand == 2){
|
||||
/* Set next n pixels to shared palette index */
|
||||
uint8_t PaletteIndex;
|
||||
if(PixelCount > Sprite->Width - pixel || Count < 2)
|
||||
return 0;
|
||||
|
||||
PaletteIndex = *(b.Buffer++);
|
||||
b.Buffer++; /* Padding byte */
|
||||
Count -= 2;
|
||||
|
||||
while(PixelCount--){
|
||||
Sprite->IndexData[(Sprite->Width*row + pixel)*2 + 0] = PaletteIndex;
|
||||
Sprite->IndexData[(Sprite->Width*row + pixel)*2 + 1] = 0xFF;
|
||||
pixel++;
|
||||
}
|
||||
}else if(PixelCommand == 3){
|
||||
/* Set next n pixels to n palette indices */
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount > Sprite->Width - pixel || PixelCount + padding > Count)
|
||||
return 0;
|
||||
Count -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
Sprite->IndexData[(Sprite->Width*row + pixel)*2 + 0] = *(b.Buffer++);
|
||||
Sprite->IndexData[(Sprite->Width*row + pixel)*2 + 1] = 0xFF;
|
||||
pixel++;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(Command == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else if(Command == 9){
|
||||
/* Leave rows as transparent */
|
||||
if(Count > Sprite->Height - row)
|
||||
return 0;
|
||||
row += Count;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_spr(void * FormattedData){
|
||||
IFFSpriteList *SpriteList = FormattedData;
|
||||
if(SpriteList->Sprites){
|
||||
unsigned s;
|
||||
for(s=0; s<SpriteList->SpriteCount; s++){
|
||||
IFFSprite *Sprite = &SpriteList->Sprites[s];
|
||||
free(Sprite->IndexData);
|
||||
free(Sprite->BGRA32Data);
|
||||
}
|
||||
free(SpriteList->Sprites);
|
||||
}
|
||||
}
|
||||
|
||||
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette){
|
||||
unsigned PixelCount = Sprite->Width*Sprite->Height;
|
||||
unsigned i;
|
||||
|
||||
Sprite->BGRA32Data = malloc(PixelCount*4);
|
||||
if(Sprite->BGRA32Data == NULL) return 0;
|
||||
|
||||
for(i=0; i<PixelCount; i++){
|
||||
uint8_t Index = Sprite->IndexData[2*i + 0];
|
||||
if(Index >= Palette->ColorCount){
|
||||
free(Sprite->BGRA32Data);
|
||||
return 0;
|
||||
}
|
||||
Sprite->BGRA32Data[4*i + 0] = Palette->Data[3*Index + 2];
|
||||
Sprite->BGRA32Data[4*i + 1] = Palette->Data[3*Index + 1];
|
||||
Sprite->BGRA32Data[4*i + 2] = Palette->Data[3*Index + 0];
|
||||
Sprite->BGRA32Data[4*i + 3] = Sprite->IndexData[2*i + 1];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(FARDive)
|
||||
add_subdirectory(hitutils)
|
||||
add_subdirectory(iff2html)
|
||||
add_subdirectory(iff2html)
|
||||
add_subdirectory(tsoscan)
|
136
Tools/iff2html/image.c
Normal file
136
Tools/iff2html/image.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
iff2html - iff web page description generator
|
||||
image.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iff/iff.h>
|
||||
#include <bmp/read_bmp.h>
|
||||
#include <setjmp.h>
|
||||
#include <libpng/png.h>
|
||||
|
||||
int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite * Sprite, size_t * Width, size_t * Height){
|
||||
FILE * hFile;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_bytep * row_pointers;
|
||||
unsigned i;
|
||||
|
||||
struct {
|
||||
size_t Width;
|
||||
size_t Height;
|
||||
uint8_t * Data;
|
||||
} Image;
|
||||
|
||||
if(ChunkData){
|
||||
/* BMP_ or FBMP chunk */
|
||||
bmpheader_t BMPHeader;
|
||||
|
||||
if(!bmp_read_header(&BMPHeader, ChunkData->Data, ChunkData->Size - 76))
|
||||
return 0;
|
||||
|
||||
Image.Data = malloc(BMPHeader.DecompressedSize);
|
||||
if(Image.Data == NULL)
|
||||
return 0;
|
||||
if(!bmp_read_data(&BMPHeader, ChunkData->Data, Image.Data)){
|
||||
free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Image.Width = BMPHeader.biWidth;
|
||||
Image.Height = BMPHeader.biHeight;
|
||||
|
||||
row_pointers = malloc(Image.Height * sizeof(png_bytep));
|
||||
if(row_pointers == NULL){
|
||||
free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<Image.Height; i++)
|
||||
row_pointers[i] = Image.Data + (Image.Height-i-1)*Image.Width*3;
|
||||
}else{
|
||||
/* SPR# or SPR2 sprite */
|
||||
Image.Width = Sprite->Width;
|
||||
Image.Height = Sprite->Height;
|
||||
Image.Data = Sprite->BGRA32Data;
|
||||
}
|
||||
|
||||
row_pointers = malloc(Image.Height * sizeof(png_bytep));
|
||||
if(row_pointers == NULL){
|
||||
if(ChunkData) free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<Image.Height; i++)
|
||||
row_pointers[i] = Image.Data + (Image.Height-i-1)*Image.Width*((ChunkData)?3:4);
|
||||
|
||||
/****
|
||||
** PNG handling
|
||||
*/
|
||||
|
||||
/* Initialization */
|
||||
hFile = fopen(OutName, "wb");
|
||||
if(hFile == NULL){
|
||||
free(row_pointers);
|
||||
if(ChunkData) free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if(png_ptr == NULL){
|
||||
fclose(hFile);
|
||||
free(row_pointers);
|
||||
if(ChunkData) free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if(info_ptr == NULL){
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
fclose(hFile);
|
||||
free(row_pointers);
|
||||
if(ChunkData) free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
if(setjmp(png_jmpbuf(png_ptr))){
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(hFile);
|
||||
free(row_pointers);
|
||||
if(ChunkData) free(Image.Data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, hFile);
|
||||
|
||||
png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
|
||||
png_set_compression_level(png_ptr, 9);
|
||||
png_set_compression_mem_level(png_ptr, 9);
|
||||
png_set_compression_window_bits(png_ptr, 15);
|
||||
png_set_compression_buffer_size(png_ptr, 32768);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, Image.Width, Image.Height, 8, ChunkData ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL);
|
||||
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(hFile);
|
||||
free(row_pointers);
|
||||
|
||||
if(ChunkData){
|
||||
free(Image.Data);
|
||||
*Width = Image.Width;
|
||||
*Height = Image.Height;
|
||||
}
|
||||
return 1;
|
||||
}
|
19
Tools/iff2html/image.h
Normal file
19
Tools/iff2html/image.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
iff2html - iff web page description generator
|
||||
image.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite * Sprite, size_t * Width, size_t * Height);
|
13
Tools/tsoscan/CMakeLists.txt
Normal file
13
Tools/tsoscan/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
project(tsoscan)
|
||||
|
||||
set(TSOSCAN_SOURCES
|
||||
tsoscan.c
|
||||
cmd.c
|
||||
stats.c
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler)
|
||||
|
||||
add_executable(tsoscan ${TSOSCAN_SOURCES})
|
||||
target_link_libraries(tsoscan iff_static)
|
67
Tools/tsoscan/cmd.c
Normal file
67
Tools/tsoscan/cmd.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
tsoscan - IFF statistical webpage generator
|
||||
cmd.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "tsoscan.h"
|
||||
|
||||
CommandLineArgs* cmd_parse_args(int argc, char *argv[]){
|
||||
CommandLineArgs *CmdArgs = calloc(1, sizeof(CommandLineArgs));
|
||||
int i, InDirIndex = 0;
|
||||
|
||||
if(CmdArgs == NULL) return 0;
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
if(!strcmp(argv[i], "-o"))
|
||||
i++;
|
||||
else if(strcmp(argv[i], "-f") != 0)
|
||||
CmdArgs->InDirCount++;
|
||||
}
|
||||
if(CmdArgs->InDirCount > 0){
|
||||
CmdArgs->InDirs = calloc(CmdArgs->InDirCount, sizeof(char*));
|
||||
if(CmdArgs->InDirs == NULL) return 0;
|
||||
}
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
if(!strcmp(argv[i], "-f")){
|
||||
CmdArgs->ForceWrite = 1;
|
||||
}else if(!strcmp(argv[i], "-o")){
|
||||
if(i == argc-1 || CmdArgs->OutFile != NULL)
|
||||
return NULL;
|
||||
CmdArgs->OutFile = argv[++i];
|
||||
}else{
|
||||
CmdArgs->InDirs[InDirIndex] = argv[i];
|
||||
InDirIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return CmdArgs;
|
||||
}
|
||||
|
||||
void cmd_delete(CommandLineArgs *args){
|
||||
unsigned i;
|
||||
|
||||
if(args == NULL) return;
|
||||
if(args->InDirs != NULL){
|
||||
for(i=0; i<args->InDirCount; i++)
|
||||
free(args->InDirs[i]);
|
||||
free(args->InDirs);
|
||||
}
|
||||
free(args->OutFile);
|
||||
free(args);
|
||||
}
|
111
Tools/tsoscan/stats.c
Normal file
111
Tools/tsoscan/stats.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
tsoscan - IFF statistical webpage generator
|
||||
stats.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iff/iff.h>
|
||||
#include "tsoscan.h"
|
||||
|
||||
IFFStats* stats_create(){
|
||||
IFFStats *stats = calloc(1, sizeof(IFFStats));
|
||||
if (stats == NULL) return NULL;
|
||||
stats->AverageChunkCount = -1;
|
||||
return stats;
|
||||
}
|
||||
|
||||
int stats_version_increment(IFFStats *stats, char *type, unsigned version){
|
||||
ChunkStats *chunk = NULL;
|
||||
VersionInfo *verinfo = NULL;
|
||||
unsigned i;
|
||||
|
||||
if(stats == NULL) return 0;
|
||||
if(type == NULL) return 0;
|
||||
|
||||
for(i=0; i<stats->ChunkTypeCount; i++){
|
||||
if(!strcmp(stats->ChunkTypes[i].Type, type)){
|
||||
chunk = stats->ChunkTypes+i;
|
||||
if(chunk == NULL) return 0;
|
||||
}
|
||||
}
|
||||
if(chunk == NULL){
|
||||
stats->ChunkTypes = realloc(stats->ChunkTypes, ++(stats->ChunkTypeCount)*sizeof(ChunkStats));
|
||||
if(stats->ChunkTypes == NULL) return 0;
|
||||
chunk = stats->ChunkTypes + stats->ChunkTypeCount - 1;
|
||||
memset(chunk, 0, sizeof(ChunkStats));
|
||||
strcpy(chunk->Type, type);
|
||||
}
|
||||
chunk->ChunkCount++;
|
||||
|
||||
for(i=0; i<chunk->VersionCount; i++){
|
||||
if(chunk->Versions[i].Version == version){
|
||||
verinfo = chunk->Versions+i;
|
||||
if(verinfo == NULL) return 0;
|
||||
}
|
||||
}
|
||||
if(verinfo == NULL){
|
||||
chunk->Versions = realloc(chunk->Versions, ++(chunk->VersionCount)*sizeof(VersionInfo));
|
||||
if(chunk->Versions == NULL) return 0;
|
||||
verinfo = chunk->Versions + chunk->VersionCount - 1;
|
||||
memset(verinfo, 0, sizeof(VersionInfo));
|
||||
verinfo->Version = version;
|
||||
}
|
||||
verinfo->Count++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned stats_get_version(char *type, uint8_t *data){
|
||||
/* I could've used iff_parse_chunk instead to determine chunk versions, but this
|
||||
would be unnecessarily slow and would require all chunk parsers to be written,
|
||||
defeating the purpose of this tool. */
|
||||
|
||||
if(!strcmp(type, "STR#") || !strcmp(type, "CTSS") || !strcmp(type, "FAMs") ||
|
||||
!strcmp(type, "TTAs") || !strcmp(type, "CST") || !strcmp(type, "BHAV") ||
|
||||
!strcmp(type, "DGRP") || !strcmp(type, "POSI"))
|
||||
return read_uint16le(data);
|
||||
|
||||
if(!strcmp(type, "FCNS") || !strcmp(type, "OBJf") || !strcmp(type, "Optn") ||
|
||||
!strcmp(type, "Rcon") || !strcmp(type, "TPRP") || !strcmp(type, "SLOT") ||
|
||||
!strcmp(type, "TRCN") || !strcmp(type, "rsmp"))
|
||||
return read_uint32le(data+4);
|
||||
|
||||
if(!strcmp(type, "OBJD") || !strcmp(type, "PALT") || !strcmp(type, "SPR2"))
|
||||
return read_uint32le(data);
|
||||
|
||||
if(!strcmp(type, "TTAB"))
|
||||
return read_uint16le(data+2);
|
||||
|
||||
if(!strcmp(type, "SPR#")){
|
||||
if(data[0] == 0) return read_uint32be(data);
|
||||
else return read_uint32le(data);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void stats_delete(IFFStats *stats){
|
||||
unsigned i;
|
||||
|
||||
if(stats == NULL) return;
|
||||
if(stats->ChunkTypes != NULL){
|
||||
for(i=0; i<stats->ChunkTypeCount; i++)
|
||||
free(stats->ChunkTypes[i].Versions);
|
||||
free(stats->ChunkTypes);
|
||||
}
|
||||
free(stats);
|
||||
}
|
331
Tools/tsoscan/tsoscan.c
Normal file
331
Tools/tsoscan/tsoscan.c
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
tsoscan - IFF statistical webpage generator
|
||||
tsoscan.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <iff/iff.h>
|
||||
#include "tsoscan.h"
|
||||
|
||||
void print_usage(){
|
||||
printf("Usage: tsoscan [-f] [-o outfile] indir1 [indir2 [...]]\n"
|
||||
"Generate a statistical HTML page based on a number of IFF files.\n"
|
||||
"Use -f to force overwriting without confirmation.\n"
|
||||
"If outfile is unspecified, the output HTML page will be written to stats.html.\n"
|
||||
"\n"
|
||||
"Report bugs to <X-Fi6@phppoll.org>.\n"
|
||||
"tsoscan is maintained by the Niotso project.\n"
|
||||
"Home page: <http://www.niotso.org/>\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
CommandLineArgs *CmdArgs;
|
||||
unsigned i, version, FileCount = 0;
|
||||
char **Files = NULL;
|
||||
IFFStats *Stats = stats_create();
|
||||
FILE *OutFile;
|
||||
|
||||
if(Stats == NULL){
|
||||
printf("%sUnable to allocate enough memory.\n", TSOSCAN_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){
|
||||
print_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CmdArgs = cmd_parse_args(argc, argv);
|
||||
if(CmdArgs == NULL || CmdArgs->InDirCount == 0){
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
if(CmdArgs->OutFile == NULL){
|
||||
CmdArgs->OutFile = "stats.html";
|
||||
}
|
||||
|
||||
/****
|
||||
** List selected input directories
|
||||
*/
|
||||
|
||||
for(i=0; i<CmdArgs->InDirCount; i++){
|
||||
DIR *dir = opendir(CmdArgs->InDirs[i]);
|
||||
struct dirent *entry;
|
||||
unsigned DirStartIndex;
|
||||
|
||||
if(dir == NULL){
|
||||
printf("%sUnable to open the specified directory '%s'. Skipping.\n", TSOSCAN_WARNING, CmdArgs->InDirs[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
DirStartIndex = FileCount;
|
||||
while((entry = readdir(dir)) != NULL){
|
||||
if(strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
|
||||
FileCount++;
|
||||
}
|
||||
rewinddir(dir);
|
||||
Files = realloc(Files, FileCount*sizeof(char**));
|
||||
if(Files == NULL){
|
||||
printf("%sUnable to allocate enough memory.\n", TSOSCAN_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(; DirStartIndex<FileCount;){
|
||||
entry = readdir(dir);
|
||||
if(strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")){
|
||||
int dirlen = strlen(CmdArgs->InDirs[i]);
|
||||
int pathlen = strlen(entry->d_name);
|
||||
Files[DirStartIndex] = malloc(dirlen+pathlen+2);
|
||||
if(Files[DirStartIndex] == NULL){
|
||||
printf("%sUnable to allocate enough memory.\n", TSOSCAN_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(Files[DirStartIndex], CmdArgs->InDirs[i], dirlen);
|
||||
Files[DirStartIndex][dirlen] = PATH_SEP;
|
||||
memcpy(Files[DirStartIndex]+dirlen+1, entry->d_name, pathlen);
|
||||
Files[DirStartIndex][dirlen+pathlen+1] = '\0';
|
||||
|
||||
DirStartIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
/****
|
||||
** Load and parse IFF files
|
||||
*/
|
||||
|
||||
Stats->AverageChunkCount = -1;
|
||||
|
||||
for(i=0; i<FileCount; i++){
|
||||
FILE *file;
|
||||
size_t FileSize;
|
||||
uint8_t *data;
|
||||
IFFFile *iff;
|
||||
IFFChunk *ChunkData;
|
||||
unsigned ChunkIndex;
|
||||
|
||||
printf("(%d/%d)\r", i+1, FileCount);
|
||||
|
||||
file = fopen(Files[i], "rb");
|
||||
if(file == NULL){
|
||||
printf("%sUnable to open the specified file '%s'. Skipping.\n", TSOSCAN_WARNING, Files[i]);
|
||||
continue;
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
FileSize = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
data = malloc(FileSize);
|
||||
if(data == NULL){
|
||||
printf("%sUnable to allocate memory for the specified files.\n", TSOSCAN_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if(!fread(data, FileSize, 1, file)){
|
||||
printf("%sUnable to read the specified file '%s'. Skipping.\n", TSOSCAN_WARNING, Files[i]);
|
||||
free(data);
|
||||
fclose(file);
|
||||
continue;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
iff = iff_create();
|
||||
if(iff == NULL){
|
||||
printf("%sUnable to allocate memory for the specified files.\n", TSOSCAN_ERROR);
|
||||
return -1;
|
||||
}
|
||||
if(!iff_read_header(iff, data, FileSize) || !iff_enumerate_chunks(iff, data+64, FileSize-64)){
|
||||
/* Skip non-IFF files silently */
|
||||
free(data);
|
||||
continue;
|
||||
}
|
||||
free(data);
|
||||
|
||||
Stats->FileCount++;
|
||||
if(Stats->AverageChunkCount == -1){
|
||||
Stats->AverageChunkCount = iff->ChunkCount;
|
||||
}else{
|
||||
Stats->AverageChunkCount += iff->ChunkCount;
|
||||
Stats->AverageChunkCount /= 2;
|
||||
}
|
||||
|
||||
for(ChunkIndex = 0, ChunkData = iff->Chunks; ChunkIndex < iff->ChunkCount; ChunkIndex++, ChunkData++){
|
||||
unsigned version = stats_get_version(ChunkData->Type, ChunkData->Data);
|
||||
if(!stats_version_increment(Stats, ChunkData->Type, version)){
|
||||
printf("%sUnable to allocate enough memory.\n", TSOSCAN_ERROR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
iff_delete(iff);
|
||||
}
|
||||
|
||||
/****
|
||||
** Write output file
|
||||
*/
|
||||
|
||||
if(!CmdArgs->ForceWrite){
|
||||
OutFile = fopen(CmdArgs->OutFile, "rb");
|
||||
if(OutFile != NULL){
|
||||
char c;
|
||||
fclose(OutFile);
|
||||
printf("File \"%s\" exists. Continue anyway? (y/n) ", CmdArgs->OutFile);
|
||||
c = getchar();
|
||||
if(c != 'y' && c != 'Y')
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
OutFile = fopen(CmdArgs->OutFile, "wb");
|
||||
if(OutFile == NULL){
|
||||
printf("%sThe output file '%s' could not be opened for writing.", TSOSCAN_ERROR, CmdArgs->OutFile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(OutFile,
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
|
||||
fprintf(OutFile, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n");
|
||||
fprintf(OutFile, "<head>\n");
|
||||
fprintf(OutFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n");
|
||||
fprintf(OutFile, "<meta http-equiv=\"Content-Style-Type\" content=\"text/css; charset=utf-8\" />\n");
|
||||
fprintf(OutFile, "<meta http-equiv=\"Content-Language\" content=\"en\" />\n");
|
||||
fprintf(OutFile, "<meta name=\"description\" content=\"tsostats\" />\n");
|
||||
fprintf(OutFile, "<meta name=\"generator\" content=\"IFF Chunk Statistics (tsostats)\" />\n");
|
||||
fprintf(OutFile, "<title>IFF Chunk Statistics (tsostats)</title>\n");
|
||||
fprintf(OutFile, "<style type=\"text/css\" media=\"all\">\n");
|
||||
fprintf(OutFile, "html, body {\n");
|
||||
fprintf(OutFile, " background: #fff;\n");
|
||||
fprintf(OutFile, " color: #000;\n");
|
||||
fprintf(OutFile, " font-family: sans-serif;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, "a:link, a:visited, a:hover, a:active { color: #00f; }\n");
|
||||
fprintf(OutFile, "a:link, a:visited { text-decoration: none; }\n");
|
||||
fprintf(OutFile, "a:hover, a:active { text-decoration: underline; }\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, "#attributes {\n");
|
||||
fprintf(OutFile, " border-left: 2px solid #888; padding-left: 4px; margin-bottom: 1em;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, "#toc {\n");
|
||||
fprintf(OutFile, " display: table-cell;\n");
|
||||
fprintf(OutFile, " margin-top: 1em;\n");
|
||||
fprintf(OutFile, " background: #eee; border: 1px solid #bbb;\n");
|
||||
fprintf(OutFile, " padding: .25em;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "#toc div {\n");
|
||||
fprintf(OutFile, " border-bottom: 1px solid #aaa;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "#toc ul {\n");
|
||||
fprintf(OutFile, " list-style-type: none;\n");
|
||||
fprintf(OutFile, " padding: 0;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "ul ul {\n");
|
||||
fprintf(OutFile, " padding: 2em;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, "h2 {\n");
|
||||
fprintf(OutFile, " border-bottom: 1px solid #888;\n");
|
||||
fprintf(OutFile, " margin: 2em 0 0.25em 0;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "h2 a {\n");
|
||||
fprintf(OutFile, " font-size: 9pt;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, "table {\n");
|
||||
fprintf(OutFile, " border: 1px #aaa solid;\n");
|
||||
fprintf(OutFile, " border-collapse: collapse;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "th, td {\n");
|
||||
fprintf(OutFile, " border: 1px #aaa solid;\n");
|
||||
fprintf(OutFile, " padding: 0.2em;\n");
|
||||
fprintf(OutFile, " white-space: pre-wrap;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, ".center {\n");
|
||||
fprintf(OutFile, " margin: auto auto;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "\n");
|
||||
fprintf(OutFile, "#footer {\n");
|
||||
fprintf(OutFile, " margin-top: 2em;\n");
|
||||
fprintf(OutFile, " padding-bottom: 0.5em;\n");
|
||||
fprintf(OutFile, " text-align: center;\n");
|
||||
fprintf(OutFile, "}\n");
|
||||
fprintf(OutFile, "</style>\n");
|
||||
fprintf(OutFile, "</head>\n");
|
||||
fprintf(OutFile, "<body>\n");
|
||||
fprintf(OutFile, "<h1>IFF Chunk Statistics (tsostats)</h1>\n");
|
||||
fprintf(OutFile, "<div id=\"attributes\">\n");
|
||||
fprintf(OutFile, "<table>\n");
|
||||
fprintf(OutFile, "<tr><td>Number of IFF files:</td><td>%u</td></tr>\n", Stats->FileCount);
|
||||
fprintf(OutFile, "<tr><td>Average chunk count:</td><td>%.1f</td></tr>\n", Stats->AverageChunkCount);
|
||||
fprintf(OutFile, "</table>\n");
|
||||
fprintf(OutFile, "</div>\n");
|
||||
|
||||
fprintf(OutFile, "<div id=\"toc\"><div><b>Contents</b> – %u chunk types</div>\n", Stats->ChunkTypeCount);
|
||||
fprintf(OutFile, "<ul>\n");
|
||||
for(i=0; i<Stats->ChunkTypeCount; i++)
|
||||
fprintf(OutFile, "<li><a href=\"#type%u\">%u %s</a></li>\n", i, i+1, Stats->ChunkTypes[i].Type);
|
||||
fprintf(OutFile, "</ul>\n");
|
||||
fprintf(OutFile, "</div>\n");
|
||||
fprintf(OutFile, "\n");
|
||||
|
||||
for(i=0; i<Stats->ChunkTypeCount; i++){
|
||||
ChunkStats *chunk = Stats->ChunkTypes+i;
|
||||
|
||||
fprintf(OutFile, "<h2 id=\"type%u\">%u %s <a href=\"#type%u\">(Jump)</a></h2>\n", i, i+1, Stats->ChunkTypes[i].Type, i);
|
||||
fprintf(OutFile, "<div>\n");
|
||||
|
||||
fprintf(OutFile, "<table>\n");
|
||||
fprintf(OutFile, "<tr><td>Number of occurrences:</td><td>%u</td></tr>\n", chunk->ChunkCount);
|
||||
if(chunk->VersionCount == 1 && chunk->Versions[0].Version == (unsigned)-1)
|
||||
fprintf(OutFile, "<tr><td>Number of versions:</td><td>N/A</td></tr>\n");
|
||||
else
|
||||
fprintf(OutFile, "<tr><td>Number of versions:</td><td>%u</td></tr>\n", chunk->VersionCount);
|
||||
fprintf(OutFile, "</table>\n");
|
||||
|
||||
if(chunk->VersionCount > 1 ||
|
||||
(chunk->VersionCount == 1 && chunk->Versions[0].Version != (unsigned)-1)){
|
||||
fprintf(OutFile, "<table class=\"center\">\n");
|
||||
fprintf(OutFile, "<tr><th></th><th>Version</th><th>Count</th></tr>\n");
|
||||
for(version=0; version<chunk->VersionCount; version++){
|
||||
VersionInfo *verinfo = chunk->Versions+version;
|
||||
float percentage = (float)verinfo->Count / chunk->ChunkCount * 100;
|
||||
|
||||
fprintf(OutFile, "<tr><td>%u</td><td>%u (<tt>0x%x</tt>)</td><td>%u (%.1f%%)</td></tr>\n",
|
||||
version+1, verinfo->Version, verinfo->Version, verinfo->Count, percentage);
|
||||
}
|
||||
fprintf(OutFile, "</table>\n");
|
||||
}
|
||||
|
||||
fprintf(OutFile, "</div>\n\n");
|
||||
}
|
||||
|
||||
fprintf(OutFile,
|
||||
"<div id=\"footer\">This page was generated by the use of <a href=\"http://www.niotso.org/\">tsostats</a>.</div>\n");
|
||||
fprintf(OutFile, "</body>\n");
|
||||
fprintf(OutFile, "</html>");
|
||||
fclose(OutFile);
|
||||
|
||||
printf("Generated statistics based on %u IFF files.\n", Stats->FileCount);
|
||||
cmd_delete(CmdArgs);
|
||||
stats_delete(Stats);
|
||||
return 0;
|
||||
}
|
65
Tools/tsoscan/tsoscan.h
Normal file
65
Tools/tsoscan/tsoscan.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
tsoscan - IFF statistical webpage generator
|
||||
tsoscan.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define TSOSCAN_WARNING "tsoscan: warning: "
|
||||
#define TSOSCAN_ERROR "tsoscan: error: "
|
||||
#ifdef _WIN32
|
||||
#define PATH_SEP '\\'
|
||||
#else
|
||||
#define PATH_SEP '/'
|
||||
#endif
|
||||
|
||||
typedef struct CommandLineArgs_s
|
||||
{
|
||||
int ForceWrite;
|
||||
char * OutFile;
|
||||
unsigned InDirCount;
|
||||
char ** InDirs;
|
||||
} CommandLineArgs;
|
||||
|
||||
typedef struct VersionInfo_s
|
||||
{
|
||||
unsigned Version;
|
||||
unsigned Count;
|
||||
} VersionInfo;
|
||||
|
||||
typedef struct ChunkStats_s
|
||||
{
|
||||
char Type[5];
|
||||
unsigned ChunkCount;
|
||||
unsigned VersionCount;
|
||||
VersionInfo * Versions;
|
||||
} ChunkStats;
|
||||
|
||||
typedef struct IFFStats_s
|
||||
{
|
||||
unsigned FileCount;
|
||||
float AverageChunkCount;
|
||||
unsigned ChunkTypeCount;
|
||||
ChunkStats * ChunkTypes;
|
||||
} IFFStats;
|
||||
|
||||
CommandLineArgs* cmd_parse_args(int argc, char *argv[]);
|
||||
void cmd_delete(CommandLineArgs *args);
|
||||
|
||||
IFFStats* stats_create();
|
||||
int stats_version_increment(IFFStats *stats, char *type, unsigned version);
|
||||
unsigned stats_get_version(char *type, uint8_t *data);
|
||||
void stats_delete(IFFStats *stats);
|
Loading…
Add table
Reference in a new issue