Index: oup/current/DataAccess/Access_OniArchive.pas
===================================================================
--- oup/current/DataAccess/Access_OniArchive.pas	(revision 181)
+++ oup/current/DataAccess/Access_OniArchive.pas	(revision 192)
@@ -53,5 +53,5 @@
 
 uses
-  SysUtils, StrUtils, Data, Functions, RawList, DatLinks;
+  SysUtils, StrUtils, Data, Functions, RawList, DatLinks, Math;
 
 
@@ -560,5 +560,5 @@
           fmOpenReadWrite);
       Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
-      Fraw_file.CopyFrom(Src, raw_info.RawSize);
+      Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
       if UnloadWhenUnused then
       begin
Index: oup/current/Global/Exporters.pas
===================================================================
--- oup/current/Global/Exporters.pas	(revision 181)
+++ oup/current/Global/Exporters.pas	(revision 192)
@@ -225,5 +225,5 @@
   img := TOniImage.Create;
   img.Load(ConnectionID, FileID);
-  img.WriteToBMP(filename+'.bmp');
+  img.WriteToFile(filename+'.bmp');
   img.Free;
 end;
Index: oup/current/Global/OniImgClass.pas
===================================================================
--- oup/current/Global/OniImgClass.pas	(revision 181)
+++ oup/current/Global/OniImgClass.pas	(revision 192)
@@ -4,8 +4,5 @@
 
 uses Math, Dialogs, Types, SysUtils, Classes, Data, ConnectionManager, TypeDefs,
-  Imaging, ImagingTypes;
-
-type
-  TImgDataType = set of (DT_OniReverted, DT_Oni, DT_Decoded32);
+  Imaging, ImagingTypes, Graphics;
 
 
@@ -13,47 +10,34 @@
   TOniImage = class
   private
-    FLoaded:    Boolean;
-    FDataType:  TImgDataType;
-    FData:      TByteData;
-    FWidth, FHeight: Word;
-    FDepth:     Byte;
-    FStoreType: Byte;
-
-    FImage:     TImageData;
-
-    function ResizeImage(oldx, oldy: Integer; img: TByteData): TByteData;
-    procedure RevertImage;
-    procedure DecompressImage;
+    FImages: TDynImageDataArray;
+    function GetImage(MipGen: Integer): TImageData;
+    function GetWidth(MipGen: Integer): Integer;
+    function GetHeight(MipGen: Integer): Integer;
+    function GetImageFormat: TImageFormat;
+    procedure SetImageFormat(Format: TImageFormat);
+    function GetHasMipMaps: Boolean;
   protected
   public
-    property Image:     TImageData   Read FImage     Write FImage;
-    property Loaded:    Boolean      Read FLoaded    Write FLoaded;
-    property DataType:  TImgDataType Read FDataType  Write FDataType;
-    property Width:     Word         Read FWidth     Write FWidth;
-    property Height:    Word         Read FHeight    Write FHeight;
-    property Depth:     Byte         Read FDepth     Write FDepth;
-    property StoreType: Byte         Read FStoreType Write FStoreType;
-    property Data:      TByteData    Read FData      Write FData;
+    property Images: TDynImageDataArray         read FImages;
+    property Image[MipGen: Integer]: TImageData read GetImage;
+    property Width[MipGen: Integer]: Integer    read GetWidth;
+    property Height[MipGen: Integer]: Integer   read GetHeight;
+    property Format: TImageFormat read GetImageFormat write SetImageFormat;
+    property HasMipMaps: Boolean read GetHasMipMaps;
 
     constructor Create;
+    procedure Free;
     function Load(ConnectionID, FileID: Integer): Boolean;
     function LoadFromPSpc(ConnectionID, FileID: Integer): Boolean;
     function LoadFromTXMP(ConnectionID, FileID: Integer): Boolean;
     function LoadFromTXMB(ConnectionID, FileID: Integer): Boolean;
-    function GetImgSize(w,h, storetype: Integer): Integer;
-    function GetImageDataSize(fading: Boolean): Integer;
-
-    procedure DecodeImageTo32bit;
-
-    procedure GetAsData(var Target: TStream); overload;
-    procedure GetAsData(var Target: TByteData); overload;
-    procedure GetAs32bit(var Target: TStream); overload;
-    procedure GetAs32bit(var Target: TByteData); overload;
-    procedure GetAsBMP(var Target: TStream); overload;
-    procedure GetAsBMP(var Target: TByteData); overload;
-    function LoadFromBMP(filename: String): Boolean;
-    function WriteToBMP(filename: String): Boolean;
-    function GetMipMappedImage(var Target: TStream): Boolean; overload;
-    function GetMipMappedImage(var Target: TByteData): Boolean; overload;
+
+    procedure SaveDataToStream(MipMaps: Boolean; var Target: TStream);
+
+    function LoadFromFile(filename: String): Boolean;
+    function WriteToFile(filename: String): Boolean;
+
+    procedure DrawOnCanvas(Canvas: TCanvas; Index: Integer);
+    function GetImageSize(MipMaps: Boolean): Integer;
   published
   end;
@@ -63,256 +47,92 @@
 
 //uses Functions;
-uses Img_DDSTypes;
+uses Img_DDSTypes, ImagingComponents;
+
+
+procedure TOniImage.DrawOnCanvas(Canvas: TCanvas; Index: Integer);
+var
+  singleimg: TImageData;
+  rect: TRect;
+begin
+  InitImage(singleimg);
+  CloneImage(FImages[Index], singleimg);
+  ConvertImage(singleimg, ifX8R8G8B8);
+  rect.Left := 0;
+  rect.Top := 0;
+  rect.Right := singleimg.Width - 1;
+  rect.Bottom := singleimg.Height - 1;
+  Canvas.Brush.Color := $C8D0D4;
+  Canvas.FillRect(Canvas.ClipRect);
+  DisplayImageData(Canvas, rect, singleimg, rect);
+  FreeImage(singleimg);
+end;
+
 
 
 constructor TOniImage.Create;
 begin
