1 | {*****************************************************************************}
|
---|
2 | {
|
---|
3 | This file is part of the Free Pascal's "Free Components Library".
|
---|
4 | Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team
|
---|
5 |
|
---|
6 | Targa reader implementation.
|
---|
7 |
|
---|
8 | See the file COPYING.FPC, included in this distribution,
|
---|
9 | for details about the copyright.
|
---|
10 |
|
---|
11 | This program is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
---|
14 | }
|
---|
15 | {*****************************************************************************}
|
---|
16 |
|
---|
17 | { - 22/11/2007 Modified by Laurent Jacques for support all format }
|
---|
18 |
|
---|
19 | {$mode objfpc}
|
---|
20 | {$h+}
|
---|
21 |
|
---|
22 | unit BGRAReadTGA;
|
---|
23 |
|
---|
24 | interface
|
---|
25 |
|
---|
26 | uses FPReadTGA, FPimage, Classes;
|
---|
27 |
|
---|
28 | type
|
---|
29 | { TBGRAReaderTarga }
|
---|
30 |
|
---|
31 | TBGRAReaderTarga = class (TFPReaderTarga)
|
---|
32 | protected
|
---|
33 | FBuffer: packed array of byte;
|
---|
34 | FBufferPos, FBufferSize: integer;
|
---|
35 | FBufferStream: TStream;
|
---|
36 | procedure ReadScanLine({%H-}Row: Integer; Stream: TStream); override;
|
---|
37 | procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); override;
|
---|
38 | procedure InitReadBuffer(AStream: TStream; ASize: integer);
|
---|
39 | procedure CloseReadBuffer;
|
---|
40 | function GetNextBufferByte: byte;
|
---|
41 | end;
|
---|
42 |
|
---|
43 | Implementation
|
---|
44 |
|
---|
45 | uses BGRABitmapTypes, targacmn;
|
---|
46 |
|
---|
47 | procedure TBGRAReaderTarga.ReadScanLine(Row: Integer; Stream: TStream);
|
---|
48 | Var
|
---|
49 | P : PByte;
|
---|
50 | B : Byte;
|
---|
51 | I,J : Integer;
|
---|
52 | PixelSizeInBytesMinus1: integer;
|
---|
53 |
|
---|
54 | begin
|
---|
55 | If Not Compressed then
|
---|
56 | Stream.ReadBuffer(FScanLine^,FLineSize)
|
---|
57 | else
|
---|
58 | begin
|
---|
59 | InitReadBuffer(Stream, 2048);
|
---|
60 | P:=FScanLine;
|
---|
61 | PixelSizeInBytesMinus1 := (BytesPerPixel shr 3)-1;
|
---|
62 | For I:=0 to ToWord(Header.Width)-1 do
|
---|
63 | begin
|
---|
64 | If (FPixelCount>0) then
|
---|
65 | Dec(FPixelCount)
|
---|
66 | else
|
---|
67 | begin
|
---|
68 | Dec(FBlockCount);
|
---|
69 | If (FBlockCount<0) then
|
---|
70 | begin
|
---|
71 | B := GetNextBufferByte;
|
---|
72 | If (B and $80)<>0 then
|
---|
73 | begin
|
---|
74 | FPixelCount:=B and $7F;
|
---|
75 | FblockCount:=0;
|
---|
76 | end
|
---|
77 | else
|
---|
78 | FBlockCount:=B and $7F
|
---|
79 | end;
|
---|
80 | For J:=0 to PixelSizeInBytesMinus1 do
|
---|
81 | FLastPixel[j] := GetNextBufferByte;
|
---|
82 | end;
|
---|
83 | For J:=0 to PixelSizeInBytesMinus1 do
|
---|
84 | begin
|
---|
85 | P[0]:=FLastPixel[j];
|
---|
86 | Inc(P);
|
---|
87 | end;
|
---|
88 | end;
|
---|
89 | CloseReadBuffer;
|
---|
90 | end;
|
---|
91 | end;
|
---|
92 |
|
---|
93 | Procedure TBGRAReaderTarga.WriteScanLine(Row : Integer; Img : TFPCustomImage);
|
---|
94 | Var
|
---|
95 | Col : Integer;
|
---|
96 | Value : NativeUint;
|
---|
97 | P : PByte;
|
---|
98 | PDest: PBGRAPixel;
|
---|
99 |
|
---|
100 | begin
|
---|
101 | P:=FScanLine;
|
---|
102 | PDest := TBGRACustomBitmap(img).ScanLine[Row];
|
---|
103 | Case Header.ImgType of
|
---|
104 | TARGA_INDEXED_IMAGE
|
---|
105 | : for Col:=Img.width-1 downto 0 do
|
---|
106 | begin
|
---|
107 | PDest^ := FPColorToBGRA(FPalette[P^]);
|
---|
108 | Inc(PDest);
|
---|
109 | Inc(P);
|
---|
110 | end;
|
---|
111 | TARGA_TRUECOLOR_IMAGE
|
---|
112 | : if (BytesPerPixel = 32) and (AlphaBits = 8) then
|
---|
113 | Move(P^,PDest^,Img.Width*sizeof(TBGRAPixel)) else
|
---|
114 | if (BytesPerPixel = 24) then
|
---|
115 | begin
|
---|
116 | for Col:=Img.Width-1 downto 0 do
|
---|
117 | begin
|
---|
118 | PDest^ := BGRA((P+2)^,(P+1)^,P^);
|
---|
119 | inc(Pdest);
|
---|
120 | Inc(p,3);
|
---|
121 | end;
|
---|
122 | end
|
---|
123 | else if (BytesPerPixel in[8,16]) then
|
---|
124 | for Col:= Img.Width-1 to 0 do
|
---|
125 | begin
|
---|
126 | Value:=P[0];
|
---|
127 | inc(P);
|
---|
128 | Value:=value or (P[0] shl 8);
|
---|
129 | PDest^ := BGRA(((value)shr 10) shl 3,((value)shr 5) shl 3,((value)) shl 3);
|
---|
130 | Inc(PDest);
|
---|
131 | Inc(P);
|
---|
132 | end;
|
---|
133 | TARGA_GRAY_IMAGE
|
---|
134 | : case BytesPerPixel of
|
---|
135 | 8 : for Col:=Img.width-1 downto 0 do
|
---|
136 | begin
|
---|
137 | PDest^ := FPColorToBGRA(FPalette[P^]);
|
---|
138 | Inc(PDest);
|
---|
139 | Inc(P);
|
---|
140 | end;
|
---|
141 | 16 : for Col:=0 to Img.width-1 do
|
---|
142 | begin
|
---|
143 | With PDest^ do
|
---|
144 | begin
|
---|
145 | blue:=FPalette[P^].blue shr 8;
|
---|
146 | green:=FPalette[P^].green shr 8;
|
---|
147 | red:=FPalette[P^].red shr 8;
|
---|
148 | Inc(P);
|
---|
149 | if alphaBits = 8 then alpha := P^ else
|
---|
150 | alpha:=255;
|
---|
151 | Inc(P);
|
---|
152 | end;
|
---|
153 | inc(PDest);
|
---|
154 | end;
|
---|
155 | end;
|
---|
156 | end;
|
---|
157 | end;
|
---|
158 |
|
---|
159 | procedure TBGRAReaderTarga.InitReadBuffer(AStream: TStream; ASize: integer);
|
---|
160 | begin
|
---|
161 | setLength(FBuffer,ASize);
|
---|
162 | FBufferSize := AStream.Read(FBuffer[0],ASize);
|
---|
163 | FBufferPos := 0;
|
---|
164 | FBufferStream := AStream;
|
---|
165 | end;
|
---|
166 |
|
---|
167 | procedure TBGRAReaderTarga.CloseReadBuffer;
|
---|
168 | begin
|
---|
169 | FBufferStream.Position:= FBufferStream.Position-FBufferSize+FBufferPos;
|
---|
170 | end;
|
---|
171 |
|
---|
172 | function TBGRAReaderTarga.GetNextBufferByte: byte;
|
---|
173 | begin
|
---|
174 | if FBufferPos < FBufferSize then
|
---|
175 | begin
|
---|
176 | result := FBuffer[FBufferPos];
|
---|
177 | inc(FBufferPos);
|
---|
178 | end else
|
---|
179 | if FBufferSize = 0 then
|
---|
180 | result := 0
|
---|
181 | else
|
---|
182 | begin
|
---|
183 | FBufferSize := FBufferStream.Read(FBuffer[0],length(FBuffer));
|
---|
184 | FBufferPos := 0;
|
---|
185 | if FBufferPos < FBufferSize then
|
---|
186 | begin
|
---|
187 | result := FBuffer[FBufferPos];
|
---|
188 | inc(FBufferPos);
|
---|
189 | end else
|
---|
190 | result := 0;
|
---|
191 | end;
|
---|
192 | end;
|
---|
193 |
|
---|
194 | initialization
|
---|
195 |
|
---|
196 | DefaultBGRAImageReader[ifTarga] := TBGRAReaderTarga;
|
---|
197 |
|
---|
198 | end.
|
---|