* refactored LoadTGA
[LazOpenGLCore.git] / glBitmap.pas
index b2a1476..88724cf 100644 (file)
@@ -593,21 +593,21 @@ type
   TglBitmapFormat = (
     tfEmpty = 0,
 
-    //tfAlpha4,
+    tfAlpha4,
     tfAlpha8,
-    //tfAlpha12,
+    tfAlpha12,
     tfAlpha16,
 
-    //tfLuminance4,
+    tfLuminance4,
     tfLuminance8,
-    //tfLuminance12,
+    tfLuminance12,
     tfLuminance16,
 
     tfLuminance4Alpha4,
     tfLuminance6Alpha2,
     tfLuminance8Alpha8,
     tfLuminance12Alpha4,
-    //tfLuminance12Alpha12,
+    tfLuminance12Alpha12,
     tfLuminance16Alpha16,
 
     tfR3G3B2,
@@ -616,7 +616,7 @@ type
     tfRGB5,
     tfRGB8,
     tfRGB10,
-    //tfRGB12,
+    tfRGB12,
     tfRGB16,
 
     tfRGBA2,
@@ -624,7 +624,7 @@ type
     tfRGB5A1,
     tfRGBA8,
     tfRGB10A2,
-    //tfRGBA12,
+    tfRGBA12,
     tfRGBA16,
 
     tfBGR4,
@@ -632,7 +632,7 @@ type
     tfBGR5,
     tfBGR8,
     tfBGR10,
-    //tfBGR12,
+    tfBGR12,
     tfBGR16,
 
     tfBGRA2,
@@ -640,12 +640,12 @@ type
     tfBGR5A1,
     tfBGRA8,
     tfBGR10A2,
-    //tfBGRA12,
-    tfBGRA16
+    tfBGRA12,
+    tfBGRA16,
 
-    //tfDepth16,
-    //tfDepth24,
-    //tfDepth32
+    tfDepth16,
+    tfDepth24,
+    tfDepth32
   );
 
   TglBitmapFileType = (
@@ -1004,6 +1004,7 @@ procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
 
 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
+function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
 
 var
   glBitmapDefaultDeleteTextureOnFree: Boolean;
@@ -1052,6 +1053,7 @@ type
     fFormat: TglBitmapFormat;
     fWithAlpha: TglBitmapFormat;
     fWithoutAlpha: TglBitmapFormat;
+    fRGBInverted: TglBitmapFormat;
     fPixelSize: Single;
 
     fRange: TglBitmapColorRec;
@@ -1066,6 +1068,7 @@ type
     property Format:       TglBitmapFormat read fFormat;
     property WithAlpha:    TglBitmapFormat read fWithAlpha;
     property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
+    property RGBInverted:  TglBitmapFormat read fRGBInverted;
     property Components:   Integer         read GetComponents;
     property PixelSize:    Single          read fPixelSize;
 
@@ -1108,180 +1111,310 @@ type
 
   TfdEmpty = class(TFormatDescriptor);
 
-  TfdAlpha8 = class(TFormatDescriptor)
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdAlpha16 = class(TFormatDescriptor)
+  TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance8 = class(TFormatDescriptor)
+  TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance16 = class(TFormatDescriptor)
+  TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance4Alpha4 = class(TFormatDescriptor)
+  TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance6Alpha2 = class(TfdLuminance4Alpha4)
+  TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance8Alpha8 = class(TFormatDescriptor)
+  TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance12Alpha4 = class(TfdLuminance8Alpha8)
+  TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte  (inverse)
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdLuminance16Alpha16 = class(TFormatDescriptor)
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdR3G3B2 = class(TFormatDescriptor)
+  TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGB4 = class(TFormatDescriptor)
+  TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdR5G6B5 = class(TfdRGB4)
+  TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGB5 = class(TfdRGB4)
+  TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGB8 = class(TFormatDescriptor)
+  TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGB10 = class(TFormatDescriptor)
+  TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGB16 = class(TFormatDescriptor)
+  TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGBA2 = class(TfdR3G3B2)
+  TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGBA4 = class(TfdRGB4)
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGB5A1 = class(TfdRGB5)
+  TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
     constructor Create; override;
   end;
 
-  TfdRGBA8 = class(TfdRGB8)
-    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
-    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TfdAlpha4 = class(TfdAlpha_UB1)
     constructor Create; override;
   end;
 
-  TfdRGB10A2 = class(TfdRGB10)
+  TfdAlpha8 = class(TfdAlpha_UB1)
     constructor Create; override;
   end;
 
-  TfdRGBA16 = class(TfdRGB16)
-    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
-    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+  TfdAlpha12 = class(TfdAlpha_US1)
     constructor Create; override;
   end;
 
-  TfdBGR4 = class(TfdRGB4)
+  TfdAlpha16 = class(TfdAlpha_US1)
     constructor Create; override;
   end;
 
-  TfdB5G6R5 = class(TfdRGB4)
+  TfdLuminance4 = class(TfdLuminance_UB1)
     constructor Create; override;
   end;
 
-  TfdBGR5 = class(TfdRGB5)
+  TfdLuminance8 = class(TfdLuminance_UB1)
     constructor Create; override;
   end;
 
-  TfdBGR8 = class(TFormatDescriptor)
-    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
-    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+  TfdLuminance12 = class(TfdLuminance_US1)
     constructor Create; override;
   end;
 
-  TfdBGR10 = class(TfdRGB10)
+  TfdLuminance16 = class(TfdLuminance_US1)
     constructor Create; override;
   end;
 
-  TfdBGR16 = class(TFormatDescriptor)
-    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
-    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+  TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
     constructor Create; override;
   end;
 
-  TfdBGRA2 = class(TfdRGBA2)
+  TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
     constructor Create; override;
   end;
 
-  TfdBGRA4 = class(TfdRGBA4)
+  TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
     constructor Create; override;
   end;
 
-  TfdBGR5A1 = class(TfdRGB5A1)
+  TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
     constructor Create; override;
   end;
 
-  TfdBGRA8 = class(TfdBGR8)
-    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
-    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+  TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
     constructor Create; override;
   end;
 
-  TfdBGR10A2 = class(TfdRGB10A2)
+  TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
     constructor Create; override;
   end;
 
-  TfdBGRA16 = class(TfdBGR16)
-    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
-    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+  TfdR3G3B2 = class(TfdUniversal_UB1)
+    constructor Create; override;
+  end;
+
+  TfdRGB4 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdR5G6B5 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdRGB5 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdRGB8 = class(TfdRGB_UB3)
+    constructor Create; override;
+  end;
+
+  TfdRGB10 = class(TfdUniversal_UI1)
+    constructor Create; override;
+  end;
+
+  TfdRGB12 = class(TfdRGB_US3)
+    constructor Create; override;
+  end;
+
+  TfdRGB16 = class(TfdRGB_US3)
+    constructor Create; override;
+  end;
+
+  TfdRGBA2 = class(TfdRGBA_UB4)
+    constructor Create; override;
+  end;
+
+  TfdRGBA4 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdRGB5A1 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdRGBA8 = class(TfdRGBA_UB4)
+    constructor Create; override;
+  end;
+
+  TfdRGB10A2 = class(TfdUniversal_UI1)
+    constructor Create; override;
+  end;
+
+  TfdRGBA12 = class(TfdRGBA_US4)
+    constructor Create; override;
+  end;
+
+  TfdRGBA16 = class(TfdRGBA_US4)
+    constructor Create; override;
+  end;
+
+  TfdBGR4 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdB5G6R5 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdBGR5 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdBGR8 = class(TfdBGR_UB3)
+    constructor Create; override;
+  end;
+
+  TfdBGR10 = class(TfdUniversal_UI1)
+    constructor Create; override;
+  end;
+
+  TfdBGR12 = class(TfdBGR_US3)
+    constructor Create; override;
+  end;
+
+  TfdBGR16 = class(TfdBGR_US3)
+    constructor Create; override;
+  end;
+
+  TfdBGRA2 = class(TfdBGRA_UB4)
+    constructor Create; override;
+  end;
+
+  TfdBGRA4 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdBGR5A1 = class(TfdUniversal_US1)
+    constructor Create; override;
+  end;
+
+  TfdBGRA8 = class(TfdBGRA_UB4)
+    constructor Create; override;
+  end;
+
+  TfdBGR10A2 = class(TfdUniversal_UI1)
+    constructor Create; override;
+  end;
+
+  TfdBGRA12 = class(TfdBGRA_US4)
+    constructor Create; override;
+  end;
+
+  TfdBGRA16 = class(TfdBGRA_US4)
+    constructor Create; override;
+  end;
+
+  TfdDepth16 = class(TfdDepth_US1)
+    constructor Create; override;
+  end;
+
+  TfdDepth24 = class(TfdDepth_UI1)
+    constructor Create; override;
+  end;
+
+  TfdDepth32 = class(TfdDepth_UI1)
     constructor Create; override;
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-  TBitfieldFormat = class(TFormatDescriptor)
+  TbmpBitfieldFormat = class(TFormatDescriptor)
   private
     procedure SetRedMask  (const aValue: UInt64);
     procedure SetGreenMask(const aValue: UInt64);
@@ -1302,17 +1435,21 @@ type
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-  TColorTableEnty = packed record
+  TbmpColorTableEnty = packed record
     b, g, r, a: Byte;
   end;
-  TColorTable = array of TColorTableEnty;
-  TColorTableFormat = class(TFormatDescriptor)
+  TbmpColorTable = array of TbmpColorTableEnty;
+  TbmpColorTableFormat = class(TFormatDescriptor)
   private
-    fColorTable: TColorTable;
+    fColorTable: TbmpColorTable;
   public
     property PixelSize:  Single            read fPixelSize  write fPixelSize;
-    property ColorTable: TColorTable       read fColorTable write fColorTable;
+    property ColorTable: TbmpColorTable    read fColorTable write fColorTable;
     property Range:      TglBitmapColorRec read fRange      write fRange;
+    property Shift:      TShiftRec         read fShift      write fShift;
+    property Format:     TglBitmapFormat   read fFormat     write fFormat;
+
+    procedure CreateColorTable;
 
     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
     procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
@@ -1328,26 +1465,30 @@ const
   ALPHA_WEIGHT_G = 0.59;
   ALPHA_WEIGHT_B = 0.11;
 
+  DEPTH_WEIGHT_R = 0.333333333;
+  DEPTH_WEIGHT_G = 0.333333333;
+  DEPTH_WEIGHT_B = 0.333333333;
+
   UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
 
   FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
     TfdEmpty,
 
-    //TfdAlpha4,
+    TfdAlpha4,
     TfdAlpha8,
-    //TfdAlpha12,
+    TfdAlpha12,
     TfdAlpha16,
 
-    //TfdLuminance4,
+    TfdLuminance4,
     TfdLuminance8,
-    //TfdLuminance12,
+    TfdLuminance12,
     TfdLuminance16,
 
     TfdLuminance4Alpha4,
     TfdLuminance6Alpha2,
     TfdLuminance8Alpha8,
     TfdLuminance12Alpha4,
-    //TfdLuminance12Alpha12,
+    TfdLuminance12Alpha12,
     TfdLuminance16Alpha16,
 
     TfdR3G3B2,
@@ -1356,7 +1497,7 @@ const
     TfdRGB5,
     TfdRGB8,
     TfdRGB10,
-    //TfdRGB12,
+    TfdRGB12,
     TfdRGB16,
 
     TfdRGBA2,
@@ -1364,7 +1505,7 @@ const
     TfdRGB5A1,
     TfdRGBA8,
     TfdRGB10A2,
-    //TfdRGBA12,
+    TfdRGBA12,
     TfdRGBA16,
 
     TfdBGR4,
@@ -1372,7 +1513,7 @@ const
     TfdBGR5,
     TfdBGR8,
     TfdBGR10,
-    //TfdBGR12,
+    TfdBGR12,
     TfdBGR16,
 
     TfdBGRA2,
@@ -1380,12 +1521,12 @@ const
     TfdBGR5A1,
     TfdBGRA8,
     TfdBGR10A2,
-    //TfdBGRA12,
-    TfdBGRA16
+    TfdBGRA12,
+    TfdBGRA16,
 
-    //TfdDepth16,
-    //TfdDepth24,
-    //TfdDepth32
+    TfdDepth16,
+    TfdDepth24,
+    TfdDepth32
   );
 
 var
