Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Teil-Records aus Stream lesen (https://www.delphipraxis.net/96652-teil-records-aus-stream-lesen.html)

Neutral General 28. Jul 2007 12:53


Teil-Records aus Stream lesen
 
Hi,

Also sagen wir ich hätte sowas:

Delphi-Quellcode:
TTest = packed record
  nein: Byte;
  ja: Word;
end;
Wenn ich jetzt das Record aus nem Stream lesen will dann mach ich das ja so:

Delphi-Quellcode:
Stream.Read(ATest,SizeOf(TTest));
Wie mach ich das aber wenn ich ab dem zweiten Byte lesen will? Also wenn ich das erste Byte des Records nicht einlesen will... also theoretisch sowas:

Delphi-Quellcode:
Stream.Read(ATest+1,SizeOf(TTest)-1);
So das in dem Beispiel die Variable "nein" nicht eingelesen wird... ?
Ich hab da schon irgendwas versucht mit Pointern und hin und her aber das war Rumprobiererei und wurde auch nichtmal compiliert..

Gruß
Neutral General

bitsetter 28. Jul 2007 13:04

Re: Teil-Records aus Stream lesen
 
Hi,
das müsste doch so gehen
Delphi-Quellcode:
stream.Position:= stream.Position+ 1;

Neutral General 28. Jul 2007 13:15

Re: Teil-Records aus Stream lesen
 
Hi,

nein so mein ich das nicht.. Im Stream steht das erste Byte nicht drin.

Mein Record:
________
1 | 2 | 3 |


Das erste (rote) Byte will ich nicht auslesen. Sondern erst das zweite und dritte. Nur ich darf halt nicht die Speicherstelle des Records angeben sondern die Speicherstelle eins weiter. Also hinter der Variable "ja".. so das in diesem Beispiel nur "nein" geladen wird.
Ich hoffe das war jetzt verständlich

Gruß
Neutral General

markusj 28. Jul 2007 13:25

Re: Teil-Records aus Stream lesen
 
Hmm, da würde ich, sofern es nur ein kleiner Teil ist (hier nur das Word), dieses per Hand auslesen.
Wenn es ein größerer Record ist, würde ich alles Auslesen und danach die unerwünschten Bestandteile resette.

mfG
Markus

Ähem Halt, ich raff gerade deine Grafik ... da hilft wohl nur die "Zu-Fuß-Variante", oder du nimmst einen zweiten Teil-Record, welchen du einliest und dann rüberschiebst in den richtigen.

Neutral General 28. Jul 2007 13:26

Re: Teil-Records aus Stream lesen
 
Nein das muss anders gehn.. Da könnt ich wetten.

Hawkeye219 28. Jul 2007 13:27

Re: Teil-Records aus Stream lesen
 
Hallo,

hier ist ein eher defensiver Ansatz, der zunächst den Offset des ersten zu lesenden Recordelements berechnet. Aus diesem Wert und der Recordgröße ergibt sich die Anzahl der zu lesenden Bytes:

Delphi-Quellcode:
var
  Test       : TTest;
  FieldOffset : Integer;
  ReadSize   : Integer;
begin
  FieldOffset := Cardinal(@Test.ja) - Cardinal(@Test);
  ReadSize := SizeOf(TTest) - FieldOffset;

  Stream.Read(Test.ja, ReadSize);
end;
Gruß Hawkeye

Neutral General 28. Jul 2007 13:36

Re: Teil-Records aus Stream lesen
 
Hi,

Also in Wirklichkeit hab ich sowas:

Delphi-Quellcode:
TGIFHeader = packed record
  Version: String[6];      
  Width: Word;              
  Height: Word;  
  //..
end;
PGIFHeader = ^TGIFHeader
Ich hab jetzt mal sowas probiert...

Delphi-Quellcode:
var P: Pointer;
begin
  P := @FHeader;
  P := PPointer(Cardinal(P) + 1)^; // Da müsste ich doch beim ersten Zeichen von Version landen oder?
  SetLength(FHeader.Version,6);   // Weil das allererste Byte ist ja das Byte wo die Länge drinsteht vom String
  AStream.Read(P,10);              // Und das darf nicht überschrieben werden.
  FHeader := PGIFHeader(PPointer(Cardinal(P) - 1)^)^;
  ShowMessage(FHeader.Version);
end;
Das wäre meine Logik aber da bekomm ich bei FHeader := ... haue^^

Gruß
Neutral General

marabu 28. Jul 2007 14:33

Re: Teil-Records aus Stream lesen
 
Hallo,

was du laut Format-Spezifikation brauchst sieht eher so aus:

Delphi-Quellcode:
type
  TGIF_HEader = packed record
    Signature: array [0..2] of Char;
    Version: array [0..2] of Char;
   end;

  TGIF_LogicalScreenDescriptor = packed record
    LogicalScreenWidth: Word;
    LogicalScreenHeight: Word;
    Options: Byte;
    BackgroundColorIndex: Byte;
    PixelAspectRatio: Byte;
  end;

// ...
String[6] ist also auf jeden Fall falsch. Wenn du jeden GIF Block-Typ einzeln gemäß Spezifikation definierst, dann fällt dein Problem einfach weg, aber grundsätzlich funktioniert die von Hawkeye vorgestellte Methode.

Grüße vom marabu

Neutral General 28. Jul 2007 15:17

Re: Teil-Records aus Stream lesen
 
Hi,

Ja ok danke.. Naja das Problem ist:

Zitat:

Zitat von GIF Dateispezifikation
Byte Nr. 0 - 5: "GIF87a" Version. Bislang gibt es GIF87a und GIF89a.

Deswegen hab ich nen String[6] definiert...

marabu 28. Jul 2007 15:33

Re: Teil-Records aus Stream lesen
 
Hallo Michael,

ich hatte dir unterstellt, dass du den feinen Unterschied zwischen String[6] und array [0..5] of Char nicht kennst - entschuldige.

Dein Problem kannst du viel einfacher lösen:

Delphi-Quellcode:
type
  TGIF_Header = packed record
    Signature: array [0..2] of Char;
    Version: array [0..2] of Char;
  end;

procedure TDemoForm.ButtonClick(Sender: TObject);
var
  gh: TGIF_Header;
begin
  gh.Signature := 'GIF';
  gh.Version := '89a';
  ShowMessage(Format('<%s> <%s>', [String(gh.Signature), String(gh.Version)]));
end;
Du brauchst kein getürktes Längenbyte.

Freundliche Grüße

Neutral General 28. Jul 2007 16:08

Re: Teil-Records aus Stream lesen
 
Ok ja hab jetzt Char Arrays benutzt aber ich hätte da noch eine kleine Frage am Rande:

Zitat:

Zitat von GIF 10. Byte
BitNr: 2 - 4
Beispiel: <111>
Erklärung: Bit/Pixel minus 1 (hier: 8 Bit/Pixel)

Dieses Byte sieht bei mir jetzt bei einem Bild so aus:

1 000 0 100

1: Globale Farbtabelle = true
000: 255 Bit/Pixel ? :gruebel:
0 : Farbtabelle nicht sortiert
100: 96 Byte große Tabelle

Das müsste dieses Byte nach meiner Dateispezifikation aussagen. Aber 0 bzw 255 Bits/Pixel.. Wie soll ich das verstehn? Also 8 Bit/Pixel versteh ich ja noch.. da wird in je einem Byte der Index der Farbe aus der Farbtabelle stehn. aber was ist das?

Gruß
Neutral General

marabu 28. Jul 2007 17:11

Re: Teil-Records aus Stream lesen
 
Wenn ich in die Original-Spezifikation von CompuServe schaue, dann möchte ich die Flags anders interpretieren:

Code:
1 000 0 100
        --- 32 entries in GCT
      - ignore (GIF 87a)
  --- one bit per color in original palette
- next block is GCT

Neutral General 28. Jul 2007 18:04

Re: Teil-Records aus Stream lesen
 
Zitat:

Zitat von marabu
Wenn ich in die Original-Spezifikation von CompuServe schaue, dann möchte ich die Flags anders interpretieren:

Code:
1 000 0 100
        --- 32 entries in GCT
      - ignore (GIF 87a)
  --- one bit per color in original palette
- next block is GCT

Naja das ist jetzt nicht soo anders als ich das geschrieben habe ... In meiner Spezifikation steht das erste Bit (bzw ja eigentl ich isses ja das letzte) dafür das es eine Globale Tabelle gibt. Und es steht dabei das nach dem Header die Tabelle kommt wenns eine gibt.. Die beiden Informationen zusammen bedeuten im Prinzip das gleiche... 32 entries à 3 byte und 96 Bytes insgesamt groß ist das gleiche wenn für jede Farbe 3 Bytes benutzt werden.

Was ich aber trotzdem nicht verstehe ist

Zitat:

one bit per color in original palette
Was hat das zu bedeuten? Ein Bit pro Farbe in der Original-Palette?... :gruebel:

Gruß
Neutral General

marabu 28. Jul 2007 18:21

Re: Teil-Records aus Stream lesen
 
Vielleicht bedeutet es: Mit einem Bit pro Basisfarbe (R,G,B) wird ein Farbraum mit 8 Farben (dual: 000 ... 111) festgelegt.
Du musst aber diesen Wert nirgends verwenden, soweit ich sehen kann.

Neutral General 28. Jul 2007 20:43

Re: Teil-Records aus Stream lesen
 
mhhh... k also das heißt ich hab im eigentlichen Bild so oder so immer nur ein Byte pro Farbe das auf eine Farbe in der Tabelle verweißt? Egal was da jetzt für Werte bei raus kommen bei diesem Bit/Pixel ?

Dax 28. Jul 2007 21:06

Re: Teil-Records aus Stream lesen
 
Zitat:

Zitat von GIF 10. Byte
BitNr: 2 - 4
Beispiel: [x = ] <111>
Erklärung: Bit/Pixel minus 1 (hier: 8 Bit/Pixel)

Ich interpretiere das so: x + 1 = Bit/Pixel. Also 000 -> 1 Bit/Pixel - zwei Farben, 001 -> 2 Bit/Pixel - 4 Farben, usw.

Neutral General 28. Jul 2007 23:12

Re: Teil-Records aus Stream lesen
 
:idea: :)

