From 3c0bac298223a0af97537ea9534c3f6cd3452746 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Tue, 9 Dec 2014 21:53:01 +0100 Subject: [PATCH] * implemented RAW file format --- glBitmap.pas | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 9 deletions(-) diff --git a/glBitmap.pas b/glBitmap.pas index bde9922..759a404 100644 --- a/glBitmap.pas +++ b/glBitmap.pas @@ -859,7 +859,8 @@ type {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} ftDDS, ftTGA, - ftBMP); + ftBMP, + ftRAW); TglBitmapFileTypes = set of TglBitmapFileType; TglBitmapMipMap = ( @@ -1201,14 +1202,17 @@ type {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF} {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF} - function LoadBMP(const aStream: TStream): Boolean; virtual; - procedure SaveBMP(const aStream: TStream); virtual; + function LoadRAW(const aStream: TStream): Boolean; + procedure SaveRAW(const aStream: TStream); - function LoadTGA(const aStream: TStream): Boolean; virtual; - procedure SaveTGA(const aStream: TStream); virtual; + function LoadBMP(const aStream: TStream): Boolean; + procedure SaveBMP(const aStream: TStream); - function LoadDDS(const aStream: TStream): Boolean; virtual; - procedure SaveDDS(const aStream: TStream); virtual; + function LoadTGA(const aStream: TStream): Boolean; + procedure SaveTGA(const aStream: TStream); + + function LoadDDS(const aStream: TStream): Boolean; + procedure SaveDDS(const aStream: TStream); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1293,6 +1297,7 @@ function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosit function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub; function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui; function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul; +function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean; function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean; function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D; @@ -1344,11 +1349,14 @@ type function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual; procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual; + + constructor Create; virtual; public class procedure Init; class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor; class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor; class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor; + class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor; class procedure Clear; class procedure Finalize; end; @@ -1890,6 +1898,18 @@ begin end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean; +var + i: Integer; +begin + result := false; + for i := 0 to high(r1.arr) do + if (r1.arr[i] <> r2.arr[i]) then + exit; + result := true; +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean; var i: Integer; @@ -2494,6 +2514,12 @@ begin end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TFormatDescriptor.Create; +begin + inherited Create; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TfdAlpha_UB1//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); @@ -3869,7 +3895,7 @@ end; procedure TfdS3tcDtx5RGBA.SetValues; begin - inherited Create; + inherited SetValues; fFormat := tfS3tcDtx3RGBA; fWithAlpha := tfS3tcDtx3RGBA; fOpenGLFormat := tfS3tcDtx3RGBA; @@ -4022,7 +4048,36 @@ begin exit; end; - result := FormatDescriptors[tfEmpty]; + result := TFormatDescriptor.Get(tfEmpty); +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor; +var + ft: TglBitmapFormat; +begin + // find matching format with OpenGL support + for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin + result := Get(ft); + if glBitmapRec4ubCompare(result.Shift, aShift) and + glBitmapRec4ubCompare(result.Precision, aPrec) and + (result.glFormat <> 0) and + (result.glInternalFormat <> 0) and + ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) + then + exit; + end; + + // find matching format without OpenGL Support + for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin + result := Get(ft); + if glBitmapRec4ubCompare(result.Shift, aShift) and + glBitmapRec4ubCompare(result.Precision, aPrec) and + ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then + exit; + end; + + result := TFormatDescriptor.Get(tfEmpty); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -4653,6 +4708,7 @@ begin if not LoadDDS(aStream) then if not LoadTGA(aStream) then if not LoadBMP(aStream) then + if not LoadRAW(aStream) then raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.'); end; @@ -4730,6 +4786,7 @@ begin ftDDS: SaveDDS(aStream); ftTGA: SaveTGA(aStream); ftBMP: SaveBMP(aStream); + ftRAW: SaveRAW(aStream); end; end; @@ -6978,6 +7035,65 @@ end; {$ENDIF} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//RAW///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +type + RawHeader = packed record + Magic: String[5]; + Version: Byte; + Width: Integer; + Height: Integer; + DataSize: Integer; + BitsPerPixel: Integer; + Precision: TglBitmapRec4ub; + Shift: TglBitmapRec4ub; + end; + +function TglBitmap.LoadRAW(const aStream: TStream): Boolean; +var + header: RawHeader; + StartPos: Int64; + fd: TFormatDescriptor; + buf: PByte; +begin + result := false; + StartPos := aStream.Position; + aStream.Read(header{%H-}, SizeOf(header)); + if (header.Magic <> 'glBMP') then begin + aStream.Position := StartPos; + exit; + end; + + fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel); + if (fd.Format = tfEmpty) then + raise EglBitmapUnsupportedFormat.Create('no supported format found'); + + buf := GetMem(header.DataSize); + aStream.Read(buf^, header.DataSize); + SetDataPointer(buf, fd.Format, header.Width, header.Height); + + result := true; +end; + +procedure TglBitmap.SaveRAW(const aStream: TStream); +var + header: RawHeader; + fd: TFormatDescriptor; +begin + fd := TFormatDescriptor.Get(Format); + header.Magic := 'glBMP'; + header.Version := 1; + header.Width := Width; + header.Height := Height; + header.DataSize := fd.GetSize(fDimension); + header.BitsPerPixel := fd.BitsPerPixel; + header.Precision := fd.Precision; + header.Shift := fd.Shift; + aStream.Write(header, SizeOf(header)); + aStream.Write(Data^, header.DataSize); +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //BMP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const -- 2.1.4