13.12.2017, 16:07
Hallo liebe Entwickler aus dem Forum. ^^
Ich habe ein kleines Umsetzungsproblem zwecks eines simplen RLE Decompressions Algorithmus.
Es geht um ILBM Bild Dateien von Electronic Arts.
Ich kann mit meinem aktuellen Programm soweit alles laden, Header, Palette, etc. pp.
Nun bin ich aber schon eine Weile daran diese blöde Lauflängenkodierung zu decodieren, damit ich das jeweilige Bild wieder habe und zeichnen lassen kann.
Im Internet gibt es zwars ein Pseudo Code wie der Prozess auszusehen hat, aber ich kann das irgendwie nicht so recht in meiner Programmiersprache umsetzen, weil ich irgendwo ein Gedankenfehler habe.
Die Palette ist nicht das Problem und wird einwandfrei erkannt.
Es geht nämlich um ein 256 Farb Bild.
Hier mal der Pseudo Code auf Wikipedia: https://en.wikipedia.org/wiki/ILBM#Compression
Hier mein QB64 (http://www.qb64.net/) Code dafür:
Zum Zeichen soll dann später folgendes dienen:
Das Bild ist in Indexen gespeichert. Jeder Index entspricht einen Wert aus der Farbpalette. 0 - 255.
Mit sRO lade ich jeweils ein Byte an der jeweiligen Offset Adresse die in der Variable 'of' enthalten ist. of wird beim nutzen von sRO immer um 1 erhöht, sodass ich dann den nächsten Offset habe.
i und r sind Zählvariablen. Wobei i die Größe des Bildes in Byte ergeben soll. Die Schleife endet sobald i > oder = die Höhe * Breite des Bildes hat. Sprich die Gesamt Bytes.
thumbnail ist ein Array das als Speicher der dekomprimierten Indexwerte dienen soll. Sprich das Bild wird in diesem Array festgehalten dann.
Ich habe hier auch mal eine RAW Datei hochgeladen, wo ihr das dann selbst probieren könnt.
Enthält die Palette, die Auflösung und das Bild selbst. Ihr braucht also nicht den ganzen Quark zwecks ILBM jetzt auslesen. Reicht wenn ich das dann habe xD.
http://www.mediafire.com/file/hqk2uakt1b9bbhu/test.pbm
Die Testdatei ist folgendermaßen gegliedert:
Offset 0 - Palette -> Größe 768 Bytes (300h)
-> 768 / 3 = 256 Farben. Jeweils 1 Byte für Rot, Grün und Blau.
Offset 300 - Auflösung -> Größe 4 Byte (4h)
-> 2 Byte Breite + 2 Byte Höhe. Beides als BigEndian gespeichert
Offset 304 - Bild Informationen (Komprimiert)
-> Siehe oben für die Problemlösungssuche.
Das Testbild müsste dann im Endeffekt so aussehen:
Wäre Geil wenn mir das einer irgendwie beibiegen kann.
Ich habe ein kleines Umsetzungsproblem zwecks eines simplen RLE Decompressions Algorithmus.
Es geht um ILBM Bild Dateien von Electronic Arts.
Ich kann mit meinem aktuellen Programm soweit alles laden, Header, Palette, etc. pp.
Nun bin ich aber schon eine Weile daran diese blöde Lauflängenkodierung zu decodieren, damit ich das jeweilige Bild wieder habe und zeichnen lassen kann.
Im Internet gibt es zwars ein Pseudo Code wie der Prozess auszusehen hat, aber ich kann das irgendwie nicht so recht in meiner Programmiersprache umsetzen, weil ich irgendwo ein Gedankenfehler habe.
Die Palette ist nicht das Problem und wird einwandfrei erkannt.
Es geht nämlich um ein 256 Farb Bild.
Hier mal der Pseudo Code auf Wikipedia: https://en.wikipedia.org/wiki/ILBM#Compression
Hier mein QB64 (http://www.qb64.net/) Code dafür:
Code:
'##############################################################
'# Problem with Decompressing
'# https://en.wikipedia.org/wiki/ILBM#Compression
'#
'# Content TINY and Body have the same Compression
'##############################################################
'Only for Compressed DATA
i = 0
DO
picData = sRO(of, 1)
IF picData > 128 THEN ' Decompressing value
decomp = 257 - picData
picData = sRO(of, 1)
FOR r = 0 TO decomp - 1
thumbnail(i + r) = picData
NEXT r
i = i + decomp - 1
ELSE
IF picData < 128 THEN ' Non-Decompressing value
decomp = picData
r = 0
DO
picData = sRO(of, 1)
IF picData = 128 THEN EXIT DO
thumbnail(i + r) = picData
r = r + 1
LOOP WHILE r = decomp - 1
i = i + decomp
END IF
END IF
i = i + 1
PRINT i 'Current position
LOOP UNTIL i >= (ILBM.TINYwidth * ILBM.TINYheight)
'#####################################################
'#####################################################
Zum Zeichen soll dann später folgendes dienen:
Code:
'#-------------------------
'# Testing Picture Output
'#-------------------------
'Set screen mode VGA 320x200 by 256 color for Graphic
' or 40x25 for Textmode
SCREEN 13
PALETTE USING pal() ' useing the loading palette from CMAP
'draw the image
FOR y = 0 TO ILBM.TINYheight - 1
FOR x = 0 TO ILBM.TINYwidth - 1
PSET (x, y), pal(thumbnail(y * ILBM.TINYwidth + x))
NEXT x
NEXT y
Das Bild ist in Indexen gespeichert. Jeder Index entspricht einen Wert aus der Farbpalette. 0 - 255.
Mit sRO lade ich jeweils ein Byte an der jeweiligen Offset Adresse die in der Variable 'of' enthalten ist. of wird beim nutzen von sRO immer um 1 erhöht, sodass ich dann den nächsten Offset habe.
i und r sind Zählvariablen. Wobei i die Größe des Bildes in Byte ergeben soll. Die Schleife endet sobald i > oder = die Höhe * Breite des Bildes hat. Sprich die Gesamt Bytes.
thumbnail ist ein Array das als Speicher der dekomprimierten Indexwerte dienen soll. Sprich das Bild wird in diesem Array festgehalten dann.
Ich habe hier auch mal eine RAW Datei hochgeladen, wo ihr das dann selbst probieren könnt.
Enthält die Palette, die Auflösung und das Bild selbst. Ihr braucht also nicht den ganzen Quark zwecks ILBM jetzt auslesen. Reicht wenn ich das dann habe xD.
http://www.mediafire.com/file/hqk2uakt1b9bbhu/test.pbm
Die Testdatei ist folgendermaßen gegliedert:
Offset 0 - Palette -> Größe 768 Bytes (300h)
-> 768 / 3 = 256 Farben. Jeweils 1 Byte für Rot, Grün und Blau.
Offset 300 - Auflösung -> Größe 4 Byte (4h)
-> 2 Byte Breite + 2 Byte Höhe. Beides als BigEndian gespeichert
Offset 304 - Bild Informationen (Komprimiert)
-> Siehe oben für die Problemlösungssuche.
Das Testbild müsste dann im Endeffekt so aussehen:
Wäre Geil wenn mir das einer irgendwie beibiegen kann.