diff --git a/src/sfs/wadcvt.dpr b/src/sfs/wadcvt.dpr
index 85666cfabe50a5811e8fbb354627f3a6254fd386..d8058379b63784914b93e0b581a934e50bc9a236 100644 (file)
--- a/src/sfs/wadcvt.dpr
+++ b/src/sfs/wadcvt.dpr
sfs,
sfsPlainFS,
sfsZipFS,
- paszlib;
+ paszlib,
+ ImagingTypes, Imaging, ImagingUtility;
procedure processed (count: Cardinal);
// returs crc
-function zpack (ds: TStream; ss: TStream): LongWord;
+function zpack (ds: TStream; ss: TStream; var aborted: Boolean): LongWord;
const
IBSize = 65536;
OBSize = 65536;
rd: Integer;
eof: Boolean;
crc: LongWord;
+ dstp, srcsize: Int64;
begin
result := 0;
+ //aborted := true; exit;
+ aborted := false;
crc := crc32(0, nil, 0);
GetMem(ib, IBSize);
GetMem(ob, OBSize);
ss.position := 0;
+ dstp := ds.position;
+ srcsize := ss.size;
try
zst.next_out := ob;
zst.avail_out := OBSize;
if zst.avail_out < OBSize then
begin
//writeln(' written ', OBSize-zst.avail_out, ' bytes');
+ if ds.position+(OBSize-zst.avail_out)-dstp >= srcsize then
+ begin
+ // this will be overwritten anyway
+ aborted := true;
+ exit;
+ end;
ds.writeBuffer(ob^, OBSize-zst.avail_out);
zst.next_out := ob;
zst.avail_out := OBSize;
if zst.avail_out < OBSize then
begin
//writeln(' .written ', OBSize-zst.avail_out, ' bytes');
+ if ds.position+(OBSize-zst.avail_out)-dstp >= srcsize then
+ begin
+ // this will be overwritten anyway
+ aborted := true;
+ exit;
+ end;
ds.writeBuffer(ob^, OBSize-zst.avail_out);
zst.next_out := ob;
zst.avail_out := OBSize;
buflen: Integer;
f: Integer;
st: string[24];
+ img: string;
begin
result := fname;
if length(ExtractFileExt(fname)) <> 0 then exit;
end;
end;
// targa (stupid hack; this "signature" is not required by specs)
+ {
if buflen >= 18 then
begin
Move((buf+buflen-18)^, (PChar(@st[1]))^, 16);
exit;
end;
end;
+ }
+ // detect image format
+ img := DetermineMemoryFormat(buf, buflen);
+ if length(img) > 0 then
+ begin
+ result := result+'.'+img;
+ exit;
+ end;
+ // check if this is text file
+ if buflen > 16 then
+ begin
+ for f := 0 to buflen-1 do
+ begin
+ if buf[f] = #127 then exit;
+ if buf[f] < #32 then
+ begin
+ if (buf[f] <> #9) and (buf[f] <> #10) and (buf[f] <> #13) then exit;
+ end;
+ end;
+ result := result+'.txt';
+ end;
finally
FreeMem(buf);
end;
sz: Word;
begin
fu := toUtf8(fname);
+ if fu = fname then begin result := nil; exit; end; // no need to write anything
crc := crc32(0, @fname[1], length(fname));
sz := 2+2+1+4+length(fu);
SetLength(result, sz);
const UtfFlags = (1 shl 10); // bit 11
{$ENDIF}
-function ZipOne (ds: TStream; fname: AnsiString; st: TStream): TFileInfo;
+function ZipOne (ds: TStream; fname: AnsiString; st: TStream; dopack: Boolean=true): TFileInfo;
var
- oldofs, nfoofs, pkdpos: Int64;
+ oldofs, nfoofs, pkdpos, rd: Int64;
sign: packed array [0..3] of Char;
+ buf: PChar;
+ bufsz: Integer;
+ aborted: Boolean = false;
{$IFDEF UTFEXTRA}
ef: TByteArray;
{$ENDIF}
result.pkofs := ds.position;
result.size := st.size;
if result.size > 0 then result.method := 8 else result.method := 0;
+ if not dopack then
+ begin
+ result.method := 0;
+ result.pksize := result.size;
+ end;
{$IFDEF UTFEXTRA}
result.name := fname;
ef := buildUtfExtra(result.name);
{$IFDEF UTFEXTRA}
if length(ef) > 0 then ds.writeBuffer(ef[0], length(ef));
{$ENDIF}
- // now write packed data
- if result.size > 0 then
+ if dopack then
+ begin
+ // now write packed data
+ if result.size > 0 then
+ begin
+ pkdpos := ds.position;
+ st.position := 0;
+ result.crc := zpack(ds, st, aborted);
+ result.pksize := ds.position-pkdpos;
+ if {result.pksize >= result.size} aborted then
+ begin
+ // there's no sence to pack this file, so just store it
+ st.position := 0;
+ ds.position := result.pkofs;
+ result.Free();
+ // store it
+ result := ZipOne(ds, fname, st, false);
+ exit;
+ end
+ else
+ begin
+ // fix header
+ oldofs := ds.position;
+ ds.position := nfoofs;
+ writeInt(ds, LongWord(result.crc)); // crc32
+ writeInt(ds, LongWord(result.pksize)); // crc32
+ ds.position := oldofs;
+ end;
+ end;
+ end
+ else
begin
- pkdpos := ds.position;
- st.position := 0;
- result.crc := zpack(ds, st);
- result.pksize := ds.position-pkdpos;
+ bufsz := 1024*1024;
+ GetMem(buf, bufsz);
+ try
+ st.position := 0;
+ result.crc := crc32(0, nil, 0);
+ result.pksize := 0;
+ while result.pksize < result.size do
+ begin
+ rd := result.size-result.pksize;
+ if rd > bufsz then rd := bufsz;
+ st.readBuffer(buf^, rd);
+ ds.writeBuffer(buf^, rd);
+ Inc(result.pksize, rd);
+ result.crc := crc32(result.crc, buf, rd);
+ end;
+ finally
+ FreeMem(buf);
+ end;
// fix header
oldofs := ds.position;
ds.position := nfoofs;
writeInt(ds, LongWord(result.crc)); // crc32
- writeInt(ds, LongWord(result.pksize)); // crc32
ds.position := oldofs;
+ write('(S) ');
end;
end;
//fs.Free();
//fs := SFSFileOpen(dvfn+'::'+fl[f].fPath+fl[f].fName);
fs.position := 0;
- writeln('[', f+1, '/', fl.Count, ']: ', fl[f].fPath, newname, ' ', fs.size);
+{$IFNDEF WINDOWS}
+ 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, ' ... ');
+{$ENDIF}
nfo := ZipOne(fo, fl[f].fPath+newname, fs);
+ write('DONE');
+{$IFDEF WINDOWS}
+ writeln;
+{$ENDIF}
SetLength(files, length(files)+1);
files[high(files)] := nfo;
end;
+{$IFNDEF WINDOWS}
+ writeln(#13, fl.Count, ' files processed'#27'[K');
+{$ENDIF}
writeCentralDir(fo, files);
except
fo.Free();