@@ -1416,10 +1557,68 @@ begin
 end;
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
+var
+  i: Integer;
+begin
+  result := false;
+  for i := 0 to high(r1.arr) do
+    if (r1.arr[i] <> r2.arr[i]) then
+      exit;
+  result := true;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
+begin
+  result.r := r;
+  result.g := g;
+  result.b := b;
+  result.a := a;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
 begin
+  result := [ftDDS];
+
+  if (aFormat in [
+        //4 bbp
+        tfLuminance4,
+
+        //8bpp
+        tfR3G3B2, tfLuminance8,
+
+        //16bpp
+        tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
+        tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
+
+        //24bpp
+        tfBGR8, tfRGB8,
+
+        //32bpp
+        tfRGB10, tfRGB10A2, tfRGBA8,
+        tfBGR10, tfBGR10A2, tfBGRA8]) then
+    result := result + [ftBMP];
+
+  if (aFormat in [
+        //8 bpp
+        tfLuminance8, tfAlpha8,
+
+        //16 bpp
+        tfLuminance16, tfLuminance8Alpha8,
+        tfRGB5, tfRGB5A1, tfRGBA4,
+        tfBGR5, tfBGR5A1, tfBGRA4,
+
+        //24 bpp
+        tfRGB8, tfBGR8,
+
+        //32 bpp
+        tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
+    result := result + [ftTGA];
+
   //TODO Supported File Formats!
-  result := [ftDDS, ftTGA, ftBMP];
+
   (*
   {$IFDEF GLB_SUPPORT_PNG_WRITE}
   if aFormat in [
@@ -1493,6 +1692,14 @@ begin
     LUMINANCE_WEIGHT_B * aPixel.Data.b);
 end;
 
+function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
+begin
+  result := Trunc(
+    DEPTH_WEIGHT_R * aPixel.Data.r +
+    DEPTH_WEIGHT_G * aPixel.Data.g +
+    DEPTH_WEIGHT_B * aPixel.Data.b);
+end;
+
 //TODO check _ARB functions and constants
 
 (* GLB_NO_NATIVE_GL
@@ -2028,6 +2235,7 @@ begin
   fFormat       := tfEmpty;
   fWithAlpha    := tfEmpty;
   fWithoutAlpha := tfEmpty;
+  fRGBInverted  := tfEmpty;
   fPixelSize    := 0.0;
 
   fglFormat         := 0;
@@ -2039,15 +2247,15 @@ begin
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TfdAlpha8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdAlpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
 begin
   aData^ := aPixel.Data.a;
   inc(aData);
 end;
 
-procedure TfdAlpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TfdAlpha_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 begin
   aPixel.Data.r := 0;
   aPixel.Data.g := 0;
@@ -2056,56 +2264,25 @@ begin
   inc(aData^);
 end;
 
-constructor TfdAlpha8.Create;
+constructor TfdAlpha_UB1.Create;
 begin
   inherited Create;
   fPixelSize        := 1.0;
-  fFormat           := tfAlpha8;
   fRange.a          := $FF;
   fglFormat         := GL_ALPHA;
-  fglInternalFormat := GL_ALPHA8;
   fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TfdAlpha16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdAlpha16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  PWord(aData)^ := aPixel.Data.a;
-  inc(aData, 2);
-end;
-
-procedure TfdAlpha16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-begin
-  aPixel.Data.r := 0;
-  aPixel.Data.g := 0;
-  aPixel.Data.b := 0;
-  aPixel.Data.a := PWord(aData)^;
-  inc(aData, 2);
-end;
-
-constructor TfdAlpha16.Create;
-begin
-  inherited Create;
-  fPixelSize        := 2.0;
-  fFormat           := tfAlpha16;
-  fRange.a          := $FFFF;
-  fglFormat         := GL_ALPHA;
-  fglInternalFormat := GL_ALPHA16;
-  fglDataFormat     := GL_UNSIGNED_SHORT;
-end;
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
 begin
   aData^ := LuminanceWeight(aPixel);
   inc(aData);
 end;
 
-procedure TfdLuminance8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TfdLuminance_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 begin
   aPixel.Data.r := aData^;
   aPixel.Data.g := aData^;
@@ -2114,273 +2291,680 @@ begin
   inc(aData);
 end;
 
-constructor TfdLuminance8.Create;
+constructor TfdLuminance_UB1.Create;
 begin
   inherited Create;
   fPixelSize        := 1.0;
-  fFormat           := tfLuminance8;
-  fWithAlpha        := tfLuminance8Alpha8;
-  fWithoutAlpha     := tfLuminance8;
   fRange.r          := $FF;
   fRange.g          := $FF;
   fRange.b          := $FF;
   fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE8;
   fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdLuminance16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+var
+  i: Integer;
 begin
-  PWord(aData)^ := LuminanceWeight(aPixel);
-  inc(aData, 2);
+  aData^ := 0;
+  for i := 0 to 3 do
+    if (fRange.arr[i] > 0) then
+      aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
+  inc(aData);
 end;
 
-procedure TfdLuminance16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TfdUniversal_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+var
+  i: Integer;
 begin
-  aPixel.Data.r := PWord(aData)^;
-  aPixel.Data.g := PWord(aData)^;
-  aPixel.Data.b := PWord(aData)^;
-  aPixel.Data.a := 0;
-  inc(aData, 2);
+  for i := 0 to 3 do
+    aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
+  inc(aData);
 end;
 
-constructor TfdLuminance16.Create;
+constructor TfdUniversal_UB1.Create;
 begin
   inherited Create;
-  fPixelSize        := 2.0;
-  fFormat           := tfLuminance16;
-  fWithAlpha        := tfLuminance16Alpha16;
-  fWithoutAlpha     := tfLuminance16;
-  fRange.r          := $FFFF;
-  fRange.g          := $FFFF;
-  fRange.b          := $FFFF;
-  fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE16;
-  fglDataFormat     := GL_UNSIGNED_SHORT;
+  fPixelSize := 1.0;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdLuminance4Alpha4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
 begin
-  aData^ :=
-    ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or
-    ((aPixel.Data.a           and fRange.a) shl fShift.a);
+  inherited Map(aPixel, aData, aMapData);
+  aData^ := aPixel.Data.a;
   inc(aData);
 end;
 
-procedure TfdLuminance4Alpha4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-var
-  i: Integer;
+procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 begin
-  for i := 0 to 3 do
-    aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
+  inherited Unmap(aData, aPixel, aMapData);
+  aPixel.Data.a := aData^;
   inc(aData);
 end;
 
-constructor TfdLuminance4Alpha4.Create;
+constructor TfdLuminanceAlpha_UB2.Create;
 begin
   inherited Create;
-  fPixelSize        := 1.0;
-  fFormat           := tfLuminance4Alpha4;
-  fWithAlpha        := tfLuminance4Alpha4;
-  fWithoutAlpha     := tfLuminance8;
-  fRange.r          := $F;
-  fRange.g          := $F;
-  fRange.b          := $F;
-  fRange.a          := $F;
-  fShift.a          :=  4;
-  fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE4_ALPHA4;
+  fPixelSize        := 2.0;
+  fRange.a          := $FF;
+  fShift.a          :=   8;
+  fglFormat         := GL_LUMINANCE_ALPHA;
   fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TfdLuminance6Alpha2.Create;
+procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
 begin
-  inherited Create;
-  fFormat           := tfLuminance6Alpha2;
-  fWithAlpha        := tfLuminance6Alpha2;
-  fWithoutAlpha     := tfLuminance8;
-  fRange.r          := $3F;
-  fRange.g          := $3F;
-  fRange.b          := $3F;
-  fRange.a          := $03;
-  fShift.a          :=   6;
-  fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE6_ALPHA2;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
+  aData^ := aPixel.Data.r;
+  inc(aData);
+  aData^ := aPixel.Data.g;
+  inc(aData);
+  aData^ := aPixel.Data.b;
+  inc(aData);
+end;
+
+procedure TfdRGB_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.r := aData^;
+  inc(aData);
+  aPixel.Data.g := aData^;
+  inc(aData);
+  aPixel.Data.b := aData^;
+  inc(aData);
+  aPixel.Data.a := 0;
+end;
+
+constructor TfdRGB_UB3.Create;
+begin
+  inherited Create;
+  fPixelSize        := 3.0;
+  fRange.r          := $FF;
+  fRange.g          := $FF;
+  fRange.b          := $FF;
+  fShift.r          :=   0;
+  fShift.g          :=   8;
+  fShift.b          :=  16;
+  fglFormat         := GL_RGB;
+  fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  aData^ := aPixel.Data.b;
+  inc(aData);
+  aData^ := aPixel.Data.g;
+  inc(aData);
+  aData^ := aPixel.Data.r;
+  inc(aData);
+end;
+
+procedure TfdBGR_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.b := aData^;
+  inc(aData);
+  aPixel.Data.g := aData^;
+  inc(aData);
+  aPixel.Data.r := aData^;
+  inc(aData);
+  aPixel.Data.a := 0;
+end;
+
+constructor TfdBGR_UB3.Create;
+begin
+  fPixelSize        := 3.0;
+  fRange.r          := $FF;
+  fRange.g          := $FF;
+  fRange.b          := $FF;
+  fShift.r          :=  16;
+  fShift.g          :=   8;
+  fShift.b          :=   0;
+  fglFormat         := GL_BGR;
+  fglDataFormat     := GL_UNSIGNED_BYTE;
+end;
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+//TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  inherited Map(aPixel, aData, aMapData);
+  aData^ := aPixel.Data.a;
+  inc(aData);
+end;
+
+procedure TfdRGBA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  inherited Unmap(aData, aPixel, aMapData);
+  aPixel.Data.a := aData^;
+  inc(aData);
+end;
+
+constructor TfdRGBA_UB4.Create;
 begin
-  PWord(aData)^ :=
-    ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or
-    ((aPixel.Data.a           and fRange.a) shl fShift.a);
+  inherited Create;
+  fPixelSize        := 4.0;
+  fRange.a          := $FF;
+  fShift.a          :=  24;
+  fglFormat         := GL_RGBA;
+  fglDataFormat     := GL_UNSIGNED_BYTE;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  inherited Map(aPixel, aData, aMapData);
+  aData^ := aPixel.Data.a;
+  inc(aData);
+end;
+
+procedure TfdBGRA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  inherited Unmap(aData, aPixel, aMapData);
+  aPixel.Data.a := aData^;
+  inc(aData);
+end;
+
+constructor TfdBGRA_UB4.Create;
+begin
+  inherited Create;
+  fPixelSize        := 4.0;
+  fRange.a          := $FF;
+  fShift.a          :=  24;
+  fglFormat         := GL_BGRA;
+  fglDataFormat     := GL_UNSIGNED_BYTE;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  PWord(aData)^ := aPixel.Data.a;
   inc(aData, 2);
 end;
 
-procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-var
-  i: Integer;
+procedure TfdAlpha_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 begin
-  for i := 0 to 3 do
-    aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
+  aPixel.Data.r := 0;
+  aPixel.Data.g := 0;
+  aPixel.Data.b := 0;
+  aPixel.Data.a := PWord(aData)^;
   inc(aData, 2);
 end;
 
-constructor TfdLuminance8Alpha8.Create;
+constructor TfdAlpha_US1.Create;
 begin
   inherited Create;
   fPixelSize        := 2.0;
-  fFormat           := tfLuminance8Alpha8;
-  fWithAlpha        := tfLuminance8Alpha8;
-  fWithoutAlpha     := tfLuminance8;
-  fRange.r          := $FF;
-  fRange.g          := $FF;
-  fRange.b          := $FF;
-  fRange.a          := $FF;
-  fShift.a          :=   8;
-  fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE8_ALPHA8;
+  fRange.a          := $FFFF;
+  fglFormat         := GL_ALPHA;
   fglDataFormat     := GL_UNSIGNED_SHORT;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TfdLuminance12Alpha4.Create;
+procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  PWord(aData)^ := LuminanceWeight(aPixel);
+  inc(aData, 2);
+end;
+
+procedure TfdLuminance_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.r := PWord(aData)^;
+  aPixel.Data.g := PWord(aData)^;
+  aPixel.Data.b := PWord(aData)^;
+  aPixel.Data.a := 0;
+  inc(aData, 2);
+end;
+
+constructor TfdLuminance_US1.Create;
 begin
   inherited Create;
-  fFormat           := tfLuminance12Alpha4;
-  fWithAlpha        := tfLuminance12Alpha4;
-  fWithoutAlpha     := tfLuminance16;
-  fRange.r          := $FFF;
-  fRange.g          := $FFF;
-  fRange.b          := $FFF;
-  fRange.a          := $00F;
-  fShift.a          :=   12;
+  fPixelSize        := 2.0;
+  fRange.r          := $FFFF;
+  fRange.g          := $FFFF;
+  fRange.b          := $FFFF;
   fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE12_ALPHA4;
   fglDataFormat     := GL_UNSIGNED_SHORT;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdLuminance16Alpha16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+var
+  i: Integer;
 begin
-  PCardinal(aData)^ :=
-    ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or
-    ((aPixel.Data.a           and fRange.a) shl fShift.a);
-  inc(aData, 4);
+  PWord(aData)^ := 0;
+  for i := 0 to 3 do
+    if (fRange.arr[i] > 0) then
+      PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
+  inc(aData, 2);
 end;
 
-procedure TfdLuminance16Alpha16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TfdUniversal_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 var
   i: Integer;
 begin
   for i := 0 to 3 do
-    aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
-  inc(aData, 4);
+    aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
+  inc(aData, 2);
 end;
 
-constructor TfdLuminance16Alpha16.Create;
+constructor TfdUniversal_US1.Create;
 begin
   inherited Create;
-  fFormat           := tfLuminance16Alpha16;
-  fWithAlpha        := tfLuminance16Alpha16;
-  fWithoutAlpha     := tfLuminance16;
+  fPixelSize := 2.0;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  PWord(aData)^ := DepthWeight(aPixel);
+  inc(aData, 2);
+end;
+
+procedure TfdDepth_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.r := PWord(aData)^;
+  aPixel.Data.g := PWord(aData)^;
+  aPixel.Data.b := PWord(aData)^;
+  aPixel.Data.a := 0;
+  inc(aData, 2);
+end;
+
+constructor TfdDepth_US1.Create;
+begin
+  inherited Create;
+  fPixelSize        := 2.0;
   fRange.r          := $FFFF;
   fRange.g          := $FFFF;
   fRange.b          := $FFFF;
+  fglFormat         := GL_DEPTH_COMPONENT;
+  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  inherited Map(aPixel, aData, aMapData);
+  PWord(aData)^ := aPixel.Data.a;
+  inc(aData, 2);
+end;
+
+procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  inherited Unmap(aData, aPixel, aMapData);
+  aPixel.Data.a := PWord(aData)^;
+  inc(aData, 2);
+end;
+
+constructor TfdLuminanceAlpha_US2.Create;
+begin
+  inherited Create;
+  fPixelSize        :=   4.0;
   fRange.a          := $FFFF;
   fShift.a          :=    16;
-  fglFormat         := GL_LUMINANCE;
-  fglInternalFormat := GL_LUMINANCE16_ALPHA16;
-  fglDataFormat     := GL_UNSIGNED_INT;
+  fglFormat         := GL_LUMINANCE_ALPHA;
+  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  PWord(aData)^ := aPixel.Data.r;
+  inc(aData, 2);
+  PWord(aData)^ := aPixel.Data.g;
+  inc(aData, 2);
+  PWord(aData)^ := aPixel.Data.b;
+  inc(aData, 2);
+end;
+
+procedure TfdRGB_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.r := PWord(aData)^;
+  inc(aData, 2);
+  aPixel.Data.g := PWord(aData)^;
+  inc(aData, 2);
+  aPixel.Data.b := PWord(aData)^;
+  inc(aData, 2);
+  aPixel.Data.a := 0;
 end;
 
+constructor TfdRGB_US3.Create;
+begin
+  inherited Create;
+  fPixelSize        :=   6.0;
+  fRange.r          := $FFFF;
+  fRange.g          := $FFFF;
+  fRange.b          := $FFFF;
+  fShift.r          :=     0;
+  fShift.g          :=    16;
+  fShift.b          :=    32;
+  fglFormat         := GL_RGB;
+  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  PWord(aData)^ := aPixel.Data.b;
+  inc(aData, 2);
+  PWord(aData)^ := aPixel.Data.g;
+  inc(aData, 2);
+  PWord(aData)^ := aPixel.Data.r;
+  inc(aData, 2);
+end;
+
+procedure TfdBGR_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.b := PWord(aData)^;
+  inc(aData, 2);
+  aPixel.Data.g := PWord(aData)^;
+  inc(aData, 2);
+  aPixel.Data.r := PWord(aData)^;
+  inc(aData, 2);
+  aPixel.Data.a := 0;
+end;
+
+constructor TfdBGR_US3.Create;
+begin
+  inherited Create;
+  fPixelSize        :=   6.0;
+  fRange.r          := $FFFF;
+  fRange.g          := $FFFF;
+  fRange.b          := $FFFF;
+  fShift.r          :=    32;
+  fShift.g          :=    16;
+  fShift.b          :=     0;
+  fglFormat         := GL_BGR;
+  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdR3G3B2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  inherited Map(aPixel, aData, aMapData);
+  PWord(aData)^ := aPixel.Data.a;
+  inc(aData, 2);
+end;
+
+procedure TfdRGBA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  inherited Unmap(aData, aPixel, aMapData);
+  aPixel.Data.a := PWord(aData)^;
+  inc(aData, 2);
+end;
+
+constructor TfdRGBA_US4.Create;
+begin
+  inherited Create;
+  fPixelSize        :=   8.0;
+  fRange.a          := $FFFF;
+  fShift.a          :=    48;
+  fglFormat         := GL_RGBA;
+  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  inherited Map(aPixel, aData, aMapData);
+  PWord(aData)^ := aPixel.Data.a;
+  inc(aData, 2);
+end;
+
+procedure TfdBGRA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  inherited Unmap(aData, aPixel, aMapData);
+  aPixel.Data.a := PWord(aData)^;
+  inc(aData, 2);
+end;
+
+constructor TfdBGRA_US4.Create;
+begin
+  inherited Create;
+  fPixelSize        :=   8.0;
+  fRange.a          := $FFFF;
+  fShift.a          :=    48;
+  fglFormat         := GL_BGRA;
+  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
 var
   i: Integer;
 begin
-  aData^ := 0;
+  PCardinal(aData)^ := 0;
   for i := 0 to 3 do
     if (fRange.arr[i] > 0) then
-      aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
-  inc(aData);
+      PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
+  inc(aData, 4);
 end;
 
-procedure TfdR3G3B2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TfdUniversal_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 var
   i: Integer;
 begin
   for i := 0 to 3 do
-    aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
-  inc(aData);
+    aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
+  inc(aData, 2);
 end;
 
-constructor TfdR3G3B2.Create;
+constructor TfdUniversal_UI1.Create;
 begin
   inherited Create;
-  fPixelSize        := 1.0;
-  fFormat           := tfR3G3B2;
-  fWithAlpha        := tfRGBA2;
-  fWithoutAlpha     := tfR3G3B2;
-  fRange.r          := $7;
-  fRange.g          := $7;
-  fRange.b          := $3;
-  fShift.r          :=  0;
-  fShift.g          :=  3;
-  fShift.b          :=  5;
-  fglFormat         := GL_RGB;
-  fglInternalFormat := GL_R3_G3_B2;
-  fglDataFormat     := GL_UNSIGNED_BYTE_2_3_3_REV;
+  fPixelSize := 4.0;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+  PCardinal(aData)^ := DepthWeight(aPixel);
+  inc(aData, 4);
+end;
+
+procedure TfdDepth_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+  aPixel.Data.r := PCardinal(aData)^;
+  aPixel.Data.g := PCardinal(aData)^;
+  aPixel.Data.b := PCardinal(aData)^;
+  aPixel.Data.a := 0;
+  inc(aData, 4);
+end;
+
+constructor TfdDepth_UI1.Create;
+begin
+  inherited Create;
+  fPixelSize        := 4.0;
+  fRange.r          := $FFFFFFFF;
+  fRange.g          := $FFFFFFFF;
+  fRange.b          := $FFFFFFFF;
+  fglFormat         := GL_DEPTH_COMPONENT;
+  fglDataFormat     := GL_UNSIGNED_INT;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdRGB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-var
-  i: Integer;
+constructor TfdAlpha4.Create;
 begin
-  PWord(aData)^ := 0;
-  for i := 0 to 3 do
-    if (fRange.arr[i] > 0) then
-      PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
-  inc(aData, 2);
+  inherited Create;
+  fFormat           := tfAlpha4;
+  fWithAlpha        := tfAlpha4;
+  fglInternalFormat := GL_ALPHA4;
+end;
+
+constructor TfdAlpha8.Create;
+begin
+  inherited Create;
+  fFormat           := tfAlpha8;
+  fWithAlpha        := tfAlpha8;
+  fglInternalFormat := GL_ALPHA8;
+end;
+
+constructor TfdAlpha12.Create;
+begin
+  inherited Create;
+  fFormat           := tfAlpha12;
+  fWithAlpha        := tfAlpha12;
+  fglInternalFormat := GL_ALPHA12;
+end;
+
+constructor TfdAlpha16.Create;
+begin
+  inherited Create;
+  fFormat           := tfAlpha16;
+  fWithAlpha        := tfAlpha16;
+  fglInternalFormat := GL_ALPHA16;
+end;
+
+constructor TfdLuminance4.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance4;
+  fWithAlpha        := tfLuminance4Alpha4;
+  fWithoutAlpha     := tfLuminance4;
+  fglInternalFormat := GL_LUMINANCE4;
+end;
+
+constructor TfdLuminance8.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance8;
+  fWithAlpha        := tfLuminance8Alpha8;
+  fWithoutAlpha     := tfLuminance8;
+  fglInternalFormat := GL_LUMINANCE8;
+end;
+
+constructor TfdLuminance12.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance12;
+  fWithAlpha        := tfLuminance12Alpha12;
+  fWithoutAlpha     := tfLuminance12;
+  fglInternalFormat := GL_LUMINANCE12;
+end;
+
+constructor TfdLuminance16.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance16;
+  fWithAlpha        := tfLuminance16Alpha16;
+  fWithoutAlpha     := tfLuminance16;
+  fglInternalFormat := GL_LUMINANCE16;
+end;
+
+constructor TfdLuminance4Alpha4.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance4Alpha4;
+  fWithAlpha        := tfLuminance4Alpha4;
+  fWithoutAlpha     := tfLuminance4;
+  fglInternalFormat := GL_LUMINANCE4_ALPHA4;
+end;
+
+constructor TfdLuminance6Alpha2.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance6Alpha2;
+  fWithAlpha        := tfLuminance6Alpha2;
+  fWithoutAlpha     := tfLuminance8;
+  fglInternalFormat := GL_LUMINANCE6_ALPHA2;
+end;
+
+constructor TfdLuminance8Alpha8.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance8Alpha8;
+  fWithAlpha        := tfLuminance8Alpha8;
+  fWithoutAlpha     := tfLuminance8;
+  fglInternalFormat := GL_LUMINANCE8_ALPHA8;
+end;
+
+constructor TfdLuminance12Alpha4.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance12Alpha4;
+  fWithAlpha        := tfLuminance12Alpha4;
+  fWithoutAlpha     := tfLuminance12;
+  fglInternalFormat := GL_LUMINANCE12_ALPHA4;
+end;
+
+constructor TfdLuminance12Alpha12.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance12Alpha12;
+  fWithAlpha        := tfLuminance12Alpha12;
+  fWithoutAlpha     := tfLuminance12;
+  fglInternalFormat := GL_LUMINANCE12_ALPHA12;
+end;
+
+constructor TfdLuminance16Alpha16.Create;
+begin
+  inherited Create;
+  fFormat           := tfLuminance16Alpha16;
+  fWithAlpha        := tfLuminance16Alpha16;
+  fWithoutAlpha     := tfLuminance16;
+  fglInternalFormat := GL_LUMINANCE16_ALPHA16;
 end;
 
-procedure TfdRGB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-var
-  i: Integer;
+constructor TfdR3G3B2.Create;
 begin
-  for i := 0 to 3 do
-    aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
-  inc(aData, 2);
+  inherited Create;
+  fFormat           := tfR3G3B2;
+  fWithAlpha        := tfRGBA2;
+  fWithoutAlpha     := tfR3G3B2;
+  fRange.r          := $7;
+  fRange.g          := $7;
+  fRange.b          := $3;
+  fShift.r          :=  0;
+  fShift.g          :=  3;
+  fShift.b          :=  6;
+  fglFormat         := GL_RGB;
+  fglInternalFormat := GL_R3_G3_B2;
+  fglDataFormat     := GL_UNSIGNED_BYTE_2_3_3_REV;
 end;
 
 constructor TfdRGB4.Create;
 begin
   inherited Create;
-  fPixelSize        := 2.0;
   fFormat           := tfRGB4;
   fWithAlpha        := tfRGBA4;
   fWithoutAlpha     := tfRGB4;
+  fRGBInverted      := tfBGR4;
   fRange.r          := $F;
   fRange.g          := $F;
   fRange.b          := $F;
@@ -2392,16 +2976,13 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdR5G6B5.Create;
 begin
   inherited Create;
-  fPixelSize        := 2.0;
   fFormat           := tfR5G6B5;
   fWithAlpha        := tfRGBA4;
   fWithoutAlpha     := tfR5G6B5;
+  fRGBInverted      := tfB5G6R5;
   fRange.r          := $1F;
   fRange.g          := $3F;
   fRange.b          := $1F;
@@ -2409,20 +2990,17 @@ begin
   fShift.g          :=   5;
   fShift.b          :=  11;
   fglFormat         := GL_RGB;
-  fglInternalFormat := GL_RGB8;
+  fglInternalFormat := GL_RGB565;
   fglDataFormat     := GL_UNSIGNED_SHORT_5_6_5_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdRGB5.Create;
 begin
   inherited Create;
-  fPixelSize        := 2.0;
   fFormat           := tfRGB5;
   fWithAlpha        := tfRGB5A1;
   fWithoutAlpha     := tfRGB5;
+  fRGBInverted      := tfBGR5;
   fRange.r          := $1F;
   fRange.g          := $1F;
   fRange.b          := $1F;
@@ -2434,162 +3012,71 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  aData^ := aPixel.Data.r;
-  inc(aData);
-  aData^ := aPixel.Data.g;
-  inc(aData);
-  aData^ := aPixel.Data.b;
-  inc(aData);
-end;
-
-procedure TfdRGB8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-begin
-  aPixel.Data.r := aData^;
-  inc(aData);
-  aPixel.Data.g := aData^;
-  inc(aData);
-  aPixel.Data.b := aData^;
-  inc(aData);
-  aPixel.Data.a := 0;
-end;
-
 constructor TfdRGB8.Create;
 begin
   inherited Create;
-  fPixelSize        := 3.0;
   fFormat           := tfRGB8;
   fWithAlpha        := tfRGBA8;
   fWithoutAlpha     := tfRGB8;
-  fRange.r          := $FF;
-  fRange.g          := $FF;
-  fRange.b          := $FF;
-  fShift.r          :=   0;
-  fShift.g          :=   8;
-  fShift.b          :=  16;
-  fglFormat         := GL_RGB;
+  fRGBInverted      := tfBGR8;
   fglInternalFormat := GL_RGB8;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
-end;
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdRGB10.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-var
-  i: Integer;
-begin
-  PCardinal(aData)^ := 0;
-  for i := 0 to 3 do
-    if (fRange.arr[i] > 0) then
-      PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
-  inc(aData, 4);
-end;
-
-procedure TfdRGB10.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-var
-  i: Integer;
-begin
-  for i := 0 to 3 do
-    aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
-  inc(aData, 4);
 end;
 
 constructor TfdRGB10.Create;
 begin
   inherited Create;
-  fPixelSize        := 4.0;
   fFormat           := tfRGB10;
   fWithAlpha        := tfRGB10A2;
   fWithoutAlpha     := tfRGB10;
+  fRGBInverted      := tfBGR10;
   fRange.r          := $3FF;
   fRange.g          := $3FF;
   fRange.b          := $3FF;
   fShift.r          :=    0;
   fShift.g          :=   10;
   fShift.b          :=   20;
-  fglFormat         := GL_RGB;
+  fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
   fglInternalFormat := GL_RGB10;
   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdRGB16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  PWord(aData)^ := aPixel.Data.r;
-  inc(aData, 2);
-  PWord(aData)^ := aPixel.Data.g;
-  inc(aData, 2);
-  PWord(aData)^ := aPixel.Data.b;
-  inc(aData, 2);
-end;
-
-procedure TfdRGB16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+constructor TfdRGB12.Create;
 begin
-  aPixel.Data.r := PWord(aData)^;
-  inc(aData, 2);
-  aPixel.Data.g := PWord(aData)^;
-  inc(aData, 2);
-  aPixel.Data.b := PWord(aData)^;
-  inc(aData, 2);
-  aPixel.Data.a := 0;
+  inherited Create;
+  fFormat           := tfRGB12;
+  fWithAlpha        := tfRGBA12;
+  fWithoutAlpha     := tfRGB12;
+  fRGBInverted      := tfBGR12;
+  fglInternalFormat := GL_RGB12;
 end;
 
 constructor TfdRGB16.Create;
 begin
   inherited Create;
-  fPixelSize        := 6.0;
   fFormat           := tfRGB16;
   fWithAlpha        := tfRGBA16;
   fWithoutAlpha     := tfRGB16;
-  fRange.r          := $FFFF;
-  fRange.g          := $FFFF;
-  fRange.b          := $FFFF;
-  fShift.r          :=     0;
-  fShift.g          :=    16;
-  fShift.b          :=    32;
-  fglFormat         := GL_RGB;
+  fRGBInverted      := tfBGR16;
   fglInternalFormat := GL_RGB16;
-  fglDataFormat     := GL_UNSIGNED_SHORT;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdRGBA2.Create;
 begin
   inherited Create;
   fFormat           := tfRGBA2;
   fWithAlpha        := tfRGBA2;
   fWithoutAlpha     := tfR3G3B2;
-  fRange.r          := $3;
-  fRange.g          := $3;
-  fRange.b          := $3;
-  fRange.a          := $3;
-  fShift.r          :=  0;
-  fShift.g          :=  2;
-  fShift.b          :=  4;
-  fShift.a          :=  6;
-  fglFormat         := GL_RGBA;
+  fRGBInverted      := tfBGRA2;
   fglInternalFormat := GL_RGBA2;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdRGBA4.Create;
 begin
   inherited Create;
   fFormat           := tfRGBA4;
   fWithAlpha        := tfRGBA4;
   fWithoutAlpha     := tfRGB4;
+  fRGBInverted      := tfBGRA4;
   fRange.r          := $F;
   fRange.g          := $F;
   fRange.b          := $F;
@@ -2603,15 +3090,13 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdRGB5A1.Create;
 begin
   inherited Create;
   fFormat           := tfRGB5A1;
   fWithAlpha        := tfRGB5A1;
   fWithoutAlpha     := tfRGB5;
+  fRGBInverted      := tfBGR5A1;
   fRange.r          := $1F;
   fRange.g          := $1F;
   fRange.b          := $1F;
@@ -2625,52 +3110,23 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  inherited Map(aPixel, aData, aMapData);
-  aData^ := aPixel.Data.a;
-  inc(aData);
-end;
-
-procedure TfdRGBA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-begin
-  inherited Unmap(aData, aPixel, aMapData);
-  aPixel.Data.a := aData^;
-  inc(aData);
-end;
-
 constructor TfdRGBA8.Create;
 begin
   inherited Create;
-  fPixelSize        := 4.0;
   fFormat           := tfRGBA8;
   fWithAlpha        := tfRGBA8;
   fWithoutAlpha     := tfRGB8;
-  fRange.r          := $FF;
-  fRange.g          := $FF;
-  fRange.b          := $FF;
-  fRange.a          := $FF;
-  fShift.r          :=   0;
-  fShift.g          :=   8;
-  fShift.b          :=  16;
-  fShift.a          :=  24;
-  fglFormat         := GL_RGBA;
+  fRGBInverted      := tfBGRA8;
   fglInternalFormat := GL_RGBA8;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdRGB10A2.Create;
 begin
   inherited Create;
   fFormat           := tfRGB10A2;
   fWithAlpha        := tfRGB10A2;
   fWithoutAlpha     := tfRGB10;
+  fRGBInverted      := tfBGR10A2;
   fRange.r          := $3FF;
   fRange.g          := $3FF;
   fRange.b          := $3FF;
@@ -2684,46 +3140,26 @@ begin
   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdRGBA16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  inherited Map(aPixel, aData, aMapData);
-  PWord(aData)^ := aPixel.Data.a;
-  inc(aData, 2);
-end;
-
-procedure TfdRGBA16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+constructor TfdRGBA12.Create;
 begin
-  inherited Unmap(aData, aPixel, aMapData);
-  aPixel.Data.a := PWord(aData)^;
-  inc(aData, 2);
+  inherited Create;
+  fFormat           := tfRGBA12;
+  fWithAlpha        := tfRGBA12;
+  fWithoutAlpha     := tfRGB12;
+  fRGBInverted      := tfBGRA12;
+  fglInternalFormat := GL_RGBA12;
 end;
 
 constructor TfdRGBA16.Create;
 begin
   inherited Create;
-  fPixelSize        := 8.0;
   fFormat           := tfRGBA16;
   fWithAlpha        := tfRGBA16;
   fWithoutAlpha     := tfRGB16;
-  fRange.r          := $FFFF;
-  fRange.g          := $FFFF;
-  fRange.b          := $FFFF;
-  fRange.a          := $FFFF;
-  fShift.r          :=     0;
-  fShift.g          :=    16;
-  fShift.b          :=    32;
-  fShift.a          :=    48;
-  fglFormat         := GL_RGBA;
+  fRGBInverted      := tfBGRA16;
   fglInternalFormat := GL_RGBA16;
-  fglDataFormat     := GL_UNSIGNED_SHORT;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGR4.Create;
 begin
   inherited Create;
@@ -2731,6 +3167,7 @@ begin
   fFormat           := tfBGR4;
   fWithAlpha        := tfBGRA4;
   fWithoutAlpha     := tfBGR4;
+  fRGBInverted      := tfRGB4;
   fRange.r          := $F;
   fRange.g          := $F;
   fRange.b          := $F;
@@ -2750,24 +3187,21 @@ end;
 constructor TfdB5G6R5.Create;
 begin
   inherited Create;
-  fPixelSize        := 2.0;
   fFormat           := tfB5G6R5;
   fWithAlpha        := tfBGRA4;
   fWithoutAlpha     := tfB5G6R5;
+  fRGBInverted      := tfR5G6B5;
   fRange.r          := $1F;
   fRange.g          := $3F;
   fRange.b          := $1F;
   fShift.r          :=  11;
   fShift.g          :=   5;
   fShift.b          :=   0;
-  fglFormat         := GL_RGB;
+  fglFormat         := GL_RGB;  //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
   fglInternalFormat := GL_RGB8;
   fglDataFormat     := GL_UNSIGNED_SHORT_5_6_5;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGR5.Create;
 begin
   inherited Create;
@@ -2775,6 +3209,7 @@ begin
   fFormat           := tfBGR5;
   fWithAlpha        := tfBGR5A1;
   fWithoutAlpha     := tfBGR5;
+  fRGBInverted      := tfRGB5;
   fRange.r          := $1F;
   fRange.g          := $1F;
   fRange.b          := $1F;
@@ -2788,59 +3223,23 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  aData^ := aPixel.Data.b;
-  inc(aData);
-  aData^ := aPixel.Data.g;
-  inc(aData);
-  aData^ := aPixel.Data.r;
-  inc(aData);
-end;
-
-procedure TfdBGR8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-begin
-  aPixel.Data.b := aData^;
-  inc(aData);
-  aPixel.Data.g := aData^;
-  inc(aData);
-  aPixel.Data.r := aData^;
-  inc(aData);
-  aPixel.Data.a := 0;
-end;
-
 constructor TfdBGR8.Create;
 begin
   inherited Create;
-  fPixelSize        := 3.0;
   fFormat           := tfBGR8;
   fWithAlpha        := tfBGRA8;
   fWithoutAlpha     := tfBGR8;
-  fRange.r          := $FF;
-  fRange.g          := $FF;
-  fRange.b          := $FF;
-  fRange.a          := $00;
-  fShift.r          :=  16;
-  fShift.g          :=   8;
-  fShift.b          :=   0;
-  fShift.a          :=   0;
-  fglFormat         := GL_BGR;
+  fRGBInverted      := tfRGB8;
   fglInternalFormat := GL_RGB8;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGR10.Create;
 begin
   inherited Create;
   fFormat           := tfBGR10;
   fWithAlpha        := tfBGR10A2;
   fWithoutAlpha     := tfBGR10;
+  fRGBInverted      := tfRGB10;
   fRange.r          := $3FF;
   fRange.g          := $3FF;
   fRange.b          := $3FF;
@@ -2849,86 +3248,48 @@ begin
   fShift.g          :=   10;
   fShift.b          :=    0;
   fShift.a          :=    0;
-  fglFormat         := GL_BGR;
+  fglFormat         := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
   fglInternalFormat := GL_RGB10;
   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdBGR16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  PWord(aData)^ := aPixel.Data.b;
-  inc(aData, 2);
-  PWord(aData)^ := aPixel.Data.g;
-  inc(aData, 2);
-  PWord(aData)^ := aPixel.Data.r;
-  inc(aData, 2);
-end;
-
-procedure TfdBGR16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+constructor TfdBGR12.Create;
 begin
-  aPixel.Data.b := PWord(aData)^;
-  inc(aData, 2);
-  aPixel.Data.g := PWord(aData)^;
-  inc(aData, 2);
-  aPixel.Data.r := PWord(aData)^;
-  inc(aData, 2);
-  aPixel.Data.a := 0;
+  inherited Create;
+  fFormat           := tfBGR12;
+  fWithAlpha        := tfBGRA12;
+  fWithoutAlpha     := tfBGR12;
+  fRGBInverted      := tfRGB12;
+  fglInternalFormat := GL_RGB12;
 end;
 
 constructor TfdBGR16.Create;
 begin
   inherited Create;
-  fPixelSize        := 6.0;
   fFormat           := tfBGR16;
   fWithAlpha        := tfBGRA16;
   fWithoutAlpha     := tfBGR16;
-  fRange.r          := $FFFF;
-  fRange.g          := $FFFF;
-  fRange.b          := $FFFF;
-  fRange.a          := $0000;
-  fShift.r          :=    32;
-  fShift.g          :=    16;
-  fShift.b          :=     0;
-  fShift.a          :=     0;
-  fglFormat         := GL_BGR;
+  fRGBInverted      := tfRGB16;
   fglInternalFormat := GL_RGB16;
-  fglDataFormat     := GL_UNSIGNED_SHORT;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGRA2.Create;
 begin
   inherited Create;
   fFormat           := tfBGRA2;
   fWithAlpha        := tfBGRA4;
   fWithoutAlpha     := tfBGR4;
-  fRange.r          := $3;
-  fRange.g          := $3;
-  fRange.b          := $3;
-  fRange.a          := $3;
-  fShift.r          :=  4;
-  fShift.g          :=  2;
-  fShift.b          :=  0;
-  fShift.a          :=  6;
-  fglFormat         := GL_BGRA;
+  fRGBInverted      := tfRGBA2;
   fglInternalFormat := GL_RGBA2;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGRA4.Create;
 begin
   inherited Create;
   fFormat           := tfBGRA4;
   fWithAlpha        := tfBGRA4;
   fWithoutAlpha     := tfBGR4;
+  fRGBInverted      := tfRGBA4;
   fRange.r          := $F;
   fRange.g          := $F;
   fRange.b          := $F;
@@ -2942,15 +3303,13 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGR5A1.Create;
 begin
   inherited Create;
   fFormat           := tfBGR5A1;
   fWithAlpha        := tfBGR5A1;
   fWithoutAlpha     := tfBGR5;
+  fRGBInverted      := tfRGB5A1;
   fRange.r          := $1F;
   fRange.g          := $1F;
   fRange.b          := $1F;
@@ -2964,52 +3323,23 @@ begin
   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////s
-procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  inherited Map(aPixel, aData, aMapData);
-  aData^ := aPixel.Data.a;
-  inc(aData);
-end;
-
-procedure TfdBGRA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
-begin
-  inherited Unmap(aData, aPixel, aMapData);
-  aPixel.Data.a := aData^;
-  inc(aData);
-end;
-
 constructor TfdBGRA8.Create;
 begin
   inherited Create;
-  fPixelSize        := 4.0;
   fFormat           := tfBGRA8;
   fWithAlpha        := tfBGRA8;
   fWithoutAlpha     := tfBGR8;
-  fRange.r          := $FF;
-  fRange.g          := $FF;
-  fRange.b          := $FF;
-  fRange.a          := $FF;
-  fShift.r          :=  16;
-  fShift.g          :=   8;
-  fShift.b          :=   0;
-  fShift.a          :=  24;
-  fglFormat         := GL_BGRA;
+  fRGBInverted      := tfRGBA8;
   fglInternalFormat := GL_RGBA8;
-  fglDataFormat     := GL_UNSIGNED_BYTE;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 constructor TfdBGR10A2.Create;
 begin
   inherited Create;
   fFormat           := tfBGR10A2;
   fWithAlpha        := tfBGR10A2;
   fWithoutAlpha     := tfBGR10;
+  fRGBInverted      := tfRGB10A2;
   fRange.r          := $3FF;
   fRange.g          := $3FF;
   fRange.b          := $3FF;
@@ -3023,41 +3353,51 @@ begin
   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
 end;
 
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TfdBGRA16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
-begin
-  inherited Map(aPixel, aData, aMapData);
-  PWord(aData)^ := aPixel.Data.a;
-  inc(aData, 2);
-end;
-
-procedure TfdBGRA16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+constructor TfdBGRA12.Create;
 begin
-  inherited Unmap(aData, aPixel, aMapData);
-  aPixel.Data.a := PWord(aData)^;
-  inc(aData, 2);
+  inherited Create;
+  fFormat           := tfBGRA12;
+  fWithAlpha        := tfBGRA12;
+  fWithoutAlpha     := tfBGR12;
+  fRGBInverted      := tfRGBA12;
+  fglInternalFormat := GL_RGBA12;
 end;
 
 constructor TfdBGRA16.Create;
 begin
   inherited Create;
-  fPixelSize        := 8.0;
   fFormat           := tfBGRA16;
   fWithAlpha        := tfBGRA16;
   fWithoutAlpha     := tfBGR16;
-  fRange.r          := $FFFF;
-  fRange.g          := $FFFF;
-  fRange.b          := $FFFF;
-  fRange.a          := $FFFF;
-  fShift.r          :=    32;
-  fShift.g          :=    16;
-  fShift.b          :=     0;
-  fShift.a          :=    48;
-  fglFormat         := GL_BGRA;
+  fRGBInverted      := tfRGBA16;
   fglInternalFormat := GL_RGBA16;
-  fglDataFormat     := GL_UNSIGNED_SHORT;
+end;
+
+constructor TfdDepth16.Create;
+begin
+  inherited Create;
+  fFormat           := tfDepth16;
+  fWithAlpha        := tfEmpty;
+  fWithoutAlpha     := tfDepth16;
+  fglInternalFormat := GL_DEPTH_COMPONENT16;
+end;
+
+constructor TfdDepth24.Create;
+begin
+  inherited Create;
+  fFormat           := tfDepth24;
+  fWithAlpha        := tfEmpty;
+  fWithoutAlpha     := tfDepth24;
+  fglInternalFormat := GL_DEPTH_COMPONENT24;
+end;
+
+constructor TfdDepth32.Create;
+begin
+  inherited Create;
+  fFormat           := tfDepth32;
+  fWithAlpha        := tfEmpty;
+  fWithoutAlpha     := tfDepth32;
+  fglInternalFormat := GL_DEPTH_COMPONENT32;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -3114,31 +3454,31 @@ end;
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.SetRedMask(const aValue: UInt64);
+procedure TbmpBitfieldFormat.SetRedMask(const aValue: UInt64);
 begin
   Update(aValue, fRange.r, fShift.r);
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.SetGreenMask(const aValue: UInt64);
+procedure TbmpBitfieldFormat.SetGreenMask(const aValue: UInt64);
 begin
   Update(aValue, fRange.g, fShift.g);
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.SetBlueMask(const aValue: UInt64);
+procedure TbmpBitfieldFormat.SetBlueMask(const aValue: UInt64);
 begin
   Update(aValue, fRange.b, fShift.b);
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.SetAlphaMask(const aValue: UInt64);
+procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: UInt64);
 begin
   Update(aValue, fRange.a, fShift.a);
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
+procedure TbmpBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
   aShift: Byte);
 begin
   aShift := 0;
@@ -3160,7 +3500,7 @@ begin
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
 var
   data: UInt64;
   s: Integer;
@@ -3185,7 +3525,7 @@ begin
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TbmpBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 var
   data: UInt64;
   s, i: Integer;
@@ -3209,12 +3549,87 @@ end;
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+procedure TbmpColorTableFormat.CreateColorTable;
+var
+  bits: Byte;
+  len: Integer;
+  i: Integer;
+begin
+  if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
+    raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
+
+  if (Format = tfLuminance4) then
+    SetLength(fColorTable, 16)
+  else
+    SetLength(fColorTable, 256);
+
+  case Format of
+    tfLuminance4: begin
+      for i := 0 to High(fColorTable) do begin
+        fColorTable[i].r := 16 * i;
+        fColorTable[i].g := 16 * i;
+        fColorTable[i].b := 16 * i;
+        fColorTable[i].a := 0;
+      end;
+    end;
+
+    tfLuminance8: begin
+      for i := 0 to High(fColorTable) do begin
+        fColorTable[i].r := i;
+        fColorTable[i].g := i;
+        fColorTable[i].b := i;
+        fColorTable[i].a := 0;
+      end;
+    end;
+
+    tfR3G3B2: begin
+      for i := 0 to High(fColorTable) do begin
+        fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
+        fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
+        fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
+        fColorTable[i].a := 0;
+      end;
+    end;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+var
+  d: Byte;
 begin
-  raise EglBitmapException.Create('mapping of color table formats is not supported');
+  if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
+    raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
+
+  case Format of
+    tfLuminance4: begin
+      if (aMapData = nil) then
+        aData^ := 0;
+      d := LuminanceWeight(aPixel) and Range.r;
+      aData^ := aData^ or (d shl (4 - PtrInt(aMapData)));
+      inc(aMapData, 4);
+      if (PtrInt(aMapData) >= 8) then begin
+        inc(aData);
+        aMapData := nil;
+      end;
+    end;
+
+    tfLuminance8: begin
+      aData^ := LuminanceWeight(aPixel) and Range.r;
+      inc(aData);
+    end;
+
+    tfR3G3B2: begin
+      aData^ := Round(
+        ((aPixel.Data.r and Range.r) shl Shift.r) or
+        ((aPixel.Data.g and Range.g) shl Shift.g) or
+        ((aPixel.Data.b and Range.b) shl Shift.b));
+      inc(aData);
+    end;
+  end;
 end;
 
-procedure TColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+procedure TbmpColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
 type
   PUInt64 = ^UInt64;
 var
@@ -3251,7 +3666,7 @@ begin
   inc(aData, s);
 end;
 
-destructor TColorTableFormat.Destroy;
+destructor TbmpColorTableFormat.Destroy;
 begin
   SetLength(fColorTable, 0);
   inherited Destroy;
@@ -3643,6 +4058,8 @@ procedure TglBitmap.LoadFromFile(const aFilename: String);
 var
   fs: TFileStream;
 begin
+  if not FileExists(aFilename) then
+    raise EglBitmapException.Create('file does not exist: ' + aFilename);
   fFilename := aFilename;
   fs := TFileStream.Create(fFilename, fmOpenRead);
   try
@@ -4482,7 +4899,7 @@ var
   end;
 
 begin
-  if aFormat <> fFormat then begin
+  if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
     SourceFD := TFormatDescriptor.Get(Format);
     DestFD   := TFormatDescriptor.Get(aFormat);
 
@@ -5657,16 +6074,6 @@ type
     biClrImportant: Cardinal;
   end;
 
-  (* TODO: delete?
-  TBMPInfoOS = packed record
-    biSize: Cardinal;
-    biWidth: Longint;
-    biHeight: Longint;
-    biPlanes: Word;
-    biBitCount: Word;
-  end;
-  *)
-
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
 
@@ -5703,10 +6110,10 @@ function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
     end;
   end;
 
-  function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TColorTableFormat;
+  function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
   var
     i, c: Integer;
-    ColorTable: TColorTable;
+    ColorTable: TbmpColorTable;
   begin
     result := nil;
     if (aInfo.biBitCount >= 16) then
@@ -5717,20 +6124,20 @@ function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
       c := 1 shl aInfo.biBitCount;
     SetLength(ColorTable, c);
     for i := 0 to c-1 do begin
-      aStream.Read(ColorTable[i], SizeOf(TColorTableEnty));
+      aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
       if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
         aFormat := tfRGB8;
     end;
 
-    result := TColorTableFormat.Create;
+    result := TbmpColorTableFormat.Create;
     result.PixelSize  := aInfo.biBitCount / 8;
     result.ColorTable := ColorTable;
-    result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
+    result.Range      := glBitmapColorRec($FF, $FF, $FF, $00);
   end;
 
   //////////////////////////////////////////////////////////////////////////////////////////////////
   function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
-    const aInfo: TBMPInfo): TBitfieldFormat;
+    const aInfo: TBMPInfo): TbmpBitfieldFormat;
   var
     TmpFormat: TglBitmapFormat;
     FormatDesc: TFormatDescriptor;
