From 65e2aac8d0705d7c501a6723ab77e3f9cc8c0ff8 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Sat, 23 Nov 2013 14:04:52 +0100 Subject: [PATCH] * Delphi XE5 fixes * PNG and JPEG magic number check * some small bufixes --- glBitmap.pas | 182 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 75 deletions(-) diff --git a/glBitmap.pas b/glBitmap.pas index 0221b4d..04297fa 100644 --- a/glBitmap.pas +++ b/glBitmap.pas @@ -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. - -- 2.1.4