-  Self.FLoaded   := False;
-  Self.FDataType := [];
-  SetLength(Self.FData, 0);
-  Self.FWidth     := 0;
-  Self.FHeight    := 0;
-  Self.FDepth     := 0;
-  Self.FStoreType := 0;
-
-  InitImage(FImage);
-end;
-
-
-
-
-function TOniImage.ResizeImage(oldx, oldy: Integer; img: TByteData): TByteData;
-var
-  i, j: Integer;
-  col, row, row_orig: Integer;
-begin
-  SetLength(Result, (oldx div 2) * (oldy div 2) * (Self.FDepth div 8));
-  row_orig := 0;
-  row      := 0;
-  col      := 0;
-  for i := 0 to (oldx * oldy) - 1 do
-  begin
-    if ((i mod oldx) = 0) and (i > 0) then
-    begin
-      Inc(row_orig);
-      if (row_orig mod 2) = 0 then
-      begin
-        Inc(row);
-        col := 0;
-      end;
-    end;
-    if (row_orig mod 2) = 0 then
-    begin
-      if (i mod 2) = 0 then
-      begin
-        for j := 0 to (Self.FDepth div 8) - 1 do
-          Result[((row * (oldx div 2)) + col) * (Self.FDepth div 8) + j] :=
-            img[(i * (Self.FDepth div 8)) + j];
-        Inc(col);
-      end;
-    end;
-  end;
-end;
-
-
-
-
-procedure TOniImage.RevertImage;
-var
-  x, y, i: Integer;
-  tempd:   TByteData;
-begin
-  SetLength(tempd, Self.FWidth * Self.FHeight * (Self.FDepth div 8));
-  for y := 0 to Self.FHeight - 1 do
-    for x := 0 to Self.FWidth - 1 do
-      for i := 0 to (Self.FDepth div 8) - 1 do
-        tempd[((Self.FWidth * (Self.FHeight - 1 - y) + x) * (Self.FDepth div 8)) + i] :=
-          Self.FData[(Self.FWidth * y + x) * (Self.FDepth div 8) + i];
-  for x := 0 to High(tempd) do
-    Self.FData[x] := tempd[x];
-  if DT_OniReverted in Self.FDataType then
-    Self.FDataType := Self.FDataType - [DT_OniReverted]
-  else
-    Self.FDataType := Self.FDataType + [DT_OniReverted];
-end;
-
-
-
-
-procedure TOniImage.DecodeImageTo32bit;
-var
-  x, y:  Integer;
-  tempd: TByteData;
-begin
-  if not (DT_Decoded32 in Self.FDataType) then
-  begin
-    SetLength(tempd, Self.FWidth * Self.FHeight * 4);
-    case Self.FStoreType of
-      0: // 16bit, RGB444, A4?
-      begin
-        for y := 0 to Self.FHeight - 1 do
-        begin
-          for x := 0 to Self.FWidth - 1 do
-          begin
-            tempd[((Self.FWidth * y + x) * 4) + 0] :=
-              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $000F) / $000F * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 1] :=
-              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $00F0) / $00F0 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 2] :=
-              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $0F00) / $0F00 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
-          end;
-        end;
-      end;
-      1, 2: // 16bit, RGB555, A1?
-      begin
-        for y := 0 to Self.FHeight - 1 do
-        begin
-          for x := 0 to Self.FWidth - 1 do
-          begin
-            tempd[((Self.FWidth * y + x) * 4) + 0] :=
-              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $001F) / $001F * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 1] :=
-              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $03E0) / $03E0 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 2] :=
-              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $7C00) / $7C00 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
-          end;
-        end;
-      end;
-      8: // 32bit, RGB888, A8?
-      begin end;
-      9: // Compressed, RGB565
-      begin
-        DecompressImage;
-      end;
-    end;
-    Self.FDepth := 32;
-    if (Self.FStoreType <> 9) and (Self.FStoreType <> 8) then
-    begin
-      SetLength(Self.FData, Length(tempd));
-      for x := 0 to High(tempd) do
-        Self.FData[x] := tempd[x];
-    end;
-    Self.FStoreType := 8;
-    if DT_Oni in Self.FDataType then
-      Self.FDataType := Self.FDataType - [DT_Oni];
-    Self.FDataType := Self.FDataType + [DT_Decoded32];
-  end;
-  if DT_OniReverted in Self.FDataType then
-    Self.RevertImage;
-end;
-
-
-
-
-procedure TOniImage.DecompressImage;
-type
-  Tcolor = record
-    RGBb: Byte;
-    RGBg: Byte;
-    RGBr: Byte;
-    RGBa: Byte;
-  end;
-var
-  i, j, x, y: Integer;
-  color:      array[1..4] of Tcolor;
-  pixel:      array[1..16] of Byte;
-  tempd:      TByteData;
-begin
-  x := 0;
-  y := 0;
-  SetLength(tempd, Self.FWidth * Self.FHeight * 4);
-  for i := 0 to ((Self.FWidth * Self.FHeight) div 16) - 1 do
-  begin
-    Color[1].RGBb := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $001F) /
-      $001F * 255);
-    Color[1].RGBg := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $07E0) /
-      $07E0 * 255);
-    Color[1].RGBr := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $F800) /
-      $F800 * 255);
-    Color[1].RGBa := 255;
-    Color[2].RGBb := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $001F) /
-      $001F * 255);
-    Color[2].RGBg := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $07E0) /
-      $07E0 * 255);
-    Color[2].RGBr := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $F800) /
-      $F800 * 255);
-    Color[2].RGBa := 255;
-    Color[3].RGBb := Round(Color[1].RGBb / 3 * 2 + Color[2].RGBb / 3);
-    Color[3].RGBg := Round(Color[1].RGBg / 3 * 2 + Color[2].RGBg / 3);
-    Color[3].RGBr := Round(Color[1].RGBr / 3 * 2 + Color[2].RGBr / 3);
-    Color[3].RGBa := 255;
-    Color[4].RGBb := Round(Color[1].RGBb / 3 + Color[2].RGBb / 3 * 2);
-    Color[4].RGBg := Round(Color[1].RGBg / 3 + Color[2].RGBg / 3 * 2);
-    Color[4].RGBr := Round(Color[1].RGBr / 3 + Color[2].RGBr / 3 * 2);
-    Color[4].RGBa := 255;
-    Pixel[1]      := Round((Self.FData[(i * 8) + 4] and $C0) / $40 + 1);
-    Pixel[2]      := Round((Self.FData[(i * 8) + 4] and $30) / $10 + 1);
-    Pixel[3]      := Round((Self.FData[(i * 8) + 4] and $0C) / $04 + 1);
-    Pixel[4]      := Round((Self.FData[(i * 8) + 4] and $03) + 1);
-    Pixel[5]      := Round((Self.FData[(i * 8) + 5] and $C0) / $40 + 1);
-    Pixel[6]      := Round((Self.FData[(i * 8) + 5] and $30) / $10 + 1);
-    Pixel[7]      := Round((Self.FData[(i * 8) + 5] and $0C) / $04 + 1);
-    Pixel[8]      := Round((Self.FData[(i * 8) + 5] and $03) + 1);
-    Pixel[9]      := Round((Self.FData[(i * 8) + 6] and $C0) / $40 + 1);
-    Pixel[10]     := Round((Self.FData[(i * 8) + 6] and $30) / $10 + 1);
-    Pixel[11]     := Round((Self.FData[(i * 8) + 6] and $0C) / $04 + 1);
-    Pixel[12]     := Round((Self.FData[(i * 8) + 6] and $03) + 1);
-    Pixel[13]     := Round((Self.FData[(i * 8) + 7] and $C0) / $40 + 1);
-    Pixel[14]     := Round((Self.FData[(i * 8) + 7] and $30) / $10 + 1);
-    Pixel[15]     := Round((Self.FData[(i * 8) + 7] and $0C) / $04 + 1);
-    Pixel[16]     := Round((Self.FData[(i * 8) + 7] and $03) + 1);
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[16 - j]].RGBb;
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[16 - j]].RGBg;
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[16 - j]].RGBr;
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[12 - j]].RGBb;
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[12 - j]].RGBg;
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[12 - j]].RGBr;
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[8 - j]].RGBb;
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[8 - j]].RGBg;
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[8 - j]].RGBr;
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[4 - j]].RGBb;
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[4 - j]].RGBg;
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[4 - j]].RGBr;
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    x := x + 4;
-    if x = Self.FWidth then
-    begin
-      y := y + 4;
-      x := 0;
-    end;
-  end;
-  SetLength(Self.FData, Length(tempd));
-  for i := 0 to High(tempd) do
-    Self.FData[i] := tempd[i];
-  Self.FStoreType := 8;
-  Self.FDepth    := 32;
-  Self.FDataType := Self.FDataType - [DT_Oni] + [DT_Decoded32];
-end;
-
-
-
+end;
+
+
+
+procedure TOniImage.Free;
+begin
+  FreeImagesInArray(FImages);
+end;
+
+
+
+
+function TOniImage.GetImage(MipGen: Integer): TImageData;
+begin
+  if MipGen <= Length(FImages) then
+  begin
+    InitImage(Result);
+    CloneImage(FImages[MipGen-1], Result);
+  end;
+end;
+
+
+
+function TOniImage.GetWidth(MipGen: Integer): Integer;
+begin
+  if MipGen <= Length(FImages) then
+    Result := FImages[MipGen-1].Width
+  else
+    Result := -1;
+end;
+
+
+function TOniImage.GetHeight(MipGen: Integer): Integer;
+begin
+  if MipGen <= Length(FImages) then
+    Result := FImages[MipGen-1].Height
+  else
+    Result := -1;
+end;
+
+
+function TOniImage.GetImageFormat: TImageFormat;
+begin
+  if Length(FImages) > 0 then
+    Result := FImages[0].Format
+  else
+    Result := ifUnknown;
+end;
+
+procedure TOniImage.SetImageFormat(Format: TImageFormat);
+var
+  i: Integer;
+begin
+  if Length(FImages) > 0 then
+    for i := 0 to High(FImages) do
+      ConvertImage(FImages[i], Format);
+end;
+
+
+function TOniImage.GetHasMipMaps: Boolean;
+begin
+  Result := Length(FImages) > 1;
+end;
 
 
@@ -370,4 +190,5 @@
   col, row: Byte;
 begin