@@ -5750,7 +6157,7 @@ function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
       if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
         aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
 
-      result := TBitfieldFormat.Create;
+      result := TbmpBitfieldFormat.Create;
       result.PixelSize := aInfo.biBitCount / 8;
       result.RedMask   := aMask.r;
       result.GreenMask := aMask.g;
@@ -5767,7 +6174,7 @@ var
   LineBuf, ImageData, TmpData: PByte;
   SourceMD, DestMD: Pointer;
   BmpFormat: TglBitmapFormat;
-  ColorTable: TColorTable;
+  ColorTable: TbmpColorTable;
 
   //records
   Mask: TglBitmapColorRec;
@@ -5885,12 +6292,15 @@ procedure TglBitmap.SaveBMP(const aStream: TStream);
 var
   Header: TBMPHeader;
   Info: TBMPInfo;
-  pData, pTemp: pByte;
+  Converter: TbmpColorTableFormat;
+  FormatDesc: TFormatDescriptor;
+  SourceFD, DestFD: Pointer;
+  pData, srcData, dstData, ConvertBuffer: pByte;
 
+  Pixel: TglBitmapPixelData;
   PixelFormat: TglBitmapPixelData;
-  FormatDesc: TFormatDescriptor;
-  ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
-  Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
+  ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx, i: Integer;
+  RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
 
   PaddingBuff: Cardinal;
 
