* Delphi XE5 fixes
authorBergmann89 <bergmann89@muo-game.de>
Sat, 23 Nov 2013 13:04:52 +0000 (14:04 +0100)
committerBergmann89 <bergmann89@muo-game.de>
Sat, 23 Nov 2013 13:04:52 +0000 (14:04 +0100)
* PNG and JPEG magic number check
* some small bufixes

glBitmap.pas

index 0221b4d..04297fa 100644 (file)
@@ -1292,7 +1292,7 @@ type
     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
 
     function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
-    function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual; 
+    function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
 
     function CreateMappingData: Pointer; virtual;
     procedure FreeMappingData(var aMappingData: Pointer); virtual;
@@ -1944,7 +1944,7 @@ end;
 var
   GL_LibHandle: Pointer = nil;
 
-function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
+function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
 begin
   if not Assigned(aLibHandle) then
     aLibHandle := GL_LibHandle;
@@ -1971,7 +1971,7 @@ begin
 
   result := dlsym(aLibHandle, aProcName);
 {$IFEND}
-  if not Assigned(result) then
+  if not Assigned(result) and aRaiseOnErr then
     raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
 end;
 
@@ -2025,42 +2025,37 @@ begin
   if not Assigned(GLU_LibHandle) then
     raise EglBitmap.Create('unable to load library: ' + libglu);
 
-  try
-  {$IF DEFINED(GLB_WIN)}
-    wglGetProcAddress    := glbGetProcAddress('wglGetProcAddress');
-  {$ELSEIF DEFINED(GLB_LINUX)}
-    glXGetProcAddress    := glbGetProcAddress('glXGetProcAddress');
-    glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
-  {$IFEND}
-
-    glEnable := glbGetProcAddress('glEnable');
-    glDisable := glbGetProcAddress('glDisable');
-    glGetString := glbGetProcAddress('glGetString');
-    glGetIntegerv := glbGetProcAddress('glGetIntegerv');
-    glTexParameteri := glbGetProcAddress('glTexParameteri');
-    glTexParameteriv := glbGetProcAddress('glTexParameteriv');
-    glTexParameterfv := glbGetProcAddress('glTexParameterfv');
-    glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
-    glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
-    glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
-    glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
-    glTexGeni := glbGetProcAddress('glTexGeni');
-    glGenTextures := glbGetProcAddress('glGenTextures');
-    glBindTexture := glbGetProcAddress('glBindTexture');
-    glDeleteTextures := glbGetProcAddress('glDeleteTextures');
-    glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
-    glReadPixels := glbGetProcAddress('glReadPixels');
-    glPixelStorei := glbGetProcAddress('glPixelStorei');
-    glTexImage1D := glbGetProcAddress('glTexImage1D');
-    glTexImage2D := glbGetProcAddress('glTexImage2D');
-    glGetTexImage := glbGetProcAddress('glGetTexImage');
-
-    gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
-    gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
-  finally
-    glbFreeLibrary(GL_LibHandle);
-    glbFreeLibrary(GLU_LibHandle);
-  end;
+{$IF DEFINED(GLB_WIN)}
+  wglGetProcAddress    := glbGetProcAddress('wglGetProcAddress');
+{$ELSEIF DEFINED(GLB_LINUX)}
+  glXGetProcAddress    := glbGetProcAddress('glXGetProcAddress');
+  glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
+{$IFEND}
+
+  glEnable := glbGetProcAddress('glEnable');
+  glDisable := glbGetProcAddress('glDisable');
+  glGetString := glbGetProcAddress('glGetString');
+  glGetIntegerv := glbGetProcAddress('glGetIntegerv');
+  glTexParameteri := glbGetProcAddress('glTexParameteri');
+  glTexParameteriv := glbGetProcAddress('glTexParameteriv');
+  glTexParameterfv := glbGetProcAddress('glTexParameterfv');
+  glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
+  glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
+  glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
+  glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
+  glTexGeni := glbGetProcAddress('glTexGeni');
+  glGenTextures := glbGetProcAddress('glGenTextures');
+  glBindTexture := glbGetProcAddress('glBindTexture');
+  glDeleteTextures := glbGetProcAddress('glDeleteTextures');
+  glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
+  glReadPixels := glbGetProcAddress('glReadPixels');
+  glPixelStorei := glbGetProcAddress('glPixelStorei');
+  glTexImage1D := glbGetProcAddress('glTexImage1D');
+  glTexImage2D := glbGetProcAddress('glTexImage2D');
+  glGetTexImage := glbGetProcAddress('glGetTexImage');
+
+  gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
+  gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
 end;
 {$ENDIF}
 