+(*
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, SizeOf(PSpc), @PSpc);
   PSpc.TXMP := PSpc.TXMP div 256;
@@ -472,4 +293,5 @@
   Self.FDataType  := [DT_Decoded32];
   //    Self.RevertImage;
+*)
 end;
 
@@ -484,9 +306,13 @@
   imginfo: Integer;
   x,y, i: Integer;
+
+  _width, _height: Word;
+  _storetype: Byte;
+  _depth: Byte;
 begin
   Result := True;
-  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(Self.FWidth), @Self.FWidth);
-  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(Self.FHeight), @Self.FHeight);
-  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(Self.FStoreType), @Self.FStoreType);
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(_width), @_width);
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(_height), @_height);
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(_storetype), @_storetype);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $88, SizeOf(imginfo), @imginfo);
   if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
@@ -495,11 +321,11 @@
     ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $A0, SizeOf(img_addr), @img_addr);
 
-  case Self.FStoreType of
+  case _storetype of
     0, 1, 2:
-      Self.FDepth := 16;
-    8:
-      Self.FDepth := 32;
+      _depth := 16;
+    7, 8:
+      _depth := 32;
     9:
-      Self.FDepth := 16;
+      _depth := 16;
     else
       Result := False;
@@ -507,9 +333,4 @@
   end;
 