@@ -5903,8 +6313,11 @@ begin
   if not (ftBMP in FormatGetSupportedFiles(Format)) then
     raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
 
-  ImageSize := TFormatDescriptor.Get(Format).GetSize(Dimension);
+  Converter  := nil;
+  FormatDesc := TFormatDescriptor.Get(Format);
+  ImageSize  := FormatDesc.GetSize(Dimension);
 
+  FillChar(Header, SizeOf(Header), 0);
   Header.bfType      := BMP_MAGIC;
   Header.bfSize      := SizeOf(Header) + SizeOf(Info) + ImageSize;
   Header.bfReserved1 := 0;
@@ -5918,105 +6331,142 @@ begin
   Info.biPlanes      := 1;
   Info.biCompression := BMP_COMP_RGB;
   Info.biSizeImage   := ImageSize;
-  case Format of
-    //TODO tfAlpha8, ifLuminance8, ifDepth8:
-    tfLuminance8:
-      begin
-        Info.biBitCount :=  8;
 
-        Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
-        Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
+  try
+    case Format of
+      tfLuminance4: begin
+        Info.biBitCount  := 4;
+        Header.bfSize    := Header.bfSize    + 16 * SizeOf(Cardinal);
+        Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
+        Converter           := TbmpColorTableFormat.Create;
+        Converter.PixelSize := 0.5;
+        Converter.Format    := Format;
+        Converter.Range     := glBitmapColorRec($F, $F, $F, $0);
+        Converter.CreateColorTable;
+      end;
 
