summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6d570e1)
raw | patch | inline | side by side (parent: 6d570e1)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sun, 24 Apr 2016 17:12:23 +0000 (20:12 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sun, 24 Apr 2016 17:12:52 +0000 (20:12 +0300) |
src/sfs/wadcvt.dpr | patch | blob | history | |
src/shared/utils.pas | patch | blob | history |
diff --git a/src/sfs/wadcvt.dpr b/src/sfs/wadcvt.dpr
index 5d1c1f1100afe4689e2c9bd4ccd377a6c90f925c..af1f8d527845c68afde2fd687790a7c8e8f9bdf6 100644 (file)
--- a/src/sfs/wadcvt.dpr
+++ b/src/sfs/wadcvt.dpr
{$APPTYPE CONSOLE}
{$ENDIF}
{$DEFINE UTFEXTRA}
+{.$DEFINE ONELINELOG}
+
+{$IFDEF WINDOWS}
+ {$UNDEF ONELINELOG}
+{$ENDIF}
program __wadcvt__;
uses
var
optConvertATX: Boolean = false;
+ optConvertTGA: Boolean = false;
+ optLoCaseNames: Boolean = false;
-function LoadAnimTexture (wadSt: TStream; wadName: AnsiString): TMemoryStream;
+function convertAnimTexture (wadSt: TStream; wadName: AnsiString): TMemoryStream;
var
WAD: TWADFile = nil;
TextureWAD: PChar = nil;
end;
-{
-procedure processed (count: Cardinal);
+function recompressImageToPng (ist: TStream): TStream;
+var
+ ia: TDynImageDataArray = nil;
+ sto: TMemoryStream = nil;
+ f: Integer;
begin
- //writeln(' read ', count, ' bytes');
+ result := nil;
+ ist.position := 0;
+ GlobalMetadata.ClearMetaItems();
+ GlobalMetadata.ClearMetaItemsForSaving();
+ if not LoadMultiImageFromStream(ist, ia) then exit;
+ try
+ GlobalMetadata.CopyLoadedMetaItemsForSaving;
+ sto := TMemoryStream.Create();
+ if SaveMultiImageToStream('png', sto, ia) then
+ begin
+ sto.position := 0;
+ result := sto;
+ sto := nil;
+ end;
+ finally
+ sto.Free();
+ for f := 0 to High(ia) do FreeImage(ia[f]);
+ end;
end;
-}
// returs crc
var
fs, fo, ast: TStream;
fl: TSFSFileList;
- f: Integer;
+ f, c: Integer;
infname: AnsiString = '';
outfname: AnsiString = '';
dvfn: AnsiString;
newname: AnsiString;
files: array of TFileInfo;
nfo: TFileInfo;
+ nomoreopts: Boolean;
+ arg: AnsiString;
begin
if ParamCount() < 1 then
begin
for f := 1 to ParamCount() do
begin
- if ParamStr(f) = '--apng' then optConvertATX := true
+ arg := ParamStr(f);
+ if length(arg) = 0 then continue;
+ if not nomoreopts and (arg[1] = '-') then
+ begin
+ if arg = '--apng' then optConvertATX := true
+ else if arg = '--tga' then optConvertTGA := true
+ else if arg = '--locase' then optLoCaseNames := true
+ else if arg = '--nocase' then optLoCaseNames := false
+ else if (arg = '--help') or (arg = '-h') then
+ begin
+ writeln('usage: wadcvt [options] file.wad');
+ writeln('options:');
+ writeln(' --apng convert animated textures to APNG format');
+ writeln(' --tga convert Targa images to PNG format');
+{$IFNDEF WINDOWS}
+ writeln(' --locase convert file names to lower case');
+{$ENDIF}
+ Halt(1);
+ end
+ else if arg = '--' then nomoreopts := true
+ else
+ begin
+ writeln('unknown option: "', arg, '"');
+ Halt(1);
+ end;
+ end
else
begin
- if length(infname) = 0 then infname := ParamStr(f)
- else if length(outfname) = 0 then outfname := ParamStr(f)
+ if length(infname) = 0 then infname := arg
+ else if length(outfname) = 0 then outfname := arg
else
begin
writeln('FATAL: too many arguments!');
Imaging.SetOption(ImagingPNGLoadAnimated, 1);
Imaging.SetOption(ImagingGIFLoadAnimated, 1);
+{$IFNDEF WINDOWS}
+ optLoCaseNames := true;
+{$ENDIF}
+
fo := TFileStream.Create(outfname, fmCreate);
try
for f := 0 to fl.Count-1 do
//fs.Free();
//fs := SFSFileOpen(dvfn+'::'+fl[f].fPath+fl[f].fName);
fs.position := 0;
-{$IFNDEF WINDOWS}
+{$IFNDEF ONELINELOG}
write(#13'[', f+1, '/', fl.Count, ']: ', fl[f].fPath, newname, ' ', fs.size, ' ... '#27'[K');
{$ELSE}
write('[', f+1, '/', fl.Count, ']: ', fl[f].fPath, newname, ' ', fs.size, ' ... ');
if optConvertATX and (StrEquCI1251(ExtractFileExt(newname), '.dfwad') or StrEquCI1251(ExtractFileExt(newname), '.wad')) then
begin
//writeln(' ANIMTEXT!');
- ast := LoadAnimTexture(fs, newname);
+ ast := convertAnimTexture(fs, newname);
+ if ast <> nil then
+ begin
+ fs.Free();
+ fs := ast;
+ newname := ChangeFileExt(newname, '.png');
+{$IFNDEF ONELINELOG}
+ write('APNG ');
+{$ENDIF}
+ end;
+ end
+ else if optConvertTGA and (StrEquCI1251(ExtractFileExt(newname), '.tga') or StrEquCI1251(ExtractFileExt(newname), '.bmp')) then
+ begin
+ ast := recompressImageToPng(fs);
if ast <> nil then
begin
fs.Free();
fs := ast;
newname := ChangeFileExt(newname, '.png');
- //writeln(' ANIMTEXT! [', newname, ']');
+{$IFNDEF ONELINELOG}
+ write('PNG ');
+{$ENDIF}
end;
+ fs.position := 0;
end;
- nfo := ZipOne(fo, fl[f].fPath+newname, fs);
+ newname := fl[f].fPath+newname;
+ if optLoCaseNames then for c := 1 to length(newname) do newname[c] := LoCase1251(newname[c]);
+ nfo := ZipOne(fo, newname, fs);
write('DONE');
-{$IFDEF WINDOWS}
+{$IFNDEF ONELINELOG}
writeln;
{$ENDIF}
SetLength(files, length(files)+1);
files[high(files)] := nfo;
end;
-{$IFNDEF WINDOWS}
- writeln(#13, fl.Count, ' files processed'#27'[K');
+{$IFNDEF ONELINELOG}
+ writeln(fl.Count, ' files processed.');
+{$ELSE}
+ writeln(#13, fl.Count, ' files processed.'#27'[K');
{$ENDIF}
writeCentralDir(fo, files);
except
diff --git a/src/shared/utils.pas b/src/shared/utils.pas
index f9d8ffafd927c2715bdf5e81907e0a752c4ae020..eab26fb9e07e53fefc6d68377b6e713866c8d94c 100644 (file)
--- a/src/shared/utils.pas
+++ b/src/shared/utils.pas
function Int64ToStrComma (i: Int64): AnsiString;
function UpCase1251 (ch: Char): Char;
+function LoCase1251 (ch: Char): Char;
// `true` if strings are equal; ignoring case for cp1251
function StrEquCI1251 (const s0, s1: AnsiString): Boolean;
end;
+function LoCase1251 (ch: Char): Char;
+begin
+ if ch < #128 then
+ begin
+ if (ch >= 'A') and (ch <= 'Z') then Inc(ch, 32);
+ end
+ else
+ begin
+ if (ch >= #192) and (ch <= #223) then
+ begin
+ Inc(ch, 32);
+ end
+ else
+ begin
+ case ch of
+ #168, #170, #175: Inc(ch, 16);
+ #161, #178: Inc(ch);
+ end;
+ end;
+ end;
+ result := ch;
+end;
+
+
function StrEquCI1251 (const s0, s1: AnsiString): Boolean;
var
i: Integer;