-  if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
-    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, TStream(data))
-  else
-    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, TStream(data));
-
   with hdr do
   begin
@@ -519,5 +340,5 @@
       Size := 124;
       Flags := DDSD_CAPS or DDSD_PIXELFORMAT or DDSD_WIDTH or DDSD_HEIGHT;
-      if FStoreType = 9 then
+      if _storetype = 9 then
         Flags := Flags or DDSD_LINEARSIZE
       else
@@ -525,19 +346,22 @@
       if (imginfo and $01) > 0 then
         Flags := Flags or DDSD_MIPMAPCOUNT;
-      Height := FHeight;
-      Width := FWidth;
-      if FStoreType = 9 then
-        PitchOrLinearSize := FWidth * FHeight div 2
+      Height := _height;
+      Width := _width;
+      if _storetype = 9 then
+        PitchOrLinearSize := width * height div 2
       else
-        PitchOrLinearSize := FWidth * FDepth div 2;
+        PitchOrLinearSize := width * _depth div 8;
       Depth := 0;
       MipMapCount := 1;
-      x := FWidth;
-      y := FHeight;
-      while (x > 1) and (y > 1) do
+      if (imginfo and $01) > 0 then
       begin
-        x := x div 2;
-        y := y div 2;
-        Inc(MipMapCount);
+        x := width;
+        y := height;
+        while (x > 1) and (y > 1) do
+        begin
+          x := x div 2;
+          y := y div 2;
+          Inc(MipMapCount);
+        end;
       end;
       for i := 1 to 11 do
@@ -546,19 +370,67 @@
       begin
         Size := 32;
-        if FStoreType = 9 then
+        if _storetype = 9 then
           Flags := DDPF_FOURCC
         else
           Flags := DDPF_RGB;
+        if _storetype in [0, 2] then
+          Flags := Flags or DDPF_ALPHAPIXELS;
+        if _storetype = 9 then
+          FOURCC := 'DXT1'
+        else
+        begin
+          RGBBitCount := _depth;
+          case _storetype of
+            0: begin
+              RBitMask := $0F00;
+              GBitMask := $00F0;
+              BBitMask := $000F;
+              AlphaBitMask := $F000;
+            end;
+            1, 2: begin
+              RBitMask := $7C00;
+              GBitMask := $03E0;
+              BBitMask := $001F;
+              if _storetype = 2 then
+                AlphaBitMask := $8000
+              else
+                AlphaBitMask := $0000;
+            end;
+            8: begin
+              RBitMask := $00FF0000;
+              GBitMask := $0000FF00;
+              BBitMask := $000000FF;
+              AlphaBitMask := $00000000;
+            end;
+          end;
+        end;
       end;
-    end;
-  end; 
-  LoadImageFromStream(data, FImage);
-{
+      with DDSCAPS2 do
+      begin
+        Caps1 := DDSCAPS_TEXTURE;
+        if (imginfo and $01) > 0 then
+          Caps1 := Caps1 or DDSCAPS_COMPLEX or DDSCAPS_MIPMAP;
+        Caps2 := 0;
+        Reserved[1] := 0;
+        Reserved[2] := 0;
+      end;
+    end;
+  end;
+
+  data := TMemoryStream.Create;
+  data.Write(hdr, SizeOf(hdr));
   if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
-    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, FData)
-  else
-    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, FData);
-}
-  Self.FDataType := [DT_OniReverted, DT_Oni];
+    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, TStream(data))
+  else
+    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, TStream(data));
+  data.Seek(0, soFromBeginning);
+  result := LoadMultiImageFromStream(data, FImages);
+  data.Free;
+
+  if not result then
+  begin
+    ShowMessage('Error while loading file' + #13#10 + DetermineStreamFormat(data));
+//    data.SaveToFile('m:\prob.dds');
+  end;
 end;
 
@@ -572,351 +444,129 @@
   linkcount: Integer;
   link: Integer;
-  images_decoded: array of TOniImage;
+  images: array of TOniImage;
   x_start, y_start: Integer;
-begin
-  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, SizeOf(Self.FWidth), @Self.FWidth);
-  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $12, SizeOf(Self.FHeight), @Self.FHeight);
+
+  width, height: Word;
+begin
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, SizeOf(width), @width);
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $12, SizeOf(height), @height);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, SizeOf(cols), @cols);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1A, SizeOf(rows), @rows);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, SizeOf(linkcount), @linkcount);
-  SetLength(images_decoded, linkcount);
+  SetLength(images, linkcount);
   for i := 0 to linkcount - 1 do
   begin
     ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * 4, SizeOf(link), @link);
     link := link div 256;
-    images_decoded[i] := TOniImage.Create;
-    images_decoded[i].LoadFromTXMP(ConnectionID, link);
-    images_decoded[i].DecodeImageTo32bit;
-    images_decoded[i].RevertImage;
-  end;
-  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
+    images[i] := TOniImage.Create;
+    images[i].LoadFromTXMP(ConnectionID, link);
+    SetLength(FImages, 1);
+    NewImage(width, height, ifA1R5G5B5, FImages[0]);
+  end;
   for y := 0 to rows - 1 do
   begin
     for x := 0 to cols - 1 do
     begin
-      imgid   := y * cols + x;
+      imgid := y * cols + x;
       x_start := 0;
       y_start := 0;
       for i := 0 to x do
         if i < x then
-          x_start := x_start + images_decoded[i].Width;
+          x_start := x_start + images[i].Image[0].Width;
       for i := 0 to y do
         if i < y then