@@ -2163,9 +2158,9 @@ begin
     glCompressedTexImage2D  := glbGetProcAddress('glCompressedTexImage2D');
     glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
   end else begin
-    glCompressedTexImage1D  := glbGetProcAddress('glCompressedTexImage1DARB');
-    glCompressedTexImage2D  := glbGetProcAddress('glCompressedTexImage2DARB');
-    glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
+    glCompressedTexImage1D  := glbGetProcAddress('glCompressedTexImage1DARB',  nil, false);
+    glCompressedTexImage2D  := glbGetProcAddress('glCompressedTexImage2DARB',  nil, false);
+    glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
   end;
 end;
 {$ENDIF}
@@ -4292,12 +4287,11 @@ begin
     fData := aData;
   end;
 
-  FillChar(fDimension, SizeOf(fDimension), 0);
   if not Assigned(fData) then begin
-    fFormat    := tfEmpty;
     fPixelSize := 0;
     fRowSize   := 0;
   end else begin
+    FillChar(fDimension, SizeOf(fDimension), 0);
     if aWidth <> -1 then begin
       fDimension.Fields := fDimension.Fields + [ffX];
       fDimension.X := aWidth;
@@ -4777,7 +4771,7 @@ begin
         tfRGBA8, tfBGRA8:
           aBitmap.PixelFormat := pf32bit;
       else
-        raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
+        raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
       end;
 
       pSource := Data;
@@ -4815,7 +4809,7 @@ begin
       pf32bit:
         IntFormat := tfBGRA8;
     else
-      raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
+      raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
     end;
 
     TempWidth  := aBitmap.Width;
@@ -4879,7 +4873,7 @@ begin
               Inc(pSource);
             end;
           end;
-        end;   
+        end;
         result := true;
       end;
     end;
@@ -5414,8 +5408,8 @@ procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
 begin
   if aUseRGB or aUseAlpha then
     AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
-      ((PtrInt(aUseAlpha) and 1) shl 1) or
-       (PtrInt(aUseRGB)   and 1)      ));
+      ((Byte(aUseAlpha) and 1) shl 1) or
+       (Byte(aUseRGB)   and 1)      ));
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -5690,13 +5684,26 @@ end;
 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
+const
+  MAGIC_LEN = 8;
+  PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
 var
   png: TPortableNetworkGraphic;
   intf: TLazIntfImage;
   StreamPos: Int64;
+  magic: String[MAGIC_LEN];
 begin
   result := true;
   StreamPos := aStream.Position;
+
+  SetLength(magic, MAGIC_LEN);
+  aStream.Read(magic[1], MAGIC_LEN);
+  aStream.Position := StreamPos;
+  if (magic <> PNG_MAGIC) then begin
+    result := false;
+    exit;
+  end;
+
   png := TPortableNetworkGraphic.Create;
   try try
     png.LoadFromStream(aStream);
@@ -5797,7 +5804,7 @@ begin
       // read informations
       png_read_info(png, png_info);
 
-      // size 
+      // size
       TempHeight := png_get_image_height(png, png_info);
       TempWidth := png_get_image_width(png, png_info);
 
@@ -6277,13 +6284,26 @@ end;
 {$IF DEFINED(GLB_LAZ_JPEG)}
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
+const
+  MAGIC_LEN = 2;
+  JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
 var
   jpeg: TJPEGImage;
   intf: TLazIntfImage;
   StreamPos: Int64;
+  magic: String[MAGIC_LEN];
 begin
   result := true;
   StreamPos := aStream.Position;
+
+  SetLength(magic, MAGIC_LEN);
+  aStream.Read(magic[1], MAGIC_LEN);
+  aStream.Position := StreamPos;
+  if (magic <> JPEG_MAGIC) then begin
+    result := false;
+    exit;
+  end;
+
   jpeg := TJPEGImage.Create;
   try try
     jpeg.LoadFromStream(aStream);
