mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bild (de) Kompression


Autor: Frank Fritze (z80-1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

viele von euch (uns) arbeiten ja schon längere Zeit mit (grafischen) 
Displays. Ich schlage mich seit Tagen mit folgendem Problem herum:

Anzeige von Bildern (Farbe) 128*128 Pixel auf (OLED) Display.
Die Bilder sollen aber im Flash (Atmega 128) gespeichert sein.
Ein Bild hat im "Normalzustand" 32768 Byte (128*128*2) wegen 16 Bit 
Farbtiefe.

Wenn ich also den Overhead für die Displaysteuerung abziehe, komme ich 
auf etwa 3 Bilder im Flash. Das ist viel zu wenig !
Momentan arbeite ich mit einem Dataflash (16 MBit) über SPI. Geht ganz 
gut (und auch schnell). Besser wäre es aber im internen Flash, da es 
"statische" Bilder sind, die sich nicht verändern.

JPEG ist in der Decompression auf einem Atmega viel zu langsam , RLE ist 
ni cht effektiv genug.
JPEG2000 wäre die Lösung, aber das gleiche Problem wie bei JPEG.

Hat irgendeiner eine Idee oder einen link zu einer Idee ?

(externer JPEG-Decoder entfällt)

Frank

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine einfache Möglichkeit wäre je nach Bildinhalt, mit indizierten 
Farben zu arbeiten, also mit einer Palette. Das ist natürlich noch keine 
richtige Kompression, aber wenn dir 8 Bit pro Pixel reichen, kannst du 
damit immerhin das Bild auf etwas mehr als die Hälfte (16384 Bytes für 
die Pixeldaten plus 512 Bytes für die Palette) reduzieren.
Dann kannst du noch Kompressionen wie sie in GIF (nur mit Palette) oder 
PNG (mit Palette oder auch direkt) verwendet werden, ansehen oder z.B. 
eine gzip-Kompression verwenden. du kannst auch mal bei den 
3D-Beschleunigern schauen (ATI/Nvidia). Da gibt es Verfahren zur 
Texturkompression wie z.B. s3tc, die relativ einfach und bestimmt auch 
für deinen Fall einsetzbar sind.

Autor: Jochen Müller (taschenbuch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Wie Rolf schon sagte, ich würde es unbedingt erstmal mit GIF versuchen.

Die Grösse der komprimierten GIF-Datei hängt sehr stark vom Bildinhalt 
ab, kann aber sogar deutlich kleiner als ein JPG-Bild sein.

Das kannst Du vor allem sehr einfach testen, OHNE vorher etwas zu 
programmieren. Nimm einfach einen der tausenden frei verfügbaren 
Formatkonverter und probiere aus wie Dein Bild als GIF aussieht und wie 
gross es wird. Wichtig wäre, dass Du die Parameter auf "optimierte 
Palette" stellst.

Die Umsetzung des GIF-Decoders ist dann nicht sooo schwer zu 
programmieren, das Format ist sehr gut dokumentiert und die Umsetzung 
ist um Potenzen leichter und schneller als es bei JPG der Fall wäre.

Gruss
Jochen Müller

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Bild einfach ZIPpen.

Autor: Frank Fritze (z80-1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Rolf:

Sehe ich mir gerade mal an - DXTx werde ich gleich mal testen - die 
Dcompression scheint ziemlich trivial zu sein und zu Komprimieren gibts 
(glaube ich) von nVidia ein Plugin für Photoshop.

@Gast:

Zip ist noch zu groß.


Ich halte euch auf dem laufenden ..

Frank

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zip kommt dem GIF recht nahe bei gleicher Farbtiefe. Darf es denn eine 
Verlustbehaftete Kompression sein?

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
128x128 Pixel = 16384 Bildpunkte * 2 Bytes = 32768 Bytes. Schon eine 
Farbtabelle würde immer eine Komprimierung bringen denn von den 65535 
möglichen Farben können nur maximal 16384 in einem Bild auftreten. Dein 
Index in die Farbtabelle mit 16384 Farben kann also nur maximal 14 Bit 
große sei, statt 16 Bit bei Echtfarbpixeln. Du sparrst also minimal 2 
Bit pro Pixel im schlechtesten Falle wenn du eine Farbtabelle benutzt, 
zuzüglich die Farbtabelle selber. Das ist der Worstcase der nur gilt 
falls jeder der Pixel eine andere Farbe hat. Schau dir mal das hier 
Beitrag "The Siemens S65 132x176, 65536 color display with AVR" und suche nach meinem 
BitmapConverter. In diesem Posting habe ich die 4 verschiedenen Methoden 
wie ich darin Bitmaps für das S65 Display komprimiere und auch wieder 
entkomprimiere aus dem AVR beschrieben.

Gruß Hagen

Autor: Benedikt K. (benedikt) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bis etwa 320x240 sollten eigentlich 256 Farben + LUT reichen. Das dürfte 
mit Sicherheit das einfachste Verfahren sein, und spart immrhin fast die 
Hälfte an Speicherplatz. Bei 320x240 wäre ein Bild dann 77568 Bytes 
groß. Bei 128x128 wären es 17152 Bytes.
RLE düfte so ziemlich die einfachste verlustfreie Kompression sein. 
Nachteil: Es funktioniert nur bei vielen gleichen Pixeln (wie einfachen 
Grafiken usw.) richtig gut. Spätestens bei verrauschten Fotos werden die 
RLE Bilder teilweise sogar größer als die unkomprimierten Daten. Dafür 
braucht man dann andere, verlustbehaftete Verfahren wie jpeg.

Ich habe mal ein wenig mit den Textur Kompressionsverfahren wie 3Dc 
gespielt. Im Prinzip ist das nichts anderes, als für jeden Block eine 
vereinfachte, optimierte Farbpalette zu speichern, und somit die 
Farbtiefe eines jeden Blocks aus 1-3bpp zu reduzieren.
Im Anhang das Ergebnis (Sorry für die große Datei). Die Bilder wurden 
von oben nach unten mit 16x16, 8x8 und 4x4 Blockgröße komprimiert. Die 
Bittiefe auf der linken Seite beträgt unglaubliche 1 Bit pro Pixel ! 
Rechts waren es immerhin 2 bpp.
Ein und Ausgabe sind jeweils 24 bpp. Die Datei ist dann genau 1 MByte 
groß. Komprimiert haben die Dateien folgende Größe:
52kB    96kB
76kB   118kB
117kB  214kB

Die Dekomprimierung sollte selbst auf einem AVR sehr schnell gehen, da 
es ja nicht viel mehr als Daten lesen + Tabelle nachschauen ist.
Man kann die Software mit Sicherheit noch etwas optimieren (vor allem 
beim Komprimieren z.B. noch Dithern) um bessere Ergebnisse zu erhalten.
Wie man schön an dem Bild sieht, funktioniert dieses blockbasierte 
Kompressionsverfahren nur gut, wenn es keine scharfen Kanten gibt.
Ob es sich lohnt, sowas auf einem AVR einzusetzen, würde ich eher 
bezweifeln, da man im Normalfall eher selten Fotos anzeigt, sondern 
häufiger Grafiken, die sich mit RLE besser komprimieren lassen.

Autor: Frank Fritze (z80-1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hagen:

Vielen Dank für deine Tipps - ich habe schon deine Font-Routinen für 
mein Display (mit Erfolg) benutzt. Dein Bitmapconverter ist auch nicht 
schlecht:
von 32768 -> 19286 bytes.

Mit der "DDS"-Komprimierung (DTX1) waren es 8320 bytes.

Jetzt bin ich beim Testen von "Polyomino Compressed Format", da habe ich
7086 bytes ! Mal den Decompressor ansehen ...

Frank

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es hängt halt auch von der Komplexität der Dekomprimierung ab. Bei 
meinem, wirklich simplen Verfahren bin ich immer davon ausgegengen das 
ich innerhalb von 2*18 Takten der MCU den nächsten 16 Bit Pixel 
dekomprimiert und fertig für das SPI habe. Das SPI benötigt diese 2*18 
Takte für 2 Bytes zum rausschieben. Somit erreicht meine Bitmaproutine, 
die 4 verschiedenen Verfahren, den maximal möglichen Datendurchsatz zum 
Display.

Auch sollte die Dekomprimierung mit möglichst wenige zusätzlichem SRAM 
auskommen, auch dies habe ich bedacht. Die Bitmap Routinen benötigen 
defakto garkeinen SRAM und die Font Routinen nur 4 Bytes + globale 
Variable die man eh benötigt.

Ich habe mal kurz das PCIF angeschaut, der Overhead an Speicher und 
Rechenzeit bei der Dekomprimierung dürfte für einen AVR gewaltig sein.

@Benedikt: hast du das Verfahren auch im Source vorliegen ? Würde es mir 
mal gerne genauer anschauen.
Allerdings müsste man das Datenformat so anpassen das zu einem zb 8x8 
Pixelblock sequentiell abspeichert. Dann kann man das im AVR auch 
sequentiell laden ohne irgendwelche Bitmanipulationen einbauen zu 
müssen. Raus käme ein 8x8 Pixelblock der dann aber nicht mehr ganz so 
einfach an das LCD gesendet werden kann. Dazu müsste man den LCD 
Controller auf ein 8x8 Pixel Fenster programmieren. Für jedes dieser 8x8 
Pixelfenter fällt also auch wieder zusätzlicher Trafik zum LCD an. Oder 
man müsste mit SRAM Buffer arbeiten.

Gruß Hagen

Autor: Benedikt K. (benedikt) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hagen Re wrote:

> @Benedikt: hast du das Verfahren auch im Source vorliegen ? Würde es mir
> mal gerne genauer anschauen.

Ja, ist zwar nur auf dem PC geschrieben und hat vermutlich noch einige 
Bugs, da ich es heute Vormittag schnell geschrieben habe. Ich habe mich 
auch nicht ganz an die Beschreibung gehalten, und es ist nichts 
kommentiert...
Mit den defines stellt man Blockgröße und BPP ein, und man kann 
auswählen, ob RGB individuell betrachtet und jede Farbe einen eigenen x 
bit Wert bekommt, oder ob RGB innerhalb eines Pixels fest ist, und nur 
ein x bit Wert für den gesamten Pixel gespeichert werden soll.

> Allerdings müsste man das Datenformat so anpassen das zu einem zb 8x8
> Pixelblock sequentiell abspeichert. Dann kann man das im AVR auch
> sequentiell laden ohne irgendwelche Bitmanipulationen einbauen zu
> müssen.

Du meinst anstelle des 4x4 oder 8x8 Block einen 16x1 oder 64x1 Block zu 
verwenden ?
Daran hatte ich auch schon gebastelt, nur das Problem ist dann, dass die 
Entfernung der Pixel innerhalb des Blocks größer werden und somit auch 
die Unterschiede in den Farbwerten. Dadurch wird die Bildqualität massiv 
schlechter (leider).

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Du meinst anstelle des 4x4 oder 8x8 Block einen 16x1 oder 64x1 Block zu
>verwenden ?

Nicht direkt ;) Der Kompressor betrachtet weiterhin seinen 8x8 Pixel 
Block. Er komprimiert diesen und speichert in der Datei aber diesen 8x8 
Block sequentiell. Die AVR Dekomprimierung liest also sequentiell den 
ersten 8x8 Block und dekomprimiert nach Möglichkeit diesen 8x8 Pixel 
Block in der Art das zuerst die 1. Zeile mit 8 Pixeln dieses Blocks 
dekomprmiert wird, dann die 2 zeile usw. Der AVR muß dann nur das LCD 
auf ein 8x8 Pixel Window initialisieren und kann so alle 8x8 Pixel am 
Stück an das LCD senden. Ich habe das Verfahren doch so verstanden das 
der 8x8 Pixel Block analysiert wird und über eine optimierte Farbtabelle 
die Bitreduktion vorgenommmen wird. Also muß zu jedem 8x8 Block auch 
eine eigene Farbtabelle gespeichert werden.

Ich schau mir aber erstmal deinen Source an, vielleicht reden wir ja 
aneinander vorbei.

Was machst du eigentlich bei Bitmaps die nicht ohne Rest in Blöcke 
teilbar sind ?

Gruß Hagen

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hagen Re wrote:
> Ich habe das Verfahren doch so verstanden das
> der 8x8 Pixel Block analysiert wird und über eine optimierte Farbtabelle
> die Bitreduktion vorgenommmen wird. Also muß zu jedem 8x8 Block auch
> eine eigene Farbtabelle gespeichert werden.

Ja, genau so ist ist. Da bei Fotos innerhalb einer kleinen Fläche 
normalerweise die Farbe nicht allzusehr abweicht, geht das ganz gut.
Momentan werden pro Block 6 Byte Farbtabelle gespeichert. Das ist 
ziemlich viel, da in einem 4x4 Block bei 2bpp nur 4Byte für die 
eigentlichen Bilddaten verbraucht werden. An diesem Punkt könnte man das 
ganze mit Sicherheit noch optimieren um so eine bessere Kompression bei 
gleicher Qualität bzw. eine bessere Bildqualität bei gleicher 
Kompression zu erziehen.

> Was machst du eigentlich bei Bitmaps die nicht ohne Rest in Blöcke
> teilbar sind ?

Dann wird das Bild auf Blockgröße auferundet (bzw. momentan landen 
irgendwelche Resete von vorhergehenden Blockberechnungen in den Pixeln 
des halb genutzen Blockes. Falls die Software mal wirklich irgendwo 
verwendet wird, muss man das natürlich noch ordentlich machen).

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt mal 3DC überflogen. Man betrachtet einen zb. 4x4 
Pixelblock und vrsucht jeden der darin gespeicherten Pixel auf 2 Bit 
Information zu reduzieren. Macht also 4 Farben die möglich sind pro 
Pixel. Die Farbtabelle besteht aber aus nur 2 Referenzfarben und 2 
weitere Farben müssen daraus errechnet werden. Das ergäbe bei 16 Bit 
Farbtiefe als 2 * 16 Bit für Farbtabelle und 4x4*2 Bit für Pixelblock, 
macht 64Bit. Was vorher 4*4*16=256Bits brauchte -> 4 zu 1 = 25%. Nicht 
schlecht. Da wir aber auf kleinen LCD arbeiten die weit weniger 
unterscheidliche Farbpixels anzeigen könmnen als Farben möglich wären 
würde ich noch einen Schritt weitergehen. Man zerlegt erstmal das Bild 
in die 4x4 Pixelblöcke. Zu jedem Block berechnet man die 2 besten 
Referenzfarben und trägt sie so sortiert in eine globale Farbtabelle 
ein. Diese Farbtabelle dürfte weitaus kleiner sein als 2^16. Nun 
optimiert man diese Farbtabelle so das man versucht möglichst viele 
2-Tuple weglassen zu können oder das man 2 Tuple zu einem Trippel 
zusammenfasen kann. Also zb. Rot-Blau und Blau-Grün, wird so gespeichert 
das man Rot-Blau-Grün in der Tabelle speichert. So entsteht eine 
optimierte Farbtabelle aus den Referenztupeln (Referenzfarben) die sehr 
kompakt sein sollte. Bevor man nun die 4x4x2 Bit Blöcke zu den 4x4 
Pixelblöcken abspeichert speichert man einen Index in diese Farbtabelle. 
Statt also 2x16 Bit Farbe würde man zb. 10 Bit Index in die Farbtabelle 
abspeichern. Macht also 4x4*16 zu 10+4x4*2 = 256 zu 42 = 6 zu 1 = 17%.

Entscheidend ist die Analyse des Bildes vor der Komprimierung und die 
möglichst gute Berechnung einer optimimalen Farbtabelle der 
Referenzfarben.

Allerdings ist das keine lossless Komprimeirung mehr.

An einem Detail knapper ich aber noch. Um aus den 2 Referenzfarben die 
zwei virtuellen Farben erechnen zu können muß man F1 = F0 * 2/3 + F3 * 
1/3 und F2 = F0 * 1/3 + F3 * 2/3 berechnen. Das wird einiges an 
Rechenzeit auf dem AVR verbrauchen. Die Berechnung muß nämlich vor jedem 
der 4x4*2 Bit Blöcke live erfolgen um auf SRAM verzichten zu können.

Gruß Hagen

Autor: Frank Fritze (z80-1)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt & @Hagen:

Ich sehe schon, dass das hier ganz schön produktiv wird.
Ich habe mal den Code von Benedikt kompiliert und ein paar Tests gemacht 
und das Ergebnis hier mal angehängt.

Links das Original, rechts nach Kompression und Dekompression.
(musste das leider als JPEG anhängen)

Orginal 24 Bit 102*128 = 39.478 Bytes
Compressed mit BLOCKSIZE=8 BPP=4 -> 7904 Bytes  -> ca. 20%

NICHT SCHLECHT !!

@Hagen: Deine Idee ist nicht schlecht, werd mal drüber nachdenken.

PS: Bei meinem "Problem" geht es wirklich um Photos.


Frank

Autor: Frank Fritze (z80-1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal zur möglichen Optimierung:

Im vorliegenden Fall (OLED) erfolgt die Bildausgabe recht effektiv:

Kommando senden: StartAdresse(0,0)
Kommando senden: Pixeldaten
Daten senden: Pixel_Low(n), Pixel_High(n)
Das ganze 128*128
Fertig!

Ideal wäre also, wenn die Dekompression zeilenweise erfolgen würde.
Kann sie aber so nicht. Demzufolge müsste man - korrigiert mich - bei 
einer Blockgröße von 8 zuerst 8 PixelZeilen (also 128*8*2 wegen 16Bit 
Farbe) im SRAM berechnen -> 2048 Byte !
Das ist recht viel für so'n kleinen AVR ...

Frank

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du entschlüsselst jeden 8*8 Block acht mal. Halt in jeder Zeile 
neu. Die anderen 7 Zeilen schmeißt du dann jeweils weg.

Aber dumme Frage: Soweit ich das jetzt verstanden hab schaust du doch eh 
nur in einer LUT nach, welcher Farbe denn in diesem Block ein bestimmter 
code entspricht. Das sollte doch auch Zeilenweise gehen??

Sebastian

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian wrote:
> Aber dumme Frage: Soweit ich das jetzt verstanden hab schaust du doch eh
> nur in einer LUT nach, welcher Farbe denn in diesem Block ein bestimmter
> code entspricht. Das sollte doch auch Zeilenweise gehen??

Prinzipiell ja. Der Nachteil ist dann aber wieder die Geschwindigkeit. 
Da nicht die komplette LUT gespeichert wird, sondern nur min und max 
Werte und der Rest davon linear interpoliert wird, ist dies schonmal ein 
Rechenaufwand, den man ansonsten nur 1x pro Block machen muss. Momentan 
besteht die LUT Berechnung aus einer Division durch BLOCKSIZE-1, bei 
einem 8er Block also durch 7. Das kann man bestimmt irgendwie besser 
optimieren, dann wäre es nicht so schlimm wenn man diesen Teil öfters 
ausführt.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Angenommen 16 Bit Farbtiefe und 4x4 Pixelblock dannspeicherst du im 
Datenstream auf folgede weise:

2 * 16 Bit für Farbe, Pixelblock links oben
4 * 2 Bit für 1. Pixelzeile, Pixel 3,2,1,0
4 * 2 Bit für 2. Pixelzeile, Pixel 3,2,1,0
4 * 2 Bit für 3. Pixelzeile, Pixel 3,2,1,0
4 * 2 Bit für 4. Pixelzeile, Pixel 3,2,1,0

2 * 16 Bit für Farbe, Pixelblock 2. links oben
4 * 2 Bit für 1. Pixelzeile, Pixel 3,2,1,0
4 * 2 Bit für 2. Pixelzeile, Pixel 3,2,1,0
4 * 2 Bit für 3. Pixelzeile, Pixel 3,2,1,0
4 * 2 Bit für 4. Pixelzeile, Pixel 3,2,1,0


im AVR machst du nun folgendes

setze Window(x,y,x+3,y+3) alle nachfolgenden Pixel die du dann sendest, 
am Stück sequentiell landen auf dem Display im Rechteck x,y,x+3,y+3. 
Diese Funktion unterstützen fast alle Display auf alle Fälle alle 
neueren. Dabei kannst du sogar noch angeben ob das Display die interne 
SRAM Addresse zu (x,y) nun X zu Y inkrementiert/dekemrniert oder erst 
Y,X inkremenriert/dekrementiert. Du kannst also dieses Window in allen 
Richtungen aus allen Ecken heraus befüllen und somit 
gespeigelt/seitenverkehrt/kopfstehend dieses Window befüllen.

Nach dem setzen des Windows, lädst du die 2 Farbwerte und rechnest die 
fehlenden 2 virtuellen Farbwerte dazwischen live aus. Kostet also 
entweder 8 register oder 8 Bytes SRAM, als LUT. Diese LUT kann im SRAM 
liegen oder im Registerfile als SRAM angesprochen, zb. r2 bis r9. So 
habe ich das bei meinem Font gemacht.

Nun lädst du Byteweise die Pixeldaten.  Jedes Byte stellt 4 Pixel a 2 
Bit dar. Dabei ist der linke 1. Pixel im LSB gespeichert. Also die 
untersten 2 Bits sind Pixel 1, nach einem Rechtsshift von 2 steht dort 
Pixel 2 usw. bis Pixel 4.

Dieses Byte wird nun insgesamt 4 mal a 2 Bits rechtsgeshiftet. Die 
untersten 2 Bits dieses Bytes werden per AND Maske 0x03 ausmaskiert und 
auf den LUT-Zeiger 2x addiert, da diese ja eine 16 Bit LUT ist.

Angenommen diese LUT steht in r0 bis r7 drinnen, dann brauchst du nach 
dem Ausmaskieren mit 0x03 nur diesen Zeiger nur einmal links shiften, 
oder eben auf sich selber addieren, zb. Register XH,XL und greifst damit 
per LD farbeH, X+ und DL FarbeL, X+ aud die Register r0 bis r7 indirekt 
zu.

Mit Blöcken a 4x4 oder 8x8 dürfte das die Resourcen des AVRs noch nicht 
sprengen, sprich alles in Register.

Gruß Hagen

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest auch versuchen inwieweit du mit niedrigerer Farbanzahl 
glücklich wirst, auf Displays ist das eigentlich meist nicht sooo 
wichtig alle Farben zu nutzen, hab dazu mal nen Tool geschrieben: 
Beitrag "Grafikkonverter Tool für AVR/Mikrocontroller (BMP2C, BMP2ASM, BMP2BASCOM)"
Ich habe auch ne HuffmanCompriemierung bzw decomprimierung für den AVR 
programmiert, wollte ich demnächst mal in die Codesammlung stellen, ist 
aber noch nicht zu 100% getestet, damit erreicht man schon gute Raten, 
jenachdem wie viel redundanz das Bild enthält bis zu 70%.
Das dekodieren geht auch wenn du die Daten direkt ans Display sendest 
ohne das du SRAM benötigst (mein Code schreibt das Ergebnis zurzeit ins 
SRAM, aber man müßte halt nur das Store durch das senden ans Display 
austauschen)

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das wäre das was ich in meinem BitmapConvert eingebaut habe. Die 
Farbtabelle wird erstmal gestutzt so das sie 2^x Einträge nicht 
überschreitet. Dann kann man das immer weiter treiben jeweils um einen 
Schritt runter -> 2^x -> 2^(x -1) usw.

Bei gleichmäßig farbigen Bitmaps geht das, aber bei schön bunten hat man 
sehr schnell Fehlfarben.

Gruß Hagen

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja man muß halt etwas mit den Farben "spielen" aber ich finde das geht 
schon recht gut.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem dürfte die effiziente Berechnung der LUT darstellen. In 
jedem Falle benötigt man immer krumme Divisionen. Auf einem ATmega mit 
Multiplikation ist das weniger ein problem da man dort mit MULFS usw. 
arbeiten kann, also Fixpoint 1.7 oder 1.15.

Es sei denn du machst es so wie ich's oben schon angedeutet habe. Statt 
die Min/Max LUT pro Pixelblock zu speichern, erxtrahierts du bei der 
Komprimierung erstmal alle diese Min/Max Werte aller Pixelblöcke. Diese 
sortierst du in eine Liste und sehr ähnliche Min/Max Werte fasst du in 
einem Min/Max Wert zusamen. Dann sortirst du diese Tabelkle so das 
möglichst viele Min/Max Tupels nahtlos aneinander passen, also der MAX 
Wert vom Tupel 1 passt zum MIN des Tupel 2. Diese fasst du so zusammen 
das die den gleichen MIN/MAX Wert nur einmal speicherst. Nach dieser 
Bearbeitng der Tabelle hast du eine globale Farbtabelle definiert. Diese 
könntest du so speichern das nun  die MIN/MAX Pare gespeichert werden 
und erst zur Laufzeit die fehlenden virtuellen Farben erechnet werden, 
entwer Live oder nach dem Laden dieser Farbtabelle. Oder du speicherst 
sie schon während der Komprimierng als vollständig ausgerechnete Tabelle 
vor die Pixelbits. Dann brauchst du sie nur im FLASH komplett speichern 
und kannst per LPM direkt die Farbwerte laden. Vor den Pixelbits 
speicherst du dann nur noch einen Index a Ln2(Anzahl Farbtabelle) Bits 
statt die beiden MIN/MAX Farbwerte. Das erhöht die Komprimierungsrate 
nochmals.

Gruß Hagen

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.