-          y_start := y_start + images_decoded[i].Height;
-      for y2 := 0 to images_decoded[imgid].Height - 1 do
+          y_start := y_start + images[i].Image[0].Height;
+      CopyRect(images[imgid].Image[0], 0, 0, images[imgid].Image[0].Width,
+          images[imgid].Image[0].Height, FImages[0], x_start, y_start);
+    end;
+  end;
+  for i := 0 to linkcount - 1 do
+    images[i].Free;
+end;
+
+
+
+procedure TOniImage.SaveDataToStream(MipMaps: Boolean; var Target: TStream);
+var
+  images: TDynImageDataArray;
+  mem: TMemoryStream;
+  i: Integer;
+begin
+  if Length(FImages) = 0 then
+    Exit;
+  if MipMaps then
+  begin
+    if Length(FImages) = 1 then
+    begin
+      if not GenerateMipMaps(FImages[0], 0, images) then
       begin
-        for x2 := 0 to images_decoded[imgid].Width - 1 do
-        begin
-          if ((x_start + x2) < Self.FWidth) and ((y_start + y2) < Self.FHeight) then
-          begin
-            pixelid := y_start * Self.FWidth + x_start + y2 * Self.FWidth + x2;
-            Self.FData[pixelid * 4 + 0] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 0];
-            Self.FData[pixelid * 4 + 1] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 1];
-            Self.FData[pixelid * 4 + 2] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 2];
-            Self.FData[pixelid * 4 + 3] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 3];
-          end;
-        end;
+        ShowMessage('Could not generate MipMaps');
+        Exit;
       end;
-    end;
-  end;
-  for i := 0 to linkcount - 1 do
-    images_decoded[i].Free;
-  Self.FDepth     := 32;
-  Self.FStoreType := 8;
-  Self.FDataType  := [DT_Decoded32];
-  Self.RevertImage;
-end;
-
-
-
-function TOniImage.GetImgSize(w,h, storetype: Integer): Integer;
-begin
-  case storetype of
-    0, 1, 2:
-      Result := w*h*2;
-    8:
-      Result := w*h*4;
-    9:
-      Result := Max(1, w div 4) * Max(1, h div 4) * 8;
-  else
-    Result := -1;
-  end;
-end;
-
-
-function TOniImage.GetImageDataSize(fading: Boolean): Integer;
-var
-  size: Integer;
-  x, y: Word;
-begin
-  x    := Self.FWidth;
-  y    := Self.FHeight;
-  size := GetImgSize(x, y, FStoreType);
-  if fading then
-  begin
-    repeat
-      x    := Max(x div 2, 1);
-      y    := Max(y div 2, 1);
-      size := size + GetImgSize(x, y, FStoreType);
-    until (x = 1) and (y = 1);
-  end;
-  Result := size;
-end;
-
-
-
-
-procedure TOniImage.GetAsData(var Target: TStream);
-var
-  revert: Boolean;
-begin
-  //    if not (DT_Decoded32 in Self.FDataType) then
-  //      Self.DecodeImage;
-  if not (DT_OniReverted in Self.FDataType) then
-  begin
-    revert := True;
-    Self.RevertImage;
+    end
+    else
+    begin
+      SetLength(images, Length(FImages));
+      for i := 0 to High(FImages) do
+        CloneImage(FImages[i], images[i]);
+    end;
+    mem := TMemoryStream.Create;
+    if not SaveMultiImageToStream('dds', mem, images) then
+    begin
+      ShowMessage('Could not save images to stream');
+      Exit;
+    end;
+    FreeImagesInArray(images);
   end
   else
-    revert := False;
+  begin
+    mem := TMemoryStream.Create;
+    if not SaveImageToStream('dds', mem, FImages[0]) then
+    begin
+      ShowMessage('Could not save image to stream');
+      Exit;
+    end;
+  end;
   if not Assigned(Target) then
     Target := TMemoryStream.Create;
-  Target.Write(FData[0], Length(FData));
+
+//  mem.Seek(0, soFromBeginning);
+//  mem.SaveToFile('m:\dds.dds');
+
+  mem.Seek(128, soFromBeginning);
+  Target.CopyFrom(mem, mem.Size - 128);
+  mem.Free;
   Target.Seek(0, soFromBeginning);
