Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi HEX und String (Bit 6 auslesen) (https://www.delphipraxis.net/65616-hex-und-string-bit-6-auslesen.html)

Amnon82 18. Mär 2006 22:31


HEX und String (Bit 6 auslesen)
 
Ich hab ein Problem.

Ich code grad an einem kleinen Tool um D2V-Dateien in Delphi zu prasen.

Hier mal die relevanten Auszüge aus dem D2V-Handbuch:

Zitat:

Following is a typical data section (real ones will typically be much longer):
d00 6 0 0 0 0 b0 b0 90 b0 b0 a0 b0 b0 a0 b0 b0 a0 b0 b0 a0
d00 6 0 384035 0 0 b0 b0 90 b0 b0 a0 b0 b0 a0 b0 b0 a0 b0 b0 a0
d00 6 0 768034 0 0 b0 b0 90 b0 b0 a0 b0 b0 a0 b0 b0 a0 b0 b0 a0
d00 6 0 1152609 0 0 b0 b0 90 b0 b0 a0 b0 b0 a0 b0 b0 a0 b0 b0 a0
d00 6 0 1537064 0 0 b0 b0 90 b0 b0 a0 b0 b0 a0 b0 b0 a0 b0 b0 a0

Therefore, the second line in the typical data section given above would break down as follows:

info matrix file position vob cell flags
d00 6 0 384035 0 0 b0 b0 90 b0 b0 a0 b0 b0 a0 b0 b0 a0 b0 b0 a0

The info field is a 12-bit hex number bit-mapped as follows:

bit 11 1 (Always 1 to signal start of data line)
bit 10 1 (This line's pictures are part of a closed GOP)
0 (Open GOP)
bit 9 1 (This line's pictures are part of a progressive sequence)
0 (Otherwise)
bit 8 1 (This I picture starts a new GOP)
0 (Otherwise)
bits 7-0 0 (Reserved)

The sequence of Flags fields contains per-picture data corresponding to the pictures in display order, that is, the Flags fields are re-ordered into display order. End Of Stream is signaled with a Flags field value of ff. Each per-picture Flags field is an 8-bit hex number bit-mapped as follows:

bit 7 1 (Picture is decodable without the previous GOP)
0 (Otherwise)
bit 6 Progressive_Frame Flag (See notes below)
0 (Interlaced)
1 (Progressive)
bits 5-4 Picture_Coding_Type Flag
00 (Reserved)
01 (I-Frame)
10 (P-Frame)
11 (B-Frame)
bits 3-2 00 (Reserved)
01 (Reserved)
10 (Reserved)
11 (Reserved)
bit 1 TFF Flag
bit 0 RFF Flag
Ich möchte nun gerne den Wert für Bit 6 herausfinden:

bit 6 Progressive_Frame Flag (See notes below)
0 (Interlaced)
1 (Progressive)

Nur wie?

D2VParse Thread @ doom9.org

jfheins 18. Mär 2006 22:56

Re: HEX und String (Bit 6 auslesen)
 
Delphi-Quellcode:
if (value and $00100000) <> 0 then
// Bit gesetzt
;)

Dax 18. Mär 2006 23:01

Re: HEX und String (Bit 6 auslesen)
 
Bit 6? Julius? :shock: War Bit 6 in Hex nicht $40? :gruebel:

Edit: so wie ich das sehe meinst du Bit 1 von Nibble 6 ;)

Amnon82 18. Mär 2006 23:16

Re: HEX und String (Bit 6 auslesen)
 
Delphi-Quellcode:
if pos(uppercase(' '),uppercase(listbox1.items[i])) > 0 then
if (strtoint(listbox1.items[i]) and $00100000) <> 0 then checkbox1.checked:=true else checkbox1.checked:=false;
... bringt mich nicht weiter, da Delphi jedes Zeichen einzeln sieht.

Wie komme ich z.B. auf b0? b0 ist doch HEX oder? Mit Copy?

Tempstring > Copy > Value und dann den Code ...

Amnon82 18. Mär 2006 23:44

Re: HEX und String (Bit 6 auslesen)
 
Mit folgenden Codes kann ich nun die Werte in grün auslesen:

d00 1 0 2048 1 1 92 b2 a2 b2 b2 a2 b2 b2 a2 b2 b2 a2

Delphi-Quellcode:
function GetTok(const Str: string; const Idx: Integer; const Sep: Char): string;
var
  StrLen: Integer;
  StrIdx: Integer;
  ResLen: Integer;
  TokIdx: Integer;
begin
  Result := '';
  if Idx > 0 then
  begin
    StrLen := Length(Str);
    SetLength(Result, StrLen);
    ResLen := 0;
    TokIdx := 0;
    for StrIdx := 1 to StrLen do
    begin
      if (Str[StrIdx] <> Sep) and ((StrIdx = 1) or (Str[StrIdx-1] = Sep)) then
        Inc(TokIdx);
      if TokIdx > Idx then
        Break
      else if (TokIdx = Idx) and (Str[StrIdx] <> Sep) then
      begin
        Inc(ResLen);
        Result[ResLen] := Str[StrIdx];
      end;
    end;
    SetLength(Result, ResLen);
  end;
end;
Delphi-Quellcode:
if pos(uppercase(' '),uppercase(listbox1.items[i])) > 0 then
begin
temp:=listbox1.Items[i];
for tempi := 7 to length(temp) do
begin
value:=GetTok(temp, tempi, ' ');
//Showmessage(value);
if (strtoint(value) and $00100000) <> 0 then checkbox1.checked:=true else checkbox1.checked:=false;
end;
end;
nur value währe kein gültiger integer:

if (strtoint(value) and $00100000) <> 0 then checkbox1.checked:=true else checkbox1.checked:=false;

jfheins 18. Mär 2006 23:51

Re: HEX und String (Bit 6 auslesen)
 
Zitat:

Zitat von Dax
Bit 6? Julius? :shock: War Bit 6 in Hex nicht $40? :gruebel:

Edit: so wie ich das sehe meinst du Bit 1 von Nibble 6 ;)