-        Info.biClrUsed := 256;
-        Info.biClrImportant := 256;
+      tfR3G3B2, tfLuminance8: begin
+        Info.biBitCount  :=  8;
+        Header.bfSize    := Header.bfSize    + 256 * SizeOf(Cardinal);
+        Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
+        Converter           := TbmpColorTableFormat.Create;
+        Converter.PixelSize := 1;
+        Converter.Format    := Format;
+        if (Format = tfR3G3B2) then begin
+          Converter.Range := glBitmapColorRec($7, $7, $3, $0);
+          Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
+        end else
+          Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
+        Converter.CreateColorTable;
       end;
-    //TODO ifLuminance8Alpha8, tfRGBA4, ifR5G6B5, tfRGB5A1:
-    tfLuminance8Alpha8, tfRGB5A1:
-      begin
-        Info.biBitCount := 16;
+
+      tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
+      tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
+        Info.biBitCount    := 16;
         Info.biCompression := BMP_COMP_BITFIELDS;
       end;
-    tfBGR8, tfRGB8:
-      Info.biBitCount := 24;
-    //TODO tfBGRA8, tfRGBA8, tfRGB10A2:
-    tfBGRA8, tfRGBA8:
-      begin
-        Info.biBitCount := 32;
+
+      tfBGR8, tfRGB8: begin
+        Info.biBitCount := 24;
+      end;
+
+      tfRGB10, tfRGB10A2, tfRGBA8,
+      tfBGR10, tfBGR10A2, tfBGRA8: begin
+        Info.biBitCount    := 32;
         Info.biCompression := BMP_COMP_BITFIELDS;
       end;
     else
       raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
