@@ -54,7 +54,7 @@ implementation
5454 STargaSignature = ' TRUEVISION-XFILE' ;
5555
5656type
57- { Targa file header. }
57+ { Targa file header }
5858 TTargaHeader = packed record
5959 IDLength: Byte;
6060 ColorMapType: Byte;
@@ -70,7 +70,7 @@ implementation
7070 Desc: Byte;
7171 end ;
7272
73- { Footer at the end of TGA file. }
73+ { Footer at the end of TGA file }
7474 TTargaFooter = packed record
7575 ExtOff: UInt32; // Extension Area Offset
7676 DevDirOff: UInt32; // Developer Directory Offset
@@ -108,34 +108,40 @@ function TTargaFileFormat.LoadData(Handle: TImagingHandle;
108108
109109 procedure LoadRLE ;
110110 var
111- I, CPixel, Cnt: LongInt;
111+ I: Integer;
112+ CurrentPixel, CountPixels: NativeInt;
112113 Bpp, Rle: Byte;
113- Buffer, Dest, Src: PByte;
114- BufSize: LongInt;
114+ Dest, Src: PByte;
115+ Buffer: TDynByteArray;
116+ BufSize: NativeInt;
117+ BytesConsumedFromBuffer, SeekOffset: NativeInt;
115118 begin
116119 with GetIO, Images[0 ] do
117120 begin
118121 // Allocates buffer large enough to hold the worst case
119122 // RLE compressed data and reads then from input
120123 BufSize := Width * Height * FmtInfo.BytesPerPixel;
121124 BufSize := BufSize + BufSize div 2 + 1 ;
122- GetMem(Buffer, BufSize);
123- Src := Buffer;
124- Dest := Bits;
125+
126+ SetLength(Buffer, BufSize);
125127 BufSize := Read(Handle, Buffer, BufSize);
126128
127- Cnt := Width * Height;
129+ Src := @Buffer[0 ];
130+ Dest := Bits;
131+
132+ CountPixels := Width * Height;
128133 Bpp := FmtInfo.BytesPerPixel;
129- CPixel := 0 ;
130- while CPixel < Cnt do
134+ CurrentPixel := 0 ;
135+
136+ while CurrentPixel < CountPixels do
131137 begin
132138 Rle := Src^;
133139 Inc(Src);
134140 if Rle < 128 then
135141 begin
136142 // Process uncompressed pixel
137143 Rle := Rle + 1 ;
138- CPixel := CPixel + Rle;
144+ CurrentPixel := CurrentPixel + Rle;
139145 for I := 0 to Rle - 1 do
140146 begin
141147 // Copy pixel from src to dest
@@ -153,7 +159,7 @@ function TTargaFileFormat.LoadData(Handle: TImagingHandle;
153159 begin
154160 // Process compressed pixels
155161 Rle := Rle - 127 ;
156- CPixel := CPixel + Rle;
162+ CurrentPixel := CurrentPixel + Rle;
157163 // Copy one pixel from src to dest (many times there)
158164 for I := 0 to Rle - 1 do
159165 begin
@@ -168,10 +174,13 @@ function TTargaFileFormat.LoadData(Handle: TImagingHandle;
168174 Inc(Src, Bpp);
169175 end ;
170176 end ;
171- // set position in source to real end of compressed data
172- Seek(Handle, -(BufSize - (PtrUInt(Src) - PtrUInt(Buffer))),
173- smFromCurrent);
174- FreeMem(Buffer);
177+
178+ // Set position in source to the real end of compressed data
179+ BytesConsumedFromBuffer := PtrUInt(Src) - PtrUInt(Buffer);
180+ SeekOffset := BytesConsumedFromBuffer - BufSize;
181+ Assert(SeekOffset <= 0 );
182+
183+ Seek(Handle, SeekOffset, smFromCurrent);
175184 end ;
176185 end ;
177186
@@ -196,7 +205,7 @@ function TTargaFileFormat.LoadData(Handle: TImagingHandle;
196205 3 , 11 : Format := ifGray8;
197206 end ;
198207 // Format was not assigned by previous testing (it should be in
199- // well formed targas ), so formats which reflects bit dept are selected
208+ // well formed Targas ), so format which reflect the bit depth is selected
200209 if Format = ifUnknown then
201210 case Hdr.PixelSize of
202211 8 : Format := ifGray8;
@@ -268,8 +277,8 @@ function TTargaFileFormat.LoadData(Handle: TImagingHandle;
268277 Format := ifX1R5G5B5;
269278 end ;
270279
271- // We must find true end of file and set input' position to it
272- // paint programs appends extra info at the end of Targas
280+ // We must find true end of file and set input's position to it.
281+ // Some paint programs appends extra info at the end of Targas,
273282 // some of them multiple times (PSP Pro 8)
274283 repeat
275284 ExtFound := False;
@@ -296,7 +305,7 @@ function TTargaFileFormat.LoadData(Handle: TImagingHandle;
296305 end ;
297306 until (not ExtFound) and (not FooterFound);
298307
299- // Some editors save targas flipped
308+ // Some editors save Targas flipped
300309 if Hdr.Desc < 31 then
301310 FlipImage(Images[0 ]);
302311
@@ -316,7 +325,7 @@ function TTargaFileFormat.SaveData(Handle: TImagingHandle;
316325
317326 procedure SaveRLE ;
318327 var
319- Dest: PByte ;
328+ DestBuffer: TDynByteArray ;
320329 WidthBytes, Written, I, Total, DestSize: LongInt;
321330
322331 function CountDiff (Data: PByte; Bpp, PixelCount: Longint): LongInt;
@@ -407,10 +416,12 @@ function TTargaFileFormat.SaveData(Handle: TImagingHandle;
407416 begin
408417 DiffCount := CountDiff(Data, Bpp, PixelCount);
409418 SameCount := CountSame(Data, Bpp, PixelCount);
419+
410420 if (DiffCount > MaxRun) then
411421 DiffCount := MaxRun;
412422 if (SameCount > MaxRun) then
413423 SameCount := MaxRun;
424+
414425 if (DiffCount > 0 ) then
415426 begin
416427 Dest^ := Byte(DiffCount - 1 );
@@ -449,19 +460,16 @@ function TTargaFileFormat.SaveData(Handle: TImagingHandle;
449460 WidthBytes := Width * FmtInfo.BytesPerPixel;
450461 DestSize := WidthBytes * Height;
451462 DestSize := DestSize + DestSize div 2 + 1 ;
452- GetMem(Dest , DestSize);
463+ SetLength(DestBuffer , DestSize);
453464 Total := 0 ;
454- try
455- for I := 0 to Height - 1 do
456- begin
457- RleCompressLine(@PByteArray(Bits)[I * WidthBytes], Width,
458- FmtInfo.BytesPerPixel, @PByteArray(Dest)[Total], Written);
459- Total := Total + Written;
460- end ;
461- GetIO.Write(Handle, Dest, Total);
462- finally
463- FreeMem(Dest);
465+
466+ for I := 0 to Height - 1 do
467+ begin
468+ RleCompressLine(@PByteArray(Bits)[I * WidthBytes], Width,
469+ FmtInfo.BytesPerPixel, @DestBuffer[Total], Written);
470+ Total := Total + Written;
464471 end ;
472+ GetIO.Write(Handle, DestBuffer, Total);
465473 end ;
466474 end ;
467475
@@ -493,11 +501,10 @@ function TTargaFileFormat.SaveData(Handle: TImagingHandle;
493501 // Choose image type
494502 if FmtInfo.IsIndexed then
495503 Hdr.ImageType := Iff(FUseRLE, 9 , 1 )
504+ else if FmtInfo.HasGrayChannel then
505+ Hdr.ImageType := Iff(FUseRLE, 11 , 3 )
496506 else
497- if FmtInfo.HasGrayChannel then
498- Hdr.ImageType := Iff(FUseRLE, 11 , 3 )
499- else
500- Hdr.ImageType := Iff(FUseRLE, 10 , 2 );
507+ Hdr.ImageType := Iff(FUseRLE, 10 , 2 );
501508
502509 Write(Handle, @Hdr, SizeOf(Hdr));
503510
@@ -520,7 +527,7 @@ function TTargaFileFormat.SaveData(Handle: TImagingHandle;
520527 end ;
521528
522529 if FUseRLE then
523- // Save rle compressed mode images
530+ // Save RLE compressed mode images
524531 SaveRLE
525532 else
526533 // Save uncompressed mode images
@@ -580,8 +587,7 @@ initialization
580587{
581588 File Notes:
582589
583- -- TODOS ----------------------------------------------------
584- - nothing now
590+ * More recent changes are in VCS history *
585591
586592 -- 0.21 Changes/Bug Fixes -----------------------------------
587593 - MakeCompatible method moved to base class, put ConvertToSupported here.
0 commit comments