@@ -6886,7 +6906,7 @@ procedure TglBitmap.SaveBMP(const aStream: TStream);
 var
   Header: TBMPHeader;
   Info: TBMPInfo;
-  Converter: TbmpColorTableFormat;
+  Converter: TFormatDescriptor;
   FormatDesc: TFormatDescriptor;
   SourceFD, DestFD: Pointer;
   pData, srcData, dstData, ConvertBuffer: pByte;
@@ -6931,26 +6951,30 @@ 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;
+        Converter := TbmpColorTableFormat.Create;
+        with (Converter as TbmpColorTableFormat) do begin
+          PixelSize := 0.5;
+          Format    := Format;
+          Range     := glBitmapColorRec($F, $F, $F, $0);
+          CreateColorTable;
+        end;
       end;
 
       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;
+        Converter := TbmpColorTableFormat.Create;
+        with (Converter as TbmpColorTableFormat) do begin
+          PixelSize := 1;
+          Format    := Format;
+          if (Format = tfR3G3B2) then begin
+            Range := glBitmapColorRec($7, $7, $3, $0);
+            Shift := glBitmapShiftRec(0, 3, 6, 0);
+          end else
+            Range := glBitmapColorRec($FF, $FF, $FF, $0);
+          CreateColorTable;
+        end;
       end;
 
       tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
@@ -6961,6 +6985,8 @@ begin
 
       tfBGR8, tfRGB8: begin
         Info.biBitCount := 24;
+        if (Format = tfRGB8) then
+          Converter := TfdBGR8.Create; //use BGR8 Format Descriptor to Swap RGB Values
       end;
 
       tfRGB10, tfRGB10A2, tfRGBA8,
@@ -6990,9 +7016,10 @@ begin
     aStream.Write(Info, SizeOf(Info));
 
     // colortable
-    if Assigned(Converter) then
-      aStream.Write(Converter.ColorTable[0].b,
-        SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
+    if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
+      with (Converter as TbmpColorTableFormat) do
+        aStream.Write(ColorTable[0].b,
+          SizeOf(TbmpColorTableEnty) * Length(ColorTable));
 
     // bitmasks
     if Info.biCompression = BMP_COMP_BITFIELDS then begin
@@ -7280,7 +7307,7 @@ begin
       if Header.ImageID <> 0 then       // skip image ID
         aStream.Position := aStream.Position + Header.ImageID;
 
-      tgaFormat := tfEmpty;        
+      tgaFormat := tfEmpty;
       case Header.Bpp of
          8: if IsGrayFormat then case (Header.ImageDesc and $F) of
                0: tgaFormat := tfLuminance8;
@@ -7799,9 +7826,11 @@ var
 begin
   // Upload data
   FormatDesc := TFormatDescriptor.Get(Format);
-  if FormatDesc.IsCompressed then
+  if FormatDesc.IsCompressed then begin
+    if not Assigned(glCompressedTexImage1D) then
+      raise EglBitmap.Create('compressed formats not supported by video adapter');
     glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
-  else if aBuildWithGlu then
+  end else if aBuildWithGlu then
     gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
   else
     glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
@@ -7890,6 +7919,8 @@ begin
 
   FormatDesc := TFormatDescriptor.Get(Format);
   if FormatDesc.IsCompressed then begin
+    if not Assigned(glCompressedTexImage2D) then
+      raise EglBitmap.Create('compressed formats not supported by video adapter');
     glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
   end else if aBuildWithGlu then begin
     gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
@@ -7967,10 +7998,12 @@ begin
   FormatDesc := TFormatDescriptor.Get(IntFormat);
   GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
   try
-    if FormatDesc.IsCompressed then
+    if FormatDesc.IsCompressed then begin
+      if not Assigned(glGetCompressedTexImage) then
+        raise EglBitmap.Create('compressed formats not supported by video adapter');
       glGetCompressedTexImage(Target, 0, Temp)
-    else
-     glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
+    end else
+      glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
     SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
   except
     if Assigned(Temp) then
@@ -8527,4 +8560,3 @@ finalization
 {$ENDIF}
 
 end.
-