SetBits / GetBits gut genug?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
#NULL
Beiträge: 2239
Registriert: 20.04.2006 09:50

Re: SetBits / GetBits gut genug?

Beitrag von #NULL »

Sicro hat geschrieben:Bei Macros werden Formeln nochmal in Klammern gesetzt, damit die Macros auch innerhalb von Formeln unproblematisch verwendet werden können (die Operatoren-Priorität bleibt erhalten).
Ich würde bei Macros aus dem selben Grund auch die Verwendung der Parameter immer einklammern, falls dort Ausdrücke angebenen werden.

Code: Alles auswählen

Macro GetBits(_variable_, _offset_)
  (((_variable_) >> (_offset_)) & %111)
EndMacro
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

STARGÅTE hat geschrieben:...
Vielleicht kannst du ja einfach mal die gesamte Bearbeitungsschleife posten, damit wie da mal drüber gucken können.
Wie ich das mitbekommen habe geht es um Grauwerte (3 Bit), was schon mal n fürchterliche Anzahl ist.

Was muss denn genau getan werden bei der Verarbeitung ...
Hallo @STARGÅTE 8)

hier mal meine Hauptschleife:

Code: Alles auswählen

Procedure.i Encode(*img.IMAGE_STRUCT)
  Protected ImageX.i
  Protected ImageY.i
  Protected *ScanLine
  Protected *Pixel.COLOR_STRUCT
  Protected Offset.i
  With *img
    \Image\Pixel\BufferSize = \Bitmap\bmWidth * \Bitmap\bmHeight
    \Image\Pixel\Buffer = AllocateMemory(\Image\Pixel\BufferSize)
    If \Image\Pixel\Buffer
      If \Bitmap\bmBitsPixel = 32
        ;//ALPHA IMG
      Else
        For ImageY = 0 To \Bitmap\bmHeight - 1
          *ScanLine = \Bitmap\bmBits + (ImageY * \Bitmap\bmWidthBytes)
          For ImageX = 0 To \Bitmap\bmWidth - 1
            *Pixel = *ScanLine + (ImageX * \Bitmap\PixelSize)  
            SetBits(\Image\Pixel\Buffer,Offset,GrayScale(*Pixel));RGBA -> GrayScaleIndex (0 - 7) -> SetBits GrayscaleIndex 
            Offset + 3;BitOffset
          Next
        Next
        \Image\Pixel\BufferSize = (Offset + 8) / 8
        ProcedureReturn #True
      EndIf
      FreeMemory(\Image\Pixel\Buffer)
      \Image\Pixel\Buffer = #Null
    EndIf
  EndWith
EndProcedure
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7035
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: SetBits / GetBits gut genug?

Beitrag von STARGÅTE »

Was macht denn GrayScale(*Pixel)?
Ich vermute RGB zu Gray umwandeln, was vermutlich um Welten länger dauert als deine SetBits-Prozedur/Makro.
Dort sollte man also auch Ansetzen!

Des weiteren könnte man immer 8 Pixel mit ein Rutsch umwandelt, weil man dann 24Bit gleichzeitig schreibt, was etwas angenehmer ist als immer nur 3 einzel Bits.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

STARGÅTE hat geschrieben:Was macht denn GrayScale(*Pixel)?
Ich vermute RGB zu Gray umwandeln, was vermutlich um Welten länger dauert als deine SetBits-Prozedur/Makro.
Dort sollte man also auch Ansetzen!

Des weiteren könnte man immer 8 Pixel mit ein Rutsch umwandelt, weil man dann 24Bit gleichzeitig schreibt, was etwas angenehmer ist als immer nur 3 einzel Bits.
Macht Sinn, aber wie kann ich 6 RGBA Werte gleichzeitig bearbeiten?

Hier ist meine Grayscale Funktion:

Code: Alles auswählen