-  end;
-  Info.biXPelsPerMeter := 2835;
-  Info.biYPelsPerMeter := 2835;
-
-  // prepare bitmasks
-  if Info.biCompression = BMP_COMP_BITFIELDS then begin
-    Info.biSize      := Info.biSize      + 4 * SizeOf(Cardinal);
-    Header.bfSize    := Header.bfSize    + 4 * SizeOf(Cardinal);
-    Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
-
-    FormatDesc := TFormatDescriptor.Get(Format);
-    RedMask   := FormatDesc.RedMask;
-    GreenMask := FormatDesc.GreenMask;
-    BlueMask  := FormatDesc.BlueMask;
-    AlphaMask := FormatDesc.AlphaMask;
-  end;
-
-  // headers
-  aStream.Write(Header, SizeOf(Header));
-  aStream.Write(Info, SizeOf(Info));
-
-  // colortable
-  if Info.biBitCount = 8 then begin
-    Temp := 0;
-    for ColorIdx := Low(Byte) to High(Byte) do begin
-      aStream.Write(Temp, 4);
-      Temp := Temp + $00010101;
     end;
-  end;
-
-  // bitmasks
-  if Info.biCompression = BMP_COMP_BITFIELDS then begin
-    aStream.Write(RedMask,   SizeOf(Cardinal));
-    aStream.Write(GreenMask, SizeOf(Cardinal));
-    aStream.Write(BlueMask,  SizeOf(Cardinal));
-    aStream.Write(AlphaMask, SizeOf(Cardinal));
-  end;
-
-  // image data
-  LineSize := Trunc(Width * TFormatDescriptor.Get(Format).PixelSize);
-  Padding := GetLineWidth - LineSize;
-  PaddingBuff := 0;
+    Info.biXPelsPerMeter := 2835;
+    Info.biYPelsPerMeter := 2835;
+
+    // prepare bitmasks
+    if Info.biCompression = BMP_COMP_BITFIELDS then begin
+      Header.bfSize    := Header.bfSize    + 4 * SizeOf(Cardinal);
+      Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
+
+      RedMask    := FormatDesc.RedMask;
+      GreenMask  := FormatDesc.GreenMask;
+      BlueMask   := FormatDesc.BlueMask;
+      AlphaMask  := FormatDesc.AlphaMask;
+    end;
 