Verdammt, warum kann man nicht in Binär coden ? :mrgreen:

Aber Bit 6 ist imho $20 und nicht $40 (Bit 7 ...) :mrgreen:

Btw.: Was ist ein Nibble ? :gruebel:

Dax 19. Mär 2006 00:10

Re: HEX und String (Bit 6 auslesen)
 
Zitat:

Zitat von jfheins
Aber Bit 6 ist imho $20 und nicht $40 (Bit 7 ...) :mrgreen:

Jetzt auf einmal kannstes, oder wie? :stupid:

Zitat:

Zitat von jfheins
Btw.: Was ist ein Nibble ? :gruebel:

Ein Nibble ist ein Halbbyte, steht im Wiki ;)

Amnon82 19. Mär 2006 09:13

Re: HEX und String (Bit 6 auslesen)
 
Ich will euch ja nicht unterbrechen ;), aber könnte mir einer von Euch "Gurus" ein Beispiel posten?
Es könnte ja sein, dass ich mit meinem Ansatz total falsch liege ...

Delphi-Quellcode:
if pos(uppercase(' '),uppercase(listbox1.items[i])) > 0 then
begin
temp:=listbox1.Items[i];
for tempi := 7 to length(temp) do
begin
value:=GetTok(temp, tempi, ' ');
//Showmessage(value);
i2:=strtoint(Inttohex(strtoint('x'+value),2));
showmessage(inttostr(i2));
if (i2 and $20) <> 0 then checkbox1.checked:=true else checkbox1.checked:=false;
end;
end;
... damit kommt immer noch ne Fehlermeldung alla 'b2' ist ein gülter Integer Wert.

Amnon82 19. Mär 2006 09:42

Re: HEX und String (Bit 6 auslesen)
 
Dann müsste das ja die Lösung sein:

Delphi-Quellcode:
if pos(uppercase(' '),uppercase(listbox1.items[i])) > 0 then
begin
temp:=listbox1.Items[i];
for tempi := 7 to length(temp) do
begin
value:=GetTok(temp, tempi, ' ');
Showmessage(value+'-'+inttostr($20));
//i2:=strtoint(Inttohex(strtoint('x'+value),2));
//showmessage(inttostr(i2));
//if (i2 and $20) <> 0 then
if value = inttostr($20) then thirtytwo:=thirtytwo+1;
if thirtytwo > 0 then
checkbox1.checked:=true else checkbox1.checked:=false;
end;
end;
Da ja mein zu prasender Text so aussieht:

Code:
d00 1 0 2048 1 1 92 b2 a2 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 53248 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 133120 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 423936 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 712704 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 917504 1 1 32 32 92 b2 b2 a2 a2 b2 b2 a2
900 1 0 1273856 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 1644544 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 1910784 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 2201600 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 2516992 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 2838528 1 1 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2

Amnon82 19. Mär 2006 21:12

Re: HEX und String (Bit 6 auslesen)
 
