AWARE [SYSTEMS] Imaging expertise voor de Delphi ontwikkelaar
AWare Systems, Imaging expertise voor de Delphi ontwikkelaar, Home TechTalks / Bestandsformaat uit gegevens
AWare Systems on-line

Home
Custom development
Imaging
TechTalks
    Bestandformaat uit gegevens
    Tiling versus banding
    VCL TGraphic grondbeginselen
    Ongebruikte kleur
Company
Links

Talen

  English version
  Nederlandse versie

Contact

Informatie: info@awaresystems.be
Helpdesk: support@awaresystems.be
Verkoop: sales@awaresystems.be



Valid HTML 4.01!



Het bestandsformaat bepalen op basis van de gegevens

> Ik heb een .bmp, .jpg of .gif bestand in een Blob veld van een ClientDataset.
> Nu zoek ik een manier om het formaat te bepalen en...

Er bestaat geen eenduidige oplossing voor dit probleem. Zo hoeft een legitiem JPEG-bestand helemaal niet te beginnen met 255,216, hoewel dit bij vele het geval is en hoewel hierop een controle uitvoeren zowat de enige doeltreffende manier is om te bepalen of de gegevens in het JPEG-formaat zijn verpakt. Als u de database tabellen zelf ontwerpt, neemt u hierin best een afzonderlijk veld op dat het bestandformaat aangeeft, waardoor de behoefte aan een wankele bestandsformaatdetectie verdwijnt.

Om het te zeggen met een citaat van Ross Finlayson, zelf citerend uit Alien:
"They mostly come at night, ... mostly."
"Ahhh!" "Aiiieeee!" "Rip-ley!"

Die beesten wil je niet tegenkomen, bij dag of bij nacht. Maar er zijn uiteraard wel situaties waarin u gegevens voorgeschoteld krijgt zonder bruikbare aanduiding van het file formaat. De onderstaande functies krijgen een pointer naar het begin van de data en geven als resultaat of het waarschijnlijk is dat de gegevens in een bepaald formaat staan. De voorgestelde functies detecteren...

  • BMP (uit de eerste 18 bytes)
  • JPEG (uit de eerste 2 bytes)
  • GIF (uit de eerste 6 bytes)
  • TIFF (uit de eerste 8 bytes)
  • PCX (uit de eerste 4 bytes)
  • PCD-overview (uit de eerste 7 bytes)
  • ZIP (uit de eerste 4 bytes)
  • RAR (uit de eerste 3 bytes)
  • Outlook Express DBX (uit de eerste 4 bytes)

Geef ons een seintje indien u op de hoogte wilt blijven van de veranderingen of toevoegingen aan deze pagina.



BMP (uit de eerste 18 bytes)

function AsCodecBmpCheckFileHeader18(const a: Pointer): Boolean;

{$IFDEF DELPHI_5}

type

PCardinal = ^Cardinal;

{$ENDIF}

var

m: Pointer;

begin

Result := False;

if (PBitmapFileHeader(a)^.bfType <> 19778) then exit;

m := Pointer(Cardinal(a)+SizeOf(TBitmapFileHeader));

if (PCardinal(m)^ = SizeOf(TBitmapInfoHeader)) or (PCardinal(m)^ = SizeOf(TBitmapCoreHeader)) then Result := True;

end;



JPEG (uit de eerste 2 bytes)

function AsCodecJpgCheckFileHeader2(const a: Pointer): Boolean;

begin

Result := ((PByte(a)^ = 255) and (PByte(Cardinal(a)+1)^ = 216));

end;



GIF (uit de eerste 6 bytes)

function AsCodecGifCheckFileHeader6(const a: Pointer): Boolean;

const

gifver: array[0..5] of Char = 'GIF87A';

var

m: PByte;

n: Integer;

begin

Result := False;

m := a;

for n := 0 to 5 do

begin

if m^ <> Integer(gifver[n]) then

begin

if n = 3 then

exit

else if n = 4 then

begin

if m^ <> Ord('9') then exit;

end

else

begin

if m^ <> Integer(gifver[n])+32 then exit;

end;

end;

Inc(m);

end;

Result := True;

end;



TIFF (uit de eerste 8 bytes)

function AsCodecTiffCheckFileHeader8(const a: Pointer): Boolean;

type

RAsCodecTiffImageFileHeader = packed record

FByteOrder: array[0..1] of Byte;

FSignature: Word;

FFirstIfdOffset: Cardinal;

end;

PRAsCodecTiffImageFileHeader = ^RAsCodecTiffImageFileHeader;

var

m: Boolean;

n: Integer;

begin

Result := False;

if (PRAsCodecTiffImageFileHeader(a)^.FByteOrder[0] = 73) and (PRAsCodecTiffImageFileHeader(a)^.FByteOrder[1] = 73) then

m := False

else if (PRAsCodecTiffImageFileHeader(a)^.FByteOrder[0] = 77) and (PRAsCodecTiffImageFileHeader(a)^.FByteOrder[1] = 77) then

m := True

else

exit;

n := PRAsCodecTiffImageFileHeader(a)^.FSignature;

if m then n := (((n and 255) shl 8) or ((n and 65280) shr 8));

if n <> 42 then exit;

Result := True;

end;



PCD-overview (uit de eerste 7 bytes)

function AsCodecPcdCheckOverviewFileHeader7(const a: Pointer): Boolean;

const

pcd_opa: array[0..6] of Char = 'PCD_OPA';

var

m: PByte;

n: Integer;

begin

Result := False;

m := a;

for n := 0 to 6 do

begin

if m^ <> Integer(pcd_opa[n]) then exit;

Inc(m);

end;

Result := True;

end;



PCX (uit de eerste 4 bytes)

function AsCodecPcxCheckFileHeader4(const a: Pointer): Boolean;

type

RHeader4 = packed record

FManufacturer: Byte;

FVersion: Byte;

FEncoding: Byte;

FBitsPerPixel: Byte;

end;

PRHeader4 = ^RHeader4;

begin

Result := False;

if PRHeader4(a)^.FManufacturer <> 10 then exit;

if (PRHeader4(a)^.FVersion = 1) or (PRHeader4(a)^.FVersion>5) then exit;

if (PRHeader4(a)^.FEncoding <> 0) and (PRHeader4(a)^.FEncoding <> 1) then exit;

if (PRHeader4(a)^.FBitsPerPixel <> 1) and (PRHeader4(a)^.FBitsPerPixel <> 2) and (PRHeader4(a)^.FBitsPerPixel <> 4) and (PRHeader4(a)^.FBitsPerPixel <> 8) then exit;

Result := True;

end;



ZIP (uit de eerste 4 bytes)

function AsCodecZipCheckFileHeader4(const a: Pointer): Boolean;

{$IFDEF DELPHI_5}

type

PCardinal = ^Cardinal;

{$ENDIF}

begin

Result := (PCardinal(a)^ = $04034B50);

end;



RAR (uit de eerste 3 bytes)

function AsCodecRarCheckFileHeader3(const a: Pointer): Boolean;

begin

Result := ((PByte(a)^ = Ord('R')) and (PByte(Cardinal(a)+1)^ = Ord('a')) and (PByte(Cardinal(a)+2)^ = Ord('r')));

end;



Outlook Express DBX (uit de eerste 4 bytes)

function AsCodecOutlookExpressDbxCheckFileHeader4(const a: Pointer): Boolean;

{$IFDEF DELPHI_5}

type

PCardinal = ^Cardinal;

{$ENDIF}

begin

Result := (PCardinal(a)^ = $FE12ADCF);

end;