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