iff2html working

This commit is contained in:
Jip 2024-05-06 19:40:19 +02:00
parent deaf3327e0
commit 4cd716e94d
89 changed files with 7711 additions and 3 deletions

View 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})

View 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> &ndash; %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) ? " &ndash; " : "", 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) ? " &ndash; " : "", 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> (&minus;1)"); break;
case -2: fprintf(hFile, "<tt>FE FF</tt> (&minus;2)"); break;
case -3: fprintf(hFile, "<tt>FD FF</tt> (&minus;3)"); break;
case -4: fprintf(hFile, "<tt>FC FF</tt> (&minus;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;
}

View 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;
}

View 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);

View 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;
}

View 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 */

File diff suppressed because it is too large Load diff

View 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 */