-  pData := Data;
-  Inc(pData, (Height -1) * LineSize);
+    // headers
+    aStream.Write(Header, SizeOf(Header));
+    aStream.Write(Info, SizeOf(Info));
+
+    // colortable
+    if Assigned(Converter) then
+      aStream.Write(Converter.ColorTable[0].b,
+        SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
+
+    // bitmasks
+    if Info.biCompression = BMP_COMP_BITFIELDS then begin
+      aStream.Write(RedMask,   SizeOf(Cardinal));
+      aStream.Write(GreenMask, SizeOf(Cardinal));
+      aStream.Write(BlueMask,  SizeOf(Cardinal));
+      aStream.Write(AlphaMask, SizeOf(Cardinal));
+    end;
 
-  // prepare row buffer. But only for RGB because RGBA supports color masks
-  // so it's possible to change color within the image.
-  if (Format = tfRGB8) then
-    GetMem(pTemp, fRowSize)
-  else
-    pTemp := nil;
+    // image data
+    rbLineSize  := Round(Info.biWidth * FormatDesc.PixelSize);
+    wbLineSize  := Round(Info.biWidth * Info.biBitCount / 8);
+    Padding     := GetLineWidth - wbLineSize;
+    PaddingBuff := 0;
+
+    pData := Data;
+    inc(pData, (Height-1) * rbLineSize);
+
+    // prepare row buffer. But only for RGB because RGBA supports color masks
+    // so it's possible to change color within the image.
+    if Assigned(Converter) then begin
+      FormatDesc.PreparePixel(Pixel);
+      GetMem(ConvertBuffer, wbLineSize);
+      SourceFD := FormatDesc.CreateMappingData;
+      DestFD   := Converter.CreateMappingData;
+    end else
+      ConvertBuffer := nil;
 
-  try
-    // write image data
-    for LineIdx := 0 to Height - 1 do begin
-      // preparing row
-      if Format = tfRGB8 then begin
-        Move(pData^, pTemp^, fRowSize);
-        SwapRGB(pTemp, Width, false);
-      end else
-        pTemp := pData;
-      aStream.Write(pTemp^, LineSize);
-      Dec(pData, LineSize);
-      if Padding > 0 then
-        aStream.Write(PaddingBuff, Padding);
+    try
+      for LineIdx := 0 to Height - 1 do begin
+        // preparing row
+        if Assigned(Converter) then begin
+          srcData := pData;
+          dstData := ConvertBuffer;
+          for PixelIdx := 0 to Info.biWidth-1 do begin
+            FormatDesc.Unmap(srcData, Pixel, SourceFD);
+            with FormatDesc do begin
+              //TODO use convert function
+              for i := 0 to 3 do
+                if (Converter.Range.arr[i] <> Range.arr[i]) then begin
+                  if (Range.arr[i] > 0) then
+                    Pixel.Data.arr[i] := Round(Pixel.Data.arr[i] / Range.arr[i] * Converter.Range.arr[i])
+                  else
+                    Pixel.Data.arr[i] := 0;
+                end;
+            end;
+            Converter.Map(Pixel, dstData, DestFD);
+          end;
+          aStream.Write(ConvertBuffer^, wbLineSize);
+        end else begin
+          aStream.Write(pData^, rbLineSize);
+        end;
+        dec(pData, rbLineSize);
+        if (Padding > 0) then
+          aStream.Write(PaddingBuff, Padding);
+      end;
+    finally
+      // destroy row buffer
+      if Assigned(ConvertBuffer) then begin
+        FormatDesc.FreeMappingData(SourceFD);
+        Converter.FreeMappingData(DestFD);
+        FreeMem(ConvertBuffer);
+      end;
     end;
   finally
-    // destroy row buffer
-    if Format = tfRGB8 then
-      FreeMem(pTemp);
+    if Assigned(Converter) then
+      Converter.Free;
   end;
 end;
 
@@ -6028,29 +6478,43 @@ type
     ImageID: Byte;
     ColorMapType: Byte;
     ImageType: Byte;
-    ColorMapSpec: Array[0..4] of Byte;
+    //ColorMapSpec: Array[0..4] of Byte;
+    ColorMapStart: Word;
+    ColorMapLength: Word;
+    ColorMapEntrySize: Byte;
     OrigX: Word;
     OrigY: Word;
     Width: Word;
     Height: Word;
     Bpp: Byte;
-    ImageDes: Byte;
+    ImageDesc: Byte;
   end;
 
 const
-  TGA_UNCOMPRESSED_RGB = 2;
-  TGA_UNCOMPRESSED_GRAY = 3;
-  TGA_COMPRESSED_RGB = 10;
-  TGA_COMPRESSED_GRAY = 11;
+  TGA_UNCOMPRESSED_COLOR_TABLE =  1;
+  TGA_UNCOMPRESSED_RGB         =  2;
+  TGA_UNCOMPRESSED_GRAY        =  3;
+  TGA_COMPRESSED_COLOR_TABLE   =  9;
+  TGA_COMPRESSED_RGB           = 10;
+  TGA_COMPRESSED_GRAY          = 11;
+
+  TGA_NONE_COLOR_TABLE = 0;
+  TGA_COLOR_TABLE      = 1;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
 var
   Header: TTGAHeader;
-  NewImage, pData: PByte;
-  StreamPos: Int64;
-  PixelSize, LineSize, YStart, YEnd, YInc: Integer;
-  Format: TglBitmapFormat;
+  ImageData: PByte;
+  StartPosition: Int64;
+  PixelSize, LineSize: Integer;
+  tgaFormat: TglBitmapFormat;
+  FormatDesc: TFormatDescriptor;
+  Counter: packed record
+    X, Y: packed record
+      low, high, dir: Integer;
+    end;
+  end;
 
 const
   CACHE_SIZE = $4000;
@@ -6058,195 +6522,233 @@ const
   ////////////////////////////////////////////////////////////////////////////////////////
   procedure ReadUncompressed;
   var
-    RowSize: Integer;
+    i, j: Integer;
+    buf, tmp1, tmp2: PByte;
   begin
-    RowSize := Header.Width * PixelSize;
-    // copy line by line
-    while YStart <> YEnd + YInc do begin
-      pData := NewImage;
-      Inc(pData, YStart * LineSize);
-      aStream.Read(pData^, RowSize);
-      Inc(YStart, YInc);
+    buf := nil;
+    if (Counter.X.dir < 0) then
+      buf := GetMem(LineSize);
+    try
+      while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
+        tmp1 := ImageData + (Counter.Y.low * LineSize); //pointer to LineStart
+        if (Counter.X.dir < 0) then begin               //flip X
+          aStream.Read(buf^, LineSize);
+          tmp2 := buf + LineSize - PixelSize;           //pointer to last pixel in line
+          for i := 0 to Header.Width-1 do begin         //for all pixels in line
+            for j := 0 to PixelSize-1 do begin          //for all bytes in pixel
+              tmp1^ := tmp2^;
+              inc(tmp1);
+              inc(tmp2);
+            end;
+            dec(tmp2, 2*PixelSize);                     //move 2 backwards, because j-loop moved 1 forward
+          end;
+        end else
+          aStream.Read(tmp1^, LineSize);
+        inc(Counter.Y.low, Counter.Y.dir);              //move to next line index
+      end;
+    finally
+      if Assigned(buf) then
+        FreeMem(buf);
     end;
   end;
 
   ////////////////////////////////////////////////////////////////////////////////////////
   procedure ReadCompressed;
-  var
-    HeaderWidth, HeaderHeight: Integer;
-    LinePixelsRead, ImgPixelsRead, ImgPixelsToRead: Integer;
-
-    Cache: PByte;
-    CacheSize, CachePos: Integer;
-
-    Temp: Byte;
-    TempBuf: Array [0..15] of Byte;
-
-    PixelRepeat: Boolean;
-    PixelToRead, TempPixels: Integer;
 
     /////////////////////////////////////////////////////////////////
+    var
+      TmpData: PByte;
+      LinePixelsRead: Integer;
     procedure CheckLine;
     begin
-      if LinePixelsRead >= HeaderWidth then begin
+      if (LinePixelsRead >= Header.Width) then begin
         LinePixelsRead := 0;
-        pData := NewImage;
-        Inc(YStart, YInc);
-        Inc(pData, YStart * LineSize);
+        inc(Counter.Y.low, Counter.Y.dir);                //next line index
+        TmpData := ImageData + Counter.Y.low * LineSize;  //set line
+        if (Counter.X.dir < 0) then                       //if x flipped then
+          TmpData := TmpData + LineSize - PixelSize;      //set last pixel
       end;
     end;
 
     /////////////////////////////////////////////////////////////////
+    var
+      Cache: PByte;
+      CacheSize, CachePos: Integer;
     procedure CachedRead(out Buffer; Count: Integer);
     var
       BytesRead: Integer;
     begin
-      if (CachePos + Count) > CacheSize then begin
+      if (CachePos + Count > CacheSize) then begin
+        //if buffer overflow save non read bytes
         BytesRead := 0;
-
-        // Read Data
-        if CacheSize - CachePos > 0 then begin
+        if (CacheSize - CachePos > 0) then begin
           BytesRead := CacheSize - CachePos;
-          Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
-          Inc(CachePos, BytesRead);
+          Move(PByteArray(Cache)^[CachePos], Buffer, BytesRead);
+          inc(CachePos, BytesRead);
         end;
 
-        // Reload Data
+        //load cache from file
         CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
         aStream.Read(Cache^, CacheSize);
         CachePos := 0;
 
-        // Read else
-        if Count - BytesRead > 0 then begin
-          Move(pByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
-          Inc(CachePos, Count - BytesRead);
+        //read rest of requested bytes
+        if (Count - BytesRead > 0) then begin
+          Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
+          inc(CachePos, Count - BytesRead);
         end;
       end else begin
-        Move(pByteArray(Cache)^[CachePos], Buffer, Count);
-        Inc(CachePos, Count);
+        //if no buffer overflow just read the data
+        Move(PByteArray(Cache)^[CachePos], Buffer, Count);
+        inc(CachePos, Count);
+      end;
+    end;
+
+    procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
+    begin
+      case PixelSize of
+        1: begin
+          aBuffer^ := aData^;
+          inc(aBuffer, Counter.X.dir);
+        end;
+        2: begin
+          PWord(aBuffer)^ := PWord(aData)^;
+          inc(aBuffer, 2 * Counter.X.dir);
+        end;
+        3: begin
+          PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
+          PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
+          PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
+          inc(aBuffer, 3 * Counter.X.dir);
+        end;
+        4: begin
+          PCardinal(aBuffer)^ := PCardinal(aData)^;
+          inc(aBuffer, 4 * Counter.X.dir);
+        end;
       end;
     end;
 
+  var
+    TotalPixelsToRead, TotalPixelsRead: Integer;
+    Temp: Byte;
+    buf: array [0..3] of Byte; //1 pixel is max 32bit long
+    PixelRepeat: Boolean;
+    PixelsToRead, PixelCount: Integer;
   begin
     CacheSize := 0;
-    CachePos := 0;
+    CachePos  := 0;
 
-    HeaderWidth := Header.Width;
-    HeaderHeight := Header.Height;
+    TotalPixelsToRead := Header.Width * Header.Height;
+    TotalPixelsRead   := 0;
+    LinePixelsRead    := 0;
 
-    GetMem(Cache, CACHE_SIZE); // 16K Buffer
+    GetMem(Cache, CACHE_SIZE);
     try
-      ImgPixelsToRead := HeaderWidth * HeaderHeight;
-      ImgPixelsRead := 0;
-      LinePixelsRead := 0;
+      TmpData := ImageData + Counter.Y.low * LineSize;  //set line
+      if (Counter.X.dir < 0) then                       //if x flipped then
+        TmpData := TmpData + LineSize - PixelSize;      //set last pixel
 
-      pData := NewImage;
-      Inc(pData, YStart * LineSize);
-
-      // Read until all Pixels
       repeat
+        //read CommandByte
         CachedRead(Temp, 1);
-
-        PixelRepeat := Temp and $80 > 0;
-        PixelToRead := (Temp and $7F) + 1;
-
-        Inc(ImgPixelsRead, PixelToRead);
-
-        if PixelRepeat then begin
-          // repeat one pixel x times
-          CachedRead(TempBuf[0], PixelSize);
-
-          // repeat Pixel
-          while PixelToRead > 0 do begin
-            CheckLine;
-
-            TempPixels := HeaderWidth - LinePixelsRead;
-            if PixelToRead < TempPixels then
-              TempPixels := PixelToRead;
-
-            Inc(LinePixelsRead, TempPixels);
-            Dec(PixelToRead, TempPixels);
-
-            while TempPixels > 0 do begin
-              case PixelSize of
-                1: begin
-                  pData^ := TempBuf[0];
-                  Inc(pData);
-                end;
-                2: begin
-                  pWord(pData)^ := pWord(@TempBuf[0])^;
-                  Inc(pData, 2);
-                end;
-                3: begin
-                  pWord(pData)^ := pWord(@TempBuf[0])^;
-                  Inc(pData, 2);
-                  pData^ := TempBuf[2];
-                  Inc(pData);
-                end;
-                4: begin
-                  pDWord(pData)^ := pDWord(@TempBuf[0])^;
-                  Inc(pData, 4);
-                end;
-              end;
-              Dec(TempPixels);
-            end;
-          end;
-        end else begin
-          // copy x pixels
-          while PixelToRead > 0 do begin
-            CheckLine;
-            TempPixels := HeaderWidth - LinePixelsRead;
-            if PixelToRead < TempPixels then
-              TempPixels := PixelToRead;
-            CachedRead(pData^, PixelSize * TempPixels);
-            Inc(pData, PixelSize * TempPixels);
-            Inc(LinePixelsRead, TempPixels);
-            Dec(PixelToRead, TempPixels);
+        PixelRepeat  := (Temp and $80) > 0;
+        PixelsToRead := (Temp and $7F) + 1;
+        inc(TotalPixelsRead, PixelsToRead);
+
+        if PixelRepeat then
+          CachedRead(buf[0], PixelSize);
+        while (PixelsToRead > 0) do begin
+          CheckLine;
+          PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
+          while (PixelCount > 0) do begin
+            if not PixelRepeat then
+              CachedRead(buf[0], PixelSize);
+            PixelToBuffer(@buf[0], TmpData);
+            inc(LinePixelsRead);
+            dec(PixelsToRead);
+            dec(PixelCount);
           end;
         end;
-      until ImgPixelsRead >= ImgPixelsToRead;
+      until (TotalPixelsRead >= TotalPixelsToRead);
     finally
-      FreeMem(Cache)
+      FreeMem(Cache);
     end;
   end;
 
+  function IsGrayFormat: Boolean;
+  begin
+    result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
+  end;
+
 begin
   result := false;
 
   // reading header to test file and set cursor back to begin
-  StreamPos := aStream.Position;
+  StartPosition := aStream.Position;
   aStream.Read(Header, SizeOf(Header));
 
   // no colormapped files
-  if (Header.ColorMapType = 0) then begin
-    if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
+  if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
+    TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
+  begin
+    try
+      if Header.ImageID <> 0 then       // skip image ID
+        aStream.Position := aStream.Position + Header.ImageID;
+
       case Header.Bpp of
-        //TODO 8: Format := tfAlpha8;
-        16: Format := tfLuminance8Alpha8;
-        24: Format := tfBGR8;
-        32: Format := tfBGRA8;
-      else
-        raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
+         8: if IsGrayFormat then case (Header.ImageDesc and $F) of
+               0: tgaFormat := tfLuminance8;
+               8: tgaFormat := tfAlpha8;
+            end;
+
+        16: if IsGrayFormat then case (Header.ImageDesc and $F) of
+               0: tgaFormat := tfLuminance16;
+               8: tgaFormat := tfLuminance8Alpha8;
+            end else case (Header.ImageDesc and $F) of
+               0: tgaFormat := tfBGR5;
+               1: tgaFormat := tfBGR5A1;
+               4: tgaFormat := tfBGRA4;
+            end;
+
+        24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
+               0: tgaFormat := tfBGR8;
+            end;
+
+        32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
+               2: tgaFormat := tfBGR10A2;
+               8: tgaFormat := tfBGRA8;
+            end;
       end;
 
-      // skip image ID
-      if Header.ImageID <> 0 then
-        aStream.Position := aStream.Position + Header.ImageID;
+      if (tgaFormat = tfEmpty) then
+        raise EglBitmapException.Create('LoadTga - unsupported format');
 
-      PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1);
-      LineSize  := Trunc(Header.Width * PixelSize);
+      FormatDesc := TFormatDescriptor.Get(tgaFormat);
+      PixelSize  := FormatDesc.GetSize(1, 1);
+      LineSize   := FormatDesc.GetSize(Header.Width, 1);
 
-      GetMem(NewImage, LineSize * Header.Height);
+      GetMem(ImageData, LineSize * Header.Height);
       try
+        //column direction
+        if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
+          Counter.X.low  := Header.Height-1;;
+          Counter.X.high := 0;
+          Counter.X.dir  := -1;
+        end else begin
+          Counter.X.low  := 0;
+          Counter.X.high := Header.Height-1;
+          Counter.X.dir  := 1;
+        end;
+
         // Row direction
-        if (Header.ImageDes and $20 > 0) then begin
-          YStart := 0;
-          YEnd := Header.Height -1;
-          YInc := 1;
+        if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
+          Counter.Y.low  := 0;
+          Counter.Y.high := Header.Height-1;
+          Counter.Y.dir  := 1;
         end else begin
-          YStart := Header.Height -1;
-          YEnd := 0;
-          YInc := -1;
+          Counter.Y.low  := Header.Height-1;;
+          Counter.Y.high := 0;
+          Counter.Y.dir  := -1;
         end;
 
         // Read Image
@@ -6257,97 +6759,106 @@ begin
             ReadCompressed;
         end;
 
-        SetDataPointer(NewImage, Format, Header.Width, Header.Height);
+        SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height);
         result := true;
       except