ahhh :)

das klingt logisch... Danke

marabu 29. Jul 2007 09:01

Re: Teil-Records aus Stream lesen
 
Guten Morgen,

ich bleibe vorerst bei meiner Interpretation. Der Wert 7 (dual 111) für die color resolution ist nach meiner Auffassung die Anzahl Bits pro Farbkanal im von GIF verwendeten RGB-Farbraum. Die größtmögliche Farbtiefe entspricht dann 24-bit Farben (TrueColor), die kleinstmögliche Farbtiefe ergibt sich zwangsläufig. Die Bezeichnung bit/pixel ist irreführend.

Compuserve schreibt in der GIF89a Specification

iv) Color Resolution - Number of bits per primary color available
to the original image, minus 1. This value represents the size of
the entire palette
from which the colors in the graphic were
selected, not the number of colors actually used in the graphic.
For example, if the value in this field is 3, then the palette of
the original image had 4 bits per primary color available to create
the image. This value should be set to indicate the richness of
the original palette, even if not every color from the whole
palette is available on the source machine.

Die Hervorhebungen stammen von mir und beziehen sich auf meine Interpretation.

Zitat:

Zitat von Neutral General
das klingt logisch

Logisch ist für mich, dass man sich auf der Suche nach Informationen auf Primärquellen konzentriert. Nur wenn diese nicht erreichbar sind, sind auch Sekundärquellen annehmbar. Etwaige Ungenauigkeiten bei Sekundärquellen muss man durch Abgleich mehrerer Quellen zu eliminieren trachten. Hat man dann immer noch Verständnisprobleme, dann hilft vielleicht das Studium am Objekt. Die Reihenfolge ist wichtig.

