Browse Source

* Delphi XE5 fixes

* PNG and JPEG magic number check
* some small bufixes
master
Bergmann89 10 years ago
parent
commit
65e2aac8d0
1 changed files with 107 additions and 75 deletions
  1. +107
    -75
      glBitmap.pas

+ 107
- 75
glBitmap.pas View File

@@ -1292,7 +1292,7 @@ type
procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract; procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;


function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual; 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; function CreateMappingData: Pointer; virtual;
procedure FreeMappingData(var aMappingData: Pointer); virtual; procedure FreeMappingData(var aMappingData: Pointer); virtual;
@@ -1944,7 +1944,7 @@ end;
var var
GL_LibHandle: Pointer = nil; 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 begin
if not Assigned(aLibHandle) then if not Assigned(aLibHandle) then
aLibHandle := GL_LibHandle; aLibHandle := GL_LibHandle;
@@ -1971,7 +1971,7 @@ begin


result := dlsym(aLibHandle, aProcName); result := dlsym(aLibHandle, aProcName);
{$IFEND} {$IFEND}
if not Assigned(result) then
if not Assigned(result) and aRaiseOnErr then
raise EglBitmap.Create('unable to load procedure form library: ' + aProcName); raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
end; end;


@@ -2025,42 +2025,37 @@ begin
if not Assigned(GLU_LibHandle) then if not Assigned(GLU_LibHandle) then
raise EglBitmap.Create('unable to load library: ' + libglu); 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; end;
{$ENDIF} {$ENDIF}


@@ -2163,9 +2158,9 @@ begin
glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D'); glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage'); glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
end else begin 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;
end; end;
{$ENDIF} {$ENDIF}
@@ -4292,12 +4287,11 @@ begin
fData := aData; fData := aData;
end; end;


FillChar(fDimension, SizeOf(fDimension), 0);
if not Assigned(fData) then begin if not Assigned(fData) then begin
fFormat := tfEmpty;
fPixelSize := 0; fPixelSize := 0;
fRowSize := 0; fRowSize := 0;
end else begin end else begin
FillChar(fDimension, SizeOf(fDimension), 0);
if aWidth <> -1 then begin if aWidth <> -1 then begin
fDimension.Fields := fDimension.Fields + [ffX]; fDimension.Fields := fDimension.Fields + [ffX];
fDimension.X := aWidth; fDimension.X := aWidth;
@@ -4777,7 +4771,7 @@ begin
tfRGBA8, tfBGRA8: tfRGBA8, tfBGRA8:
aBitmap.PixelFormat := pf32bit; aBitmap.PixelFormat := pf32bit;
else else
raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
end; end;


pSource := Data; pSource := Data;
@@ -4815,7 +4809,7 @@ begin
pf32bit: pf32bit:
IntFormat := tfBGRA8; IntFormat := tfBGRA8;
else else
raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
end; end;


