| @@ -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. | |||