Multi-thread scan improvement;

Some crashes fixed;
This commit is contained in:
meffi@lab313.ru
2014-02-19 08:48:59 +00:00
parent 20f1dbf7ce
commit 057405ebfe
5 changed files with 166 additions and 162 deletions

View File

@@ -118,6 +118,7 @@ type
LastDir: string;
WaitThread: TEventWaitThread;
function ScanRes: TScanResult;
procedure SetListCount(Count: Integer);
procedure ScanFinished(Sender: TObject);
function CheckForFileOpened(const FileName: string): boolean;
@@ -125,16 +126,11 @@ type
procedure ScanPath(const Path: string);
procedure ScanFile(const FileName: string);
procedure ScanDirectory(const Directory: string);
function CurrentFileName: string;
function CurrentTimPos(Index: Integer): Integer;
function CurrentTimSize(Index: Integer): Integer;
function CurrentTimBitMode(Index: Integer): Byte;
function CurrentTimWidth(Index: Integer): Word;
function CurrentTimHeight(Index: Integer): Word;
function CurrentFileIsImage: boolean;
function CurrentTIM(NewBitMode: Integer = $FF): PTIM;
function CurrentTIMName(Index: Integer): string;
procedure DrawCurrentTIM;
function ListIdx: Integer;
function TimIdx(Index: Integer): TScanTim;
function SelTim(NewBitMode: Integer = $FF): PTIM;
function SelTimName: string;
procedure DrawSelTim;
procedure DrawCurrentCLUT;
procedure UpdateCLUTInfo;
procedure SetCLUTListToNoCLUT;
@@ -271,7 +267,7 @@ end;
procedure TfrmMain.actCloseFileExecute(Sender: TObject);
begin
ScanResult[cbbFiles.ItemIndex].Free;
ScanRes.Free;
ScanResult.Delete(cbbFiles.ItemIndex);
lvList.Items.BeginUpdate;
lvList.Items.Count := 0;
@@ -280,7 +276,7 @@ begin
actTimInfo.Enabled := False;
actTimInfo.Caption := 'TIM Info';
lvList.Column[0].Caption := '# / 0';
DrawCurrentTIM;
DrawSelTim;
DrawCurrentCLUT;
cbbCLUT.Items.BeginUpdate;
@@ -293,9 +289,13 @@ begin
cbbFiles.Items.Delete(cbbFiles.ItemIndex);
cbbFiles.Items.EndUpdate;
cbbFiles.Enabled := cbbFiles.Items.Count <> 0;
CheckButtonsAndMainMenu;
if cbbFiles.Enabled then
begin
cbbFiles.ItemIndex := cbbFiles.Items.Count - 1;
cbbFilesChange(Self);
end;
end;
procedure TfrmMain.actCloseFilesExecute(Sender: TObject);
@@ -322,17 +322,17 @@ var
begin
lblStatus.Caption := sStatusBarTimsExtracting;
FName := ScanResult[cbbFiles.ItemIndex].ScanFile;
IsImage := ScanResult[cbbFiles.ItemIndex].IsImage;
FName := ScanRes.ScanFile;
IsImage := ScanRes.IsImage;
for I := 1 to ScanResult[cbbFiles.ItemIndex].Count do
for I := 1 to ScanRes.Count do
begin
ScanTim := ScanResult[cbbFiles.ItemIndex].ScanTim[I - 1];
ScanTim := TimIdx(I - 1);
OFFSET := ScanTim.Position;
SIZE := ScanTim.Size;
BIT_MODE := ScanTim.BitMode;
TIM_NAME := Format(cAutoExtractionTimFormat, [ExtractFileNameWOext(FName), I, BIT_MODE]);
TIM_NAME := Format(cAutoExtractionTimFormat, [ExtractJustName(FName), I, BIT_MODE]);
Path := IncludeTrailingPathDelimiter(GetStartDir + cExtractedTimsDir);
CreateDir(Path);
@@ -351,11 +351,11 @@ procedure TfrmMain.actExtractTimExecute(Sender: TObject);
var
TIM: PTIM;
begin
dlgSaveTIM.FileName := CurrentTIMName(lvList.Selected.Index);
dlgSaveTIM.FileName := SelTimName;
if not dlgSaveTIM.Execute then Exit;
TIM := CurrentTIM;
TIM := SelTim;
SaveTimToFile(dlgSaveTIM.FileName, TIM);
FreeTIM(TIM);
end;
@@ -376,7 +376,7 @@ begin
if GetFileSizeAPI(dlgOpenFile.FileName) > cTIMMaxSize then Exit;
ReplaceTimInFile(CurrentFileName, dlgOpenFile.FileName, CurrentTimPos(lvList.Selected.Index), CurrentFileIsImage);
ReplaceTimInFile(ScanRes.ScanFile, dlgOpenFile.FileName, TimIdx(ListIdx).Position, ScanRes.IsImage);
lvListClick(Self);
MessageBeep(MB_ICONINFORMATION);
end;
@@ -405,14 +405,14 @@ end;
procedure TfrmMain.actStretchExecute(Sender: TObject);
begin
DrawCurrentTIM;
DrawSelTim;
end;
procedure TfrmMain.actTim2PngExecute(Sender: TObject);
var
FName: string;
begin
FName := CurrentTIMName(lvList.Selected.Index);
FName := SelTimName;
FName := ChangeFileExt(FName, '.png');
dlgSavePNG.FileName := FName;
@@ -432,8 +432,8 @@ var
begin
if actTimInfo.Enabled then
begin
Index := lvList.Selected.Index;
TIM := CurrentTIM;
Index := ListIdx;
TIM := SelTim;
if TIMIsGood(TIM) then
IsGoodTIM := 'YES'
@@ -445,7 +445,7 @@ begin
+ Tab + '%s' + Row + Row +
'HEADER INFO' + Row + 'Version:' + Tab + '%d' + Row + 'BPP:' + Tab + '%d'
+ Row + Row, [CurrentTIMName(Index), Index + 1, CurrentTimPos(Index),
+ Row + Row, [SelTimName, Index + 1, TimIdx(Index).Position,
BppToBitMode(TIM), IsGoodTIM,
GetTimVersion(TIM), GetTimBPP(TIM)]);
@@ -487,77 +487,81 @@ end;
procedure TfrmMain.cbbFilesChange(Sender: TObject);
begin
lvList.Items.Count := ScanResult[cbbFiles.ItemIndex].Count;
lvList.Items.Count := ScanRes.Count;
lvList.Column[0].Caption := Format('# / %d', [lvList.Items.Count]);
lvList.Invalidate;
lvListClick(Self);
lvList.Items[0].Selected := True;
lvList.Items[0].Focused := True;
lvList.SetFocus;
end;
procedure TfrmMain.cbbTransparenceModeChange(Sender: TObject);
begin
DrawCurrentTIM;
DrawSelTim;
end;
procedure TfrmMain.cbbBitModeChange(Sender: TObject);
begin
DrawCurrentTIM;
DrawSelTim;
end;
procedure TfrmMain.cbbCLUTChange(Sender: TObject);
begin
DrawCurrentTIM;
DrawSelTim;
DrawCurrentCLUT;
end;
function TfrmMain.CheckForFileOpened(const FileName: string): boolean;
var
I: Integer;
begin
Result := (cbbFiles.Items.IndexOf(ExtractFileName(FileName)) <> -1);
Result := False;
for I := 1 to ScanResult.Count do
if ExtractFileName(ScanResult[I - 1].ScanFile) = ExtractFileName(FileName) then
begin
Result := True;
Exit;
end;
end;
procedure TfrmMain.CheckButtonsAndMainMenu;
begin
actCloseFile.Enabled := (cbbFiles.Items.Count <> 0);
actCloseFiles.Enabled := (cbbFiles.Items.Count <> 0);
actTim2Png.Enabled := (PNG^ <> nil);
cbbFiles.Enabled := (cbbFiles.Items.Count <> 0);
lvList.Enabled := cbbFiles.Enabled;
actExtractList.Enabled := cbbFiles.Enabled;
actCloseFile.Enabled := cbbFiles.Enabled;
actCloseFiles.Enabled := cbbFiles.Enabled;
actReplaceTim.Enabled := (lvList.SelCount = 1);
actExtractTim.Enabled := (lvList.SelCount = 1);
actTim2Png.Enabled := (PNG^ <> nil) and actReplaceTim.Enabled;
actExtractTim.Enabled := actReplaceTim.Enabled;
cbbCLUT.Enabled := actReplaceTim.Enabled;
cbbTransparenceMode.Enabled := actReplaceTim.Enabled;
cbbBitMode.Enabled := actReplaceTim.Enabled;
chkStretch.Enabled := actReplaceTim.Enabled;
end;
function TfrmMain.CurrentTIM(NewBitMode: Integer = $FF): PTIM;
function TfrmMain.SelTIM(NewBitMode: Integer = $FF): PTIM;
var
OFFSET, SIZE: Integer;
P: Integer;
begin
Result := nil;
if lvList.Selected = nil then Exit;
OFFSET := CurrentTimPos(lvList.Selected.Index);
SIZE := CurrentTimSize(lvList.Selected.Index);
Result := LoadTimFromFile(CurrentFileName, OFFSET, CurrentFileIsImage, SIZE);
P := TimIdx(ListIdx).Position;
Result := LoadTimFromFile(ScanRes.ScanFile, P, ScanRes.IsImage, TimIdx(ListIdx).Size);
if NewBitMode = $FF then Exit;
Result^.HEAD^.bBPP := NewBitMode;
end;
function TfrmMain.CurrentTimBitMode(Index: Integer): Byte;
function TfrmMain.SelTimName: string;
begin
Result := ScanResult[cbbFiles.ItemIndex].ScanTim[Index].BitMode;
end;
function TfrmMain.CurrentTimHeight(Index: Integer): Word;
begin
Result := ScanResult[cbbFiles.ItemIndex].ScanTim[Index].Height;
end;
function TfrmMain.CurrentTIMName(Index: Integer): string;
begin
Result := Format(cAutoExtractionTimFormat, [ExtractFileNameWOext(CurrentFileName), Index + 1, CurrentTimBitMode(Index)]);
end;
function TfrmMain.CurrentTimWidth(Index: Integer): Word;
begin
Result := ScanResult[cbbFiles.ItemIndex].ScanTim[Index].Width;
Result := Format(cAutoExtractionTimFormat, [ExtractJustName(ScanRes.ScanFile), ListIdx + 1, TimIdx(ListIdx).BitMode]);
end;
procedure TfrmMain.DrawCurrentCLUT;
@@ -566,7 +570,7 @@ var
begin
ClearGrid(@grdCurrCLUT);
TIM := CurrentTIM;
TIM := SelTim;
if TIM = nil then
begin
grdCurrCLUT.ColCount := 1;
@@ -587,7 +591,7 @@ begin
FreeTIM(TIM);
end;
procedure TfrmMain.DrawCurrentTIM;
procedure TfrmMain.DrawSelTim;
var
TIM: PTIM;
Index: Integer;
@@ -604,7 +608,7 @@ begin
mode := $FF;
end;
TIM := CurrentTIM(mode);
TIM := SelTim(mode);
if TIM = nil then Exit;
if PNG^ <> nil then
@@ -626,24 +630,9 @@ begin
pbTim.Invalidate;
end;
function TfrmMain.CurrentFileIsImage: boolean;
function TfrmMain.ScanRes: TScanResult;
begin
Result := ScanResult[cbbFiles.ItemIndex].IsImage;
end;
function TfrmMain.CurrentFileName: string;
begin
Result := ScanResult[cbbFiles.ItemIndex].ScanFile;
end;
function TfrmMain.CurrentTimPos(Index: Integer): Integer;
begin
Result := ScanResult[cbbFiles.ItemIndex].ScanTim[Index].Position;
end;
function TfrmMain.CurrentTimSize(Index: Integer): Integer;
begin
Result := ScanResult[cbbFiles.ItemIndex].ScanTim[Index].Size;
Result := ScanResult[cbbFiles.ItemIndex];
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
@@ -657,7 +646,15 @@ begin
end;
procedure TfrmMain.FormCreate(Sender: TObject);
var
hGridRect: TGridRect;
begin
hGridRect.Top := -1;
hGridRect.Left := -1;
hGridRect.Right := -1;
hGridRect.Bottom := -1;
grdCurrClut.Selection := hGridRect;
ScanThreads := TList<TScanThread>.Create;
ScanResult := TList<TScanResult>.Create;
New(PNG);
@@ -681,7 +678,7 @@ var
R, G, B: Byte;
CLUT_COLOR: TCLUT_COLOR;
begin
TIM := CurrentTIM;
TIM := SelTim;
if TIM = nil then Exit;
SELECTED_CELL := grdCurrCLUT.Row * grdCurrCLUT.ColCount + grdCurrCLUT.Col;
@@ -725,11 +722,11 @@ begin
WriteCLUTColor(TIM, CLUT_NUM, SELECTED_CELL, CLUT_COLOR);
ReplaceTimInFileFromMemory(CurrentFileName, TIM, CurrentTimPos(lvList.Selected.Index), CurrentFileIsImage);
ReplaceTimInFileFromMemory(ScanRes.ScanFile, TIM, TimIdx(ListIdx).Position, ScanRes.IsImage);
FreeTIM(TIM);
DrawCurrentTIM;
DrawSelTim;
DrawCurrentCLUT;
end;
@@ -738,7 +735,7 @@ procedure TfrmMain.grdCurrClutDrawCell(Sender: TObject; ACol, ARow: Integer;
var
TIM: PTIM;
begin
TIM := CurrentTIM;
TIM := SelTim;
if TIM = nil then Exit;
if not TIMHasCLUT(TIM) then
@@ -752,6 +749,11 @@ begin
FreeTIM(TIM);
end;
function TfrmMain.ListIdx: Integer;
begin
Result := lvList.Selected.Index;
end;
procedure TfrmMain.ScanDirectory(const Directory: string);
var
sRec: TSearchRec;
@@ -775,33 +777,34 @@ begin
end;
procedure TfrmMain.lvListClick(Sender: TObject);
var
OFFSET, SIZE: Integer;
begin
if (lvList.Selected = nil) then Exit;
if (lvList.Items.Count = 0) then Exit;
cbbBitMode.ItemIndex := 0;
OFFSET := CurrentTimPos(lvList.Selected.Index);
SIZE := CurrentTimSize(lvList.Selected.Index);
UpdateCLUTInfo;
DrawCurrentTIM;
DrawSelTim;
DrawCurrentCLUT;
actTimInfo.Caption := Format('[OFFSET: 0x%x | SIZE: 0x%x]', [OFFSET, SIZE]);
actTimInfo.Caption := Format('[OFFSET: 0x%x | SIZE: 0x%x]', [TimIdx(ListIdx).Position, TimIdx(ListIdx).Size]);
actTimInfo.Enabled := True;
CheckButtonsAndMainMenu;
end;
procedure TfrmMain.lvListData(Sender: TObject; Item: TListItem);
var
W, H: Word;
begin
if cbbFiles.ItemIndex = -1 then Exit;
if ScanResult[cbbFiles.ItemIndex] = nil then Exit;
W := TimIdx(Item.Index).Width;
H := TimIdx(Item.Index).Height;
Item.Caption := Format('%.6d', [Item.Index + 1]);
Item.SubItems.Add(Format('%dx%d', [CurrentTimWidth(Item.Index), CurrentTimHeight(Item.Index)]));
Item.SubItems.Add(Format('%d', [CurrentTimBitMode(Item.Index)]));
Item.SubItems.Add(Format('%dx%d', [W, H]));
Item.SubItems.Add(Format('%d', [TimIdx(Item.Index).BitMode]));
end;
procedure TfrmMain.lvListSelectItem(Sender: TObject; Item: TListItem;
@@ -817,13 +820,17 @@ begin
lvList.Column[0].Caption := Format('# / %d', [Count]);
end;
function TfrmMain.TimIdx(Index: Integer): TScanTim;
begin
Result := ScanRes.ScanTim[Index];
end;
procedure TfrmMain.ScanFile(const FileName: string);
begin
if CheckForFileOpened(FileName) then
begin
cbbFiles.ItemIndex := cbbFiles.Items.IndexOf(ExtractFileName(FileName));
cbbFiles.ItemIndex := cbbFiles.Items.IndexOf(FileName);
btnStopScan.Enabled := False;
cbbFiles.Enabled := True;
CheckButtonsAndMainMenu;
Exit;
end;
@@ -833,36 +840,26 @@ begin
ScanThreads.Last.Priority := tpNormal;
ScanThreads.Last.OnTerminate := ScanFinished;
if not ScanThreads.First.Started then
ScanThreads.First.Start;
ScanThreads.Last.Start;
end;
procedure TfrmMain.ScanFinished(Sender: TObject);
begin
ScanThreads.Delete(0);
ScanThreads.Remove(Sender as TScanThread);
if ScanResult.Last.Count > 0 then
cbbFiles.Items.Add(ScanResult.Last.ScanFile)
else
ScanResult.Delete(ScanResult.Count - 1);
if ScanThreads.Count <> 0 then Exit;
if ScanThreads.Count > 0 then
if ScanResult.Count <> 0 then SetListCount(ScanResult.Last.Count);
CheckButtonsAndMainMenu;
if cbbFiles.Enabled then
begin
ScanThreads.First.Start;
Exit;
cbbFiles.ItemIndex := cbbFiles.Items.Count - 1;
cbbFilesChange(Self);
end;
SetListCount(ScanResult.Last.Count);
cbbFiles.ItemIndex := cbbFiles.Items.Count - 1;
lblStatus.Caption := '';
cbbFiles.Enabled := True;
pnlList.Enabled := True;
actExtractList.Enabled := True;
btnStopScan.Enabled := False;
lvList.Items[0].Selected := True;
lvList.Items[0].Focused := True;
lvList.SetFocus;
end;
procedure TfrmMain.ScanPath(const Path: string);
@@ -889,7 +886,7 @@ var
TIM: PTIM;
I, CLUTS: Word;
begin
TIM := CurrentTIM;
TIM := SelTim;
if TIM = nil then Exit;
CLUTS := GetTIMClutsCount(TIM);