Procedure.i GrayScale(*Color.COLOR_STRUCT)
  Protected Diffusion.i
  Protected GrayScale.i
  Diffusion = Int(Round(#COLOR_FAC * *Color\RGBA[0] / #COLOR_SEG,#PB_Round_Nearest) * #COLOR_DIV)
  Diffusion + Int(Round(#COLOR_FAC * *Color\RGBA[1] / #COLOR_SEG,#PB_Round_Nearest) * #COLOR_DIV)
  Diffusion + Int(Round(#COLOR_FAC * *Color\RGBA[2] / #COLOR_SEG,#PB_Round_Nearest) * #COLOR_DIV)
  Diffusion = Diffusion / 3   ;get grayscale
  Diffusion / 32              ;get index (0 - 7) bits 
  GrayScale = Diffusion * 32  ;set the grayscale to the current image (map it to the actual grayscale table)
  *Color\RGBA[0] = GrayScale
  *Color\RGBA[1] = GrayScale
  *Color\RGBA[2] = GrayScale
  ProcedureReturn Diffusion   ;return index bits
EndProcedure
Benutzeravatar
juergenkulow
Beiträge: 190
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: SetBits / GetBits gut genug?

Beitrag von juergenkulow »

Hallo Mijikai,

Code: Alles auswählen

; Register r8..r13 mit Daten laden, Shift the Bits, Gebe 2. Byte r8 Register aus.   
CompilerIf #PB_Processor_x64<>#PB_Compiler_Processor : CompilerError: "X64 Code" : CompilerEndIf
EnableASM : DisableDebugger
Define RegR8L.a=$42
RegRAX=?mydata
mov rax,RegRAX
Mov r8, [rax]
mov r9, [rax+3]
mov r10,[rax+6]
mov r11,[rax+9]
mov r12,[rax+$c]
mov r13,[rax+$f]
SAR r8,8  ; Shift the Bits Right - in PureBasic Reg8=RegR8>>8 
Mov RegR8L,r8l
EnableDebugger
Debug Hex(RegR8L,#PB_Byte)
DataSection : mydata:
  Data.a $FF,$EE,$DD,$CC,$BB,$AA,$99,$88,$77,$66,$55,$44,$33,$22,$11,$00,$FE,$ED : EndDataSection
Gruß
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

juergenkulow hat geschrieben: ; Register r8..r13 mit Daten laden, Shift the Bits, Gebe 2. Byte r8 Register aus.
...
:? ...was macht der Code?
Benutzeravatar
juergenkulow
Beiträge: 190
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: SetBits / GetBits gut genug?

Beitrag von juergenkulow »

Der Code schreibt 6 RGB Werte aus dem Speicher, hier der Datasection, in die Prozessorregister r8 bis r13. Auf die Register kann dann quasi gleichzeitig zugegriffen werden.
Ablauf: Die Adresse von mydata: wird in die Variable RegRAX geschrieben.
Die Variable RegRAX wird in das Register rax geschrieben.
Der Inhalt von der Adresse rax wird in das Register r8 geschrieben.
Der Inhalt von der Adresse rax+3 wird in das Register r9 geschreiben.
...
Inhalt Register ist:
R8 : 8899AABBCCDDEEFF
R9 : 5566778899AABBCC
R10 : 2233445566778899
R11 : FE00112233445566
R12 : 0000EDFE00112233
R13 : 0030500000EDFE00
Nur die letzten 3 Byte sind wichtig.
Um an das 2. Byte von R8 zu kommen mache ich SAR r8,8 und hole das unterste Byte von R8 mit dem R8L-Register heraus zur weiteren Verarbeitung, hier Ausgabe mit Debug.

Mit Zeigern kann man einfach auf Daten zugreifen:

Code: Alles auswählen

Structure DreiByteTyp : Dreier.a[3] :EndStructure
Structure SechsMalDreiByteTyp : z18.a[18] : EndStructure
*Zeiger.DreiByteTyp=?mydata
*z.SechsMalDreiByteTyp=*Zeiger
Debug Hex(*Zeiger\Dreier[1],#PB_Byte)
Debug Hex(*z\z18[1],#PB_Byte)
*Zeiger+3
Debug Hex(*Zeiger\Dreier[0],#PB_Byte)+" "+Hex(*Zeiger\Dreier[1],#PB_Byte)+" "+Hex(*Zeiger\Dreier[2],#PB_Byte)
*Zeiger+$C
Debug Hex(*Zeiger\Dreier[0],#PB_Byte)+" "+Hex(*Zeiger\Dreier[1],#PB_Byte)+" "+Hex(*Zeiger\Dreier[2],#PB_Byte)
Debug Hex(*z\z18[15],#PB_Byte)+" "+Hex(*z\z18[16],#PB_Byte)+" "+Hex(*z\z18[17],#PB_Byte)
DataSection : mydata:
  Data.a $FF,$EE,$DD,$CC,$BB,$AA,$99,$88,$77,$66,$55,$44,$33,$22,$11,$00,$FE,$ED : EndDataSection
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

juergenkulow hat geschrieben:Der Code schreibt 6 RGB Werte aus dem Speicher, hier der Datasection, in die Prozessorregister r8 bis r13. Auf die Register kann dann quasi gleichzeitig zugegriffen werden.
Ablauf: Die Adresse von mydata: wird in die Variable RegRAX geschrieben.
Die Variable RegRAX wird in das Register rax geschrieben.
Der Inhalt von der Adresse rax wird in das Register r8 geschrieben.
Der Inhalt von der Adresse rax+3 wird in das Register r9 geschreiben.
...
Ich steh aufm Schlauch... :?
Was für Vorteile hat das?
Alle Berechnungen werden nach wie vor nacheinander abgearbeitet.
Da brauch ich nicht erst noch alles in Register schreiben?
Benutzeravatar
juergenkulow
Beiträge: 190
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: SetBits / GetBits gut genug?

Beitrag von juergenkulow »

Hallo Mijikai,
der Vorteil von Operationen die direkt auf dem Prozessor ohne Speicherzugriffe ausgeführt werden ist Geschwindigkeit. Für vier Setbits mit Grayscale liegt die bei mir gemessene Geschwindigkeit bei etwa 11.000 Takten. Das wäre bei einem 4k-Bild etwa 10 Sekunden.

Noch eine Frage: Warum sind die Farben gleich gewichted? (#COLOR_DIV, #COLOR_FAC,#COLOR_SEG) Das ist irgentwie ungewöhnlich.

Gruß
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: SetBits / GetBits gut genug?

Beitrag von ccode_new »

Hallo,
mich interessiert das Thema mit den Grafikfiltern (z.B. Graustufen) auch.
Aber in fast Echtzeit! Also werde ich kaum um Shader herumkommen.
(Das hier ist für den Einstieg ganz interessant.)
Für Game/Video-Filter.

Das mit Gewichtung würde mich hier auch mal interessieren.

Normal sollte man bei einer Graustufenumwandlung eine Gewichtung vornehmen und nicht nur eine einfache Entsättigung.

(Z.B. Rot 30%, Grün 59%, Blau 11%) - Grün sollte den höchsten Prozentanteil haben.

(Für ein "Warum" hilft die Suchmaschine des Vertrauens.)
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Antworten