-  if revert then
-    Self.RevertImage;
-end;
-
-procedure TOniImage.GetAsData(var Target: TByteData);
-var
-  mem: TStream;
-begin
-  mem := TMemoryStream.Create;
-  GetAsData(mem);
-  SetLength(Target, mem.Size);
-  mem.Read(Target[0], mem.Size);
-  mem.Free;
-end;
-
-
-procedure TOniImage.GetAs32bit(var Target: TStream);
-begin
-  if not (DT_Decoded32 in Self.FDataType) then
-    Self.DecodeImageTo32bit;
-  if not Assigned(Target) then
-    Target := TMemoryStream.Create;
-  Target.Write(FData[0], Length(FData));
-  Target.Seek(0, soFromBeginning);
-end;
-
-procedure TOniImage.GetAs32bit(var Target: TByteData);
-var
-  mem: TStream;
-begin
-  mem := TMemoryStream.Create;
-  GetAs32bit(mem);
-  SetLength(Target, mem.Size);
-  mem.Read(Target[0], mem.Size);
-  mem.Free;
-end;
-
-
-procedure TOniImage.GetAsBMP(var Target: TByteData);
-const
-  BMPheader: array[0..53] of Byte =
-    ($42, $4D, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
-    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,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-var
-  i, x, y: Integer;
-begin
-  if not (DT_Decoded32 in Self.FDataType) then
-    Self.DecodeImageTo32bit;
-
-  SetLength(Target, Self.FWidth * Self.FHeight * 3 + 54);
-  for y := 0 to Self.FHeight - 1 do
-  begin
-    for x := 0 to Self.FWidth - 1 do
-    begin
-      Target[((Self.FWidth * y + x) * 3) + 0 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 0];
-      Target[((Self.FWidth * y + x) * 3) + 1 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 1];
-      Target[((Self.FWidth * y + x) * 3) + 2 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 2];
-    end;
-  end;
-
-  for i := 0 to High(BMPheader) do
-    Target[i] := BMPheader[i];
-  Target[2] := ((Self.FWidth * Self.FHeight * 3 + 54) and $000000FF) div $1;
-  Target[3]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $0000FF00) div $100;
-  Target[4]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $00FF0000) div $10000;
-  Target[5]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $FF000000) div $1000000;
-  Target[18] := (Self.FWidth and $000000FF) div $1;
-  Target[19] := (Self.FWidth and $0000FF00) div $100;
-  Target[20] := (Self.FWidth and $00FF0000) div $10000;
-  Target[21] := (Self.FWidth and $FF000000) div $1000000;
-  Target[22] := (Self.FHeight and $000000FF) div $1;
-  Target[23] := (Self.FHeight and $0000FF00) div $100;
-  Target[24] := (Self.FHeight and $00FF0000) div $10000;
-  Target[25] := (Self.FHeight and $FF000000) div $1000000;
-  Target[34] := ((Self.FWidth * Self.FHeight * 3) and $000000FF) div $1;
-  Target[35] := ((Self.FWidth * Self.FHeight * 3) and $0000FF00) div $100;
-  Target[36] := ((Self.FWidth * Self.FHeight * 3) and $00FF0000) div $10000;
-  Target[37] := ((Self.FWidth * Self.FHeight * 3) and $FF000000) div $1000000;
-end;
-
-
-procedure TOniImage.GetAsBMP(var Target: TStream);
-var
-  data: TByteData;
-  streampos: Integer;
-begin
-  GetAsBMP(data);
-  streampos := Target.Position;
-  Target.Write(data[0], Length(data));
-  Target.Seek(streampos, soFromBeginning);
-end;
-
-
-function TOniImage.LoadFromBMP(filename: String): Boolean;
-var
-  filestream: TFileStream;
-  tempd:      TByteData;
-
-  x, y: Integer;
-begin
-  filestream := TFileStream.Create(filename, fmOpenRead);
-  SetLength(tempd, filestream.Size);
-  filestream.Read(tempd[0], filestream.Size);
-  filestream.Free;
-
-  if not ((tempd[00] = $42) and (tempd[01] = $4D)) then
-  begin
-    Result := False;
-    ShowMessage('Not a standard 24bit bitmap');
-    Exit;
-  end;
-  if not (tempd[10] = 54) then
-  begin
-    Result := False;
-    ShowMessage('Imagedata has to start at 0x54');
-    Exit;
-  end;
-  if not (tempd[14] = 40) then
-  begin
-    Result := False;
-    ShowMessage('Second bitmap header has to have 40 bytes');
-    Exit;
-  end;
-  if not (tempd[28] = 24) then
-  begin
-    Result := False;
-    ShowMessage('Bitmap has to have 24bits');
-    Exit;
-  end;
-  if not (tempd[30] = 0) then
-  begin
-    Result := False;
-    ShowMessage('Bitmap has to be uncompressed');
-    Exit;
-  end;
-
-  Self.FWidth     := tempd[18] + tempd[19] * 256 + tempd[20] * 256 * 256 + tempd[21] * 256 * 256 * 256;
-  Self.FHeight    := tempd[22] + tempd[23] * 256 + tempd[24] * 256 * 256 + tempd[25] * 256 * 256 * 256;
-  Self.FDepth     := 32;
-  Self.FStoreType := 8;
-
-  SetLength(Self.FData, Self.FWidth * Self.FHeight * Self.FDepth div 8);
-  for y := 0 to Self.FHeight - 1 do
-  begin
-    for x := 0 to Self.FWidth - 1 do
-    begin
-      Self.FData[((Self.FWidth * y + x) * 4) + 0] := tempd[54 + (Self.FWidth * y + x) * 3 + 0];
-      Self.FData[((Self.FWidth * y + x) * 4) + 1] := tempd[54 + (Self.FWidth * y + x) * 3 + 1];
-      Self.FData[((Self.FWidth * y + x) * 4) + 2] := tempd[54 + (Self.FWidth * y + x) * 3 + 2];
-      Self.FData[((Self.FWidth * y + x) * 4) + 3] := 0;
-    end;
-  end;
-
-  Self.FDataType := [DT_Decoded32];
-end;
-
-
-
-
-function TOniImage.WriteToBMP(filename: String): Boolean;
-var
-  filestream: TFileStream;
-begin
-  filestream := TFileStream.Create(filename, fmCreate);
-  GetAsBMP(TStream(filestream));
-  filestream.Free;
-end;
-
-
-
-function TOniImage.GetMipMappedImage(var Target: TByteData): Boolean;
-var
-  i:      Integer;
-  x, y:   Word;
-  fadelvldata: TByteData;
-  revert: Boolean;
-begin
-  Result := False;
-
-  //    if not (DT_Decoded32 in Self.FDataType) then
-  //      Self.DecodeImage;
-  if Self.FStoreType = 9 then
-    Self.DecompressImage;
-  if not (DT_OniReverted in Self.FDataType) then
-  begin
-    revert := True;
-    Self.RevertImage;
+end;
+
+
+function TOniImage.LoadFromFile(filename: String): Boolean;
+begin
+  if not LoadMultiImageFromFile(filename, FImages) then
+    ShowMessage('Couldn''t load image file');
+end;
+
+
+function TOniImage.WriteToFile(filename: String): Boolean;
+begin
+  SaveMultiImageToFile(filename, FImages);
+end;
+
+
+
+function TOniImage.GetImageSize(MipMaps: Boolean): Integer;
+var
+  i: Integer;
+begin
+  if Length(FImages) > 0 then
+  begin
+    Result := FImages[0].Size;
+    if mipmaps then
+      for i := 1 to High(FImages) do
+        Result := Result + FImages[i].Size;
   end
   else