TempWidth := aBitmap.Width; TempWidth := aBitmap.Width;
@@ -4879,7 +4873,7 @@ begin
Inc(pSource); Inc(pSource);
end; end;
end; end;
end;
end;
result := true; result := true;
end; end;
end; end;
@@ -5414,8 +5408,8 @@ procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
begin begin
if aUseRGB or aUseAlpha then if aUseRGB or aUseAlpha then
AddFunc(glBitmapInvertFunc, false, {%H-}Pointer( 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; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -5690,13 +5684,26 @@ end;
//PNG///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TglBitmap.LoadPNG(const aStream: TStream): Boolean; 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 var
png: TPortableNetworkGraphic; png: TPortableNetworkGraphic;
intf: TLazIntfImage; intf: TLazIntfImage;
StreamPos: Int64; StreamPos: Int64;
magic: String[MAGIC_LEN];
begin begin
result := true; result := true;
StreamPos := aStream.Position; 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; png := TPortableNetworkGraphic.Create;
try try try try
png.LoadFromStream(aStream); png.LoadFromStream(aStream);
@@ -5797,7 +5804,7 @@ begin
// read informations // read informations
png_read_info(png, png_info); png_read_info(png, png_info);


// size
// size
TempHeight := png_get_image_height(png, png_info); TempHeight := png_get_image_height(png, png_info);
TempWidth := png_get_image_width(png, png_info); TempWidth := png_get_image_width(png, png_info);


@@ -6277,13 +6284,26 @@ end;
{$IF DEFINED(GLB_LAZ_JPEG)} {$IF DEFINED(GLB_LAZ_JPEG)}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TglBitmap.LoadJPEG(const aStream: TStream): Boolean; function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
const
MAGIC_LEN = 2;
JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
var var
jpeg: TJPEGImage; jpeg: TJPEGImage;
intf: TLazIntfImage; intf: TLazIntfImage;
StreamPos: Int64; StreamPos: Int64;
magic: String[MAGIC_LEN];
begin begin
result := true; result := true;
StreamPos := aStream.Position; 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; jpeg := TJPEGImage.Create;
try try try try
jpeg.LoadFromStream(aStream); jpeg.LoadFromStream(aStream);
@@ -6886,7 +6906,7 @@ procedure TglBitmap.SaveBMP(const aStream: TStream);
var var
Header: TBMPHeader; Header: TBMPHeader;
Info: TBMPInfo; Info: TBMPInfo;
Converter: TbmpColorTableFormat;
Converter: TFormatDescriptor;
FormatDesc: TFormatDescriptor; FormatDesc: TFormatDescriptor;
SourceFD, DestFD: Pointer; SourceFD, DestFD: Pointer;
pData, srcData, dstData, ConvertBuffer: pByte; pData, srcData, dstData, ConvertBuffer: pByte;
@@ -6931,26 +6951,30 @@ begin
Info.biBitCount := 4; Info.biBitCount := 4;
Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal); Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries 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; end;


tfR3G3B2, tfLuminance8: begin tfR3G3B2, tfLuminance8: begin
Info.biBitCount := 8; Info.biBitCount := 8;
Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal); Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries 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; end;


tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4, tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
@@ -6961,6 +6985,8 @@ begin


tfBGR8, tfRGB8: begin tfBGR8, tfRGB8: begin
Info.biBitCount := 24; Info.biBitCount := 24;
if (Format = tfRGB8) then
Converter := TfdBGR8.Create; //use BGR8 Format Descriptor to Swap RGB Values
end; end;


tfRGB10, tfRGB10A2, tfRGBA8, tfRGB10, tfRGB10A2, tfRGBA8,
@@ -6990,9 +7016,10 @@ begin
aStream.Write(Info, SizeOf(Info)); aStream.Write(Info, SizeOf(Info));


// colortable // 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 // bitmasks
if Info.biCompression = BMP_COMP_BITFIELDS then begin if Info.biCompression = BMP_COMP_BITFIELDS then begin
@@ -7280,7 +7307,7 @@ begin
if Header.ImageID <> 0 then // skip image ID if Header.ImageID <> 0 then // skip image ID
aStream.Position := aStream.Position + Header.ImageID; aStream.Position := aStream.Position + Header.ImageID;


tgaFormat := tfEmpty;
tgaFormat := tfEmpty;
case Header.Bpp of case Header.Bpp of
8: if IsGrayFormat then case (Header.ImageDesc and $F) of 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
0: tgaFormat := tfLuminance8; 0: tgaFormat := tfLuminance8;
@@ -7799,9 +7826,11 @@ var
begin begin
// Upload data // Upload data
FormatDesc := TFormatDescriptor.Get(Format); 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) 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) gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
else else
glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data); glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
@@ -7890,6 +7919,8 @@ begin


FormatDesc := TFormatDescriptor.Get(Format); FormatDesc := TFormatDescriptor.Get(Format);
if FormatDesc.IsCompressed then begin 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) glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
end else if aBuildWithGlu then begin end else if aBuildWithGlu then begin
gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height, gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
@@ -7967,10 +7998,12 @@ begin
FormatDesc := TFormatDescriptor.Get(IntFormat); FormatDesc := TFormatDescriptor.Get(IntFormat);
GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight)); GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
try 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) 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 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
except except
if Assigned(Temp) then if Assigned(Temp) then
@@ -8527,4 +8560,3 @@ finalization
{$ENDIF} {$ENDIF}


end. end.


Loading…
Cancel
Save