Hmm, stimmt jetzt doch nicht, da folgender Code auch progressiv ist:

Code:
d00 1 0 2048 1 1 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2 f2 e2
900 1 0 65536 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 176128 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 284672 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 391168 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 505856 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 630784 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 794624 1 1 72 d2 f2 f2 e2 e2 f2 f2 e2 f2 f2 e2
900 1 0 1011712 1 1 72 72 d2 f2 f2 e2 f2 e2 f2 f2 e2 e2
900 1 0 1280000 1 1 72 72 d2 f2 e2 f2 f2 e2 e2 f2 f2 e2
900 1 0 1585152 1 1 72 d2 f2 f2 e2 e2 f2 f2 e2 f2 f2 e2
900 1 0 1943552 1 1 72 72 d2 f2 f2 e2 f2 f2 e2 f2 f2 e2
900 1 0 2318336 1 1 72 72 d2 e2 f2 f2 e2 f2 e2 f2 f2 e2

Garfield 25. Mär 2006 19:10

Re: HEX und String (Bit 6 auslesen)
 
Problem gelöst?

http://forum.doom9.org/showthread.php?t=108858

Garfield 26. Mär 2006 00:41

Re: HEX und String (Bit 6 auslesen)
 
Ich habe mir mal die v0.06a angesehen.

Als erstes ist mir negativ aufgefallen, dass teilweise nichts eingerückt wird.

Dann finden sich zwei Verzweigungen zu Frame_Rate:
Delphi-Quellcode:
if pos(uppercase('Frame_Rate'),uppercase(memo.lines[i])) > 0 then
begin
temp:=stringreplace(uppercase(memo.lines[i]),uppercase('Frame_Rate='),'',[rfReplaceAll]);
temp:=stringreplace(uppercase(temp),uppercase('/'),' ',[rfReplaceAll]);
temp:=stringreplace(uppercase(temp),uppercase('('),' ',[rfReplaceAll]);
temp:=stringreplace(uppercase(temp),uppercase(')'),' ',[rfReplaceAll]);
text:=GetTok(temp, 2, ' ');
value:=GetTok(temp, 3, ' ');
Edit11.text:=formatfloat('0.00',strtofloat(text)/strtofloat(value));

