Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   TGA - Was ein Dateiformat o.O (https://www.delphipraxis.net/74623-tga-ein-dateiformat-o-o.html)

Neutral General 6. Aug 2006 17:44


TGA - Was ein Dateiformat o.O
 
Hi,

Wie man in einem gewissen anderen Post erkennen kann befasse ich mich in letzter Zeit (jetzt seit etwa ner Stunde :mrgreen:) mit dem Targa-Format. Das Format ist in hier bei Wikipedia beschrieben.
Nunja es gibt etliche Abschnitte in der Datei die als optional gekennzeichnet sind.. nunja "zum Glück" stehen aber im Dateifuß die Offsets zu den vielleicht vorhandenen Informationen... Naja das blöde ist nur der Dateifuß ist auch optional o.O
Was mach ich denn wenn ich keinen Dateifuß hab ? Dann weiß ich ja nichtmehr wo ich anfangen soll mit dem lesen von Targa-Dateien. Weil ja alles irgendwo da oder nicht da sein kann :pale:

Gruß
Neutral General

Khabarakh 6. Aug 2006 18:08

Re: TGA - Was ein Dateiformat o.O
 
Steht doch unten dran: Der Dateifuß kann optional sein, wenn diese optionalen Abschnitte aber enthalten sind, muss er natürlich auch enthalten sein.
Zitat:

1optional ab Version 2.0, Entwicklerverzeichnis und Dateifuß erforderlich
2optional ab Version 2.0, Dateifuß erforderlich
3optional ab Version 2.0, Metainformationen und Dateifuß erforderlich
4optional ab Version 2.0 (wenn vorhanden, dann immer die letzten 26 Bytes)
[add]
Im Klartext: Wenn nach dem Bitmap noch Daten folgen, muss es auch einen Dateifuß geben.
[/add]

Neutral General 6. Aug 2006 18:17

Re: TGA - Was ein Dateiformat o.O
 
Ok.

Aber ein weiteres Problem:

Zitat:

Bild-ID
(optional) 0-255 Bytes Bildidentifikator
Farbpalette
(optional) 0-8192 Bytes Palettendaten
die beiden Informationen kommen vor den Bilddaten und sind optional.. Woher weiß ich nun ob die Informationen vorhanden sind ? Bzw es würde ja schon reichen wenn ich wüsste wie ich die Bilddaten von den anderen unterscheide...

Gruß
Neutral General

Khabarakh 6. Aug 2006 18:21

Re: TGA - Was ein Dateiformat o.O
 
Steht doch alles im Dateikopf :gruebel: .

Neutral General 6. Aug 2006 18:26

Re: TGA - Was ein Dateiformat o.O
 
*Brillengläser putz* :shock: :oops:

ups :mrgreen:

Neutral General 7. Aug 2006 12:22

Re: TGA - Was ein Dateiformat o.O
 
Ok ich hätte da aber noch ne kleine Frage: Da steht unter "Entwicklerverzeichnis" "weitere Verzeichniseinträge
(je 10 Bytes)". Das auszulesen ist im Prinzip ja kein Problem weil die Anzahl etc steht ja vorher schon drin aber was steht in diesen 10 Bytes drin ? Sind das Zeichen (also 1Byte = 1Char?) oder sind das mehrere Informationen?. Jedenfalls wie soll ich das einlesen ?

Neutral General 12. Aug 2006 16:29

Re: TGA - Was ein Dateiformat o.O
 
*Push*

Siehe oben

Khabarakh 12. Aug 2006 16:38

Re: TGA - Was ein Dateiformat o.O
 
Zitat:

Zitat von Neutral General
Das auszulesen ist im Prinzip ja kein Problem weil die Anzahl etc steht ja vorher schon drin aber was steht in diesen 10 Bytes drin ?

Hm?
Ein Verzeichniseintrag besteht immer aus ID (Word), Offset (DWord) und Größe (DWord), macht 10 Byte. Und was im variabel langen Entwicklerbereich steht, weiß nur der Entwickler selbst.

Neutral General 14. Aug 2006 12:35

Re: TGA - Was ein Dateiformat o.O
 
Also das Bild usw wird alles wunderbar ausgelesen, aber ab dem markierten Bereich läuft irgendwas falsch. Ich habe mir mal aus dem Metadata-Bereich einige Werte anzeigen lassen und die können einfach nicht so stimmen... Ich habe schon tausendmal drübergeguckt, aber ich konnte keinen Fehler entdecken :|

Meine Informationen habe ich aus Wikipedia:

Delphi-Quellcode:
procedure TTgaImage.LoadFromStream(AStream: TStream);
var i,j: Integer;
    buf: Word;
    lPtr: Pointer;
begin
  AStream.Read(TGAInfo.Header.IDLength, SizeOf(Byte));
  AStream.Read(TGAInfo.Header.HasPalette, SizeOf(Byte));
  AStream.Read(TGAInfo.Header.PictureFormat, SizeOf(Byte));

   // Palette-Info
  AStream.Read(TGAInfo.Header.Palette.Start, SizeOf(Word));
  AStream.Read(TGAInfo.Header.Palette.Length, SizeOf(Word));
  AStream.Read(TGAInfo.Header.Palette.Size, SizeOf(Byte));
  // Zero Point
  AStream.Read(TGAInfo.Header.xZero, SizeOf(Word));
  AStream.Read(TGAInfo.Header.yZero, SizeOf(Word));
  // Picture Width/Height
  AStream.Read(TGAInfo.Header.Width, SizeOf(Word));
  AStream.Read(TGAInfo.Header.Height, SizeOf(Word));
  // Bits per Pixel
  AStream.Read(TGAInfo.Header.Bpp, SizeOf(Byte));
  // Attrubutes
  AStream.Read(TGAInfo.Header.Attributes, SizeOf(Byte));

  if TGAInfo.Header.IDLength > 0 then
  begin
    SetLength(TGAInfo.ID, TGAInfo.Header.IDLength);
    AStream.Read(TGAInfo.ID[0], TGAInfo.Header.IDLength);
  end;

  if Boolean(TGAInfo.Header.HasPalette) then
  begin
    SetLength(TGAInfo.Palette.Colors,TGAInfo.Header.Palette.Length);
    case TGAInfo.Header.Palette.Size of
      15,16: begin
              for i:= 0 to TGAInfo.Header.Palette.Length-1 do
              begin
                AStream.Read(buf,2);
                TGAInfo.Palette.Colors[i].R := (buf and $7C00) shr 10;
                TGAInfo.Palette.Colors[i].G := (buf and $03E0) shr 5;
                TGAInfo.Palette.Colors[i].B := (buf and $001F);
              end;
               // Ist alles noch beta
             end;
      24:   begin
               for i:= 0 to TGAInfo.Header.Palette.Length-1 do
               begin
                AStream.Read(TGAInfo.Palette.Colors[i].B,SizeOf(Byte));
                AStream.Read(TGAInfo.Palette.Colors[i].G,SizeOf(Byte));
                AStream.Read(TGAInfo.Palette.Colors[i].R,SizeOf(Byte));
               end;
             end;
      32:   begin
              // Ist alles noch beta
             end;
    end;
  end;

  SetLength(TGAInfo.Picture, TGAInfo.Header.Width, TGAInfo.Header.Height);
  // Read Picture Data
  if TGAInfo.Header.PictureFormat in [1..3] then
  begin
   FBitmap.Width := TGAInfo.Header.Width;
   FBitmap.Height := TGAInfo.Header.Height;
   FBitmap.PixelFormat := pf24bit;
   for i:= 0 to FBitmap.Height-1 do
   begin
    lptr := FBitmap.ScanLine[i];
    AStream.Read(lptr^,SizeOf(Byte)*3*FBitmap.Width);
   end;
  end
  else if TGAInfo.Header.PictureFormat in [9..11] then
  begin
    // Wird später eingefügt
  end;

  // Read First Footer
  AStream.Position := AStream.Size - 26;
  AStream.Read(TGAInfo.Footer.MetaOffset, SizeOf(Longword));
  AStream.Read(TGAInfo.Footer.DevOffset, SizeOf(Longword));
  for i:= 0 to 17 do
   AStream.Read(TGAInfo.Footer.Signature[i], SizeOf(Char));
 
  {
   !!!!!!! ------------- !!!!!!! <-- ab hier läuft was schief :|
  }     

  // Dev Area
  AStream.Position := TGAInfo.Footer.DevOffset;

  AStream.Read(TGAInfo.DevCount, SizeOf(Word));

  SetLength(TGAInfo.DevelopmentAreas, TGAInfo.DevCount);
  for i:= 0 to TGAInfo.DevCount-1 do
  begin
   AStream.Read(TGAInfo.DevelopmentAreas[i].ID, SizeOf(Word));
   AStream.Read(TGAInfo.DevelopmentAreas[i].Offset, SizeOf(Longword));
   AStream.Read(TGAInfo.DevelopmentAreas[i].Size, SizeOf(Longword));
  end;

  AStream.Position := TGAInfo.Footer.MetaOffset;
  AStream.Read(TGAInfo.Metadata.Size, SizeOf(Longword));

  SetLength(TGAInfo.Metadata.Author, 41);
  AStream.Read(TGAInfo.Metadata.Author[0], 41);

  SetLength(TgaInfo.Metadata.Comment, 324);
  AStream.Read(TGAInfo.Metadata.Comment[0], 324);

  AStream.Read(TGAInfo.Metadata.Month, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.Day, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.Year, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.Hour, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.Minute, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.Second, SizeOf(Word));

  SetLength(TGAInfo.Metadata.Jobname, 41);
  AStream.Read(TGAInfo.Metadata.Jobname[0], 41);

  AStream.Read(TGAInfo.Metadata.JHour, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.JMinute, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.JSecond, SizeOf(Word));

  SetLength(TGAInfo.Metadata.SoftwareID, 41);
  AStream.Read(TGAInfo.Metadata.SoftwareID[0], 41);

  // Version
  AStream.Read(TGAInfo.Metadata.Version, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.VersionEx, SizeOf(Byte));
  // Realations + BG Color
  AStream.Read(TGAInfo.Metadata.BackgroundColor, SizeOf(Longword));
  AStream.Read(TGAInfo.Metadata.PixRealationH, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.PixRealationL, SizeOf(Word));
  // Gamma Info
  AStream.Read(TGAInfo.Metadata.GammaH, SizeOf(Word));
  AStream.Read(TGAInfo.Metadata.GammaL, SizeOf(Word));

  AStream.Read(TGAInfo.Metadata.ColorCorrTabOffset, SizeOf(Longword));
  AStream.Read(TGAInfo.Metadata.ThumbnailOffset, SizeOf(Longword));
  AStream.Read(TGAInfo.Metadata.ScanLineOffset, SizeOf(Longword));

  // Scanline Info
  SetLength(TGAInfo.ScanLineInfo, TGAInfo.Header.Height * SizeOf(Longword));
  AStream.Read(TGAInfo.ScanLineInfo[0], TGAInfo.Header.Height * SizeOf(Longword));

  // Thumbnail Width/Height
  AStream.Read(TGAInfo.Tumbnail.Width, SizeOf(Byte));
  AStream.Read(TGAInfo.Tumbnail.Width, SizeOf(Byte));

  FThumb.Width := TGAInfo.Tumbnail.Width;
  FThumb.Height := TGAInfo.Tumbnail.Height;
  FThumb.PixelFormat := pf24bit;
  // Thumbnail Data
  for i:= 0 to FThumb.Height-1 do
  begin
    lptr := FThumb.ScanLine[i];
    AStream.Read(lptr^,SizeOf(Byte)*3*FThumb.Width);
  end;
  // Color Correction Tab
  for i:= 0 to 255 do begin
   for j:= 0 to 4 do begin
    AStream.Read(TGAInfo.ColorCorTab[i,j], SizeOf(Longword));
   end;
  end;
end;
Kann sich vielleicht einer die Mühe machen und mal gucken ob er einen Fehler findet ? :|
Also ich finde nichts... :(

[EDIT]: Ach ja wenn ich

Delphi-Quellcode:
 AStream.Position := TGAInfo.Metadata.ScanLineOffset;
 AStream.Position := TGAInfo.Metadata.ThumbnailOffset;
 AStream.Position := TGAInfo.Metadata.ColorCorrTabOffset;
an den enstprechenden Stellen einfüge dann gibts en Fehler beim Laden -.- [/EDIT]

Gruß
Neutral General

Phoenix 14. Aug 2006 12:44

Re: TGA - Was ein Dateiformat o.O
 
An genau der Stelle würde aufhören der Wikipedia zu vertrauen und lieber auf die Format Specification von Wotsit.org ( http://www.wotsit.org/ ) zurückgreifen. Da mal nach Targa suchen und die große Spec runterladen.

DP-Maintenance 14. Aug 2006 12:57

DP-Maintenance
 
Dieses Thema wurde von "Phoenix" von "Klatsch und Tratsch" nach "Multimedia" verschoben.
Und Grafikformate gehören imho nach Multimedia.

Neutral General 14. Aug 2006 13:02

Re: TGA - Was ein Dateiformat o.O
 
Da steht leider genau das gleiche was auch in Wikipedia steht :(

Der_Unwissende 14. Aug 2006 13:19

Re: TGA - Was ein Dateiformat o.O
 
Zitat:

Zitat von Neutral General
Ich habe schon tausendmal drübergeguckt, aber ich konnte keinen Fehler entdecken :|

Meine Informationen habe ich aus Wikipedia:

Delphi-Quellcode:
  // Read First Footer
  AStream.Position := AStream.Size - 26;
  AStream.Read(TGAInfo.Footer.MetaOffset, SizeOf(Longword));
  AStream.Read(TGAInfo.Footer.DevOffset, SizeOf(Longword));
  for i:= 0 to 17 do
   AStream.Read(TGAInfo.Footer.Signature[i], SizeOf(Char));
 
  {
   !!!!!!! ------------- !!!!!!! <-- ab hier läuft was schief :|
  }     

  // Dev Area
  AStream.Position := TGAInfo.Footer.DevOffset;

Hi, ich zitiere mal aus deiner Quelle:
Zitat:

Zitat von http://de.wikipedia.org/wiki/Targa_Image_File
(4) optional ab Version 2.0 (wenn vorhanden, dann immer die letzten 26 Bytes)
(Anm. des Autors : Bezieht sich auf Footer in TGA-Dateien)

Die letzten 26 Byte sind bei einem Nullbasierten Index natürlich AStream.Size - 27 (1tes Byte = AStream.Postion = 0), du liest hier also einen vollkommen falschen Footer ein, darin liegen sicher die Probleme.

Zitat:

Zitat von Neutral General
Kann sich vielleicht einer die Mühe machen und mal gucken ob er einen Fehler findet ? :|
Also ich finde nichts... :(

Du hast doch eigentlich schon oft genug gepostet um zu wissen, dass sich die Leute hier gerne die Mühe machen, du es ihnen aber auch leichter machen kannst, indem du zum Beispiel mal das Projekt anhängen würdest! Dann guckt sich vielleicht auch jmd. die anderen Probleme an.
Sorry falls ich hier oder im anderen Beitrag den Anhang übersehen haben sollte! Wenn du aber wirklich nur das Stück Code hier gepostet hast, dann die Bitte beim nächsten mal dran denken, macht vieles einfacher! (zusätzlich zu dem geposteten Code)

Gruß Der Unwissende

[EDIT]
Mal nach einem zweiten Blick auf deinen Source, möchte ich hier noch ein paar Dinge ergänzen. Die Betreffen auch direkt deine noch anstehenden Probleme.
Du verarbeitest die Datei etwas zu blauäugig. Nicht jedes File dass mit einem Programm geöffnet wird hält sich immer an die Spezifikation. Dies kann an einer falschen Implementierung des Erstellers liegen, die dann auch mutwillig sein kann. Bevor du in einem Stream einen Wert ausliest (oder auch nur die Position wechselst) solltest du unbedingt validieren, ob es ein gültiger Zugriff ist. Beim Stream heißt das, dass du gucken solltest ob die Position Offset + sizeOf(Datum) < Stream.Size ist. Nur wenn dies der Fall ist, liegt das Datum in der Datei. Alles andere kann ein Versehen sein oder nicht und würde nur im besten Fall zu einer Fehlermeldung führen. Schlechter ist es, wenn du hier in einem fremden Speicherbereich landest, besonders wenn es hier zum Schreiben kommen würde...
Jedenfalls kannst du das leicht in eine Methode auslagern, die du dann zum Lesen verwendest.
An sich solltest du schon hier weniger in einer Methode machen. Lies lieber die einzelnen Teile in einzelnen Methoden aus, sollte es mal eine Version 2.x oder 3.0 geben, kannst du hier leichter Teile wiederverwenden und austauschen.
[/EDIT]

Neutral General 14. Aug 2006 13:50

Re: TGA - Was ein Dateiformat o.O
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also -27 ist nachweislich falsch. Denn bei -27 wird die Signatur falsch ausgelesen. Bei -26 richtig!
Ok habe dann mal die TGA-Unit angehängt.. Zum benutzen innem Image einfach in das Projekt einbinden und halt

Delphi-Quellcode:
Image1.Picture.LoadFromFile('APicture.tga');

Neutral General 15. Aug 2006 16:33

Re: TGA - Was ein Dateiformat o.O
 
Hat sich denn mal jemand die Unit angeguckt ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz