mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-07-04 21:50:35 -04:00
iff2html working
This commit is contained in:
parent
deaf3327e0
commit
4cd716e94d
89 changed files with 7711 additions and 3 deletions
19
library/tools/iff2html/CMakeLists.txt
Normal file
19
library/tools/iff2html/CMakeLists.txt
Normal file
|
@ -0,0 +1,19 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
project(iff2html)
|
||||
|
||||
include_directories(${LIBPNG_INCLUDE})
|
||||
include_directories(${ZLIB_INCLUDE})
|
||||
|
||||
include_directories( "${CMAKE_SOURCE_DIR}/formats")
|
||||
|
||||
set(IFF2HTML_SOURCES
|
||||
iff2html.c
|
||||
md5.c
|
||||
image.c
|
||||
opngreduc.c
|
||||
"${CMAKE_SOURCE_DIR}/formats/iff/iff.h"
|
||||
"${CMAKE_SOURCE_DIR}/formats/bmp/read_bmp.c"
|
||||
)
|
||||
|
||||
add_executable(iff2html ${IFF2HTML_SOURCES})
|
||||
target_link_libraries(iff2html iff_static FileHandler_static ${LIBPNG_LINK} ${ZLIB_LINK})
|
713
library/tools/iff2html/iff2html.c
Normal file
713
library/tools/iff2html/iff2html.c
Normal file
|
@ -0,0 +1,713 @@
|
|||
/*
|
||||
iff2html - iff web page description generator
|
||||
iff2html.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <iff/iff.h>
|
||||
#include "md5.h"
|
||||
#include "image.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(x,y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
static void printsize(FILE * hFile, size_t FileSize){
|
||||
/* For our purposes, our units are best described in kB and MB, if not bytes */
|
||||
size_t temp = FileSize;
|
||||
unsigned position = 1;
|
||||
if(FileSize >= 1048576)
|
||||
fprintf(hFile, "%.1f MB (", (float)FileSize/1048576);
|
||||
else
|
||||
fprintf(hFile, "%.1f kB (", (float)FileSize/1024);
|
||||
while((temp/=1000) != 0)
|
||||
position *= 1000;
|
||||
fprintf(hFile, "%u", (unsigned) FileSize/position);
|
||||
FileSize -= (FileSize/position)*position;
|
||||
while((position/=1000) != 0){
|
||||
fprintf(hFile, ",%.3u", (unsigned) FileSize/position);
|
||||
FileSize -= (FileSize/position)*position;
|
||||
}
|
||||
fprintf(hFile, " bytes)");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
unsigned c;
|
||||
int slash;
|
||||
FILE * hFile;
|
||||
int overwrite = 0;
|
||||
char *InFile, *OutFile = NULL, *FileName, *OutDir = NULL;
|
||||
size_t FileSize;
|
||||
struct MD5Context md5c;
|
||||
unsigned char digest[16];
|
||||
uint8_t * IFFData;
|
||||
IFFFile IFFFileInfo;
|
||||
IFFChunk * ChunkData;
|
||||
|
||||
if(argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){
|
||||
printf("Usage: iff2html [-f] infile (outfile)\n"
|
||||
"Produce an HTML webpage describing an EA IFF file.\n"
|
||||
"Use -f to force overwriting without confirmation.\n"
|
||||
"If outfile is unspecified, file.iff will output to file.html.\n"
|
||||
"\n"
|
||||
"Report bugs to <X-Fi6@phppoll.org>.\n"
|
||||
"iff2html is maintained by the Niotso project.\n"
|
||||
"Home page: <http://www.niotso.org/>\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(argc >= 4 && !strcmp(argv[1], "-f")){
|
||||
overwrite++;
|
||||
InFile = argv[2];
|
||||
OutFile = argv[3];
|
||||
}else if(argc == 3){
|
||||
if(!strcmp(argv[1], "-f")){
|
||||
overwrite++;
|
||||
InFile = argv[2];
|
||||
}else{
|
||||
InFile = argv[1];
|
||||
OutFile = argv[2];
|
||||
}
|
||||
}else InFile = argv[1];
|
||||
if(OutFile == NULL){
|
||||
unsigned length = strlen(InFile);
|
||||
OutFile = malloc(max(length+2, 6));
|
||||
strcpy(OutFile, InFile);
|
||||
strcpy(max(OutFile+length-4, OutFile), ".html");
|
||||
}
|
||||
|
||||
for(c=0, slash=-1; OutFile[c]; c++)
|
||||
if(OutFile[c] == '/' || OutFile[c] == '\\') slash = c;
|
||||
if(slash >= 0){
|
||||
OutDir = malloc(slash+2);
|
||||
memcpy(OutDir, OutFile, slash+1);
|
||||
OutDir[slash+1] = 0x00;
|
||||
}else OutDir = "";
|
||||
|
||||
for(c=0, slash=-1; InFile[c]; c++)
|
||||
if(InFile[c] == '/' || InFile[c] == '\\') slash = c;
|
||||
FileName = InFile + slash + 1;
|
||||
|
||||
/****
|
||||
** Open the file and read in entire contents to memory
|
||||
*/
|
||||
|
||||
hFile = fopen(InFile, "rb");
|
||||
if(hFile == NULL){
|
||||
printf("%sThe specified input file does not exist or could not be opened for reading.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
fseek(hFile, 0, SEEK_END);
|
||||
FileSize = ftell(hFile);
|
||||
if(FileSize < 64){
|
||||
fclose(hFile);
|
||||
printf("%sNot a valid IFF file.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
fseek(hFile, 0, SEEK_SET);
|
||||
|
||||
IFFData = malloc(FileSize);
|
||||
if(IFFData == NULL){
|
||||
fclose(hFile);
|
||||
printf("%sMemory for this file could not be allocated.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
if(fread(IFFData, 1, FileSize, hFile) != FileSize){
|
||||
fclose(hFile);
|
||||
printf("%sThe input file could not be read.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
fclose(hFile);
|
||||
|
||||
/****
|
||||
** Load header information
|
||||
*/
|
||||
|
||||
if(!iff_create(&IFFFileInfo)){
|
||||
printf("%sMemory for this file could not be allocated.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
if(!iff_read_header(&IFFFileInfo, IFFData, FileSize)){
|
||||
printf("%sNot a valid IFF file.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****
|
||||
** Load entry information
|
||||
*/
|
||||
|
||||
if(!iff_enumerate_chunks(&IFFFileInfo, IFFData+64, FileSize-64)){
|
||||
printf("%sChunk data is corrupt.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Calculate the MD5, and then we can free the IFF data because we're done with it */
|
||||
MD5Init(&md5c);
|
||||
MD5Update(&md5c, IFFData, FileSize);
|
||||
MD5Final(digest, &md5c);
|
||||
free(IFFData);
|
||||
|
||||
for(c = 0, ChunkData = IFFFileInfo.Chunks; c < IFFFileInfo.ChunkCount; c++, ChunkData++)
|
||||
iff_parse_chunk(ChunkData, ChunkData->Data);
|
||||
|
||||
/****
|
||||
** Open the output file and write the header
|
||||
*/
|
||||
if(!overwrite){
|
||||
hFile = fopen(OutFile, "rb");
|
||||
if(hFile != NULL){
|
||||
/* File exists */
|
||||
char c;
|
||||
fclose(hFile);
|
||||
printf("File \"%s\" exists.\nContinue anyway? (y/n) ", OutFile);
|
||||
c = getchar();
|
||||
if(c != 'y' && c != 'Y'){
|
||||
printf("\nAborted.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
hFile = fopen(OutFile, "wb");
|
||||
if(hFile == NULL){
|
||||
printf("%sThe output file could not be opened for writing.", "iff2html: error: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****
|
||||
** We're splitting fprintf by line to guarantee compatibility;
|
||||
** even C99 compilers are only required to support 4096 byte strings in printf()-related functions
|
||||
*/
|
||||
fprintf(hFile,
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
|
||||
fprintf(hFile, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n");
|
||||
fprintf(hFile, "<head>\n");
|
||||
fprintf(hFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n");
|
||||
fprintf(hFile, "<meta http-equiv=\"Content-Style-Type\" content=\"text/css; charset=iso-8859-1\" />\n");
|
||||
fprintf(hFile, "<meta http-equiv=\"Content-Language\" content=\"en\" />\n");
|
||||
fprintf(hFile, "<meta name=\"description\" content=\"%s (iff2html)\" />\n", FileName);
|
||||
fprintf(hFile, "<meta name=\"generator\" content=\"iff2html\" />\n");
|
||||
fprintf(hFile, "<title>%s (iff2html)</title>\n", FileName);
|
||||
fprintf(hFile, "<style type=\"text/css\" media=\"all\">\n");
|
||||
fprintf(hFile, "html, body {\n");
|
||||
fprintf(hFile, " background: #fff;\n");
|
||||
fprintf(hFile, " color: #000;\n");
|
||||
fprintf(hFile, " font-family: sans-serif;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "a:link, a:visited, a:hover, a:active { color: #00f; }\n");
|
||||
fprintf(hFile, "a:link, a:visited { text-decoration: none; }\n");
|
||||
fprintf(hFile, "a:hover, a:active { text-decoration: underline; }\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "#attributes {\n");
|
||||
fprintf(hFile, " border-left: 2px solid #888; padding-left: 4px; margin-bottom: 1em;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "#toc {\n");
|
||||
fprintf(hFile, " display: table-cell;\n");
|
||||
fprintf(hFile, " margin-top: 1em;\n");
|
||||
fprintf(hFile, " background: #eee; border: 1px solid #bbb;\n");
|
||||
fprintf(hFile, " padding: .25em;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "#toc div {\n");
|
||||
fprintf(hFile, " border-bottom: 1px solid #aaa;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "#toc ul {\n");
|
||||
fprintf(hFile, " list-style-type: none;\n");
|
||||
fprintf(hFile, " padding: 0;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "ul ul {\n");
|
||||
fprintf(hFile, " padding: 2em;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "h2 {\n");
|
||||
fprintf(hFile, " border-bottom: 1px solid #888;\n");
|
||||
fprintf(hFile, " margin: 2em 0 0.25em 0;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "h2 a {\n");
|
||||
fprintf(hFile, " font-size: 9pt;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "table {\n");
|
||||
fprintf(hFile, " border: 1px #aaa solid;\n");
|
||||
fprintf(hFile, " border-collapse: collapse;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "th, td {\n");
|
||||
fprintf(hFile, " border: 1px #aaa solid;\n");
|
||||
fprintf(hFile, " padding: 0.2em;\n");
|
||||
fprintf(hFile, " white-space: pre-wrap;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, ".center {\n");
|
||||
fprintf(hFile, " margin: auto auto;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, ".centerall * {\n");
|
||||
fprintf(hFile, " text-align: center;\n");
|
||||
fprintf(hFile, " vertical-align: middle;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, ".palette td, .palette th {\n");
|
||||
fprintf(hFile, " border: none;\n");
|
||||
fprintf(hFile, " width: 16px;\n");
|
||||
fprintf(hFile, " height: 16px;\n");
|
||||
fprintf(hFile, " font-size: 12px;\n");
|
||||
fprintf(hFile, " line-height: 16px;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, ".palette td[title] {\n");
|
||||
fprintf(hFile, " border: 1px solid #000;\n");
|
||||
fprintf(hFile, " cursor: help;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "#footer {\n");
|
||||
fprintf(hFile, " margin-top: 2em;\n");
|
||||
fprintf(hFile, " padding-bottom: 0.5em;\n");
|
||||
fprintf(hFile, " text-align: center;\n");
|
||||
fprintf(hFile, "}\n");
|
||||
fprintf(hFile, "</style>\n");
|
||||
fprintf(hFile, "</head>\n");
|
||||
fprintf(hFile, "<body>\n");
|
||||
fprintf(hFile, "<h1>%s</h1>\n", FileName);
|
||||
fprintf(hFile, "<div id=\"attributes\">\n");
|
||||
fprintf(hFile, "<div>");
|
||||
for(c=0; c<16; c++)
|
||||
fprintf(hFile, "%.2x", digest[c]);
|
||||
fprintf(hFile, " (md5), ");
|
||||
printsize(hFile, FileSize);
|
||||
fprintf(hFile, "</div>\n");
|
||||
fprintf(hFile, "<div>Dumped by iff2html.</div></div>\n");
|
||||
fprintf(hFile, "\n");
|
||||
fprintf(hFile, "<div id=\"toc\"><div><b>Contents</b> – %u chunks</div>\n", IFFFileInfo.ChunkCount);
|
||||
fprintf(hFile, "<ul>\n");
|
||||
for(c=1, ChunkData = IFFFileInfo.Chunks; c <= IFFFileInfo.ChunkCount; c++, ChunkData++)
|
||||
fprintf(hFile, "<li><a href=\"#chunk%u_%.4x\">%u [%s] (%.4X)%s%s</a></li>\n",
|
||||
c, ChunkData->ChunkID, c, ChunkData->Type, ChunkData->ChunkID,
|
||||
(ChunkData->Label[0] != 0x00) ? " – " : "", ChunkData->Label);
|
||||
fprintf(hFile, "</ul>\n");
|
||||
fprintf(hFile, "</div>\n");
|
||||
fprintf(hFile, "\n");
|
||||
|
||||
for(c=0, ChunkData = IFFFileInfo.Chunks; c < IFFFileInfo.ChunkCount; c++, ChunkData++){
|
||||
fprintf(hFile, "<h2 id=\"chunk%u_%.4x\">%u [%s] (%.4X)%s%s <a href=\"#chunk%u_%.4x\">(Jump)</a></h2>\n",
|
||||
c+1, ChunkData->ChunkID, c+1, ChunkData->Type, ChunkData->ChunkID,
|
||||
(ChunkData->Label[0] != 0x00) ? " – " : "", ChunkData->Label,
|
||||
c+1, ChunkData->ChunkID);
|
||||
fprintf(hFile, "<div>\n");
|
||||
|
||||
if(ChunkData->FormattedData == NULL){
|
||||
int success = 0;
|
||||
/* The iff library does not parse BMP_ or FBMP chunks */
|
||||
if(!strcmp(ChunkData->Type, "BMP_") || !strcmp(ChunkData->Type, "FBMP")){
|
||||
int bmp = !strcmp(ChunkData->Type, "BMP_");
|
||||
size_t Width, Height;
|
||||
char filename[32];
|
||||
sprintf(filename, "%s%s_%u_%.4x.png", OutDir, bmp ? "bmp" : "fbmp", c+1, ChunkData->ChunkID);
|
||||
|
||||
if(WritePNG(filename, ChunkData, 0, NULL, &Width, &Height)){
|
||||
fprintf(hFile, "<table class=\"center centerall\">\n");
|
||||
fprintf(hFile, "<tr><th>Image</th></tr>\n");
|
||||
fprintf(hFile, "<tr><td><img src=\"%s_%u_%.4x.png\" width=\"%u\" height=\"%u\" alt=\"\" /></td></tr>\n",
|
||||
bmp ? "bmp" : "fbmp", c+1, ChunkData->ChunkID, (unsigned) Width, (unsigned) Height);
|
||||
fprintf(hFile, "</table>\n");
|
||||
success++;
|
||||
}
|
||||
}
|
||||
if(!success)
|
||||
fprintf(hFile, "The contents of this chunk could not be parsed.\n");
|
||||
}else if(!strcmp(ChunkData->Type, "STR#") ||
|
||||
!strcmp(ChunkData->Type, "CTSS") ||
|
||||
!strcmp(ChunkData->Type, "FAMs") ||
|
||||
!strcmp(ChunkData->Type, "TTAs") ||
|
||||
!strcmp(ChunkData->Type, "CST") ){
|
||||
/****
|
||||
** STR# parsing
|
||||
*/
|
||||
|
||||
IFFString * StringData = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Format:</td><td>");
|
||||
switch(StringData->Format){
|
||||
case 0: fprintf(hFile, "<tt>00 00</tt> (0)"); break;
|
||||
case -1: fprintf(hFile, "<tt>FF FF</tt> (−1)"); break;
|
||||
case -2: fprintf(hFile, "<tt>FE FF</tt> (−2)"); break;
|
||||
case -3: fprintf(hFile, "<tt>FD FF</tt> (−3)"); break;
|
||||
case -4: fprintf(hFile, "<tt>FC FF</tt> (−4)"); break;
|
||||
default: fprintf(hFile, "Unrecognized"); break;
|
||||
}
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(StringData->Format >= -4 && StringData->Format <= 0){
|
||||
unsigned LanguageSet;
|
||||
const char * LanguageStrings[] = {
|
||||
"English (US)",
|
||||
"English (International)",
|
||||
"French",
|
||||
"German",
|
||||
"Italian",
|
||||
"Spanish",
|
||||
"Dutch",
|
||||
"Danish",
|
||||
"Swedish",
|
||||
"Norwegian",
|
||||
"Finnish",
|
||||
"Hebrew",
|
||||
"Russian",
|
||||
"Portuguese",
|
||||
"Japanese",
|
||||
"Polish",
|
||||
"Simplified Chinese",
|
||||
"Traditional Chinese",
|
||||
"Thai",
|
||||
"Korean"
|
||||
};
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th>Language</th><th colspan=\"3\">String pairs</th></tr>\n");
|
||||
|
||||
for(LanguageSet=0; LanguageSet<20; LanguageSet++){
|
||||
IFFStringPair * Pair;
|
||||
unsigned PairIndex;
|
||||
if(StringData->LanguageSets[LanguageSet].PairCount == 0)
|
||||
continue;
|
||||
|
||||
fprintf(hFile, "<tr><td rowspan=\"%u\">%s</td>\n", StringData->LanguageSets[LanguageSet].PairCount,
|
||||
LanguageStrings[LanguageSet]);
|
||||
for(PairIndex=1, Pair = StringData->LanguageSets[LanguageSet].Pairs;
|
||||
PairIndex <= StringData->LanguageSets[LanguageSet].PairCount; PairIndex++, Pair++){
|
||||
if(PairIndex != 1)
|
||||
fprintf(hFile, "<tr>");
|
||||
fprintf(hFile, "<td>%u</td><td>%s</td><td>%s</td></tr>\n", PairIndex,
|
||||
(Pair->Key) != NULL ? Pair->Key : "",
|
||||
(Pair->Value) != NULL ? Pair->Value : "");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "CATS")){
|
||||
/****
|
||||
** Regular string pair
|
||||
*/
|
||||
|
||||
IFFStringPair * Pair = ChunkData->FormattedData;
|
||||
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th>Key</th><th>Value</th></tr>\n");
|
||||
fprintf(hFile, "<tr><td>%s</td><td>%s</td></tr>\n",
|
||||
(Pair->Key) != NULL ? Pair->Key : "",
|
||||
(Pair->Value) != NULL ? Pair->Value : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "FWAV") || !strcmp(ChunkData->Type, "GLOB")){
|
||||
/****
|
||||
** Regular string
|
||||
*/
|
||||
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th>String</th></tr>\n");
|
||||
fprintf(hFile, "<tr><td>%s</td></tr>\n", ChunkData->FormattedData ? (char*) ChunkData->FormattedData : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "BCON")){
|
||||
/****
|
||||
** BCON parsing
|
||||
*/
|
||||
|
||||
IFF_BCON * BCONData = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Flags:</td><td><tt>%02X</tt> (%u)</td></tr>\n", BCONData->Flags, BCONData->Flags);
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(BCONData->ConstantCount > 0){
|
||||
unsigned i;
|
||||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Constant Value</th></tr>\n");
|
||||
for(i=0; i<BCONData->ConstantCount; i++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%u</td></tr>\n", i+1, BCONData->Constants[i]);
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "FCNS")){
|
||||
/****
|
||||
** FCNS parsing
|
||||
*/
|
||||
|
||||
IFFConstantList * List = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", List->Version);
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(List->ConstantCount > 0){
|
||||
IFFConstant * Constant;
|
||||
unsigned i;
|
||||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Name</th><th>Value</th><th>Description</th></tr>\n");
|
||||
for(i=0, Constant=List->Constants; i<List->ConstantCount; i++, Constant++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%s</td><td>%g</td><td>%s</td></tr>\n",
|
||||
i+1,
|
||||
Constant->Name ? Constant->Name : "",
|
||||
Constant->Value,
|
||||
Constant->Description ? Constant->Description : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "TMPL")){
|
||||
/****
|
||||
** TMPL parsing
|
||||
*/
|
||||
|
||||
IFFTemplate * Template = ChunkData->FormattedData;
|
||||
IFFTemplateField * Field;
|
||||
unsigned i;
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Name</th><th>Type</th>\n");
|
||||
for(i=0, Field=Template->Fields; i<Template->FieldCount; i++, Field++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%s</td><td>%s</td></tr>\n",
|
||||
i+1,
|
||||
Field->Name ? Field->Name : "",
|
||||
Field->Type ? Field->Type : "");
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "TRCN")){
|
||||
/****
|
||||
** TRCN parsing
|
||||
*/
|
||||
|
||||
IFFRangeSet * RangeSet = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", RangeSet->Version);
|
||||
fprintf(hFile, "</table>\n");
|
||||
if(RangeSet->RangeCount > 0){
|
||||
unsigned i;
|
||||
IFFRangeEntry * Range;
|
||||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">In use</th><th>Default value</th><th>Name</th>"
|
||||
"<th>Comment</th><th>Range is enforced</th><th>Minimum</th><th>Maximum</th></tr>\n");
|
||||
for(i=0, Range=RangeSet->Ranges; i<RangeSet->RangeCount; i++, Range++)
|
||||
fprintf(hFile,
|
||||
"<tr><td>%u</td><td>%s</td><td>%u</td><td>%s</td><td>%s</td><td>%s</td><td>%u</td><td>%u</td></tr>\n",
|
||||
i+1,
|
||||
Range->IsUsed ? "Yes" : "No", Range->DefaultValue,
|
||||
Range->Name ? Range->Name : "",
|
||||
Range->Comment ? Range->Comment : "",
|
||||
Range->Enforced ? "Yes" : "No",
|
||||
Range->RangeMin, Range->RangeMax);
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "PALT")){
|
||||
/****
|
||||
** PALT parsing
|
||||
*/
|
||||
|
||||
IFFPalette * Palette = ChunkData->FormattedData;
|
||||
uint8_t * Data = Palette->Data;
|
||||
unsigned i, j;
|
||||
|
||||
fprintf(hFile, "<table class=\"center palette\" border=\"0\">\n");
|
||||
fprintf(hFile, "<tr><th></th>");
|
||||
for(i=0; i<16; i++) fprintf(hFile, "<th>%X</th>", i);
|
||||
fprintf(hFile, "</tr>\n");
|
||||
for(i=0; i<16; i++){
|
||||
fprintf(hFile, "<tr><th>%X</th>", i);
|
||||
for(j=0; j<16; j++){
|
||||
if(i*16 + j < Palette->ColorCount){
|
||||
unsigned red = *(Data++);
|
||||
unsigned green = *(Data++);
|
||||
unsigned blue = *(Data++);
|
||||
|
||||
fprintf(hFile, "\n<td style=\"background:#%.2x%.2x%.2x\" title=\"%u: #%.2x%.2x%.2x\"></td>",
|
||||
red, green, blue, i*16 + j, red, green, blue);
|
||||
}else
|
||||
fprintf(hFile, "\n<td></td>");
|
||||
}
|
||||
fprintf(hFile, "</tr>\n");
|
||||
}
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "SPR#") || !strcmp(ChunkData->Type, "SPR2")){
|
||||
/****
|
||||
** SPR# and SPR2 parsing
|
||||
*/
|
||||
|
||||
int spr1 = !strcmp(ChunkData->Type, "SPR#");
|
||||
IFFSpriteList * SpriteList = ChunkData->FormattedData;
|
||||
IFFChunk * Palette = NULL;
|
||||
IFFPalette BlankPalette;
|
||||
IFFPalette * PaletteData;
|
||||
unsigned i;
|
||||
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", SpriteList->Version);
|
||||
fprintf(hFile, "<tr><td>Palette ID:</td><td>%.4X</td></tr>\n", SpriteList->PaletteID);
|
||||
fprintf(hFile, "</table>\n");
|
||||
|
||||
if(SpriteList->PaletteID < 0xFFFF){
|
||||
Palette = iff_find_chunk(&IFFFileInfo, "PALT", SpriteList->PaletteID);
|
||||
if(!Palette || !Palette->FormattedData) Palette = iff_find_chunk(&IFFFileInfo, "PALT", ChunkData->ChunkID);
|
||||
if(!Palette || !Palette->FormattedData) Palette = iff_find_chunk(&IFFFileInfo, "PALT", -1);
|
||||
}
|
||||
if(!Palette || !Palette->FormattedData){
|
||||
memset(&BlankPalette, 0, sizeof(IFFPalette));
|
||||
BlankPalette.Version = 1;
|
||||
BlankPalette.ColorCount = 256;
|
||||
PaletteData = &BlankPalette;
|
||||
}else PaletteData = Palette->FormattedData;
|
||||
|
||||
fprintf(hFile, "<table class=\"center centerall\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Sprite</th>");
|
||||
if(!spr1) fprintf(hFile, "<th>Z-Buffer</th>");
|
||||
fprintf(hFile, "</tr>\n");
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
char filename[32];
|
||||
sprintf(filename, "%s%s_%u_%.4x_%u.png", OutDir, spr1 ? "spr1" : "spr2", c+1, ChunkData->ChunkID, i+1);
|
||||
|
||||
fprintf(hFile, "<tr><td>%u</td><td", i+1);
|
||||
if(Sprite->IndexData && iff_depalette(Sprite, PaletteData)){
|
||||
WritePNG(filename, NULL, 0, Sprite, NULL, NULL);
|
||||
fprintf(hFile, "><img src=\"%s_%u_%.4x_%u.png\" width=\"%u\" height=\"%u\" alt=\"\" />",
|
||||
spr1 ? "spr1" : "spr2", c+1, ChunkData->ChunkID, i+1, Sprite->Width, Sprite->Height);
|
||||
if(!spr1){
|
||||
sprintf(filename, "%sspr2_%u_%.4x_%u_z.png", OutDir, c+1, ChunkData->ChunkID, i+1);
|
||||
if(Sprite->ZBuffer){
|
||||
WritePNG(filename, NULL, 1, Sprite, NULL, NULL);
|
||||
fprintf(hFile, "</td><td><img src=\"spr2_%u_%.4x_%u_z.png\" width=\"%u\" height=\"%u\" alt=\"\" />",
|
||||
c+1, ChunkData->ChunkID, i+1, Sprite->Width, Sprite->Height);
|
||||
}else
|
||||
fprintf(hFile, "None provided");
|
||||
}
|
||||
}else
|
||||
fprintf(hFile, Sprite->InvalidDimensions ? "%sBlank sprite" : "%sThis sprite cannot be displayed.",
|
||||
!spr1 ? " colspan=\"2\">" : ">");
|
||||
fprintf(hFile, "</td></tr>\n");
|
||||
}
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "DGRP")){
|
||||
/****
|
||||
** DGRP parsing
|
||||
*/
|
||||
|
||||
IFFDrawGroup * Group = ChunkData->FormattedData;
|
||||
IFFDrawAngle * Angle;
|
||||
IFFSpriteInfo * Sprite;
|
||||
unsigned i,j;
|
||||
const char * Zooms[] = {"Far", "Middle", "Close"};
|
||||
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", Group->Version);
|
||||
fprintf(hFile, "</table>\n");
|
||||
fprintf(hFile, "<br />\n");
|
||||
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th>Direction</th><th>Zoom</th><th colspan=\"6\">Sprite</th></tr>\n");
|
||||
for(i=0, Angle=Group->DrawAngles; i<12; i++, Angle++){
|
||||
const char * Direction =
|
||||
(Angle->Direction == IFFDIRECTION_NORTHEAST) ? "North east" :
|
||||
(Angle->Direction == IFFDIRECTION_SOUTHEAST) ? "South east" :
|
||||
(Angle->Direction == IFFDIRECTION_NORTHWEST) ? "North west" :
|
||||
"South west";
|
||||
|
||||
if(Angle->SpriteCount){
|
||||
fprintf(hFile,
|
||||
"<tr><td rowspan=\"%u\">%s</td><td rowspan=\"%u\">%s</td>"
|
||||
"<th>#</th><th>Type</th><th>Chunk ID</th><th>Sprite index</th>"
|
||||
"<th>Flags</th><th>Sprite offset</th><th>Object offset</th></tr>\n",
|
||||
1+Angle->SpriteCount, Direction, 1+Angle->SpriteCount, Zooms[Angle->Zoom-1]);
|
||||
for(j=0, Sprite = Angle->SpriteInfo; j<Angle->SpriteCount; j++, Sprite++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td>%u</td><td>%.4X</td><td>%u</td><td>%u</td>"
|
||||
"<td>(%+d,%+d)</td><td>(%+g,%+g,%+g)</td></tr>",
|
||||
j+1, Sprite->Type, Sprite->ChunkID, Sprite->SpriteIndex, Sprite->Flags,
|
||||
Sprite->SpriteX, Sprite->SpriteY, Sprite->ObjectX, Sprite->ObjectY, Sprite->ObjectZ);
|
||||
|
||||
}else{
|
||||
fprintf(hFile, "<tr><td>%s</td><td>%s</td><td>None specified</td></tr>", Direction, Zooms[Angle->Zoom-1]);
|
||||
}
|
||||
}
|
||||
fprintf(hFile, "</table>\n");
|
||||
}else if(!strcmp(ChunkData->Type, "BHAV")){
|
||||
/****
|
||||
** BHAV parsing
|
||||
*/
|
||||
|
||||
IFFBehavior * Behavior = ChunkData->FormattedData;
|
||||
IFFInstruction * Instruction;
|
||||
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", Behavior->Version);
|
||||
fprintf(hFile, "<tr><td>Type:</td><td>%u</td></tr>\n", Behavior->Type);
|
||||
fprintf(hFile, "<tr><td>Arguments:</td><td>%u</td></tr>\n", Behavior->ArgumentCount);
|
||||
fprintf(hFile, "<tr><td>Locals:</td><td>%u</td></tr>\n", Behavior->LocalCount);
|
||||
fprintf(hFile, "<tr><td>Flags:</td><td>%.4X</td></tr>\n", Behavior->Flags);
|
||||
fprintf(hFile, "</table>\n");
|
||||
|
||||
if(Behavior->InstructionCount > 0){
|
||||
unsigned i;
|
||||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Opcode</th><th>T-Dest</th><th>F-Dest</th><th>Operand data</th></tr>\n");
|
||||
for(i=0, Instruction = Behavior->Instructions; i<Behavior->InstructionCount; i++, Instruction++)
|
||||
fprintf(hFile, "<tr><td>%u</td><td><tt>%.4X</tt></td><td>%u</td><td>%u</td>"
|
||||
"<td><tt>%.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X</tt></td></tr>\n",
|
||||
i, Instruction->Opcode, Instruction->TDest, Instruction->FDest,
|
||||
Instruction->Operands[0], Instruction->Operands[1],
|
||||
Instruction->Operands[2], Instruction->Operands[3],
|
||||
Instruction->Operands[4], Instruction->Operands[5],
|
||||
Instruction->Operands[6], Instruction->Operands[7]);
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else if(!strcmp(ChunkData->Type, "OBJf")){
|
||||
/****
|
||||
** OBJf parsing
|
||||
*/
|
||||
|
||||
IFFFunctionTable * Table = ChunkData->FormattedData;
|
||||
fprintf(hFile, "<table>\n");
|
||||
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", Table->Version);
|
||||
fprintf(hFile, "</table>\n");
|
||||
|
||||
if(Table->FunctionCount > 0){
|
||||
unsigned i;
|
||||
|
||||
fprintf(hFile, "<br />\n");
|
||||
fprintf(hFile, "<table class=\"center\">\n");
|
||||
fprintf(hFile, "<tr><th colspan=\"2\">Condition function</th><th>Action function</th></tr>\n");
|
||||
for(i=0; i<Table->FunctionCount; i++)
|
||||
fprintf(hFile,
|
||||
"<tr><td>%u</td><td>%.4X</td><td>%.4X</td></tr>\n",
|
||||
i+1, Table->Functions[i].ConditionID, Table->Functions[i].ActionID);
|
||||
fprintf(hFile, "</table>\n");
|
||||
}
|
||||
}else{
|
||||
fprintf(hFile, "The contents of this chunk cannot be shown on this page.\n");
|
||||
}
|
||||
|
||||
fprintf(hFile, "</div>\n\n");
|
||||
}
|
||||
iff_delete(&IFFFileInfo);
|
||||
|
||||
fprintf(hFile,
|
||||
"<div id=\"footer\">This page was generated by the use of <a href=\"http://www.niotso.org/\">iff2html</a>.\n");
|
||||
fprintf(hFile, "The content of this page may be subject to copyright by the author(s) of the original iff file.</div>\n");
|
||||
fprintf(hFile, "</body>\n");
|
||||
fprintf(hFile, "</html>");
|
||||
fclose(hFile);
|
||||
|
||||
printf("Wrote contents to '%s'.\n", OutFile);
|
||||
return 0;
|
||||
}
|
149
library/tools/iff2html/image.c
Normal file
149
library/tools/iff2html/image.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
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 <png.h>
|
||||
#include <setjmp.h> /* Used for libpng */
|
||||
#include "opngreduc.h"
|
||||
|
||||
int WritePNG(const char * OutName, const IFFChunk * ChunkData, int ZBuffer,
|
||||
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;
|
||||
|
||||
/* We must swap from BGR to RGB; this cannot be done with libpng when you use
|
||||
** opng_reduce_image due to the state that it leaves png_ptr in */
|
||||
|
||||
if(ChunkData){
|
||||
/* BMP_ or FBMP chunk */
|
||||
bmpheader_t BMPHeader;
|
||||
|
||||
if(!bmp_read_header(&BMPHeader, ChunkData->Data, ChunkData->Size))
|
||||
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;
|
||||
|
||||
for(i=0; i<Image.Width*Image.Height; i++){
|
||||
uint8_t temp = Image.Data[i*3 + 0];
|
||||
Image.Data[i*3 + 0] = Image.Data[i*3 + 2];
|
||||
Image.Data[i*3 + 2] = temp;
|
||||
}
|
||||
}else{
|
||||
/* SPR# or SPR2 sprite */
|
||||
Image.Width = Sprite->Width;
|
||||
Image.Height = Sprite->Height;
|
||||
Image.Data = (!ZBuffer) ? Sprite->BGRA32Data : Sprite->ZBuffer;
|
||||
|
||||
if(!ZBuffer){
|
||||
for(i=0; i<Image.Width*Image.Height; i++){
|
||||
uint8_t temp = Image.Data[i*4 + 0];
|
||||
Image.Data[i*4 + 0] = Image.Data[i*4 + 2];
|
||||
Image.Data[i*4 + 2] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.Width*((ChunkData) ? 3*(Image.Height-i-1) : ((!ZBuffer)?4:1)*i);
|
||||
|
||||
/****
|
||||
** 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 : (!ZBuffer) ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_GRAY,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||||
opng_reduce_image(png_ptr, info_ptr, OPNG_REDUCE_ALL);
|
||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 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;
|
||||
}
|
20
library/tools/iff2html/image.h
Normal file
20
library/tools/iff2html/image.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
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, int ZBuffer,
|
||||
const IFFSprite * Sprite, size_t * Width, size_t * Height);
|
255
library/tools/iff2html/md5.c
Normal file
255
library/tools/iff2html/md5.c
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*/
|
||||
|
||||
/* Brutally hacked by John Walker back from ANSI C to K&R (no
|
||||
prototypes) to maintain the tradition that Netfone will compile
|
||||
with Sun's original "cc". */
|
||||
|
||||
#include <memory.h> /* for memcpy() */
|
||||
#include "md5.h"
|
||||
|
||||
#ifndef HIGHFIRST
|
||||
#define byteReverse(buf, len) /* Nothing */
|
||||
#else
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
void byteReverse(buf, longs)
|
||||
unsigned char *buf; unsigned longs;
|
||||
{
|
||||
uint32 t;
|
||||
do {
|
||||
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(uint32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void MD5Init(ctx)
|
||||
struct MD5Context *ctx;
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void MD5Update(ctx, buf, len)
|
||||
struct MD5Context *ctx; unsigned char *buf; unsigned len;
|
||||
{
|
||||
uint32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in.c + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx->in.c, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in.c);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in.c, buf, 64);
|
||||
byteReverse(ctx->in.c, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in.c);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in.c, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void MD5Final(digest, ctx)
|
||||
unsigned char digest[16]; struct MD5Context *ctx;
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in.c + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in.c, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in.c);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in.c, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in.c, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ctx->in.i[14] = ctx->bits[0];
|
||||
ctx->in.i[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in.c);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(buf, in)
|
||||
uint32 buf[4]; uint32 in[16];
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
57
library/tools/iff2html/md5.h
Normal file
57
library/tools/iff2html/md5.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
/* The following tests optimise behaviour on little-endian
|
||||
machines, where there is no need to reverse the byte order
|
||||
of 32 bit words in the MD5 computation. By default,
|
||||
HIGHFIRST is defined, which indicates we're running on a
|
||||
big-endian (most significant byte first) machine, on which
|
||||
the byteReverse function in md5.c must be invoked. However,
|
||||
byteReverse is coded in such a way that it is an identity
|
||||
function when run on a little-endian machine, so calling it
|
||||
on such a platform causes no harm apart from wasting time.
|
||||
If the platform is known to be little-endian, we speed
|
||||
things up by undefining HIGHFIRST, which defines
|
||||
byteReverse as a null macro. Doing things in this manner
|
||||
insures we work on new platforms regardless of their byte
|
||||
order. */
|
||||
|
||||
#define HIGHFIRST
|
||||
|
||||
#ifdef __i386__
|
||||
#undef HIGHFIRST
|
||||
#endif
|
||||
|
||||
/* On machines where "long" is 64 bits, we need to declare
|
||||
uint32 as something guaranteed to be 32 bits. */
|
||||
|
||||
#ifdef __alpha
|
||||
typedef unsigned int uint32;
|
||||
#else
|
||||
typedef unsigned long uint32;
|
||||
#endif
|
||||
|
||||
struct MD5Context {
|
||||
uint32 buf[4];
|
||||
uint32 bits[2];
|
||||
union {
|
||||
unsigned char c[64];
|
||||
uint32 i[16];
|
||||
} in;
|
||||
};
|
||||
|
||||
extern void MD5Init();
|
||||
extern void MD5Update();
|
||||
extern void MD5Final();
|
||||
extern void MD5Transform();
|
||||
|
||||
/*
|
||||
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||
*/
|
||||
typedef struct MD5Context MD5_CTX;
|
||||
|
||||
/* Define CHECK_HARDWARE_PROPERTIES to have main,c verify
|
||||
byte order and uint32 settings. */
|
||||
#define CHECK_HARDWARE_PROPERTIES
|
||||
|
||||
#endif /* !MD5_H */
|
1311
library/tools/iff2html/opngreduc.c
Normal file
1311
library/tools/iff2html/opngreduc.c
Normal file
File diff suppressed because it is too large
Load diff
97
library/tools/iff2html/opngreduc.h
Normal file
97
library/tools/iff2html/opngreduc.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* opngreduc.h - libpng extension: lossless image reductions.
|
||||
*
|
||||
* Copyright (C) 2003-2011 Cosmin Truta.
|
||||
* This software is distributed under the same licensing and warranty terms
|
||||
* as libpng.
|
||||
*
|
||||
* This code is functional, although it is still work in progress.
|
||||
* Upon completion, it will be submitted for incorporation into libpng.
|
||||
*/
|
||||
|
||||
#ifndef OPNGREDUC_H
|
||||
#define OPNGREDUC_H
|
||||
|
||||
#include <png.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PNG_INFO_IMAGE_SUPPORTED
|
||||
|
||||
/*
|
||||
* Indicate whether the image information is valid, i.e.
|
||||
* all the required critical information is present in the png structures.
|
||||
*/
|
||||
int PNGAPI opng_validate_image(png_structp png_ptr, png_infop info_ptr);
|
||||
|
||||
#endif /* PNG_INFO_IMAGE_SUPPORTED */
|
||||
|
||||
|
||||
#ifndef OPNG_NO_IMAGE_REDUCTIONS
|
||||
#define OPNG_IMAGE_REDUCTIONS_SUPPORTED
|
||||
#endif
|
||||
|
||||
#ifdef OPNG_IMAGE_REDUCTIONS_SUPPORTED
|
||||
|
||||
#ifndef PNG_INFO_IMAGE_SUPPORTED
|
||||
#error OPNG_IMAGE_REDUCTIONS_SUPPORTED requires PNG_INFO_IMAGE_SUPPORTED
|
||||
#endif
|
||||
|
||||
#ifndef PNG_tRNS_SUPPORTED
|
||||
#error OPNG_IMAGE_REDUCTIONS_SUPPORTED requires proper transparency support
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reduce the image (bit depth + color type + palette) without
|
||||
* losing any information. The image data must be present
|
||||
* (e.g. after calling png_set_rows(), or after loading IDAT).
|
||||
*/
|
||||
png_uint_32 PNGAPI opng_reduce_image(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 reductions);
|
||||
|
||||
/*
|
||||
* PNG reduction flags.
|
||||
*/
|
||||
#define OPNG_REDUCE_NONE 0x0000
|
||||
#define OPNG_REDUCE_16_TO_8 0x0001 /* discard bits 8-15 */
|
||||
#define OPNG_REDUCE_8_TO_4_2_1 0x0002 /* discard bits 4-7, 2-7 or 1-7 */
|
||||
#define OPNG_REDUCE_RGB_TO_GRAY 0x0004 /* ...also RGBA to GA */
|
||||
#define OPNG_REDUCE_STRIP_ALPHA 0x0008 /* ...and create tRNS if needed */
|
||||
#define OPNG_REDUCE_RGB_TO_PALETTE 0x0010 /* ...also RGBA to palette/tRNS */
|
||||
#define OPNG_REDUCE_PALETTE_TO_RGB 0x0020 /* TODO */
|
||||
#define OPNG_REDUCE_GRAY_TO_PALETTE 0x0040 /* ...also GA to palette/tRNS */
|
||||
#define OPNG_REDUCE_PALETTE_TO_GRAY 0x0080 /* ...also palette/tRNS to GA */
|
||||
#define OPNG_REDUCE_PALETTE_SLOW 0x0100 /* TODO: remove all sterile entries
|
||||
and reorder PLTE */
|
||||
#define OPNG_REDUCE_PALETTE_FAST 0x0200 /* remove trailing sterile entries
|
||||
only; do not reorder PLTE */
|
||||
#define OPNG_REDUCE_ANCILLARY 0x1000 /* TODO */
|
||||
|
||||
#define OPNG_REDUCE_BIT_DEPTH \
|
||||
(OPNG_REDUCE_16_TO_8 | OPNG_REDUCE_8_TO_4_2_1)
|
||||
|
||||
#define OPNG_REDUCE_COLOR_TYPE \
|
||||
(OPNG_REDUCE_RGB_TO_GRAY | OPNG_REDUCE_STRIP_ALPHA | \
|
||||
OPNG_REDUCE_RGB_TO_PALETTE | OPNG_REDUCE_PALETTE_TO_RGB | \
|
||||
OPNG_REDUCE_GRAY_TO_PALETTE | OPNG_REDUCE_PALETTE_TO_GRAY)
|
||||
|
||||
#define OPNG_REDUCE_PALETTE \
|
||||
(OPNG_REDUCE_PALETTE_SLOW | OPNG_REDUCE_PALETTE_FAST)
|
||||
|
||||
#define OPNG_REDUCE_ALL \
|
||||
(OPNG_REDUCE_BIT_DEPTH | OPNG_REDUCE_COLOR_TYPE | \
|
||||
OPNG_REDUCE_PALETTE | OPNG_REDUCE_ANCILLARY)
|
||||
|
||||
#endif /* OPNG_IMAGE_REDUCTIONS_SUPPORTED */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* OPNGREDUC_H */
|
Loading…
Add table
Add a link
Reference in a new issue