ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/oup/current/Global/OniImgClass.pas
(Generate patch)

Comparing oup/current/Global/OniImgClass.pas (file contents):
Revision 122 by alloc, Fri Mar 23 01:41:15 2007 UTC vs.
Revision 199 by alloc, Sat May 26 20:41:34 2007 UTC

# Line 2 | Line 2 | unit OniImgClass;
2  
3   interface
4  
5 < uses Math, Dialogs, Types, SysUtils, Classes, Data, ConnectionManager, TypeDefs;
5 > uses Math, Dialogs, Types, SysUtils, Classes, Data, ConnectionManager, TypeDefs,
6 >  Imaging, ImagingTypes, Graphics;
7  
7 type
8  TImgDataType = set of (DT_OniReverted, DT_Oni, DT_Decoded32);
8  
9   type
10    TOniImage = class
11    private
12 <    FLoaded:    Boolean;
13 <    FDataType:  TImgDataType;
14 <    FData:      TByteData;
15 <    FWidth, FHeight: Word;
16 <    FDepth:     Byte;
17 <    FStoreType: Byte;
18 <
19 <    function ResizeImage(oldx, oldy: Integer; img: TByteData): TByteData;
21 <    procedure RevertImage;
22 <    procedure DecompressImage;
12 >    FImages: TDynImageDataArray;
13 >    function GetImage(MipGen: Integer): TImageData;
14 >    function GetWidth(MipGen: Integer): Integer;
15 >    function GetHeight(MipGen: Integer): Integer;
16 >    function GetImageFormat: TImageFormat;
17 >    procedure SetImageFormat(Format: TImageFormat);
18 >    function pGetImageFormatInfo: TImageFormatInfo;
19 >    function GetHasMipMaps: Boolean;
20    protected
21    public
22 <    property Loaded:    Boolean      Read FLoaded    Write FLoaded;
23 <    property DataType:  TImgDataType Read FDataType  Write FDataType;
24 <    property Width:     Word         Read FWidth     Write FWidth;
25 <    property Height:    Word         Read FHeight    Write FHeight;
26 <    property Depth:     Byte         Read FDepth     Write FDepth;
27 <    property StoreType: Byte         Read FStoreType Write FStoreType;
28 <    property Data:      TByteData    Read FData      Write FData;
22 >    property Images: TDynImageDataArray         read FImages;
23 >    property Image[MipGen: Integer]: TImageData read GetImage;
24 >    property Width[MipGen: Integer]: Integer    read GetWidth;
25 >    property Height[MipGen: Integer]: Integer   read GetHeight;
26 >    property Format: TImageFormat read GetImageFormat write SetImageFormat;
27 >    property FormatInfo: TImageFormatInfo read pGetImageFormatInfo;
28 >    property HasMipMaps: Boolean read GetHasMipMaps;
29  
30      constructor Create;
31 +    procedure Free;
32      function Load(ConnectionID, FileID: Integer): Boolean;
33      function LoadFromPSpc(ConnectionID, FileID: Integer): Boolean;
34      function LoadFromTXMP(ConnectionID, FileID: Integer): Boolean;
35      function LoadFromTXMB(ConnectionID, FileID: Integer): Boolean;
38    function GetImageDataSize(fading: Boolean): Integer;
36  
37 <    procedure DecodeImageTo32bit;
37 >    procedure SaveDataToStream(MipMaps: Boolean; var Target: TStream);
38 >
39 >    function LoadFromFile(filename: String): Boolean;
40 >    function WriteToFile(filename: String): Boolean;
41  
42 <    procedure GetAsData(var Target: TStream); overload;
43 <    procedure GetAsData(var Target: TByteData); overload;
44 <    procedure GetAs32bit(var Target: TStream); overload;
45 <    procedure GetAs32bit(var Target: TByteData); overload;
46 <    procedure GetAsBMP(var Target: TStream); overload;
47 <    procedure GetAsBMP(var Target: TByteData); overload;
48 <    function LoadFromBMP(filename: String): Boolean;
49 <    function WriteToBMP(filename: String): Boolean;
50 <    function GetMipMappedImage(var Target: TStream): Boolean; overload;
51 <    function GetMipMappedImage(var Target: TByteData): Boolean; overload;
42 >    procedure DrawOnCanvas(Canvas: TCanvas; Index: Integer);
43 >    function GetImageSize(MipMaps: Boolean): Integer;
44    published
45    end;
46  
47  
48   implementation
49  
50 < //uses Functions;
50 > uses Img_DDSTypes, ImagingComponents;
51  
52  
53 + procedure TOniImage.DrawOnCanvas(Canvas: TCanvas; Index: Integer);
54 + var
55 +  singleimg: TImageData;
56 +  rect: TRect;
57 + begin
58 +  InitImage(singleimg);
59 +  CloneImage(FImages[Index-1], singleimg);
60 +  ConvertImage(singleimg, ifX8R8G8B8);
61 +  rect.Left := 0;
62 +  rect.Top := 0;
63 +  rect.Right := singleimg.Width - 1;
64 +  rect.Bottom := singleimg.Height - 1;
65 +  Canvas.Brush.Color := $C8D0D4;
66 +  Canvas.FillRect(Canvas.ClipRect);
67 +  DisplayImageData(Canvas, rect, singleimg, rect);
68 +  FreeImage(singleimg);
69 + end;
70 +
71  
72  
73   constructor TOniImage.Create;
74   begin
65  Self.FLoaded   := False;
66  Self.FDataType := [];
67  SetLength(Self.FData, 0);
68  Self.FWidth     := 0;
69  Self.FHeight    := 0;
70  Self.FDepth     := 0;
71  Self.FStoreType := 0;
75   end;
76  
77  
78  
79 + procedure TOniImage.Free;
80 + begin
81 +  FreeImagesInArray(FImages);
82 + end;
83  
84 < function TOniImage.ResizeImage(oldx, oldy: Integer; img: TByteData): TByteData;
85 < var
86 <  i, j: Integer;
87 <  col, row, row_orig: Integer;
84 >
85 >
86 >
87 > function TOniImage.GetImage(MipGen: Integer): TImageData;
88   begin
89 <  SetLength(Result, (oldx div 2) * (oldy div 2) * (Self.FDepth div 8));
83 <  row_orig := 0;
84 <  row      := 0;
85 <  col      := 0;
86 <  for i := 0 to (oldx * oldy) - 1 do
89 >  if MipGen <= Length(FImages) then
90    begin
91 <    if ((i mod oldx) = 0) and (i > 0) then
92 <    begin
90 <      Inc(row_orig);
91 <      if (row_orig mod 2) = 0 then
92 <      begin
93 <        Inc(row);
94 <        col := 0;
95 <      end;
96 <    end;
97 <    if (row_orig mod 2) = 0 then
98 <    begin
99 <      if (i mod 2) = 0 then
100 <      begin
101 <        for j := 0 to (Self.FDepth div 8) - 1 do
102 <          Result[((row * (oldx div 2)) + col) * (Self.FDepth div 8) + j] :=
103 <            img[(i * (Self.FDepth div 8)) + j];
104 <        Inc(col);
105 <      end;
106 <    end;
91 >    InitImage(Result);
92 >    CloneImage(FImages[MipGen-1], Result);
93    end;
94   end;
95  
96  
97  
98 <
113 < procedure TOniImage.RevertImage;
114 < var
115 <  x, y, i: Integer;
116 <  tempd:   TByteData;
98 > function TOniImage.GetWidth(MipGen: Integer): Integer;
99   begin
100 <  SetLength(tempd, Self.FWidth * Self.FHeight * (Self.FDepth div 8));
101 <  for y := 0 to Self.FHeight - 1 do
120 <    for x := 0 to Self.FWidth - 1 do
121 <      for i := 0 to (Self.FDepth div 8) - 1 do
122 <        tempd[((Self.FWidth * (Self.FHeight - 1 - y) + x) * (Self.FDepth div 8)) + i] :=
123 <          Self.FData[(Self.FWidth * y + x) * (Self.FDepth div 8) + i];
124 <  for x := 0 to High(tempd) do
125 <    Self.FData[x] := tempd[x];
126 <  if DT_OniReverted in Self.FDataType then
127 <    Self.FDataType := Self.FDataType - [DT_OniReverted]
100 >  if MipGen <= Length(FImages) then
101 >    Result := FImages[MipGen-1].Width
102    else
103 <    Self.FDataType := Self.FDataType + [DT_OniReverted];
103 >    Result := -1;
104   end;
105  
106  
107 <
134 <
135 < procedure TOniImage.DecodeImageTo32bit;
136 < var
137 <  x, y:  Integer;
138 <  tempd: TByteData;
107 > function TOniImage.GetHeight(MipGen: Integer): Integer;
108   begin
109 <  if not (DT_Decoded32 in Self.FDataType) then
110 <  begin
111 <    SetLength(tempd, Self.FWidth * Self.FHeight * 4);
112 <    case Self.FStoreType of
144 <      0: // 16bit, RGB444, A4?
145 <      begin
146 <        for y := 0 to Self.FHeight - 1 do
147 <        begin
148 <          for x := 0 to Self.FWidth - 1 do
149 <          begin
150 <            tempd[((Self.FWidth * y + x) * 4) + 0] :=
151 <              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
152 <              $000F) / $000F * 255);
153 <            tempd[((Self.FWidth * y + x) * 4) + 1] :=
154 <              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
155 <              $00F0) / $00F0 * 255);
156 <            tempd[((Self.FWidth * y + x) * 4) + 2] :=
157 <              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
158 <              $0F00) / $0F00 * 255);
159 <            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
160 <          end;
161 <        end;
162 <      end;
163 <      1, 2: // 16bit, RGB555, A1?
164 <      begin
165 <        for y := 0 to Self.FHeight - 1 do
166 <        begin
167 <          for x := 0 to Self.FWidth - 1 do
168 <          begin
169 <            tempd[((Self.FWidth * y + x) * 4) + 0] :=
170 <              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
171 <              $001F) / $001F * 255);
172 <            tempd[((Self.FWidth * y + x) * 4) + 1] :=
173 <              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
174 <              $03E0) / $03E0 * 255);
175 <            tempd[((Self.FWidth * y + x) * 4) + 2] :=
176 <              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
177 <              $7C00) / $7C00 * 255);
178 <            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
179 <          end;
180 <        end;
181 <      end;
182 <      8: // 32bit, RGB888, A8?
183 <      begin end;
184 <      9: // Compressed, RGB565
185 <      begin
186 <        DecompressImage;
187 <      end;
188 <    end;
189 <    Self.FDepth := 32;
190 <    if (Self.FStoreType <> 9) and (Self.FStoreType <> 8) then
191 <    begin
192 <      SetLength(Self.FData, Length(tempd));
193 <      for x := 0 to High(tempd) do
194 <        Self.FData[x] := tempd[x];
195 <    end;
196 <    Self.FStoreType := 8;
197 <    if DT_Oni in Self.FDataType then
198 <      Self.FDataType := Self.FDataType - [DT_Oni];
199 <    Self.FDataType := Self.FDataType + [DT_Decoded32];
200 <  end;
201 <  if DT_OniReverted in Self.FDataType then
202 <    Self.RevertImage;
109 >  if MipGen <= Length(FImages) then
110 >    Result := FImages[MipGen-1].Height
111 >  else
112 >    Result := -1;
113   end;
114  
115  
116 + function TOniImage.GetImageFormat: TImageFormat;
117 + begin
118 +  if Length(FImages) > 0 then
119 +    Result := FImages[0].Format
120 +  else
121 +    Result := ifUnknown;
122 + end;
123  
124 <
208 < procedure TOniImage.DecompressImage;
209 < type
210 <  Tcolor = record
211 <    RGBb: Byte;
212 <    RGBg: Byte;
213 <    RGBr: Byte;
214 <    RGBa: Byte;
215 <  end;
124 > procedure TOniImage.SetImageFormat(Format: TImageFormat);
125   var
126 <  i, j, x, y: Integer;
218 <  color:      array[1..4] of Tcolor;
219 <  pixel:      array[1..16] of Byte;
220 <  tempd:      TByteData;
126 >  i: Integer;
127   begin
128 <  x := 0;
129 <  y := 0;
130 <  SetLength(tempd, Self.FWidth * Self.FHeight * 4);
225 <  for i := 0 to ((Self.FWidth * Self.FHeight) div 16) - 1 do
226 <  begin
227 <    Color[1].RGBb := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $001F) /
228 <      $001F * 255);
229 <    Color[1].RGBg := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $07E0) /
230 <      $07E0 * 255);
231 <    Color[1].RGBr := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $F800) /
232 <      $F800 * 255);
233 <    Color[1].RGBa := 255;
234 <    Color[2].RGBb := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $001F) /
235 <      $001F * 255);
236 <    Color[2].RGBg := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $07E0) /
237 <      $07E0 * 255);
238 <    Color[2].RGBr := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $F800) /
239 <      $F800 * 255);
240 <    Color[2].RGBa := 255;
241 <    Color[3].RGBb := Round(Color[1].RGBb / 3 * 2 + Color[2].RGBb / 3);
242 <    Color[3].RGBg := Round(Color[1].RGBg / 3 * 2 + Color[2].RGBg / 3);
243 <    Color[3].RGBr := Round(Color[1].RGBr / 3 * 2 + Color[2].RGBr / 3);
244 <    Color[3].RGBa := 255;
245 <    Color[4].RGBb := Round(Color[1].RGBb / 3 + Color[2].RGBb / 3 * 2);
246 <    Color[4].RGBg := Round(Color[1].RGBg / 3 + Color[2].RGBg / 3 * 2);
247 <    Color[4].RGBr := Round(Color[1].RGBr / 3 + Color[2].RGBr / 3 * 2);
248 <    Color[4].RGBa := 255;
249 <    Pixel[1]      := Round((Self.FData[(i * 8) + 4] and $C0) / $40 + 1);
250 <    Pixel[2]      := Round((Self.FData[(i * 8) + 4] and $30) / $10 + 1);
251 <    Pixel[3]      := Round((Self.FData[(i * 8) + 4] and $0C) / $04 + 1);
252 <    Pixel[4]      := Round((Self.FData[(i * 8) + 4] and $03) + 1);
253 <    Pixel[5]      := Round((Self.FData[(i * 8) + 5] and $C0) / $40 + 1);
254 <    Pixel[6]      := Round((Self.FData[(i * 8) + 5] and $30) / $10 + 1);
255 <    Pixel[7]      := Round((Self.FData[(i * 8) + 5] and $0C) / $04 + 1);
256 <    Pixel[8]      := Round((Self.FData[(i * 8) + 5] and $03) + 1);
257 <    Pixel[9]      := Round((Self.FData[(i * 8) + 6] and $C0) / $40 + 1);
258 <    Pixel[10]     := Round((Self.FData[(i * 8) + 6] and $30) / $10 + 1);
259 <    Pixel[11]     := Round((Self.FData[(i * 8) + 6] and $0C) / $04 + 1);
260 <    Pixel[12]     := Round((Self.FData[(i * 8) + 6] and $03) + 1);
261 <    Pixel[13]     := Round((Self.FData[(i * 8) + 7] and $C0) / $40 + 1);
262 <    Pixel[14]     := Round((Self.FData[(i * 8) + 7] and $30) / $10 + 1);
263 <    Pixel[15]     := Round((Self.FData[(i * 8) + 7] and $0C) / $04 + 1);
264 <    Pixel[16]     := Round((Self.FData[(i * 8) + 7] and $03) + 1);
265 <    for j := 0 to 3 do
266 <    begin
267 <      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[16 - j]].RGBb;
268 <      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[16 - j]].RGBg;
269 <      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[16 - j]].RGBr;
270 <      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 3] := 0;
271 <    end;
272 <    for j := 0 to 3 do
273 <    begin
274 <      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[12 - j]].RGBb;
275 <      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[12 - j]].RGBg;
276 <      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[12 - j]].RGBr;
277 <      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 3] := 0;
278 <    end;
279 <    for j := 0 to 3 do
280 <    begin
281 <      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[8 - j]].RGBb;
282 <      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[8 - j]].RGBg;
283 <      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[8 - j]].RGBr;
284 <      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 3] := 0;
285 <    end;
286 <    for j := 0 to 3 do
287 <    begin
288 <      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[4 - j]].RGBb;
289 <      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[4 - j]].RGBg;
290 <      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[4 - j]].RGBr;
291 <      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 3] := 0;
292 <    end;
293 <    x := x + 4;
294 <    if x = Self.FWidth then
295 <    begin
296 <      y := y + 4;
297 <      x := 0;
298 <    end;
299 <  end;
300 <  SetLength(Self.FData, Length(tempd));
301 <  for i := 0 to High(tempd) do
302 <    Self.FData[i] := tempd[i];
303 <  Self.FStoreType := 8;
304 <  Self.FDepth    := 32;
305 <  Self.FDataType := Self.FDataType - [DT_Oni] + [DT_Decoded32];
128 >  if Length(FImages) > 0 then
129 >    for i := 0 to High(FImages) do
130 >      ConvertImage(FImages[i], Format);
131   end;
132  
133  
134 + function TOniImage.pGetImageFormatInfo: TImageFormatInfo;
135 + begin
136 +  if Length(FImages) > 0 then
137 +    GetImageFormatInfo(FImages[0].Format, Result);
138 + end;
139  
140  
141 + function TOniImage.GetHasMipMaps: Boolean;
142 + begin
143 +  Result := Length(FImages) > 1;
144 + end;
145 +
146  
147   function TOniImage.Load(ConnectionID, FileID: Integer): Boolean;
148   var
# Line 343 | Line 178 | type
178      x_txmp, y_txmp: Word;
179      x_pspc, y_pspc: Word;
180      w, h:    Word;
181 <    imgdata: TByteData;
181 >    imgdata: TImageData;
182      used:    Boolean;
183    end;
184   const
185    PartMatch: array[0..8] of Byte = (0, 3, 6, 1, 4, 7, 2, 5, 8);
186 +  stretch_x: Integer = 1;
187 +  stretch_y: Integer = 1;
188   var
189 <  x, y, pixel: Word;
189 >  x, y: Word;
190    i: Integer;
191  
192    PSpc:     TPSpc;
193    txmpimg:  TOniImage;
194 <  txmpdata: TByteData;
194 > //  txmpdata: TByteData;
195  
196    parts:    array[0..8] of TPart;
197    part:     Byte;
198    cols:     array[0..2] of Word;
199    rows:     array[0..2] of Word;
200    col, row: Byte;
201 +
202 +  pspcimage: TImageData;
203   begin
204    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, SizeOf(PSpc), @PSpc);
205    PSpc.TXMP := PSpc.TXMP div 256;
# Line 370 | Line 209 | begin
209      Exit;
210    end;
211    txmpimg := TOniImage.Create;
212 <  txmpimg.LoadFromTXMP(ConnectionID, PSpc.TXMP);
213 <  txmpimg.DecodeImageTo32bit;
214 < //  txmpimg.WriteToBMP('C:\file.bmp');
215 <  txmpimg.GetAs32bit(txmpdata);
216 < {    ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height));
378 <    for i:=0 to High(txmpdata) do
379 <      txmpimg.Data[i]:=txmpdata[i];
380 <    txmpimg.WriteToBMP('D:\file2.bmp');
381 < }
382 <  with PSpc do
212 >  txmpimg.Load(ConnectionID, PSpc.TXMP);
213 >  CloneImage(txmpimg.Image[1], pspcimage);
214 >  txmpimg.Free;
215 >
216 >  with pspc do
217    begin
218      for i := 0 to 2 do
219      begin
# Line 393 | Line 227 | begin
227        row  := i mod 3;
228        if (p2[i].X > 0) or (p2[i].Y > 0) then
229        begin
230 <        parts[part].x_txmp := p1[i].X - 1;
231 <        parts[part].y_txmp := p1[i].Y - 1;
230 >        parts[part].x_txmp := p1[i].X;// - 1;
231 >        parts[part].y_txmp := p1[i].Y;// - 1;
232          parts[part].x_pspc := 0;
233          if col > 0 then
234            for x := 0 to col - 1 do
# Line 403 | Line 237 | begin
237          if row > 0 then
238            for y := 0 to row - 1 do
239              Inc(parts[part].y_pspc, rows[y]);
240 <        parts[part].w := p2[i].X - p1[i].X + 1;
241 <        parts[part].h := p2[i].Y - p1[i].Y + 1;
240 >        parts[part].w := Max(p2[i].X - p1[i].X, 1);// + 1;
241 >        parts[part].h := Max(p2[i].Y - p1[i].Y, 1);// + 1;
242          parts[part].used := True;
243          cols[col] := parts[part].w;
244          rows[row] := parts[part].h;
245 <        SetLength(parts[part].imgdata, parts[part].w * parts[part].h * 4);
246 <        for y := 0 to parts[part].h - 1 do
247 <        begin
248 <          for x := 0 to parts[part].w - 1 do
249 <          begin
250 <            for pixel := 0 to 3 do
417 <            begin
418 <              parts[part].imgdata[(y * parts[part].w + x) * 4 + pixel] :=
419 <                txmpdata[((parts[part].y_txmp + y) * txmpimg.Width +
420 <                parts[part].x_txmp + x) * 4 + pixel];
421 <            end;
422 <          end;
423 <        end;
245 >
246 >        NewImage(parts[part].w, parts[part].h, pspcimage.Format, parts[part].imgdata);
247 >
248 >        CopyRect(pspcimage,
249 >            parts[part].x_txmp, parts[part].y_txmp, parts[part].w, parts[part].h,
250 >            parts[part].imgdata, 0, 0);
251        end
252        else
253        begin
# Line 430 | Line 257 | begin
257  
258    end;
259  
433  txmpimg.Free;
434  txmpimg := TOniImage.Create;
260    for i := 0 to 8 do
261    begin
262      if parts[i].used then
263      begin
264 <      SetLength(txmpimg.FData, Length(parts[i].imgdata));
440 <      for pixel := 0 to High(parts[i].imgdata) do
441 <        txmpimg.Data[pixel] := parts[i].imgdata[pixel];
442 <      txmpimg.Width := parts[i].w;
443 <      txmpimg.Height    := parts[i].h;
444 <      txmpimg.StoreType := 8;
445 <      txmpimg.DataType  := [DT_Decoded32];
446 <      txmpimg.Depth     := 32;
447 <      txmpimg.WriteToBMP('M:\' + IntToStr(i) + '.bmp');
264 > //      SaveImageToFile('M:\' + IntToStr(i) + '.bmp', parts[i].imgdata);
265      end;
266    end;
450  txmpimg.Free;
267  
268 <  Self.FWidth  := 0;
269 <  Self.FHeight := 0;
270 <  for i := 0 to 2 do
268 >  SetLength(FImages, 1);
269 >  x := cols[0] + cols[1] * stretch_x + cols[2];
270 >  y := rows[0] + rows[1] * stretch_y + rows[2];
271 >
272 >  NewImage(x, y, pspcimage.Format, FImages[0]);
273 >
274 >  x := 0;
275 >  for col := 0 to 2 do
276    begin
277 <    Inc(Self.FWidth, cols[i]);
278 <    Inc(Self.FHeight, rows[i]);
277 >    y := 0;
278 >    for row := 0 to 2 do
279 >    begin
280 >      part := row*3 + col;
281 >      if parts[part].used then
282 >      begin
283 >        if (row = 1) and (col = 1) then
284 >          StretchRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h,
285 >              FImages[0], x, y, parts[part].w * stretch_x, parts[part].h * stretch_y, rfNearest)
286 >        else
287 >        if (row = 1) then
288 >          StretchRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h,
289 >              FImages[0], x, y, parts[part].w, parts[part].h * stretch_y, rfNearest)
290 >        else
291 >        if (col = 1) then
292 >          StretchRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h,
293 >              FImages[0], x, y, parts[part].w * stretch_x, parts[part].h, rfNearest)
294 >        else
295 >          CopyRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h,
296 >              FImages[0], x, y );
297 >        if row = 1 then
298 >          y := y + parts[part].h * stretch_y
299 >        else
300 >          y := y + parts[part].h;
301 >      end;
302 >    end;
303 >    if cols[col] > 0 then
304 >    begin
305 >      if (col = 1) then
306 >        x := x + parts[part].w * stretch_x
307 >      else
308 >        x := x + parts[part].w;
309 >    end;
310    end;
459  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
311  
312 <  //Combine data parts
313 <
314 <  Self.FDepth     := 32;
315 <  Self.FStoreType := 8;
465 <  Self.FDataType  := [DT_Decoded32];
466 <  //    Self.RevertImage;
312 >  FreeImage(pspcimage);
313 >  for i := 0 to 8 do
314 >    if parts[i].used then
315 >      FreeImage(parts[i].imgdata);
316   end;
317  
318  
# Line 472 | Line 321 | end;
321   function TOniImage.LoadFromTXMP(ConnectionID, FileID: Integer): Boolean;
322   var
323    img_addr: Integer;
324 +  data: TMemoryStream;
325 +  hdr: TDDSDXTHeader;
326 +  imginfo: Integer;
327 +  x,y, i: Integer;
328 +
329 +  _width, _height: Word;
330 +  _storetype: Byte;
331 +  _depth: Byte;
332   begin
333    Result := True;
334 <  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(Self.FWidth), @Self.FWidth);
335 <  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(Self.FHeight), @Self.FHeight);
336 <  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(Self.FStoreType),
337 <    @Self.FStoreType);
334 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(_width), @_width);
335 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(_height), @_height);
336 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(_storetype), @_storetype);
337 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $88, SizeOf(imginfo), @imginfo);
338    if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
339      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $9C, SizeOf(img_addr), @img_addr)
340    else
341      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $A0, SizeOf(img_addr), @img_addr);
342  
343 <  case Self.FStoreType of
343 >  case _storetype of
344      0, 1, 2:
345 <    begin
346 <      SetLength(Self.FData, Self.FWidth * Self.FHeight * 2);
347 <      Self.FDepth := 16;
491 <    end;
492 <    8:
493 <    begin
494 <      SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
495 <      Self.FDepth := 32;
496 <    end;
345 >      _depth := 16;
346 >    7, 8:
347 >      _depth := 32;
348      9:
349 <    begin
499 <      SetLength(Self.FData, Self.FWidth * Self.FHeight div 2);
500 <      Self.FDepth := 16;
501 <    end;
349 >      _depth := 16;
350      else
351        Result := False;
352        Exit;
353    end;
354  
355 +  with hdr do
356 +  begin
357 +    FOURCC := 'DDS ';
358 +    with SURFACEDESC2 do
359 +    begin
360 +      Size := 124;
361 +      Flags := DDSD_CAPS or DDSD_PIXELFORMAT or DDSD_WIDTH or DDSD_HEIGHT;
362 +      if _storetype = 9 then
363 +        Flags := Flags or DDSD_LINEARSIZE
364 +      else
365 +        Flags := Flags or DDSD_PITCH;
366 +      if (imginfo and $01) > 0 then
367 +        Flags := Flags or DDSD_MIPMAPCOUNT;
368 +      Height := _height;
369 +      Width := _width;
370 +      if _storetype = 9 then
371 +        PitchOrLinearSize := width * height div 2
372 +      else
373 +        PitchOrLinearSize := width * _depth div 8;
374 +      Depth := 0;
375 +      MipMapCount := 1;
376 +      if (imginfo and $01) > 0 then
377 +      begin
378 +        x := width;
379 +        y := height;
380 +        while (x > 1) and (y > 1) do
381 +        begin
382 +          x := x div 2;
383 +          y := y div 2;
384 +          Inc(MipMapCount);
385 +        end;
386 +      end;
387 +      for i := 1 to 11 do
388 +        Reserved[i] := 0;
389 +      with PIXELFORMAT do
390 +      begin
391 +        Size := 32;
392 +        if _storetype = 9 then
393 +          Flags := DDPF_FOURCC
394 +        else
395 +          Flags := DDPF_RGB;
396 +        if _storetype in [0, 2] then
397 +          Flags := Flags or DDPF_ALPHAPIXELS;
398 +        if _storetype = 9 then
399 +          FOURCC := 'DXT1'
400 +        else
401 +        begin
402 +          RGBBitCount := _depth;
403 +          case _storetype of
404 +            0: begin
405 +              RBitMask := $0F00;
406 +              GBitMask := $00F0;
407 +              BBitMask := $000F;
408 +              AlphaBitMask := $F000;
409 +            end;
410 +            1, 2: begin
411 +              RBitMask := $7C00;
412 +              GBitMask := $03E0;
413 +              BBitMask := $001F;
414 +              if _storetype = 2 then
415 +                AlphaBitMask := $8000
416 +              else
417 +                AlphaBitMask := $0000;
418 +            end;
419 +            8: begin
420 +              RBitMask := $00FF0000;
421 +              GBitMask := $0000FF00;
422 +              BBitMask := $000000FF;
423 +              AlphaBitMask := $00000000;
424 +            end;
425 +          end;
426 +        end;
427 +      end;
428 +      with DDSCAPS2 do
429 +      begin
430 +        Caps1 := DDSCAPS_TEXTURE;
431 +        if (imginfo and $01) > 0 then
432 +          Caps1 := Caps1 or DDSCAPS_COMPLEX or DDSCAPS_MIPMAP;
433 +        Caps2 := 0;
434 +        Reserved[1] := 0;
435 +        Reserved[2] := 0;
436 +      end;
437 +    end;
438 +  end;
439 +
440 +  data := TMemoryStream.Create;
441 +  data.Write(hdr, SizeOf(hdr));
442    if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
443 <    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, FData)
443 >    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, TStream(data))
444    else
445 <    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, FData);
445 >    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, TStream(data));
446 >
447 > //  data.Seek(0, soFromBeginning);
448 > //  data.SaveToFile('m:\test.txmp');
449  
450 <  Self.FDataType := [DT_OniReverted, DT_Oni];
450 >  data.Seek(0, soFromBeginning);
451 >  result := LoadMultiImageFromStream(data, FImages);
452 >  data.Free;
453 > {
454 >  if result then
455 >  begin
456 >    for i := 0 to High(FImages) do
457 >    begin
458 >      data := TMemoryStream.Create;
459 >      data.Write(FImages[i].Bits^, FImages[i].Size);
460 >      data.Seek(0, soFromBeginning);
461 >      data.SaveToFile('m:\test.txmp.'+IntToStr(i));
462 >      data.Free;
463 >    end;
464 >  end;
465 > }
466 >  if not result then
467 >  begin
468 >    ShowMessage('Error while loading file' + #13#10 + DetermineStreamFormat(data));
469 > //    data.SaveToFile('m:\prob.dds');
470 >  end;
471   end;
472  
473  
# Line 517 | Line 475 | end;
475  
476   function TOniImage.LoadFromTXMB(ConnectionID, FileID: Integer): Boolean;
477   var
478 <  i, x, y, x2, y2, pixelid, imgid: Integer;
478 >  i, x, y, imgid: Integer;
479    rows, cols: Word;
480    linkcount: Integer;
481    link: Integer;
482 <  images_decoded: array of TOniImage;
482 >  images: array of TOniImage;
483    x_start, y_start: Integer;
484 +
485 +  width, height: Word;
486   begin
487 <  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, SizeOf(Self.FWidth), @Self.FWidth);
488 <  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $12, SizeOf(Self.FHeight), @Self.FHeight);
487 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, SizeOf(width), @width);
488 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $12, SizeOf(height), @height);
489    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, SizeOf(cols), @cols);
490    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1A, SizeOf(rows), @rows);
491    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, SizeOf(linkcount), @linkcount);
492 <  SetLength(images_decoded, linkcount);
492 >  SetLength(images, linkcount);
493    for i := 0 to linkcount - 1 do
494    begin
495      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * 4, SizeOf(link), @link);
496      link := link div 256;
497 <    images_decoded[i] := TOniImage.Create;
498 <    images_decoded[i].LoadFromTXMP(ConnectionID, link);
499 <    images_decoded[i].DecodeImageTo32bit;
500 <    images_decoded[i].RevertImage;
497 >    images[i] := TOniImage.Create;
498 >    images[i].LoadFromTXMP(ConnectionID, link);
499 >    SetLength(FImages, 1);
500 >    NewImage(width, height, ifA1R5G5B5, FImages[0]);
501    end;
542  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
502    for y := 0 to rows - 1 do
503    begin
504      for x := 0 to cols - 1 do
505      begin
506 <      imgid   := y * cols + x;
506 >      imgid := y * cols + x;
507        x_start := 0;
508        y_start := 0;
509        for i := 0 to x do
510          if i < x then
511 <          x_start := x_start + images_decoded[i].Width;
511 >          x_start := x_start + images[i].Image[0].Width;
512        for i := 0 to y do
513          if i < y then
514 <          y_start := y_start + images_decoded[i].Height;
515 <      for y2 := 0 to images_decoded[imgid].Height - 1 do
516 <      begin
558 <        for x2 := 0 to images_decoded[imgid].Width - 1 do
559 <        begin
560 <          if ((x_start + x2) < Self.FWidth) and ((y_start + y2) < Self.FHeight) then
561 <          begin
562 <            pixelid := y_start * Self.FWidth + x_start + y2 * Self.FWidth + x2;
563 <            Self.FData[pixelid * 4 + 0] :=
564 <              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 0];
565 <            Self.FData[pixelid * 4 + 1] :=
566 <              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 1];
567 <            Self.FData[pixelid * 4 + 2] :=
568 <              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 2];
569 <            Self.FData[pixelid * 4 + 3] :=
570 <              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 3];
571 <          end;
572 <        end;
573 <      end;
514 >          y_start := y_start + images[i].Image[0].Height;
515 >      CopyRect(images[imgid].Image[0], 0, 0, images[imgid].Image[0].Width,
516 >          images[imgid].Image[0].Height, FImages[0], x_start, y_start);
517      end;
518    end;
519    for i := 0 to linkcount - 1 do
520 <    images_decoded[i].Free;
578 <  Self.FDepth     := 32;
579 <  Self.FStoreType := 8;
580 <  Self.FDataType  := [DT_Decoded32];
581 <  Self.RevertImage;
520 >    images[i].Free;
521   end;
522  
523  
524  
525 <
587 < function TOniImage.GetImageDataSize(fading: Boolean): Integer;
525 > procedure TOniImage.SaveDataToStream(MipMaps: Boolean; var Target: TStream);
526   var
527 <  size: Integer;
528 <  x, y: Word;
529 <  bpp:  Byte;
527 >  images: TDynImageDataArray;
528 >  mem: TMemoryStream;
529 >  i: Integer;
530   begin
531 <  case Self.FStoreType of
532 <    9:
533 <      bpp := 8;
534 <    0, 1, 2:
535 <      bpp := 16;
536 <    8:
537 <      bpp := 32;
531 >  if Length(FImages) = 0 then
532 >    Exit;
533 >  if MipMaps then
534 >  begin
535 >    if Length(FImages) = 1 then
536 >    begin
537 >      if not GenerateMipMaps(FImages[0], 0, images) then
538 >      begin
539 >        ShowMessage('Could not generate MipMaps');
540 >        Exit;
541 >      end;
542 >    end
543      else
544 <      Result := 0;
544 >    begin
545 >      SetLength(images, Length(FImages));
546 >      for i := 0 to High(FImages) do
547 >        CloneImage(FImages[i], images[i]);
548 >    end;
549 >    mem := TMemoryStream.Create;
550 >    if not SaveMultiImageToStream('dds', mem, images) then
551 >    begin
552 >      ShowMessage('Could not save images to stream');
553        Exit;
554 <  end;
555 <
605 <  x    := Self.FWidth;
606 <  y    := Self.FHeight;
607 <  size := (x * y * bpp) div 8;
608 <  if fading then
609 <  begin
610 <    repeat
611 <      x    := x div 2;
612 <      y    := y div 2;
613 <      size := size + (x * y * bpp) div 8;
614 <    until (x = 1) or (y = 1);
615 <  end;
616 <  Result := size;
617 < end;
618 <
619 <
620 <
621 <
622 < procedure TOniImage.GetAsData(var Target: TStream);
623 < var
624 <  revert: Boolean;
625 < begin
626 <  //    if not (DT_Decoded32 in Self.FDataType) then
627 <  //      Self.DecodeImage;
628 <  if not (DT_OniReverted in Self.FDataType) then
629 <  begin
630 <    revert := True;
631 <    Self.RevertImage;
554 >    end;
555 >    FreeImagesInArray(images);
556    end
557    else
634    revert := False;
635  if not Assigned(Target) then
636    Target := TMemoryStream.Create;
637  Target.Write(FData[0], Length(FData));
638  Target.Seek(0, soFromBeginning);
639  if revert then
640    Self.RevertImage;
641 end;
642
643 procedure TOniImage.GetAsData(var Target: TByteData);
644 var
645  mem: TStream;
646 begin
647  mem := TMemoryStream.Create;
648  GetAsData(mem);
649  SetLength(Target, mem.Size);
650  mem.Read(Target[0], mem.Size);
651  mem.Free;
652 end;
653
654
655 procedure TOniImage.GetAs32bit(var Target: TStream);
656 begin
657  if not (DT_Decoded32 in Self.FDataType) then
658    Self.DecodeImageTo32bit;
659  if not Assigned(Target) then
660    Target := TMemoryStream.Create;
661  Target.Write(FData[0], Length(FData));
662  Target.Seek(0, soFromBeginning);
663 end;
664
665 procedure TOniImage.GetAs32bit(var Target: TByteData);
666 var
667  mem: TStream;
668 begin
669  mem := TMemoryStream.Create;
670  GetAs32bit(mem);
671  SetLength(Target, mem.Size);
672  mem.Read(Target[0], mem.Size);
673  mem.Free;
674 end;
675
676
677 procedure TOniImage.GetAsBMP(var Target: TByteData);
678 const
679  BMPheader: array[0..53] of Byte =
680    ($42, $4D, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
681    40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, $18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
682    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
683 var
684  i, x, y: Integer;
685 begin
686  if not (DT_Decoded32 in Self.FDataType) then
687    Self.DecodeImageTo32bit;
688
689  SetLength(Target, Self.FWidth * Self.FHeight * 3 + 54);
690  for y := 0 to Self.FHeight - 1 do
558    begin
559 <    for x := 0 to Self.FWidth - 1 do
559 >    mem := TMemoryStream.Create;
560 >    if not SaveImageToStream('dds', mem, FImages[0]) then
561      begin
562 <      Target[((Self.FWidth * y + x) * 3) + 0 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 0];
563 <      Target[((Self.FWidth * y + x) * 3) + 1 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 1];
696 <      Target[((Self.FWidth * y + x) * 3) + 2 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 2];
562 >      ShowMessage('Could not save image to stream');
563 >      Exit;
564      end;
565    end;
566 +  if not Assigned(Target) then
567 +    Target := TMemoryStream.Create;
568  
569 <  for i := 0 to High(BMPheader) do
570 <    Target[i] := BMPheader[i];
702 <  Target[2] := ((Self.FWidth * Self.FHeight * 3 + 54) and $000000FF) div $1;
703 <  Target[3]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $0000FF00) div $100;
704 <  Target[4]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $00FF0000) div $10000;
705 <  Target[5]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $FF000000) div $1000000;
706 <  Target[18] := (Self.FWidth and $000000FF) div $1;
707 <  Target[19] := (Self.FWidth and $0000FF00) div $100;
708 <  Target[20] := (Self.FWidth and $00FF0000) div $10000;
709 <  Target[21] := (Self.FWidth and $FF000000) div $1000000;
710 <  Target[22] := (Self.FHeight and $000000FF) div $1;
711 <  Target[23] := (Self.FHeight and $0000FF00) div $100;
712 <  Target[24] := (Self.FHeight and $00FF0000) div $10000;
713 <  Target[25] := (Self.FHeight and $FF000000) div $1000000;
714 <  Target[34] := ((Self.FWidth * Self.FHeight * 3) and $000000FF) div $1;
715 <  Target[35] := ((Self.FWidth * Self.FHeight * 3) and $0000FF00) div $100;
716 <  Target[36] := ((Self.FWidth * Self.FHeight * 3) and $00FF0000) div $10000;
717 <  Target[37] := ((Self.FWidth * Self.FHeight * 3) and $FF000000) div $1000000;
718 < end;
719 <
569 > //  mem.Seek(0, soFromBeginning);
570 > //  mem.SaveToFile('m:\dds.dds');
571  
572 < procedure TOniImage.GetAsBMP(var Target: TStream);
573 < var
574 <  data: TByteData;
575 <  streampos: Integer;
725 < begin
726 <  GetAsBMP(data);
727 <  streampos := Target.Position;
728 <  Target.Write(data[0], Length(data));
729 <  Target.Seek(streampos, soFromBeginning);
572 >  mem.Seek(128, soFromBeginning);
573 >  Target.CopyFrom(mem, mem.Size - 128);
574 >  mem.Free;
575 >  Target.Seek(0, soFromBeginning);
576   end;
577  
578  
579 < function TOniImage.LoadFromBMP(filename: String): Boolean;
734 < var
735 <  filestream: TFileStream;
736 <  tempd:      TByteData;
737 <
738 <  x, y: Integer;
579 > function TOniImage.LoadFromFile(filename: String): Boolean;
580   begin
581 <  filestream := TFileStream.Create(filename, fmOpenRead);
582 <  SetLength(tempd, filestream.Size);
742 <  filestream.Read(tempd[0], filestream.Size);
743 <  filestream.Free;
744 <
745 <  if not ((tempd[00] = $42) and (tempd[01] = $4D)) then
746 <  begin
747 <    Result := False;
748 <    ShowMessage('Not a standard 24bit bitmap');
749 <    Exit;
750 <  end;
751 <  if not (tempd[10] = 54) then
752 <  begin
753 <    Result := False;
754 <    ShowMessage('Imagedata has to start at 0x54');
755 <    Exit;
756 <  end;
757 <  if not (tempd[14] = 40) then
758 <  begin
759 <    Result := False;
760 <    ShowMessage('Second bitmap header has to have 40 bytes');
761 <    Exit;
762 <  end;
763 <  if not (tempd[28] = 24) then
764 <  begin
765 <    Result := False;
766 <    ShowMessage('Bitmap has to have 24bits');
767 <    Exit;
768 <  end;
769 <  if not (tempd[30] = 0) then
770 <  begin
771 <    Result := False;
772 <    ShowMessage('Bitmap has to be uncompressed');
773 <    Exit;
774 <  end;
775 <
776 <  Self.FWidth     := tempd[18] + tempd[19] * 256 + tempd[20] * 256 * 256 + tempd[21] * 256 * 256 * 256;
777 <  Self.FHeight    := tempd[22] + tempd[23] * 256 + tempd[24] * 256 * 256 + tempd[25] * 256 * 256 * 256;
778 <  Self.FDepth     := 32;
779 <  Self.FStoreType := 8;
780 <
781 <  SetLength(Self.FData, Self.FWidth * Self.FHeight * Self.FDepth div 8);
782 <  for y := 0 to Self.FHeight - 1 do
783 <  begin
784 <    for x := 0 to Self.FWidth - 1 do
785 <    begin
786 <      Self.FData[((Self.FWidth * y + x) * 4) + 0] := tempd[54 + (Self.FWidth * y + x) * 3 + 0];
787 <      Self.FData[((Self.FWidth * y + x) * 4) + 1] := tempd[54 + (Self.FWidth * y + x) * 3 + 1];
788 <      Self.FData[((Self.FWidth * y + x) * 4) + 2] := tempd[54 + (Self.FWidth * y + x) * 3 + 2];
789 <      Self.FData[((Self.FWidth * y + x) * 4) + 3] := 0;
790 <    end;
791 <  end;
792 <
793 <  Self.FDataType := [DT_Decoded32];
581 >  if not LoadMultiImageFromFile(filename, FImages) then
582 >    ShowMessage('Couldn''t load image file');
583   end;
584  
585  
586 <
798 <
799 < function TOniImage.WriteToBMP(filename: String): Boolean;
800 < var
801 <  filestream: TFileStream;
586 > function TOniImage.WriteToFile(filename: String): Boolean;
587   begin
588 <  filestream := TFileStream.Create(filename, fmCreate);
804 <  GetAsBMP(TStream(filestream));
805 <  filestream.Free;
588 >  SaveMultiImageToFile(filename, FImages);
589   end;
590  
591  
592  
593 < function TOniImage.GetMipMappedImage(var Target: TByteData): Boolean;
593 > function TOniImage.GetImageSize(MipMaps: Boolean): Integer;
594   var
595 <  i:      Integer;
596 <  x, y:   Word;
597 <  fadelvldata: TByteData;
815 <  revert: Boolean;
816 < begin
817 <  Result := False;
818 <
819 <  //    if not (DT_Decoded32 in Self.FDataType) then
820 <  //      Self.DecodeImage;
821 <  if Self.FStoreType = 9 then
822 <    Self.DecompressImage;
823 <  if not (DT_OniReverted in Self.FDataType) then
595 >  i: Integer;
596 > begin
597 >  if Length(FImages) > 0 then
598    begin
599 <    revert := True;
600 <    Self.RevertImage;
599 >    Result := FImages[0].Size;
600 >    if mipmaps then
601 >      for i := 1 to High(FImages) do
602 >        Result := Result + FImages[i].Size;
603    end
604    else
605 <    revert := False;
830 <
831 <  x := Self.FWidth;
832 <  y := Self.FHeight;
833 <  SetLength(Target, x * y * Self.FDepth div 8);
834 <  SetLength(fadelvldata, x * y * Self.FDepth div 8);
835 <  for i := 0 to Length(Target) - 1 do
836 <  begin
837 <    Target[i] := Self.FData[i];
838 <    fadelvldata[i] := Self.FData[i];
839 <  end;
840 <  repeat
841 <    fadelvldata := Self.ResizeImage(x, y, fadelvldata);
842 <    x := x div 2;
843 <    y := y div 2;
844 <    SetLength(Target, Length(Target) + x * y * Self.FDepth div 8);
845 <    for i := 0 to Length(fadelvldata) - 1 do
846 <      Target[Length(Target) - x * y * Self.FDepth div 8 + i] := fadelvldata[i];
847 <  until (x = 1) or (y = 1) or ((x mod 2) = 1) or ((y mod 2) = 1);
848 <  if (x > 1) and (y > 1) then
849 <    Exit;
850 <  Result := True;
851 <
852 <  if revert then
853 <    Self.RevertImage;
854 < end;
855 <
856 <
857 < function TOniImage.GetMipMappedImage(var Target: TStream): Boolean;
858 < var
859 <  data: TByteData;
860 <  streampos: Integer;
861 < begin
862 <  Result := GetMipMappedImage(data);
863 <  if not Assigned(Target) then
864 <    Target := TMemoryStream.Create;
865 <  streampos := Target.Position;
866 <  Target.Write(data[0], Length(data));
867 <  Target.Seek(streampos, soFromBeginning);
605 >    Result := -1;
606   end;
607  
870
608   end.

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)