2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Graphic engine friendly loading of TGA image.
8
04/04/11 - Yar - Creation
31
TGLTGAImage = class(TGLBaseImage)
34
procedure LoadFromFile(const filename: string); override;
35
procedure SaveToFile(const filename: string); override;
36
procedure LoadFromStream(stream: TStream); override;
37
procedure SaveToStream(stream: TStream); override;
38
class function Capabilities: TGLDataFileCapabilities; override;
40
procedure AssignFromTexture(textureContext: TGLContext;
41
const textureHandle: TGLuint;
42
textureTarget: TGLTextureTarget;
43
const CurrentFormat: boolean;
44
const intFormat: TGLInternalFormat); reintroduce;
54
TTGAFileHeader = packed record
60
ColorMapEntrySize: Byte;
66
ImageDescriptor: Byte;
69
// ReadAndUnPackRLETGA24
72
procedure ReadAndUnPackRLETGA24(stream: TStream; destBuf: PAnsiChar; totalSize: Integer);
74
TRGB24 = packed record
84
bufEnd := @destBuf[totalSize];
85
while destBuf < bufEnd do
91
stream.Read(color, 3);
95
PRGB24(destBuf)^ := color;
102
n := ((b and 127) + 1) * 3;
103
stream.Read(destBuf^, n);
109
// ReadAndUnPackRLETGA32
112
procedure ReadAndUnPackRLETGA32(stream: TStream; destBuf: PAnsiChar; totalSize: Integer);
114
TRGB32 = packed record
124
bufEnd := @destBuf[totalSize];
125
while destBuf < bufEnd do
131
stream.Read(color, 4);
132
b := (b and 127) + 1;
135
PRGB32(destBuf)^ := color;
142
n := ((b and 127) + 1) * 4;
143
stream.Read(destBuf^, n);
152
procedure TGLTGAImage.LoadFromFile(const filename: string);
156
if FileStreamExists(fileName) then
158
fs := CreateFileStream(fileName, fmOpenRead);
163
ResourceName := filename;
167
raise EInvalidRasterFile.CreateFmt('File %s not found', [filename]);
173
procedure TGLTGAImage.SaveToFile(const filename: string);
177
fs := CreateFileStream(fileName, fmOpenWrite or fmCreate);
183
ResourceName := filename;
189
procedure TGLTGAImage.LoadFromStream(stream: TStream);
191
LHeader: TTGAFileHeader;
192
y, rowSize, bufSize: Integer;
193
verticalFlip: Boolean;
194
unpackBuf: PAnsiChar;
197
stream.Read(LHeader, Sizeof(TTGAFileHeader));
199
if LHeader.ColorMapType <> 0 then
200
raise EInvalidRasterFile.Create('ColorMapped TGA unsupported');
203
FLOD[0].Width := LHeader.Width;
204
FLOD[0].Height := LHeader.Height;
207
case LHeader.PixelSize of
210
FColorFormat := GL_BGR;
211
FInternalFormat := tfRGB8;
216
FColorFormat := GL_RGBA;
217
FInternalFormat := tfRGBA8;
221
raise EInvalidRasterFile.Create('Unsupported TGA ImageType');
224
FDataType := GL_UNSIGNED_BYTE;
226
FTextureArray := False;
227
ReallocMem(FData, DataSize);
229
rowSize := GetWidth * FElementSize;
230
verticalFlip := ((LHeader.ImageDescriptor and $20) <> 1);
232
if LHeader.IDLength > 0 then
233
stream.Seek(LHeader.IDLength, soFromCurrent);
235
case LHeader.ImageType of
237
begin // uncompressed RGB/RGBA
241
Inc(Ptr, rowSize * (GetHeight - 1));
242
for y := 0 to GetHeight - 1 do
244
stream.Read(Ptr^, rowSize);
249
stream.Read(FData^, rowSize * GetHeight);
252
begin // RLE encoded RGB/RGBA
253
bufSize := GetHeight * rowSize;
254
GetMem(unpackBuf, bufSize);
256
// read & unpack everything
257
if LHeader.PixelSize = 24 then
258
ReadAndUnPackRLETGA24(stream, unpackBuf, bufSize)
260
ReadAndUnPackRLETGA32(stream, unpackBuf, bufSize);
265
Inc(Ptr, rowSize * (GetHeight - 1));
266
for y := 0 to GetHeight - 1 do
268
Move(unPackBuf[y * rowSize], Ptr^, rowSize);
273
Move(unPackBuf[rowSize * GetHeight], FData^, rowSize * GetHeight);
279
raise EInvalidRasterFile.CreateFmt('Unsupported TGA ImageType %d',
280
[LHeader.ImageType]);
287
procedure TGLTGAImage.SaveToStream(stream: TStream);
289
{$MESSAGE Hint 'TGLTGAImage.SaveToStream not yet implemented' }
295
procedure TGLTGAImage.AssignFromTexture(textureContext: TGLContext;
296
const textureHandle: TGLuint; textureTarget: TGLTextureTarget;
297
const CurrentFormat: boolean; const intFormat: TGLInternalFormat);
299
{$MESSAGE Hint 'TGLTGAImage.AssignFromTexture not yet implemented' }
302
class function TGLTGAImage.Capabilities: TGLDataFileCapabilities;
304
Result := [dfcRead {, dfcWrite}];
309
{ Register this Fileformat-Handler with GLScene }
310
RegisterRasterFormat('tga', 'TARGA Image File', TGLTGAImage);
311
// TGLPicture.RegisterFileFormat('tga', 'TARGA Image File', TGLTGAImage);
315
// TGLPicture.UnregisterGraphicClass(TGLTGAImage);