-        FreeMem(NewImage);
+        FreeMem(ImageData);
         raise;
       end;
-    end
-      else aStream.Position := StreamPos;
+    finally
+      aStream.Position := StartPosition;
+    end;
   end
-    else aStream.Position := StreamPos;
+    else aStream.Position := StartPosition;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure TglBitmap.SaveTGA(const aStream: TStream);
 var
   Header: TTGAHeader;
-  Size: Integer;
-  pTemp: pByte;
+  LineSize, Size, x, y: Integer;
+  Pixel: TglBitmapPixelData;
+  LineBuf, SourceData, DestData: PByte;
+  SourceMD, DestMD: Pointer;
   FormatDesc: TFormatDescriptor;
-
-  procedure ConvertData(pTemp: pByte);
-  var
-    Idx, PixelSize: Integer;
-    Temp: byte;
-  begin
-    PixelSize := fPixelSize;
-    for Idx := 1 to Height * Width do begin
-      Temp := pByteArray(pTemp)^[2];
-      pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
-      pByteArray(pTemp)^[0] := Temp;
-      Inc(pTemp, PixelSize);
-    end;
-  end;
-
+  Converter: TFormatDescriptor;
 begin
   if not (ftTGA in FormatGetSupportedFiles(Format)) then
     raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
 
+  //prepare header
   FillChar(Header, SizeOf(Header), 0);
-  case Format of
-    //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
-    tfLuminance8: begin
-      Header.ImageType := TGA_UNCOMPRESSED_GRAY;
-      Header.Bpp := 8;
-    end;
-    tfLuminance8Alpha8: begin
-      Header.ImageType := TGA_UNCOMPRESSED_GRAY;
-      Header.Bpp := 16;
-    end;
-    tfRGB8, tfBGR8: begin
-      Header.ImageType := TGA_UNCOMPRESSED_RGB;
-      Header.Bpp := 24;
-    end;
-    tfRGBA8, tfBGRA8: begin
-      Header.ImageType := TGA_UNCOMPRESSED_RGB;
-      Header.Bpp := 32;
-    end;
-  else
-    raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
-  end;
 
-  Header.Width    := Width;
-  Header.Height   := Height;
-  Header.ImageDes := $20;
-  FormatDesc      := TFormatDescriptor.Get(Format);
+  //set ImageType
+  if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
+                 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
+    Header.ImageType := TGA_UNCOMPRESSED_GRAY
+  else
+    Header.ImageType := TGA_UNCOMPRESSED_RGB;
+
+  //set BitsPerPixel
+  if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
+    Header.Bpp := 8
+  else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
+                      tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
+    Header.Bpp := 16
+  else if (Format in [tfBGR8, tfRGB8]) then
+    Header.Bpp := 24
+  else
+    Header.Bpp := 32;
 
-  if FormatDesc.HasAlpha then
-    Header.ImageDes := Header.ImageDes or $08;
+  //set AlphaBitCount
+  case Format of
+    tfRGB5A1, tfBGR5A1:
+      Header.ImageDesc := 1 and $F;
+    tfRGB10A2, tfBGR10A2:
+      Header.ImageDesc := 2 and $F;
+    tfRGBA4, tfBGRA4:
+      Header.ImageDesc := 4 and $F;
+    tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
+      Header.ImageDesc := 8 and $F;
+  end;
+
+  Header.Width     := Width;
+  Header.Height    := Height;
+  Header.ImageDesc := Header.ImageDesc or $20; //flip y
   aStream.Write(Header, SizeOf(Header));
 
   // convert RGB(A) to BGR(A)
-  Size := FormatDesc.GetSize(Dimension);
-  if Format in [tfRGB8, tfRGBA8] then begin
-    GetMem(pTemp, Size);
-  end else
-    pTemp := Data;
-
-  try
-    // convert data
-    if Format in [tfRGB8, tfRGBA8] then begin
-      Move(Data^, pTemp^, Size);
-      ConvertData(pTemp);
+  Converter  := nil;
+  FormatDesc := TFormatDescriptor.Get(Format);
+  Size       := FormatDesc.GetSize(Dimension);
+  if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
+    if (FormatDesc.RGBInverted = tfEmpty) then
+      raise EglBitmapException.Create('inverted RGB format is empty');
+    Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
+    if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
+       (Converter.PixelSize <> FormatDesc.PixelSize) then
+      raise EglBitmapException.Create('invalid inverted RGB format');
+  end;
+
+  if Assigned(Converter) then begin
+    LineSize := FormatDesc.GetSize(Width, 1);
+    LineBuf  := GetMem(LineSize);
+    SourceMD := FormatDesc.CreateMappingData;
+    DestMD   := Converter.CreateMappingData;
+    try
+      SourceData := Data;
+      for y := 0 to Height-1 do begin
+        DestData := LineBuf;
+        for x := 0 to Width-1 do begin
+          FormatDesc.Unmap(SourceData, Pixel, SourceMD);
+          Converter.Map(Pixel, DestData, DestMD);
+        end;
+        aStream.Write(LineBuf^, LineSize);
+      end;
+    finally
+      FreeMem(LineBuf);
+      FormatDesc.FreeMappingData(SourceMD);
+      FormatDesc.FreeMappingData(DestMD);
     end;
-
-    // write data
-    aStream.Write(pTemp^, Size);
-  finally
-    // free tempdata
-    if Format in [tfRGB8, tfRGBA8] then
-      FreeMem(pTemp);
-  end;
+  end else
+    aStream.Write(Data^, Size);
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -7458,3 +7969,4 @@ finalization
   TFormatDescriptor.Finalize;
 
 end.
+