-    revert := False;
-
-  x := Self.FWidth;
-  y := Self.FHeight;
-  SetLength(Target, x * y * Self.FDepth div 8);
-  SetLength(fadelvldata, x * y * Self.FDepth div 8);
-  for i := 0 to Length(Target) - 1 do
-  begin
-    Target[i] := Self.FData[i];
-    fadelvldata[i] := Self.FData[i];
-  end;
-  repeat
-    fadelvldata := Self.ResizeImage(x, y, fadelvldata);
-    x := x div 2;
-    y := y div 2;
-    SetLength(Target, Length(Target) + x * y * Self.FDepth div 8);
-    for i := 0 to Length(fadelvldata) - 1 do
-      Target[Length(Target) - x * y * Self.FDepth div 8 + i] := fadelvldata[i];
-  until (x = 1) or (y = 1) or ((x mod 2) = 1) or ((y mod 2) = 1);
-  if (x > 1) and (y > 1) then
-    Exit;
-  Result := True;
-
-  if revert then
-    Self.RevertImage;
-end;
-
-
-function TOniImage.GetMipMappedImage(var Target: TStream): Boolean;
-var
-  data: TByteData;
-  streampos: Integer;
-begin
-  Result := GetMipMappedImage(data);
-  if not Assigned(Target) then
-    Target := TMemoryStream.Create;
-  streampos := Target.Position;
-  Target.Write(data[0], Length(data));
-  Target.Seek(streampos, soFromBeginning);
-end;
-
+    Result := -1;
+end;
 
 end.
Index: oup/current/OniUnPacker.bdsproj
===================================================================
--- oup/current/OniUnPacker.bdsproj	(revision 181)
+++ oup/current/OniUnPacker.bdsproj	(revision 192)
@@ -131,5 +131,5 @@
 		</Directories>
 		<Parameters>
-			<Parameters Name="RunParams"></Parameters>
+			<Parameters Name="RunParams">dat "C:\Spiele\Oni\GameDataFolder\level1_final.dat"</Parameters>
 			<Parameters Name="HostApplication"></Parameters>
 			<Parameters Name="Launcher"></Parameters>
Index: oup/current/Tools/Preview.pas
===================================================================
--- oup/current/Tools/Preview.pas	(revision 181)
+++ oup/current/Tools/Preview.pas	(revision 192)
@@ -30,5 +30,5 @@
     procedure LoadImage(fileid, index: Integer);
   private
-    bitmaps:   array of TBitmap;
+    bitmaps:   array of TOniImage;
     actualimg: Byte;
     _fileid:   Integer;
@@ -41,4 +41,5 @@
 implementation
 {$R *.dfm}
+uses Imaging, ImagingComponents, ImagingTypes;
 
 
@@ -83,15 +84,6 @@
 
 procedure TForm_Preview.LoadImage(fileid, index: Integer);
-var
-  memstream: TMemoryStream;
-  OniImage:  TOniImage;
-begin
-  OniImage := TOniImage.Create;
-  OniImage.Load(ConnectionID, fileid);
-  memstream := TMemoryStream.Create;
-  OniImage.GetAsBMP(TStream(memstream));
-  OniImage.Free;
-  bitmaps[index].LoadFromStream(memstream);
-  memstream.Free;
+begin
+  bitmaps[index].Load(ConnectionID, fileid);
 end;
 
@@ -99,9 +91,5 @@
 procedure TForm_Preview.DrawImage(index: Integer);
 begin
-  BitBlt(img.Canvas.Handle, 0, 0, img.Width, img.Height,
-    bitmaps[index].Canvas.Handle, 0, 0, WHITENESS);
-  BitBlt(img.Canvas.Handle, 0, 0, bitmaps[index].Width, bitmaps[index].Height,
-    bitmaps[index].Canvas.Handle, 0, 0, SRCCOPY);
-  img.Invalidate;
+  bitmaps[index].DrawOnCanvas(img.Canvas, 0);
 end;
 
@@ -122,5 +110,5 @@
     SetLength(bitmaps, Count);
     for i := i to High(bitmaps) do
-      bitmaps[i] := TBitmap.Create;
+      bitmaps[i] := TOniImage.Create;
   end;
 end;
Index: oup/current/Tools/TxmpReplace.dfm
===================================================================
--- oup/current/Tools/TxmpReplace.dfm	(revision 181)
+++ oup/current/Tools/TxmpReplace.dfm	(revision 192)
@@ -147,5 +147,4 @@
   end
   object opend: TOpenDialog [4]
-    Filter = '24bit Bitmap (*.bmp)|*.bmp'
     Options = [ofPathMustExist, ofFileMustExist, ofEnableSizing]
     Left = 352
@@ -154,5 +153,8 @@
   object saved: TSaveDialog [5]
     DefaultExt = 'bmp'
-    Filter = 'Windows Bitmap (*.bmp)|*.bmp'
+    Filter = 
+      'All supported files (*.bmp, *.dds)|*.bmp;*.dds|Windows Bitmap (*' +
+      '.bmp)|*.bmp|DirectDraw Surface (*.dds)|*.dds|Targa (*.tga)|*.tga' +
+      '|JPEG (*.jpg, *.jpeg)|*.jpg;*.jpeg|All files (*.*)|*'
     Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing]
     Left = 104
Index: oup/current/Tools/TxmpReplace.pas
===================================================================
--- oup/current/Tools/TxmpReplace.pas	(revision 181)
+++ oup/current/Tools/TxmpReplace.pas	(revision 192)
@@ -41,5 +41,5 @@
 implementation
 {$R *.dfm}
