Mam taki kod:
type
TTextureData = record // Własny typ zawierający wysokość i szerokość tekstury, format kolorów oraz wskaźnik na dane.
Width,
Height : Word;
Format : TColorFormat;
Data : Pointer;
end;
type
TTGAImageHeader = packed record
header : array[0..5] of byte;
BytesPerPixel : glUInt;
ImageSize : glUInt;
ImageType : glUInt;
Height : glUInt;
Width : glUInt;
Bpp : glUInt;
end;
function LoadCompressedTGA(FileName : String) : TTextureData;
var
TGAFile : TFileStream;
ImageHeader : TTGAImageHeader;
ImageData : PByteArray;
PixelCount : glUInt;
CurrentPixel : glUInt;
CurrentByte : glUInt;
ColorBuffer : PByteArray;
ChunkHeader : Byte;
i : LongWord;
begin
TGAFile := TFileStream.Create(Filename, fmOpenRead);
try
TGAFile.Seek(12, soFromBeginning);
TGAFile.ReadBuffer(ImageHeader.Header, SizeOf(ImageHeader.Header));
ImageHeader.Width := ImageHeader.Header[1] * 256 + ImageHeader.Header[0];
ImageHeader.Height := ImageHeader.Header[3] * 256 + ImageHeader.Header[2];
ImageHeader.Bpp := ImageHeader.Header[4];
if ImageHeader.Bpp = 24 then
result.Format := RGB;
if ImageHeader.Bpp = 32 then
result.Format := RGBA;
ImageHeader.BytesPerPixel := ImageHeader.Bpp div 8;
ImageHeader.ImageSize := ImageHeader.BytesPerPixel * ImageHeader.Width * ImageHeader.Height;
GetMem(ImageData, ImageHeader.ImageSize);
GetMem(ColorBuffer, ImageHeader.BytesPerPixel);
PixelCount := ImageHeader.Width * ImageHeader.Height;
ChunkHeader := 0;
CurrentPixel := 0;
CurrentByte := 0;
while (CurrentPixel < PixelCount) do
begin
TGAFile.ReadBuffer(ChunkHeader, SizeOf(ChunkHeader));
if ChunkHeader < 128 then
begin
Inc(ChunkHeader);
for i := 0 to ChunkHeader - 1 do
begin
TGAFile.ReadBuffer(ColorBuffer[0], ImageHeader.BytesPerPixel);
ImageData[CurrentByte] := ColorBuffer[2];
ImageData[CurrentByte + 1] := ColorBuffer[1];
ImageData[CurrentByte + 2] := ColorBuffer[0];
if ImageHeader.BytesPerPixel = 4 then
ImageData[CurrentByte + 3] := ColorBuffer[3];
Inc(CurrentByte, ImageHeader.BytesPerPixel);
Inc(CurrentPixel);
end;
end
else
begin
Dec(ChunkHeader, 127);
TGAFile.ReadBuffer(ColorBuffer[0], ImageHeader.BytesPerPixel);
for i := 0 to ChunkHeader - 1 do
begin
ImageData[CurrentByte] := ColorBuffer[2]; // <- Tutak się wywala.
ImageData[CurrentByte + 1] := ColorBuffer[1];
ImageData[CurrentByte + 2] := ColorBuffer[0];
if ImageHeader.BytesPerPixel = 4 then
ImageData[CurrentByte + 3] := ColorBuffer[3];
Inc(CurrentByte, ImageHeader.BytesPerPixel);
Inc(CurrentPixel);
end;
end;
end;
finally
FreeAndNil(TGAFIle);
end;
result.Width := ImageHeader.Width;
result.Height := ImageHeader.Height;
result.Data := ImageData;
end;
Jest to funkcja wczytująca skompresowany plik TGA. Próbuję nią wczytać plik o rozdzielczości 128 na 128 pikseli z kanałem alfa. W zaznaczonym miejscu w trzecim obrocie pętli For wywala mi SIGSEGV. Nie mam pojęcia dlaczego. 10 razy sprawdzałem czy getmem alokuje wystarczającą ilość pamięci oracz czy nie przekraczam tablicy i wszystko jest ok jednak program się sypie. Ktoś może wie gdzie leży błąd?
Funkcję przetłumaczyłem z c/c++ z tej strony http://aklimx.sppieniezno.pl/nehepl/display.php?id=33 Dlatego może wymagać kosmetycznych poprawek.