end;
...
if pos(uppercase('Frame_Rate'),uppercase(memo.lines[i])) > 0 then {nothing} else
if pos(uppercase(' '),uppercase(memo.lines[i])) > 0 then
begin
...
Theoretisch könnte man diese zusammenfassen. Allerdings wäre es sinnvoller, die zweite Stelle in
Delphi-Quellcode:
if (pos(uppercase(' '), uppercase(memo.lines[i])) > 0)
and (pos(uppercase(':\'),uppercase(memo.lines[i])) = 0)
then begin
...
zu ändern.

Die function GetTok lieferte mir bei der Frame_Rate nur leere Strings zurück. Warum, habe ich nicht weiter untersucht.

Amnon82 18. Apr 2006 23:19

Re: HEX und String (Bit 6 auslesen)
 
@Garfield:

Das Problem ist noch nicht ganz gelöst. Ich komm mit der Bit-Auslesung nicht klar.

0.06a war nur so ein Versuch. 0.06 war eigentlich die letzte Version.

Das mit den zwei Frame_rate ist so:

Wenn ich nach Leerzeichen suche kommt automatisch auch die Zeile mit Frame_rate.

Hier nochmal ein Ausschnitt der zu bearbeiteten Datei:

Code:
DGIndexProjectFile13
1
I:\Delphi\D2VCreateCLI\test\test.vob

Stream_Type=1
MPEG_Type=2
iDCT_Algorithm=2
YUVRGB_Scale=1
Luminance_Filter=0,0
Clipping=0,0,0,0
Aspect_Ratio=16:9
Picture_Size=704x576
Field_Operation=2
Frame_Rate=25000 (25/1)
Location=0,0,0,26F7F

900 1 0 190464 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 638976 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 1081344 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 1523712 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 1921024 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 2351104 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 2754560 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
900 1 0 3147776 1 16 32 32 92 b2 b2 a2 b2 b2 a2 b2 b2 a2
Der Leerzeichencode hat eh noch einen Bug, da ich erst ab der Zeile Stream_Type= anfangen zu Suchen müsste. Es würd ein Fehler passieren, wenn die Dateienpfade (hier im Beispiel 'I:\Delphi\D2VCreateCLI\test\test.vob') Leerzeichen enthalten. (Edit: habs grad getestet. Passiert anscheinend doch nichts ...)

Mit dem neuen Tool D2VCreate hab ich einen Weg gefunden, die Datei über das Programm DGIndex auszulesen, welches auch die Dateien erstellt hat. Nur würd ich gern das Gleiche auch anhand der D2V-Datei mit D2VParse können wollen.

Falls Du also noch nen Tip für mich hättest, wie ich das mit den Bit6 machen kann, währe ich dankbar.

Auch über folgendes müsste ich mir noch Gedanken machen:

Zitat:

by neuron2

There's too much context missing for me to do more than make a few comments. Certainly, I can't see *any* bit operations in that last code fragment.

Why would you try to convert '0' and '2' to uppercase?

Seems to me that Pos() is just going to test if a '2' is present, i.e., in either the least significant or the most significant nibble of the flags byte. But it is only the least significant nibble of the flags byte that should be considered. You should use bit operations as I showed in an earlier post.

You are missing cases for '1' and '3'. A clip starting with a BFF repeat (1) is BFF. A clip starting with a TFF repeat (3) is TFF.

I'll just warn you that you have to be careful in interpreting the meaning of the TFF flag when pulldown is present. For example, a clip may start off as TFF (2). Then say a TFF repeat occurs (3). Now, strangely, the next frame will be flagged as BFF (0) even though it is continuing a TFF sequence!

And here's something else to think about... An MPEG2 clip can change field order anywhere at any time:

000000000002222222222222222...

It's OK as long as the display process skips or repeats a field so that a strict field alternation is preserved. But if you convert such a clip to AVI and do not correct that, you'll have a mess (that's why DGIndex has the 'Correct Field Order' option). Also, how would you report a clip like the one above, TFF or BFF?

My policy to avoid all these complications is to look at just the flags byte of the first encoded picture. If it is TFF, then the clip is called TFF.

Garfield 29. Apr 2006 14:00

Re: HEX und String (Bit 6 auslesen)
 
Zitat:

Zitat von Amnon82
Der Leerzeichencode hat eh noch einen Bug, da ich erst ab der Zeile Stream_Type= anfangen zu Suchen müsste.

Da könnte man die Schleife mit 4 (= Zeile 5) beginnen lassen. Vorausgesetzt, die Liste der Dateinamen wird ab einer bestimmten Länge nicht auf mehrere Zeilen verteilt.

Zitat:

Zitat von Amnon82
Das Problem ist noch nicht ganz gelöst. Ich komm mit der Bit-Auslesung nicht klar.

Sollte doch nicht so schwer sein. :gruebel:

Zitat:

Zitat von jfheins
Delphi-Quellcode:
if (value and $00100000) <> 0 then
// Bit gesetzt
;)

Das ist natürlich falsch, weil $ einer hexadezimalen und keiner dualen Zahl vorangestellt wird. Damit sind es nicht 8 Bit sondern 8 Byte. $00100000 müsste 1.048.576 sein. Das sechste Bit ist 32 bzw $20.

$20 ist vom Typ Integer. Da Du Strings hast, muss konvertiert werden. Aus dem String musst Du die beiden Zeichen, welche Du auswerten willst - zum Beispiel 'B0' - extrahieren. Dann kannst Du es so auswerten:

Delphi-Quellcode:
...
var
  Wert : String;
  Zahl : Byte;  // $00 bis $FF
...
begin
  ...
  Wert := 'B0';

  Zahl := StrToInt ('$' + Wert);

  if Zahl AND $20 > 0
  then
    { Bit 6 gesetzt }
  else
    { Bit 6 nicht gesetzt };
  ...
Die anderen Bits lassen sich entsprechend auswerten.

Amnon82 1. Mai 2006 23:55

Re: HEX und String (Bit 6 auslesen)
 
@Garfield: Hmm, so ähnlich hab ichs schon. Schau Dir auch mal diesen Thread an.

Garfield 2. Mai 2006 08:25

Re: HEX und String (Bit 6 auslesen)
 
Zitat:

Zitat von Amnon82
Bit0 = $01
Bit1 = Bit0*2 > $02
Bit2 = Bit1*2 > $04
Bit3 = Bit2*2 > $10
Bit5 = Bit4*2 > $20
Bit6 = Bit5*2 > $40

Ich habe bisher immer mit Bit 1 bis Bit 8 gerechnet. Aber in der Doku gibt es, wie ich sehe, auch ein Bit 0. Demnach wäre der Wert doch nicht $20 sondern $40. Bit 0 ist das niederwertigste, wobei wir davon ausgehen, dass dies das ganz rechts stehende ist.

Offensichtlich werden die Informationen neu zusammengestellt. Denn ob ein Picture progressive ist, steht zum Beispiel in der PICTURE_CODING_EXTENSION

Delphi-Quellcode:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*************************** iso 13818-2 ****************************
// 32 bslbf - extension_start_code
//  4 uimsbf - extension_start_code_identifier
// picture_coding_extension()
// {
//  4 uimsbf - f_code[0][0] - forward_horizontal
//  4 uimsbf - f_code[0][1] - forward_vertical
//  4 uimsbf - f_code[1][0] - backward_horizontal
//  4 uimsbf - f_code[1][1] - backward_vertical
//  2 uimsbf - intra_dc_precision
//  2 uimsbf - picture_structure
//  1 uimsbf - top_field_first
//  1 uimsbf - frame_pred_frame_dct
//  1 uimsbf - concealment_motion_vectors
//  1 uimsbf - q_scale_type
//  1 uimsbf - intra_vlc_format
//  1 uimsbf - alternate_scan
//  1 uimsbf - repeat_first_field
//  1 uimsbf - chroma_420_type
//  1 uimsbf - progressive_frame
//  1 uimsbf - composite_display_flag
// if ( composite_display_flag )
//   {
//     1 uimsbf - v_axis
//     3 uimsbf - field_sequence
//     1 uimsbf - sub_carrier
//     7 uimsbf - burst_amplitude
//     8 uimsbf - sub_carrier_phase
//   }
// next_start_code()
// }
//********************************************************************
oder der SEQUENCE_EXTENSION:

Delphi-Quellcode:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//************************** iso 13818-2 ***************************
// sequence_extension() {
// 32 - bslbf - extension_start_code
//  4 - uimsb - fextension_start_code_identifier
//  8 - uimsbf - profile_and_level_indication
//  1 - uimsbf - progressive_sequence
//  2 - uimsbf - chroma_format
//  2 - uimsbf - horizontal_size_extension
//  2 - uimsbf - vertical_size_extension
// 12 - uimsbf - bit_rate_extension
//  1 - bslbf - marker_bit
//  8 - uimsbf - vbv_buffer_size_extension
//  1 - uimsbf - low_delay
//  2 - uimsbf - frame_rate_extension_n
//  5 - uimsbf - frame_rate_extension_d
// next_start_code()
// }
//******************************************************************
während der Frametyp im PICTURE_HEADER steht:

Delphi-Quellcode:
//***************************** iso 13818-2 ******************************
// picture_header()
// {
// 32 bslbf - picture_start_code
// 10 uimsbf - temporal_reference
//  3 uimsbf - picture_coding_type
// 16 uimsbf - vbv_delay
// if ( picture_coding_type == 2 || picture_coding_type == 3)
//    {
//      1 bslbf - full_pel_forward_vector
//      3 bslbf - forward_f_code
//    }
// if ( picture_coding_type == 3 )
//    {
//      1 bslbf - full_pel_backward_vector
//      3 bslbf - backward_f_code
//    }
// while ( nextbits() == ‘1' )
//    {
//      1 uimsbf - extra_bit_picture /* with the value ‘1' */
//      8 uimsbf - extra_information_picture
//    }
//  1 uimsbf - extra_bit_picture /* with the value ‘0' */
// next_start_code()
// }
//************************************************************************
Allerdings ist der picture_coding_type in der Spez nicht mit 2 sondern 3 Bit angegeben:

Delphi-Quellcode:
// I_TYPE 1
// P_TYPE 2
// B_TYPE 3
// D_TYPE 4
// Frame_Type: Array [0..7] of CHAR = 'xIPBDrrr';
x = forbidden, r = reserved, D = Dropped.

Da anscheinend Dein Bit 6 trotz progressiver Quelle den Wert 0 besitzt, nehme ich an, dass Deine Quelle eine DVD vermutlich mit einem amerikanischen Film ist. Wenn Du mal in Videoforen in den Beiträgen von 2002/2003 nachsiehst, dürftest Du einige Diskussionen finden, in denen darüber diskutiert wurde, ob eine DVD interlaced oder progressive ist. Denn der Bitrateviewer gab oft interlaced an, obwohl der Sichttest progressive ergab. DVDs sind meist progressive, während das Ausgangsmaterial interlaced gewesen sein kann. Der Encoder hat dann nur das Flag nicht gesetzt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:12 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 by Thomas Breitkreuz