-uses Main, ConnectionManager;
+uses Main, ConnectionManager, ImagingTypes;
 
 
@@ -54,14 +54,12 @@
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $89, SizeOf(depthbyte), @depthbyte);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(storebyte), @storebyte);
-  check_fading.Checked := (fadingbyte and $01) > 0;
-  check_transparency.Checked := (depthbyte and $04) > 0;
 
   OniImage_Old.LoadFromTXMP(ConnectionID, fileid);
-  old_size := OniImage_Old.GetImageDataSize((fadingbyte and $01) > 0);
-  mem  := TMemoryStream.Create;
-  OniImage_Old.GetAsBMP(TStream(mem));
-  mem.Seek(0, soFromBeginning);
-  image_txmppreview.Picture.Bitmap.LoadFromStream(mem);
-  mem.Free;
+  old_size := OniImage_Old.GetImageSize(True);
+  OniImage_Old.DrawOnCanvas(image_txmppreview.Canvas, 0);
+
+  check_fading.Checked := OniImage_Old.HasMipMaps;
+//  check_transparency.Checked := (depthbyte and $04) > 0;
+  check_transparency.Checked := storebyte in [0, 2, 7];
 
   group_bmpselect.Enabled := True;
@@ -75,10 +73,6 @@
   if opend.Execute then
   begin
-    OniImage_New.LoadFromBMP(opend.FileName);
-    mem   := TMemoryStream.Create;
-    OniImage_New.GetAsBMP(TStream(mem));
-    mem.Seek(0, soFromBeginning);
-    image_bmppreview.Picture.Bitmap.LoadFromStream(mem);
-    mem.Free;
+    OniImage_New.LoadFromFile(opend.FileName);
+    OniImage_New.DrawOnCanvas(image_bmppreview.Canvas, 0);
     group_options.Enabled := True;
   end;
@@ -104,13 +98,14 @@
       ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $9C, 4, @old_rawaddr);
 
-    if (OniImage_Old.Width <> OniImage_New.Width) or
-      (OniImage_Old.Height <> OniImage_New.Height) then
+    if (OniImage_Old.Width[1] <> OniImage_New.Width[1]) or
+      (OniImage_Old.Height[1] <> OniImage_New.Height[1]) then
     begin
       if MessageBox(Self.Handle,
             PChar(
               'Current image and new image have different size' + CrLf +
-              '(Current: ' + IntToStr(OniImage_Old.Width) + 'x' +
-              IntToStr(OniImage_Old.Height) + ' - New: ' +
-              IntToStr(OniImage_New.Width) + 'x' + IntToStr(OniImage_New.Height) +
+              '(Current: ' + IntToStr(OniImage_Old.Width[1]) + 'x' +
+              IntToStr(OniImage_Old.Height[1]) + ' - New: ' +
+              IntToStr(OniImage_New.Width[1]) + 'x' +
+              IntToStr(OniImage_New.Height[1]) +
               ')' + CrLf + 'Replace anyway?'),
             PChar(filelist.Items.Strings[filelist.ItemIndex]), MB_YESNO) = idNo then
@@ -120,25 +115,13 @@
     mem := TMemoryStream.Create;
 
-    if check_fading.Checked then
-      if not OniImage_New.GetMipMappedImage(TStream(mem)) then
-        if MessageBox(Self.Handle,
-              PChar('Can not create a MipMapped-image (probably because of a wrong dimension).' +
-                #13 + #10 + 'Do you want to continue without MipMapping?'), PChar('Warning'),
-                MB_YESNO) = ID_YES then
-          check_fading.Checked := False
-        else
-          Exit;
-
-    if not check_fading.Checked then
-    begin
-      mem.Clear;
-      OniImage_New.GetAsData(TStream(mem));
-    end;
-
-    newsize := OniImage_New.GetImageDataSize(check_fading.Checked);
+    OniImage_New.SaveDataToStream(check_fading.Checked, TStream(mem));
+
+    newsize := mem.Size;
+    mem.Seek(0, soFromBeginning);
 
     if (newsize > old_size) and (ConManager.Connection[ConnectionID].Backend = DB_ONI) then
       new_rawaddr := ConManager.Connection[ConnectionID].AppendRawFile(
-        not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN), mem.Size, mem)
+        not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN),
+        mem.Size, mem)
     else
     begin
@@ -152,10 +135,25 @@
     ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $88, 1, @datbyte);
     datbyte := $10;
-    if check_transparency.Checked then
-      datbyte := datbyte or $04;
+//    if check_transparency.Checked then
+//      datbyte := datbyte or $04;
     ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $89, 1, @datbyte);
-    ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $8C, 2, @OniImage_New.Width);
-    ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $8E, 2, @OniImage_New.Height);
-    datbyte := $08;
+    datbyte := OniImage_New.Width[1];
+    ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $8C, 2, @datbyte);
+    datbyte := OniImage_New.Height[1];
+    ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $8E, 2, @datbyte);
+    case OniImage_New.Format of
+      ifA1R5G5B5: datbyte := 2;
+      ifA4R4G4B4: datbyte := 0;
+      ifA8R8G8B8:
+        begin
+          datbyte := 8;
+          OniImage_New.Format := ifX8R8G8B8;
+        end;
+      ifX8R8G8B8: datbyte := 8;
+      ifDXT1: datbyte := 9;
+    else
+      OniImage_New.Format := ifX8R8G8B8;
+      datbyte := 8;
+    end;
     ConManager.Connection[ConnectionID].UpdateDatFilePart(fileid, $90, 1, @datbyte);
     if not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN) then
@@ -188,4 +186,5 @@
   Self.AllowedExts := 'TXMP';
   Self.OnNewFileSelected := SelectFile;
+  opend.Filter := saved.Filter;
 end;
 
@@ -196,5 +195,5 @@
 begin
   if saved.Execute then
-    OniImage_Old.WriteToBMP(saved.FileName);
+    OniImage_Old.WriteToFile(saved.FileName);
 end;
 
