logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C]Kompresja danych w tablicach

xamrex 23 Maj 2011 18:13 5540 16
  • #1 9536563
    xamrex
    Poziom 28  
    Bawię się w wyświetlenie animacji na telefonia Nokia3310.
    Znalazłem jakiegoś gifa, przerobiłem go na 12klatek w BMP i wygenerowałem sobie dane.

    Wkleję może jak wyglądają 3 pierwsze klatki:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W sumie jest 12 klatek.

    Zajmuje mi to 98% pamięci procesora;/

    Tak jak widać ogrom danych się powtarza,
    Czy dałoby się w jakiś prosty sposób skompresować te dane?

    NP. badając przykład pierwszej tablicy buzia[0] to od elementu drugiego (0x01) to się cały czas powtarza.

    Myślałem nad zrobieniem czegoś takiego, że element trzeci tablicy, to byłby wskaźnik na element drugi, tak samo element czwarty tablicy to byłby wskaźnik na element drugi.

    Dobrze myślę??

    W jaki sposób to skompresować ?
  • #2 9536865
    Krauser
    Poziom 26  
    Proponuje coś takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    -zamiana tablicy dwuwymiarowej na jednowymiarową
    -elementy są dwu-bajtowe i w starszej części jest umieszczona liczba powtórzeń, a w drugiej wartość dla wyświetlacza
  • #3 9536874
    xamrex
    Poziom 28  
    W sumie moja tablica jest 3 wymiarowa (teraz nie ma mnie w domu i nie mam dokładnie tego kodu)

    Mógłbyś napisać troszkę kodu jak by to miało wyglądać.
  • #5 9537254
    Krauser
    Poziom 26  
    Twoja funkcja wyświetlająca wygląda pewnie jakoś tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    zatem należy to zmienić na coś takiego
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kody nie są sprawdzone (napisane przed chwilą) i prezentują tylko sposób modyfikacji funkcji wyświetlającej.
  • #6 9537463
    mirekk36
    Poziom 42  
    Jak widzisz zabawa z wyświetlaczami graficznymi przy takiej animacji (podmiana plików bmp) jest bardzo ale to bardzo kosztowna jeśli chodzi o pamięć nieulotną ;)

    Kompresja cię tu nie uratuje (korzystasz zapewne z jakiegoś AVR'ka) .... bo teraz masz jakąś grafikę typu buźka1, buźka2 itd .... ale za chwilę bdziesz chciał mieć coś innego co nawet przy wyborze jakiegoś algorytmu kompresji/dekompresji i tak doprowadzi cię do szału.

    W końcu nie na darmo wymyślono np kompresję JPEG, no ale o tym bez jakiegoś ARM'a to raczej można zapomnieć .... Zresztą na inne algorytmy dekompresji też stracisz co nieco pamięci i przy różnych grafikach zysk będzie mizerny raczej .....

    jak już to ja bym może pomyślał nad jakąś albo większą pamięcią FLASH procesora, albo nad jakąś zewnętrzną pamięcią podłączaną na szynie I2C albo SPI ...... wtedy mógłbyś sobie ładować animacji aż do znudzenia.
  • #7 9537488
    Konto nie istnieje
    Poziom 1  
  • #8 9537677
    asembler
    Poziom 32  
    Najlepiej pamiec zewnetrzna typu FLASH do tego dorób sobie połaczenie z PC po uarcie i bedziesz mogł sobie nawet filmiki ładować bez koniecznosci kazdorazowej kompilacji i programowania układu.
  • #9 9537786
    mirekk36
    Poziom 42  
    asembler napisał:
    Najlepiej pamiec zewnetrzna typu FLASH do tego dorób sobie połaczenie z PC po uarcie i bedziesz mogł sobie nawet filmiki ładować bez koniecznosci kazdorazowej kompilacji i programowania układu.


    No przecież wyżej atom1477 właśnie podał nawet konkretny typ takiej zewn. pamięci FLASH ;)

    .... a jeszcze inna alternatywa to podłączenie karty pamięci SD/MMC na przykład ;) i można sobie od razu na PC wgrać na nią pliki do animacji a potem w procku odcytywać i przesyłać na swój LCD .... o ile po dłuższym przemyśleniu nadal będzie się chciało bawić w takie animacje na takim wyświetlaczu ;)
  • #10 9537904
    asembler
    Poziom 32  
    mirekk36 napisał:
    asembler napisał:
    Najlepiej pamiec zewnetrzna typu FLASH do tego dorób sobie połaczenie z PC po uarcie i bedziesz mogł sobie nawet filmiki ładować bez koniecznosci kazdorazowej kompilacji i programowania układu.


    No przecież wyżej atom1477 właśnie podał nawet konkretny typ takiej zewn. pamięci FLASH ;)

    .... a jeszcze inna alternatywa to podłączenie karty pamięci SD/MMC na przykład ;) i można sobie od razu na PC wgrać na nią pliki do animacji a potem w procku odcytywać i przesyłać na swój LCD .... o ile po dłuższym przemyśleniu nadal będzie się chciało bawić w takie animacje na takim wyświetlaczu ;)

    Sensem mojej wypowiedzi było raczej połaczenie z PC po uarcie ale każdy czyta jak chce.
  • #12 9537966
    xamrex
    Poziom 28  
    Wygląda to tak:
    Tu mam tablicę z 8 buźkami:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    I funkcja wyświetlająca obrazek:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W załączniku może doda jeszcze 2 pliki z wszystkimi funkcjami:

    Oczywiście dołączenie zewnętrznej pamięci to najprostsze rozwiązanie, dlatego wybrałem coś ambitniejszego czyli próba kompresji tego :)
  • #13 9538041
    asembler
    Poziom 32  
    To skoncz na ambicji bo skoro chcesz animacje to przy konkretnej kompresji bedziesz mógł wyświetlać chromającego dziada najwyżej.
  • #14 9538051
    xamrex
    Poziom 28  
    OK, skoro to nie jest takie proste jak mi się na początku wydawało, to sobie odpuszczę.
  • #15 9538229
    skynet_2
    Poziom 26  
    Kompresja tego jest banalna, najprościej zaimplementować RLE a dla kolejnych klatek XOR do poprzedniej + RLE.
    Skompresujesz dane które zamieściłeś bez problemu do 10%.

    Używaj najmniej używanego bajt'u jako klucza. np.
    x - klucz
    y - liczba powtórzeń
    n - liczba która się powtarza
    b - dowolny bajt != x
    W tablicy wygląda to tak bbbbxynbbbbbxynbbbb
    Wadą jest to że odtworzenie bajtu klucza wymaga 3 bajtów.
    Lecąc po tablicy jeśli napotkasz na klucz, to ładujesz licznik[y] do pętli która powtarza n.

    Później możesz już XOR'ować klatki przez siebie i kompresować wynik, dzięki czemu powtarzające się np. tło prawie nie zajmuje dodatkowego miejsca na kolejnych klatkach.

    Używając podwójnej kompresji RLE czyli kompresja 1 klatki później XOR pierwszej z drugą, drugą z trzecią itd + RLE wszystkiego zmniejszyłem 16KiB obraz znaków używany przez wyświetlacz do nieco ponad 1KiB.
    Tyle że miałem całe 200us na dekompresje kolejnego bajtu przy zegarze 1.8432Mhz.
  • #16 9540256
    Krauser
    Poziom 26  
    Kompresje dobiera się do typu danych i do twoich buziek najprostsza jest metoda którą podałem, bo masz duże bloki danych które składają się z takich samych bajtów. Kompresję możesz przeprowadzić na piechotę. Z tym, że nie możesz trzymać w tym wypadku wszystkich buziek w jednej tablicy bo w zależności od buźki będziesz miał inny wymiar. Tablica powinna być jednowymiarowa, ponieważ nie ma potrzeby dzielenia bajtów na należące do innego wiersza. Lepiej zgromadzić wszystkie bajty razem i po zbliżeniu się do końca wiersza przeskoczyć do następnej linii. Argumenty by dokładać kartę SD są bezpodstawne w tym akurat przypadku, gdzie masz bitmapy monochromatyczne. Dla grafik kolorowych jak najbardziej i wtedy nawet nie używałbym JPG, bo nie mam algorytmu dekompresji na mikrokontrolery.
  • #17 9540349
    Konto nie istnieje
    Poziom 1  
REKLAMA