diff --git a/tim2view.lpi b/tim2view.lpi index f877305..9f049ea 100644 --- a/tim2view.lpi +++ b/tim2view.lpi @@ -23,12 +23,188 @@ - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -143,12 +319,14 @@ + - + + diff --git a/tim2view.lps b/tim2view.lps index 6e6bb93..9046247 100644 --- a/tim2view.lps +++ b/tim2view.lps @@ -3,13 +3,13 @@ - - + + - + @@ -25,8 +25,8 @@ - - + + @@ -55,7 +55,7 @@ - + @@ -65,8 +65,8 @@ - - + + @@ -76,8 +76,8 @@ - - + + @@ -96,7 +96,7 @@ - + @@ -109,8 +109,8 @@ - - + + @@ -132,8 +132,8 @@ - - + + @@ -149,10 +149,10 @@ - + - + @@ -160,53 +160,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + @@ -225,24 +185,38 @@ - - + + - - + + - - + + + + + + + + + + + + + + + + diff --git a/tim2view.res b/tim2view.res index cc4ac69..3c0edff 100644 Binary files a/tim2view.res and b/tim2view.res differ diff --git a/todos.inc b/todos.inc index 15283c5..45a6f01 100644 --- a/todos.inc +++ b/todos.inc @@ -1,2 +1 @@ { TODO : Zooming? } -{ TODO 1 : Export: save as paletted PNG. Import: find matched colors in CLUT when importing } diff --git a/ucdimage.pas b/ucdimage.pas index bc7622e..bd3597a 100644 --- a/ucdimage.pas +++ b/ucdimage.pas @@ -78,14 +78,12 @@ function GetImageScan(const FileName: string): Boolean; pFile := GetMemory(cSectorHeaderSize); - try - tmp := TFileStream.Create(Utf8ToSys(FileName), fmOpenRead or fmShareDenyWrite); - tmp.Read(pFile^[0], cSectorHeaderSize); - Result := ((Sz mod cSectorSize) = 0) and (CompareMem(@cSectorHeader, pFile, cSectorHeaderSize)); - finally - tmp.free; - FreeMemory(pFile); - end; + tmp := TFileStream.Create(Utf8ToSys(FileName), fmOpenRead or fmShareDenyWrite); + tmp.Read(pFile^[0], cSectorHeaderSize); + Result := ((Sz mod cSectorSize) = 0) and (CompareMem(@cSectorHeader, pFile, cSectorHeaderSize)); + + tmp.free; + FreeMemory(pFile); end; procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; @@ -124,7 +122,7 @@ procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; FillChar(Sector, cSectorSize, 0); sImageStream.Read(Sector, cSectorSize); - sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning); + sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning); Move(Sector.dwAddress[0], SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize); FillChar(Sector.dwAddress[0], cSectorAddressSize + cSectorModeSize, 0); @@ -140,7 +138,7 @@ procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; sImageStream.Seek(TimStartSectorPos, soBeginning); sImageStream.Write(Sector, cSectorSize); - sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning); + sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning); sImageStream.Write(SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize); Inc(TimStartSectorPos, cSectorSize); @@ -167,7 +165,7 @@ procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; sImageStream.Seek(TimStartSectorPos, soBeginning); sImageStream.Write(Sector, cSectorSize); - sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning); + sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning); sImageStream.Write(SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize); Inc(TimStartSectorPos, cSectorSize); @@ -195,7 +193,7 @@ procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; sImageStream.Seek(TimStartSectorPos, soBeginning); sImageStream.Write(Sector, cSectorSize); - sImageStream.Seek(TimStartSectorPos + cSectorHeaderSize, soBeginning); + sImageStream.Seek(Int64(TimStartSectorPos) + Int64(cSectorHeaderSize), soBeginning); sImageStream.Write(SecAddrAndMode[0], cSectorAddressSize + cSectorModeSize); end; end; diff --git a/ucommon.pas b/ucommon.pas index 9ba0167..6ab8156 100644 --- a/ucommon.pas +++ b/ucommon.pas @@ -3,7 +3,7 @@ interface const - cProgramName = 'Tim2View SVN.r70 by [Lab 313] (for ' + + cProgramName = 'Tim2View SVN.r74 by [Lab 313] (for ' + {$IFDEF Linux}'Linux' + {$IFEND} {$IFDEF Darwin}'Mac OS X' + {$IFEND} {$IFDEF Windows}'Windows' + {$IFEND} diff --git a/udrawtim.pas b/udrawtim.pas index c88d81b..1f1e7c0 100644 --- a/udrawtim.pas +++ b/udrawtim.pas @@ -92,17 +92,17 @@ procedure PrepareClut(TIM: PTIM; CLUT_NUM: Integer; Pal: PFPPalette; TranspMode: CC := GetCLUTColor(TIM, CLUT_NUM, I - 1); if I <= COUNT then begin - R := CC.R; - G := CC.G; - B := CC.B; + R := CC.R + ((I - 1) and %00000011) shl 1 + CC.STP; + G := CC.G + ((I - 1) and %00011100) shr 2; + B := CC.B + ((I - 1) and %11100000) shr 5; A := CC.STP; end else begin - R := 0; - G := 0; - B := 0; - A := 1; + R := ((I - 1) and %00000011) shl 1 + CC.STP; + G := ((I - 1) and %00011100) shr 2; + B := ((I - 1) and %11100000) shr 5; + A := 0; end; FC := BGRAToFPColor(BGRA(R, G, B, A)); @@ -209,7 +209,8 @@ procedure Tim2Png(TIM: PTIM; CLUT_NUM: Integer; Surf: PDrawSurf; TranspMode: Byt for X := 1 to RW do begin case TIM^.HEAD^.bBPP of - cTIM4C, cTIM4NC, cTIM8C, cTIM8NC: Surf^.Pixels[X - 1, Y - 1] := INDEXES^[IDX] mod COLORS; + cTIM4C, cTIM4NC, cTIM8C, cTIM8NC: + Surf^.Pixels[X - 1, Y - 1] := INDEXES^[IDX] mod COLORS; cTIM16C, cTIM16NC, cTIMMix: begin CW := 0; @@ -243,7 +244,7 @@ procedure Png2Tim(Image: PDrawSurf; Dest: PTIM); var IW, IH, X, Y, CW: Word; TData: PTIMDataArray; - IDX, POS, C: Integer; + POS: Integer; CC: TCLUT_COLOR; PC: TBGRAPixel; FC: TFPColor; @@ -253,33 +254,29 @@ procedure Png2Tim(Image: PDrawSurf; Dest: PTIM); IH := Image^.Height; TData := @Dest^.DATA^[SizeOf(TTIMHeader) + GetTIMCLUTSize(Dest) + SizeOf(TIMAGEHeader)]; - { TODO : Fix colors finding. } POS := 0; - for Y := 1 to IH do + for Y := 0 to IH-1 do case Dest^.HEAD^.bBPP of cTIM4C, cTIM4NC: - for X := 1 to (IW div 2) do + for X := 0 to (IW div 2)-1 do begin - IDX := Image^.Pixels[X - 1, Y - 1]; - TData^[POS] := (IDX and $F); - IDX := Image^.Pixels[X, Y - 1]; - TData^[POS] := TData^[0] + (IDX and $F0); + TData^[POS] := Byte(Image^.Pixels[X * 2, Y]); + TData^[POS] := (Byte(Image^.Pixels[X * 2 + 1, Y]) shl 4) and $F0 + TData^[POS]; Inc(POS); end; cTIM8C, cTIM8NC: - for X := 1 to IW do + for X := 0 to IW-1 do begin - C := Image^.Pixels[X - 1, Y - 1]; - TData^[POS] := Byte(C); + TData^[POS] := Byte(Image^.Pixels[X, Y]); Inc(POS); end; cTIM16C, cTIM16NC: - for X := 1 to IW do + for X := 0 to IW-1 do begin - FC := Image^.Colors[X - 1, Y - 1]; + FC := Image^.Colors[X, Y]; CC.STP := StpFromAlpha(@FC); PC := FPColorToBGRA(FC); CC.R := PC.red; @@ -293,16 +290,16 @@ procedure Png2Tim(Image: PDrawSurf; Dest: PTIM); end; cTIM24C, cTIM24NC: - for X := 1 to IW do + for X := 0 to IW-1 do begin - FC := Image^.Colors[X - 1, Y - 1]; + FC := Image^.Colors[X, Y]; PC := FPColorToBGRA(FC); CD := (PC.blue shl 16) + (PC.green shl 8) + PC.red; Move(CD, TData^[POS], 3); Inc(POS, 3); - if Odd(IW) and ((IW - X) = 0) then + if Odd(IW) and ((IW - X + 1) = 0) then begin TData^[POS] := 0; Inc(POS); diff --git a/uexportimport.pas b/uexportimport.pas index aa9ede2..a369545 100644 --- a/uexportimport.pas +++ b/uexportimport.pas @@ -3,55 +3,44 @@ interface uses - FPWritePNG, zstream, udrawtim; + udrawtim; -procedure SaveImage(Surf: PDrawSurf; Indexed: Boolean; const FileName: string; PngWriter: TFPWriterPNG); -function LoadImage(const FileName: string; var Surf: PDrawSurf): Boolean; -function CreatePngWriter(ForExport: Boolean): TFPWriterPNG; +procedure SaveImage(const FileName: string; Surf: PDrawSurf; Indexed: Boolean); +function LoadImage(const FileName: string): PDrawSurf; implementation uses - FPReadPNG, Classes, BGRABitmap, FileUtil, sysutils; + FPReadPNG, Classes, BGRABitmap, FileUtil, sysutils, zstream, FPWritePNG; -function CreatePngWriter(ForExport: Boolean): TFPWriterPNG; +procedure SaveImage(const FileName: string; Surf: PDrawSurf; Indexed: Boolean); +var + Writer: TFPWriterPNG; begin - Result := TFPWriterPNG.Create; - Result.CompressionLevel := clnone; - Result.WordSized := False; - Result.UseAlpha := (not ForExport); -end; + Writer := TFPWriterPNG.Create; + Writer.CompressionLevel := clnone; + Writer.UseAlpha := True; -procedure SaveImage(Surf: PDrawSurf; Indexed: Boolean; const FileName: string; PngWriter: TFPWriterPNG); -begin - PngWriter.Indexed := Indexed; - Surf^.SaveToFileUTF8(FileName, PngWriter); + Writer.Indexed := Indexed; + Surf^.SaveToFileUTF8(FileName, Writer); + Writer.Free; end; -function LoadImage(const FileName: string; var Surf: PDrawSurf): Boolean; +function LoadImage(const FileName: string): PDrawSurf; var Reader: TFPReaderPNG; - Image: TFileStream; + Stream: TFileStream; begin - Result := False; - - try Reader := TFPReaderPNG.Create; - Image := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite); - Result := Reader.CheckContents(Image); - - if Result then - begin - New(Surf); - Surf^ := TBGRABitmap.Create; - Image.Position := 0; - Surf^.LoadFromStream(Image); - end; - - finally - Image.Free; - Reader.Free; - end; + Stream := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite); + Stream.Position := 0; + + New(Result); + Result^ := TBGRABitmap.Create; + Result^.UsePalette := True; + Reader.ImageRead(Stream, Result^); + Stream.Free; + Reader.Free; end; end. diff --git a/umain.lfm b/umain.lfm index 38bf6a1..dd7606a 100644 --- a/umain.lfm +++ b/umain.lfm @@ -828,12 +828,12 @@ object frmMain: TfrmMain DefaultExt = '.bin' Filter = 'All Files (*.*)|*.*' Options = [ofHideReadOnly, ofNoChangeDir, ofAllowMultiSelect, ofNoNetworkButton, ofEnableSizing, ofForceShowHidden] - left = 576 - top = 448 + left = 560 + top = 112 end object mmMain: TMainMenu - left = 352 - top = 448 + left = 336 + top = 112 object mnFile: TMenuItem Caption = '&File' object mnScanFile: TMenuItem @@ -863,16 +863,13 @@ object frmMain: TfrmMain object mnReplaceIn: TMenuItem Action = actReplaceTim end - object mnSaveToPNG: TMenuItem - Action = actTim2Png + object MenuItem1: TMenuItem + Caption = '-' end - end - object mnEdit: TMenuItem - Caption = '&Edit' - object mnExportTim: TMenuItem + object mnSaveToPNG: TMenuItem Action = actPngExport end - object mnImport: TMenuItem + object mnImportPng: TMenuItem Action = actPngImport end end @@ -912,17 +909,17 @@ object frmMain: TfrmMain Title = 'Please, select filename for PNG...' DefaultExt = '.png' Filter = 'Portable Network Graphics (*.png)|*.png' - Options = [ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing] - left = 688 - top = 448 + Options = [ofOverwritePrompt, ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing] + left = 672 + top = 112 end object dlgSaveTIM: TSaveDialog Title = 'Please, select where to save TIM file...' DefaultExt = '.tim' Filter = 'PSX TIM Files (*.tim)|*.tim|All Files (*.*)|*.*' Options = [ofOverwritePrompt, ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing] - left = 608 - top = 448 + left = 592 + top = 112 end object dlgColor: TColorDialog Color = clBlack @@ -948,12 +945,12 @@ object frmMain: TfrmMain 'ColorS=F0FBFF' 'ColorT=A4A0A0' ) - left = 496 - top = 448 + left = 480 + top = 112 end object actList: TActionList - left = 416 - top = 448 + left = 400 + top = 112 object actScanFile: TAction Caption = 'Scan &File...' OnExecute = actScanFileExecute @@ -984,14 +981,18 @@ object frmMain: TfrmMain OnExecute = actExtractTimExecute ShortCut = 113 end + object actPngImport: TAction + Caption = '&Import PNG...' + OnExecute = actPngImportExecute + end object actReplaceTim: TAction Caption = '&Replace TIM...' OnExecute = actReplaceTimExecute ShortCut = 114 end - object actTim2Png: TAction - Caption = 'Save as &PNG...' - OnExecute = actTim2PngExecute + object actPngExport: TAction + Caption = 'Export &PNG...' + OnExecute = actPngExportExecute ShortCut = 115 end object actOpenRepo: TAction @@ -1043,18 +1044,10 @@ object frmMain: TfrmMain Caption = '&Background Color' OnExecute = actChangeBackColorExecute end - object actPngImport: TAction - Caption = '&Import PNG to TIM...' - OnExecute = actPngImportExecute - end - object actPngExport: TAction - Caption = '&Export TIM to PNG...' - OnExecute = actTim2PngExecute - end end object pmList: TPopupMenu - left = 448 - top = 448 + left = 432 + top = 112 object ExtractTIM1: TMenuItem Action = actExtractTim end @@ -1062,7 +1055,7 @@ object frmMain: TfrmMain Action = actReplaceTim end object SaveasPNG1: TMenuItem - Action = actTim2Png + Action = actPngExport end object N7: TMenuItem Caption = '-' @@ -1075,10 +1068,10 @@ object frmMain: TfrmMain end end object pmImage: TPopupMenu - left = 384 - top = 448 + left = 368 + top = 112 object mnSaveAsPng: TMenuItem - Action = actTim2Png + Action = actPngExport end object mnSaveAsTim: TMenuItem Action = actExtractTim @@ -1096,15 +1089,15 @@ object frmMain: TfrmMain end object dlgSelectDir: TSelectDirectoryDialog Options = [ofNoChangeDir, ofNoNetworkButton, ofEnableSizing, ofViewDetail] - left = 528 - top = 448 + left = 512 + top = 112 end object dlgOpenPNG: TOpenPictureDialog Title = 'Please, select PNG...' DefaultExt = '.png' Filter = 'Portable Network Graphics (*.png)|*.png' Options = [ofHideReadOnly, ofNoChangeDir, ofNoNetworkButton, ofEnableSizing] - left = 656 - top = 448 + left = 640 + top = 112 end end diff --git a/umain.pas b/umain.pas index af418b0..9588975 100644 --- a/umain.pas +++ b/umain.pas @@ -28,7 +28,6 @@ TfrmMain = class(TForm) actExtractTIMs: TAction; actChangeFile: TAction; actChangeBackColor: TAction; - actPngExport: TAction; actPngImport: TAction; actStopScan: TAction; actOpenLab: TAction; @@ -39,7 +38,7 @@ TfrmMain = class(TForm) actScanFile: TAction; actList: TActionList; actStretch: TAction; - actTim2Png: TAction; + actPngExport: TAction; btnExtractAllTims: TButton; btnExtractPNGs: TButton; btnShowClut: TButton; @@ -57,9 +56,8 @@ TfrmMain = class(TForm) imgTim: TImage; lblStatus: TLabel; lvList: TListView; - mnImport: TMenuItem; - mnExportTim: TMenuItem; - mnEdit: TMenuItem; + MenuItem1: TMenuItem; + mnImportPng: TMenuItem; mnChangeBackColor2: TMenuItem; N8: TMenuItem; mnChangeBackColor: TMenuItem; @@ -126,7 +124,7 @@ TfrmMain = class(TForm) procedure actScanFileExecute(Sender: TObject); procedure actStopScanExecute(Sender: TObject); procedure actStretchExecute(Sender: TObject); - procedure actTim2PngExecute(Sender: TObject); + procedure actPngExportExecute(Sender: TObject); procedure btnShowClutClick(Sender: TObject); procedure cbbBitModeChange(Sender: TObject); procedure cbbTranspModeChange(Sender: TObject); @@ -156,9 +154,8 @@ TfrmMain = class(TForm) function FGetTimInfoByIdx(Index: Integer): TTimInfo; property TimInfoByIdx[Index: Integer]: TTimInfo read FGetTimInfoByIdx; //Info about tim by index - function FGetSelectedTim(NewBitMode: Integer): PTIM; - property SelectedTim: PTIM Index $FF read FGetSelectedTim; //Tim, selected in list - property SelectedTimInMode[NewBitMode: Integer]: PTIM read FGetSelectedTim; //Tim, selected in list + function FGetSelectedTim: PTIM; + property SelectedTimInMode: PTIM read FGetSelectedTim; //Tim, selected in list procedure ScanPath(const Path: string); procedure ScanFile(const FileName: string); @@ -188,7 +185,7 @@ TfrmMain = class(TForm) implementation -uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf, uexportimport, FPWritePNG +uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf, uexportimport {$IFDEF windows} ,registry @@ -237,21 +234,18 @@ procedure TfrmMain.actStretchExecute(Sender: TObject); UpdateTim(True, False, False); end; -procedure TfrmMain.actTim2PngExecute(Sender: TObject); +procedure TfrmMain.actPngExportExecute(Sender: TObject); var TIM: PTIM; - Writer: TFPWriterPNG; begin - TIM := SelectedTim; + TIM := SelectedTimInMode; if TIM = nil then Exit; dlgSavePNG.FileName := FormatPngName(SelectedScanResult.ScanFile, TIM^.dwTimNumber, SelectedTimInfo.BitMode, cbbCLUT.ItemIndex); if not dlgSavePNG.Execute then Exit; - Writer := CreatePngWriter((Sender as TAction) = actPngExport); - SaveImage(Surf, TIMisIndexed(TIM), dlgSavePNG.FileName, Writer); - Writer.Free; + SaveImage(dlgSavePNG.FileName, Surf, TIMisIndexed(TIM)); FreeTIM(TIM); {$IFDEF Linux}FpChmod(dlgSavePNG.FileName, &777){$IFEND} end; @@ -265,6 +259,17 @@ procedure TfrmMain.btnShowClutClick(Sender: TObject); procedure TfrmMain.cbbBitModeChange(Sender: TObject); begin + case cbbBitMode.ItemIndex of + 1: cbbBitMode.Tag := NativeInt(cTIM4C); + 2: cbbBitMode.Tag := NativeInt(cTIM4NC); + 3: cbbBitMode.Tag := NativeInt(cTIM8C); + 4: cbbBitMode.Tag := NativeInt(cTIM8NC); + 5: cbbBitMode.Tag := NativeInt(cTIM16NC); + 6: cbbBitMode.Tag := NativeInt(cTIM24NC); + else + cbbBitMode.Tag := NativeInt($FF); + end; + UpdateTim(True, False, False); end; @@ -284,7 +289,7 @@ procedure TfrmMain.actChangeFileExecute(Sender: TObject); lvList.Items[0].Focused := True; lvList.Items[0].Selected := True; - ShowTim; + //ShowTim; end; procedure TfrmMain.actAboutExecute(Sender: TObject); @@ -377,18 +382,15 @@ procedure TfrmMain.actExtractPNGsExecute(Sender: TObject); IsImage: Boolean; ScanTim: TTimInfo; TIM: PTIM; - Surf_: PDrawSurf; - Writer: TFPWriterPNG; + PNG: PDrawSurf; begin lblStatus.Caption := sStatusBarPngsExtracting; FName := SelectedScanResult.ScanFile; IsImage := SelectedScanResult.IsImage; - New(Surf_); - Surf_^ := nil; - - Writer := CreatePngWriter(False); + New(PNG); + PNG^ := nil; pbProgress.Position := 0; pbProgress.Max := SelectedScanResult.Count; @@ -405,21 +407,20 @@ procedure TfrmMain.actExtractPNGsExecute(Sender: TObject); CreateDirUTF8(Path); TIM := LoadTimFromFile(FName, OFFSET, IsImage, SIZE); - Tim2Png(TIM, cbbCLUT.ItemIndex, Surf_, cbbTranspMode.ItemIndex); + Tim2Png(TIM, cbbCLUT.ItemIndex, PNG, cbbTranspMode.ItemIndex); Path := Path + FormatPngName(FName, I - 1, BIT_MODE, 0); - SaveImage(Surf_, TIMisIndexed(TIM), Path, Writer); + SaveImage(Path, PNG, TIMisIndexed(TIM)); {$IFDEF Linux}FpChmod(Path, &777){$IFEND} - Surf_^.Free; - Surf_^ := nil; + PNG^.Free; + PNG^ := nil; FreeTIM(TIM); pbProgress.Position := I; Application.ProcessMessages; end; - Dispose(Surf_); - Writer.Free; + Dispose(PNG); lblStatus.Caption := sStatusBarExtracted; pbProgress.Position := 0; end; @@ -432,7 +433,7 @@ procedure TfrmMain.actExtractTimExecute(Sender: TObject); if not dlgSaveTIM.Execute then Exit; - TIM := SelectedTim; + TIM := SelectedTimInMode; SaveTimToFile(dlgSaveTIM.FileName, TIM); {$IFDEF Linux}FpChmod(dlgSaveTIM.FileName, &777){$IFEND} FreeTIM(TIM); @@ -495,13 +496,12 @@ procedure TfrmMain.actPngImportExecute(Sender: TObject); ScanRes: TScanResult; begin if not dlgOpenPNG.Execute then Exit; - if not LoadImage(dlgOpenPNG.FileName, Image) then Exit; - TIM := SelectedTim; + TIM := SelectedTimInMode; if TIM = nil then Exit; + Image := LoadImage(dlgOpenPNG.FileName); Png2Tim(Image, TIM); - SaveTimToFile('test.tim', TIM); ScanRes := SelectedScanResult; ReplaceTimInFileFromMemory(ScanRes.ScanFile, TIM, SelectedTimInfo.Position, ScanRes.IsImage); ShowTim; @@ -561,6 +561,8 @@ procedure TfrmMain.FormCreate(Sender: TObject); begin Settings := TSettings.Create(ExtractFilePath(ParamStrUTF8(0))); + cbbBitMode.Tag := NativeInt($FF); + actStretch.Checked := Settings.StretchMode; cbbTranspMode.ItemIndex := Settings.TranspMode; LastDir := Settings.LastDir; @@ -598,7 +600,7 @@ procedure TfrmMain.grdClutDblClick(Sender: TObject); R, G, B: Byte; CLUT_COLOR: TCLUT_COLOR; begin - TIM := SelectedTim; + TIM := SelectedTimInMode; if TIM = nil then Exit; SELECTED_CELL := grdClut.Row * grdClut.ColCount + grdClut.Col; @@ -654,7 +656,7 @@ procedure TfrmMain.grdClutDrawCell(Sender: TObject; aCol, aRow: Integer; var TIM: PTIM; begin - TIM := SelectedTim; + TIM := SelectedTimInMode; if TIM = nil then Exit; if not TIMHasCLUT(TIM) then @@ -712,7 +714,7 @@ function TfrmMain.FGetTimInfoByIdx(Index: Integer): TTimInfo; Result := SelectedScanResult.ScanTim[Index]; end; -function TfrmMain.FGetSelectedTim(NewBitMode: Integer): PTIM; +function TfrmMain.FGetSelectedTim: PTIM; var P: Integer; begin @@ -723,8 +725,8 @@ function TfrmMain.FGetSelectedTim(NewBitMode: Integer): PTIM; P := SelectedTimInfo.Position; Result := LoadTimFromFile(SelectedScanResult.ScanFile, P, SelectedScanResult.IsImage, SelectedTimInfo.Size); - if NewBitMode = $FF then Exit; - Result^.HEAD^.bBPP := NewBitMode; + if Integer(cbbBitMode.Tag) = $FF then Exit; + Result^.HEAD^.bBPP := Integer(cbbBitMode.Tag); end; function TfrmMain.CheckForFileOpened(const FileName: string): boolean; @@ -818,7 +820,7 @@ procedure TfrmMain.CheckButtonsAndMainMenu; actCloseFiles.Enabled := cbbFiles.Enabled; actReplaceTim.Enabled := (lvList.Selected <> nil) and (lvList.Selected.Index <> -1); - actTim2Png.Enabled := (Surf^ <> nil) and actReplaceTim.Enabled; + actPngExport.Enabled := (Surf^ <> nil) and actReplaceTim.Enabled; actExtractTim.Enabled := actReplaceTim.Enabled; pnlImageOptions.Enabled := actReplaceTim.Enabled; @@ -871,7 +873,7 @@ procedure TfrmMain.UpdateCLUTInfo; TIM: PTIM; I, CLUTS: Word; begin - TIM := SelectedTim; + TIM := SelectedTimInMode; if TIM = nil then Exit; CLUTS := GetTIMClutsCount(TIM); @@ -892,28 +894,13 @@ procedure TfrmMain.UpdateCLUTInfo; procedure TfrmMain.DrawSelTim; var TIM: PTIM; - Index: Integer; - mode: Byte; begin imgTim.Picture.Bitmap := nil; - case cbbBitMode.ItemIndex of - 1: mode := cTIM4C; - 2: mode := cTIM4NC; - 3: mode := cTIM8C; - 4: mode := cTIM8NC; - 5: mode := cTIM16NC; - 6: mode := cTIM24NC; - else - mode := $FF; - end; - - TIM := SelectedTimInMode[mode]; + TIM := SelectedTimInMode; if TIM = nil then Exit; - Index := cbbCLUT.ItemIndex; - - Tim2Png(TIM, Index, Surf, cbbTranspMode.ItemIndex); + Tim2Png(TIM, cbbCLUT.ItemIndex, Surf, cbbTranspMode.ItemIndex); imgTim.Picture.Bitmap := Surf^.Bitmap; FreeTIM(TIM); @@ -928,7 +915,7 @@ procedure TfrmMain.DrawSelClut; ClearGrid(@grdClut); - TIM := SelectedTim; + TIM := SelectedTimInMode; if TIM = nil then begin grdClut.ColCount := 1; @@ -995,7 +982,7 @@ procedure TfrmMain.ShowTimInfo(ShowInfo: Boolean); if not ShowInfo then Exit; TimInfo := SelectedTimInfo; - TIM := SelectedTim; + TIM := SelectedTimInMode; I := 0; diff --git a/uscanthread.pas b/uscanthread.pas index 20864b9..db8f1be 100644 --- a/uscanthread.pas +++ b/uscanthread.pas @@ -89,11 +89,10 @@ procedure TScanThread.Execute; begin Synchronize(@StartScan); - try - if pScanResult.IsImage then - pSectorBufferSize := cSectorBufferSize - else - pSectorBufferSize := cClearBufferSize; + if pScanResult.IsImage then + pSectorBufferSize := cSectorBufferSize + else + pSectorBufferSize := cClearBufferSize; pClearBufferSize := cClearBufferSize; @@ -122,8 +121,8 @@ procedure TScanThread.Execute; begin if pScanResult.IsImage then pTimPosition := pFilePos - pRealBufSize + - ((pClearBufferPosition - 1) div cSectorDataSize) * cSectorSize + - ((pClearBufferPosition - 1) mod cSectorDataSize) + cSectorInfoSize + ((pClearBufferPosition - 1) div cSectorDataSize) * cSectorSize + + ((pClearBufferPosition - 1) mod cSectorDataSize) + cSectorInfoSize else pTimPosition := pFilePos - pRealBufSize + (pClearBufferPosition - 1); @@ -147,7 +146,7 @@ procedure TScanThread.Execute; begin if pRealBufSize >= (pSectorBufferSize div 2) then // Need to check file size - pRealBufSize := pRealBufSize - (pSectorBufferSize div 2); + pRealBufSize := pRealBufSize - (pSectorBufferSize div 2); end else begin @@ -161,18 +160,17 @@ procedure TScanThread.Execute; ClearSectorBuffer(SectorBuffer, ClearBuffer); end; end; - finally - FreeTIM(TIM); - FreeMemory(SectorBuffer); - FreeMemory(ClearBuffer); - pSrcFileStream.Free; - pStopScan := True; - pFilePos := 0; - pStatusText := ''; + FreeTIM(TIM); + FreeMemory(SectorBuffer); + FreeMemory(ClearBuffer); - Synchronize(@FinishScan); - end; + pSrcFileStream.Free; + pStopScan := True; + pFilePos := 0; + pStatusText := ''; + + Synchronize(@FinishScan); end; procedure TScanThread.FinishScan; diff --git a/utim.pas b/utim.pas index 7173e80..92f3a13 100644 --- a/utim.pas +++ b/utim.pas @@ -149,7 +149,7 @@ function ConvertTIMColor(COLOR: word): TCLUT_COLOR; function ConvertCLUTColor(COLOR: TCLUT_COLOR): word; begin - Result := (COLOR.STP shl 15) or ((COLOR.B div 8) shl 10) or ((COLOR.G div 8) shl 5) or (COLOR.R div 8); + Result := Word(COLOR.STP shl 15) or Word((COLOR.B div 8) shl 10) or Word((COLOR.G div 8) shl 5) or Word(COLOR.R div 8); end; function GetCLUTColor(TIM: PTIM; CLUT_NUM, COLOR_NUM: Integer): TCLUT_COLOR; @@ -353,57 +353,55 @@ function LoadTimFromCDFile(const FileName: string; var Position: Integer; Sector: TCDSector; P, TIM_FULL_SECTORS: Integer; begin - try - sImageStream := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite); + sImageStream := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite); - TimSectorNumber := Position div cSectorSize + 1; - TimOffsetInSector := Position mod cSectorSize - cSectorInfoSize; - TimStartSectorPos := (TimSectorNumber - 1) * cSectorSize; - FirstPartSize := cSectorDataSize - TimOffsetInSector; + TimSectorNumber := Position div cSectorSize + 1; + TimOffsetInSector := Position mod cSectorSize - cSectorInfoSize; + TimStartSectorPos := (TimSectorNumber - 1) * cSectorSize; + FirstPartSize := cSectorDataSize - TimOffsetInSector; - New(TIM_BUF); - P := 0; + New(TIM_BUF); + P := 0; - if SIZE < FirstPartSize then FirstPartSize := SIZE; + if SIZE < FirstPartSize then FirstPartSize := SIZE; - sImageStream.Seek(TimStartSectorPos, soBeginning); - sImageStream.Read(Sector, cSectorSize); + sImageStream.Seek(TimStartSectorPos, soBeginning); + sImageStream.Read(Sector, cSectorSize); - Move(Sector.dwData[TimOffsetInSector], TIM_BUF^[P], FirstPartSize); - Inc(P, FirstPartSize); + Move(Sector.dwData[TimOffsetInSector], TIM_BUF^[P], FirstPartSize); + Inc(P, FirstPartSize); - Inc(TimStartSectorPos, cSectorSize); - sImageStream.Seek(TimStartSectorPos, soBeginning); + Inc(TimStartSectorPos, cSectorSize); + sImageStream.Seek(TimStartSectorPos, soBeginning); - TIM_FULL_SECTORS := (SIZE - P) div cSectorDataSize; + TIM_FULL_SECTORS := (SIZE - P) div cSectorDataSize; - while TIM_FULL_SECTORS > 0 do - begin - sImageStream.Read(Sector, cSectorSize); + while TIM_FULL_SECTORS > 0 do + begin + sImageStream.Read(Sector, cSectorSize); - Move(Sector.dwData[0], TIM_BUF^[P], cSectorDataSize); - Inc(P, cSectorDataSize); + Move(Sector.dwData[0], TIM_BUF^[P], cSectorDataSize); + Inc(P, cSectorDataSize); - Inc(TimStartSectorPos, cSectorSize); - sImageStream.Seek(TimStartSectorPos, soBeginning); + Inc(TimStartSectorPos, cSectorSize); + sImageStream.Seek(TimStartSectorPos, soBeginning); - Dec(TIM_FULL_SECTORS); - end; + Dec(TIM_FULL_SECTORS); + end; - sImageStream.Read(Sector, cSectorSize); + sImageStream.Read(Sector, cSectorSize); - if SIZE > P then - begin - LastPartSize := SIZE - P; - Move(Sector.dwData[0], TIM_BUF^[P], LastPartSize); - end; - finally - P := 0; - Result := nil; - LoadTimFromBuf(TIM_BUF, Result, P); - sImageStream.Free; - Dispose(TIM_BUF); + if SIZE > P then + begin + LastPartSize := SIZE - P; + Move(Sector.dwData[0], TIM_BUF^[P], LastPartSize); end; + + P := 0; + Result := nil; + LoadTimFromBuf(TIM_BUF, Result, P); + sImageStream.Free; + Dispose(TIM_BUF); end; function LoadTimFromStream(Stream: TStream; var Position: Integer; @@ -433,18 +431,14 @@ function LoadTimFromFile(const FileName: string; var Position: Integer; var sTIM: TFileStream; begin - if not ImageScan then + if ImageScan then + Result := LoadTimFromCDFile(FileName, Position, dwSize) + else begin - try - sTIM := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite); - Result := LoadTimFromStream(sTIM, Position, dwSize); - finally - sTIM.Free; - end; - Exit; + sTIM := TFileStream.Create(UTF8ToSys(FileName), fmOpenRead or fmShareDenyWrite); + Result := LoadTimFromStream(sTIM, Position, dwSize); + sTIM.Free; end; - - Result := LoadTimFromCDFile(FileName, Position, dwSize); end; procedure SaveTimToFile(const FileName: string; TIM: PTIM);