Windows GDI und WinAPI
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
Auf Linux ist mir klar, das Pendant auf Windoofs kanns nicht. Habs probiert, animated GIF's werden als Ebenen angezeigt, MNG garnicht (libmng ist installiert).
Im Übrigen regelt das Kylix auch über die Qt, die kann das Format und erkennt das beim einlesen selbst. Gibt keinen Anlass anzunehmen, das Gimp das anders machen sollte. Wenns aber nicht da ist (MNG, JNG scheint zu fehlen), dann kann Gimp eben auch nicht.
Von der Logik her gehören solche Formate eigentlich auch in die Desktop-Lib, das mag zwar auf den ersten Blick unflexibel sein, für Standardformate macht es aber Sinn.
Hat jemand von euch schonmal versucht TNGImage auf Lazarus zu portieren? Ich hab das gerade mal unter Kylix3 prof installiert, läuft ganz prima. Das sollte sich also verhältnismäßig einfach portieren lassen, so man sich mit den Grafik-Lib's von FPC/Lazarus gut auskennt. Das stellt MNG, JNG und zusätzlich noch JPEG und NGBitmap z.V.. Für LINUX wird lediglich statt stdcall cdecl angewendet. Ansonsten wird das über TPicture eingehängt.
Im Übrigen regelt das Kylix auch über die Qt, die kann das Format und erkennt das beim einlesen selbst. Gibt keinen Anlass anzunehmen, das Gimp das anders machen sollte. Wenns aber nicht da ist (MNG, JNG scheint zu fehlen), dann kann Gimp eben auch nicht.
Von der Logik her gehören solche Formate eigentlich auch in die Desktop-Lib, das mag zwar auf den ersten Blick unflexibel sein, für Standardformate macht es aber Sinn.
Hat jemand von euch schonmal versucht TNGImage auf Lazarus zu portieren? Ich hab das gerade mal unter Kylix3 prof installiert, läuft ganz prima. Das sollte sich also verhältnismäßig einfach portieren lassen, so man sich mit den Grafik-Lib's von FPC/Lazarus gut auskennt. Das stellt MNG, JNG und zusätzlich noch JPEG und NGBitmap z.V.. Für LINUX wird lediglich statt stdcall cdecl angewendet. Ansonsten wird das über TPicture eingehängt.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
http://de.wikipedia.org/wiki/GIMP-Toolkit" onclick="window.open(this.href);return false;Christian hat geschrieben:Stimmt auch wieder über den Namen hab ich mir noch nie Gedanken gemacht.
Und übrigens: Das mit den Masken zum transparenten Zeichnen des OPBitmap auf Win/GTK habe ich langsam im Griff. Das ist halt einfach ein Haufen Feinarbeit.
Während auf GTK ein Maskenbild im Grunde ein "straight" Bitmap (1bit) ist, muss man auf Windows die Bits in jedem Byte "umdrehen", damit's stimmt:
Code: Alles auswählen
function ReverseBits(b:Byte):Byte;
var c:Byte;
begin
c:=b;
c := ((c shr 1) and $55) or ((c shl 1) and $aa);
c := ((c shr 2) and $33) or ((c shl 2) and $cc);
c := ((c shr 4) and $0f) or ((c shl 4) and $f0);
result:=c;
end;
Knifflig aber machbar.
Aber ein Problem habe ich noch: Ich kriege bei manchen Bildern eine total fiese Zugriffsverletzung unter Laz, nicht Kylix. Reproduzierbar mit diesen Bildern aber normalerweise läuft's
Und zwar ganz am Schluss, wenn das Bild im Prinzip gezeichnet ist, beim Freigeben des OPBitmap.
Hat jemand aus Erfahrung oder so Brainstormmässig einen verdacht was das sein könnte?
Bzw, warum macht nur FPC dieses Problem?
Bin für Tipps dankbar, weil ich im Moment nicht dahinterkomme.
Code: Alles auswählen
procedure TBitmapData32.UpdateSize;
begin
if (fWidth > 0) and (fHeight > 0) then
begin
fLineLength := fWidth * 4;
if (fPixels <> nil) then FreeMem(fPixels);
GetMem(fPixels, fHeight * fLineLength)
end else
if (fPixels <> nil) then begin
FreeMem(fPixels); <!--- hier SEGFAULT
fPixels := nil;
end;
end;
[font=Courier New]TApplication.HandleException Access violation
Stack trace:
$080641E3
$08064250
$0806426A
$0806488B
$080648DF
$08063B00
$081F7444 TBITMAPDATA32__UPDATESIZE, line 1154 of opbitmap.pas
$081F5627 TBITMAPDATA__DESTROY, line 633 of opbitmap.pas
$0805D855
$081F7EA1 TOPBITMAP__DESTROY, line 1332 of opbitmap.pas
$081FB286 TCANVASOPBITMAP__DESTROY, line 2478 of opbitmap.pas
$081FC7A7 TJPEGIMAGE__DESTROY, line 141 of opbitmapformats.pas
$0805D855
$0807834C TFORM1__BUTTON1CLICK, line 95 of unit1.pas
$081107D6 TCONTROL__CLICK, line 1948 of ./include/control.inc
$081649AD TBUTTONCONTROL__CLICK, line 57 of ./include/buttoncontrol.inc
$08166401 TCUSTOMBUTTON__CLICK, line 187 of ./include/buttons.inc
^running
(gdb)
*stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",thread-id="1",frame={addr="0x080641e3",func="SYSTEM_CONCAT_TWO_BLOCKS$PMEMCHUNK_VAR$PMEMCHUNK_VAR",args=[]}
(gdb)
^done,depth="53"
(gdb)
^done,stack-args=[frame={level="0",args=[]}]
(gdb)
^done,stack=[frame={level="0",addr="0x080641e3",func="SYSTEM_CONCAT_TWO_BLOCKS$PMEMCHUNK_VAR$PMEMCHUNK_VAR"}]
(gdb)
^done,stack-args=[frame={level="1",args=[]}]
(gdb)
^done,stack=[frame={level="1",addr="0x08064250",func="SYSTEM_TRY_CONCAT_FREE_CHUNK_FORWARD$PMEMCHUNK_VAR"}]
(gdb)
^done,stack-args=[frame={level="2",args=[]}]
(gdb)
^done,stack=[frame={level="2",addr="0x0806426a",func="SYSTEM_TRY_CONCAT_FREE_CHUNK$PMEMCHUNK_VAR$$PMEMCHUNK_VAR"}]
(gdb)
^done,stack-args=[frame={level="3",args=[]}]
(gdb)
^done,stack=[frame={level="3",addr="0x0806488b",func="SYSTEM_SYSFREEMEM_VAR$PMEMCHUNK_VAR$$LONGINT"}]
(gdb)
^done,stack-args=[frame={level="4",args=[]}]
(gdb)
^done,stack=[frame={level="4",addr="0x080648df",func="SYSTEM_SYSFREEMEM$POINTER$$LONGINT"}]
(gdb)
^done,stack-args=[frame={level="5",args=[]}]
(gdb)
^done,stack=[frame={level="5",addr="0x08063b00",func="SYSTEM_FREEMEM$POINTER$$LONGINT"}]
(gdb)
^done,stack-args=[frame={level="6",args=[{name="this",value="(^TBITMAPDATA32) 0x40027e98"}]}]
(gdb)
^done,stack=[frame={level="6",addr="0x081f7444",func="TBITMAPDATA32__UPDATESIZE",file="opbitmap.pas",line="1154"}]
(gdb)
[/font]
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
@theo
Dein fPixels war doch als Array of BlaBla deklariert? Da hätte ich mal das GetMem im Verdacht, das scheint den Speicher für die Struktur so zu verkürzen, das der bereits am Ende ankommt bevor der letzte Eintrag gelöscht wird (#0). Ich würde das lieber als Array mit SetLength machen. Eine Möglichkeit besteht darin, das GetMem Byte-oriented reseviert während das Array auf Word ausrichtet, dann hast du künstlich das Array verkürzt und er klatscht auf.
Dein fPixels war doch als Array of BlaBla deklariert? Da hätte ich mal das GetMem im Verdacht, das scheint den Speicher für die Struktur so zu verkürzen, das der bereits am Ende ankommt bevor der letzte Eintrag gelöscht wird (#0). Ich würde das lieber als Array mit SetLength machen. Eine Möglichkeit besteht darin, das GetMem Byte-oriented reseviert während das Array auf Word ausrichtet, dann hast du künstlich das Array verkürzt und er klatscht auf.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
Hmm, ja Danke für die Anregung. Ich werde das mit SetLength (Dynarray) vielleicht auspobieren müssenschnullerbacke hat geschrieben:@theo
Dein fPixels war doch als Array of BlaBla deklariert? Da hätte ich mal das GetMem im Verdacht, das scheint den Speicher für die Struktur so zu verkürzen, das der bereits am Ende ankommt bevor der letzte Eintrag gelöscht wird (#0). Ich würde das lieber als Array mit SetLength machen. Eine Möglichkeit besteht darin, das GetMem Byte-oriented reseviert während das Array auf Word ausrichtet, dann hast du künstlich das Array verkürzt und er klatscht auf.
Was gegen deine Vermutung spricht:
- Wenn so was nicht geht (bei FPC), warum dann nur bei 5% der Bilder, die sich z.B. nicht durch extreme Grösse von anderen unterscheiden? Sollte das dann nicht immer in die Hose gehen?
- Mit den Byte: Aber gerade das 32bit Bitmap richtet doch "von Natur aus" auf Doubleword (4 Byte) aus. Also daran wird's wohl kaum liegen.
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
Sag ich ja. Ich spreche aber von 32 bit.schnullerbacke hat geschrieben:Nö, nicht unbedingt. Das könnte bei 8-Bit schief gehen, bei 16,24,32 gehts dann gut. Da ist die word-Ausrichtung implizit durch die Größe gegeben.
Übrigens: Ich habe jetzt eine "Lösung" gefunden. Keinen blassen Schimmer wieso aber so geht alles:
Code: Alles auswählen
procedure TBitmapData32.UpdateSize;
begin
if (fWidth > 0) and (fHeight > 0) then
begin
fLineLength := fWidth * 4;
if (fPixels <> nil) then FreeMem(fPixels);
GetMem(fPixels, fHeight * fLineLength+1) <-- Ein einziges Byte mehr reservieren
end else
if (fPixels <> nil) then begin
FreeMem(fPixels);
fPixels := nil;
end;
end;
//Todo: Sich fragen wieso?
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Wie jetzt ? weil Borland die ja auch n windows programm gegen die wine bibliotheken linken damits so aussäh als sei es n linux programm das so macht müssen alle anderen das auch so machen die logik versteh ich nicht sorry.Im Übrigen regelt das Kylix auch über die Qt, die kann das Format und erkennt das beim einlesen selbst. Gibt keinen Anlass anzunehmen, das Gimp das anders machen sollte. Wenns aber nicht da ist (MNG, JNG scheint zu fehlen), dann kann Gimp eben auch nicht.
gtk,qt und co sind keine desktop libs sondern widgetsets die sind lediglich dazu da um benutzeroberflächen zu zeichen weiter nix da gehören keine dateifoprmate rein, wenn qt das macht is gut aber für lazaruzs macht das gar keinen sinn die zu nutzen da lazarus widgetsetunabhängig ist.Von der Logik her gehören solche Formate eigentlich auch in die Desktop-Lib, das mag zwar auf den ersten Blick unflexibel sein, für Standardformate macht es aber Sinn.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
@Christian
Kylix nutzt die Qt-Lib für seine Oberfläche. Für dein fertiges Proggi brauchste kein Wine, nur die Qt-Lib's mußte mitliefern. Die Qt-Lib kann GIF, auch animated, deswegen funzt das bei Kylix mit dem normalen TImage, während du für Delphi zusätzliche sourcen brauchst (etwa Anders Mellander GIFImage). Für MNG, JNG, PNG gilt bei Delphi das gleiche, bei Kylix nur für MNG, JNG.
Das macht mir ja das Leben so schwer. Idealerweise sollten diese Klamotten vom Development-System z.V. stehen und das für beide OS. Ich hab einfach keinen Bock mehr, jedesmal unterschiedliche Sourcen nur wegen solcher halbgaren Vorgaben zu haben. Dabei ist es Schißkujennum ob das nun von der Dekstop-Lib kommt oder im Quelltext OS-unabhängig läuft, nur laufen muß es.
@theo
0tes Byte nicht mitgezählt?
Kylix nutzt die Qt-Lib für seine Oberfläche. Für dein fertiges Proggi brauchste kein Wine, nur die Qt-Lib's mußte mitliefern. Die Qt-Lib kann GIF, auch animated, deswegen funzt das bei Kylix mit dem normalen TImage, während du für Delphi zusätzliche sourcen brauchst (etwa Anders Mellander GIFImage). Für MNG, JNG, PNG gilt bei Delphi das gleiche, bei Kylix nur für MNG, JNG.
Das macht mir ja das Leben so schwer. Idealerweise sollten diese Klamotten vom Development-System z.V. stehen und das für beide OS. Ich hab einfach keinen Bock mehr, jedesmal unterschiedliche Sourcen nur wegen solcher halbgaren Vorgaben zu haben. Dabei ist es Schißkujennum ob das nun von der Dekstop-Lib kommt oder im Quelltext OS-unabhängig läuft, nur laufen muß es.
@theo
0tes Byte nicht mitgezählt?
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
@theo
Ich würd's trotzdem mit SetLength über dem Array machen. Sonst bekommst du eventuell bei 8- und 24-Bit Probleme damit. Die könnten beide durch word-alignment mit GetMem genau den Käse produzieren. Mal abgesehen davon, das man mit nem Index, weil ganzzahlig, auch verhältnißmäßig schnell ist, das braucht kaum Prozessor-Takte (3 mein ich). Bei Adress-Rechnung sieht das schon anders aus. Beim Array geht er über den Offset, das könnte deutliche Geschwindigkeitsvorteile bringen, von der Sicherheit mal ganz abgesehen.
Ich würd's trotzdem mit SetLength über dem Array machen. Sonst bekommst du eventuell bei 8- und 24-Bit Probleme damit. Die könnten beide durch word-alignment mit GetMem genau den Käse produzieren. Mal abgesehen davon, das man mit nem Index, weil ganzzahlig, auch verhältnißmäßig schnell ist, das braucht kaum Prozessor-Takte (3 mein ich). Bei Adress-Rechnung sieht das schon anders aus. Beim Array geht er über den Offset, das könnte deutliche Geschwindigkeitsvorteile bringen, von der Sicherheit mal ganz abgesehen.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
schmeiss nicht n dynamisches array und n array durcheinander, n dynamisches array braucht mindestens genauso viel rechenzeit wie wenn du getmem nimmst da man mit getmem noch die kontrolle hat alles auf einen schlag zu holen und somit nen nicht segmentierten speicherbereich bekommt das array kann das schon mit realloc machen
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
Ja mei, ich probiers mal aus mit dem dynamischen Array. Schneller wird das aber kaum sein.Christian hat geschrieben:schmeiss nicht n dynamisches array und n array durcheinander, n dynamisches array braucht mindestens genauso viel rechenzeit wie wenn du getmem nimmst da man mit getmem noch die kontrolle hat alles auf einen schlag zu holen und somit nen nicht segmentierten speicherbereich bekommt das array kann das schon mit realloc machen
Ich hatte es ursprünglich nicht damit gemacht, weil ich irgendwo gelesen habe FPC hätte noch seine Problemchen damit. Ausserdem war mir das Reference Counting für meine Zwecke eher suspekt, das ich den Speicher sowieso selber freigeben möchte.
Wie Verhalten sich denn Dynamische Arrays mit z.B. Move befehlen? Problemlos?
Warum ich's Probiere: Um die Hypothese mit dem word-alignment zu testen.
Zuletzt geändert von theo am Mi 31. Jan 2007, 19:02, insgesamt 2-mal geändert.
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
nur weil es bei einem anderen Programm nicht geht, sollte man nicht auf eine Funktion versichetet werden. oder wenn es anders gemacht wird/wurde !
wenn es eine Möglichkeit gibt Platform übergreifend Grafiken/Animationen/Videos
anzuzeigen währe das schon toll !
(Wenn ich euch Richtig verstanden habe)
wenn es eine Möglichkeit gibt Platform übergreifend Grafiken/Animationen/Videos
anzuzeigen währe das schon toll !
(Wenn ich euch Richtig verstanden habe)
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
Bei move verhält sich das genauso wie ein statisches array, nur kannst du da wohl nicht mit SizeOf arbeiten, das wirst du wohl per (High(array) + 1) * SizeOf(arg) oder ähnlich machen müssen.
Bei Adressrechnung hab ich irgendwas mit 11-12 Prozessortakte im Hinterkopf, da ist ganzzahlige Arythmetik klar im Vorteil. Entscheidend ist aber bei wechselnden Größen ganz sicher das Alignment.
Aber wenn's denn unbedingt GetMem sein soll, dann bezieh das nicht auf ein dynamisches Array, dann rechne lieber selber und allozier den Speicher dann. Hat natürlich den Nachteil der Rechnerei, ansonsten bliebe nur eine verkettete Pointerliste. Die letzte Methode ist allerdings nicht jedermanns Sache.
Bei Adressrechnung hab ich irgendwas mit 11-12 Prozessortakte im Hinterkopf, da ist ganzzahlige Arythmetik klar im Vorteil. Entscheidend ist aber bei wechselnden Größen ganz sicher das Alignment.
Aber wenn's denn unbedingt GetMem sein soll, dann bezieh das nicht auf ein dynamisches Array, dann rechne lieber selber und allozier den Speicher dann. Hat natürlich den Nachteil der Rechnerei, ansonsten bliebe nur eine verkettete Pointerliste. Die letzte Methode ist allerdings nicht jedermanns Sache.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Ich wäre mit dem move auch vorsichtig auf ein element sicher lich problemlos aber wenns über mehrere gehen soll wirds früher oder später access violations hageln schliesslich ist nicht geregelt wie die speicherbelegung innerhalb des arrays auszusehn hat bei nem statischen array ist das klar
@schnullerbacke ich habe nie gesagt das man wine braucht um kylix applikationen auszuführen
@schnullerbacke ich habe nie gesagt das man wine braucht um kylix applikationen auszuführen
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/