Freundliche Grüße

Neutral General 29. Jul 2007 13:24

Re: Teil-Records aus Stream lesen
 
Zitat:

Zitat von marabu
Guten Morgen,

ich bleibe vorerst bei meiner Interpretation. Der Wert 7 (dual 111) für die color resolution ist nach meiner Auffassung die Anzahl Bits pro Farbkanal im von GIF verwendeten RGB-Farbraum. Die größtmögliche Farbtiefe entspricht dann 24-bit Farben (TrueColor), die kleinstmögliche Farbtiefe ergibt sich zwangsläufig. Die Bezeichnung bit/pixel ist irreführend.

Freundliche Grüße

Mh naja also 24 Bit wären dann 3 Byte pro Farbe also 1 Byte pro Kanal.. Also so das übliche.. Naja wie bringt man eine Farbe in 1 Bit pro Kanal unter? Und ich habe KEIN schwarz-weiß GIF hier... Vielleicht reden wir (oder ich) aneinander vorbei aber in meiner Spezifikation (der ich mittlerweile selbst etwas misstraue) stehn die Farben der Palette in der Form RR GG BB RR GG BB RR GG BB drin...

Gruß
Neutral General

marabu 29. Jul 2007 15:14

Re: Teil-Records aus Stream lesen
 
Du verschwendest deine Aufmerksamkeit an eine Information, deren Wert für dich zweifelhaft ist. Die Größe der ursprünglichen Palette (welche dem Generator des Bildes zur Verfügung stand) könnte sogar ein willkürlicher Wert sein. Ich denke du brauchst ihn nicht, aber ich kenne mich mit GIF (wie mit so vielem anderen) nicht aus und kann deshalb auch falsch liegen.

Die Farben in GCT und LCT sind laut Spezifikation RGB Byte-Tripel. Die GCT kannst du aber getrost vergessen, solange der Local Image Descriptor eine Local Color Table aufweist. Dort würde ich mal nachsehen.

Vielleicht solltest du wirklich ein oder mehrere (kleine) Referenzbilder erzeugen, bereit stellen und die Format-Diskussion auf diesen aufbauen.

Freundliche Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:08 Uhr.

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