Browse Source

* Delphi XE5 fixes

* PNG and JPEG magic number check
* some small bufixes
master
Bergmann89 11 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;

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.


Loading…
Cancel
Save