W trakcie startu systemu AmigaOS4.1 na ekranie pokazuje się obrazek symbolizujący z czym mamy do czynienia. Po jakimś czasie zaczyna on nam się nudzić i najchętniej chcielibyśmy go zmienić na coś swojego, indywidualnego.

Jakiś czas po tym jak na swoim SAM440ep zainstalowałem OS4.1, przyszedł mi do głowy pomysł żeby podmienić oryginalny obrazek startowy na jakiś taki który by mi bardziej odpowiadał. Niestety, choć przeszukałem wszystkie opcje w preferencjach Workbencha nie znalazłem żadnej która by to umożliwiała.
Zapytałem więc na forum eXeca czy jest to w ogóle możliwe. W odpowiedzi dowiedziałem się że obrazek startowy który pokazuje się na starcie systemu jest zawarty w jednym z plików KickStartu.
W związku z tym podmiana go w sposób bezpośredni nie jest w żaden sposób możliwa.
Szaman tak mimochodem napisał: „A może byś spróbował?”. Jako że za młodu bawiłem się w ripowanie modułów z gier i programów demonstracyjnych więc czemu nie. Zabrałem się za to.

Wszystkie opisane tu czynności wykonywałem na pliku BootImage z systemu AmigaOS4.1 który był dostarczany przy zakupie komputera SAM 440ep. Jest to wersja starsza niż Final Edition. Ponieważ nie posiadam tej wersji nie jestem w stanie stwierdzić czy operacje które tu opiszę będą w dalszym ciągu aktualne.
Jednak do Update 6 wszystko działa bez zarzutu.

Na samym początku trzeba się dowiedzieć w którym konkretnie elemencie Kickstartu może znajdować się ten obrazek. W systemie 4.x KickStart nie jest umieszczony w pamięci ROM jak to ma miejsce starszych systemach. Dodatkowo nie jest też w jednym kawałku lecz składa się kilkunastu pojedynczych plików które w trakcie startu systemu są wczytywane z twardego dysku. Ma to swoje zalety gdyż jakakolwiek aktualizacja KickStartu polega tylko na podmianie konkretnego pliku. Taka sytuacja sprawę podmiany obrazka bardzo upraszcza.

Odszukanie konkretnego pliku było banalnie proste. Wystarczyło wejść do katalogu Sys:Kickstart.
Plik którego szukałem sam swoją nazwa BootImage podpowiadał że jest tym czego szukałem.

Niestety. Plik ten nie był jakimś zwykłym obrazkiem w jednym z popularnych formatów ze zmienioną nazwą lecz programem który posiada w sobie dane tego obrazka zapisane tylko w sobie znanym formacie i wyświetla w odpowiednim momencie.

Dekompilacja tego programu w ogóle nie wchodziła w grę.

Każdy z czytających który spodziewał się profesjonalnego podejścia do tematu z pokazaniem jak to można prosto zrobić dostępnymi programami
muszę rozczarować. Opisane przeze mnie czynności można potraktować jako prymitywny włam w zawartość pliku wykorzystując do tego własne oprogramowanie.

ETAP PIERWSZY – Obrazku pokaż się!

W pierwszej kolejności należało ustalić w jakiej wielkości i w ilu kolorach mógłby to być obrazek.
Monitor do którego miałem podłączony komputer wykazał że aktualnie wyświetlany obraz ma rozmiary 640×480.
To już jest jakaś wskazówka. Szybka kalkulacja wykazała jednak że wielkość obrazka znacznie przekracza wielkość pliku.
A więc obrazek musi być jakoś skompresowany a to z kolei może utrudnić sprawę.

Dalsze czynności nad plikiem przeprowadzałem na mojej Amidze 1200 gdzie mam środowisko programistyczne.
Wykorzystując File Mastera, który posiada opcje hex-edytora, postanowiłem poszukać w zawartości pliku slow kluczowych takich jak: PNG, JPG, JFIF, ILBM i t.p, w nadziei że zapisany obrazek jest tam po prostu doklejony.

Poszukiwania niestety niczego nie przyniosły.

Należało mu się więc baczniej przyjrzeć w poszukiwaniu czegokolwiek co mogło by przypominać dane graficzne.

W trakcie jego przeglądania w oczy rzucił mi się offset 0x010058 (65624) w którym dane podejrzanie się powtarzały.
Przypominało to sposób zapisu palety barw w systemie amigowym, gdzie dane koloru jednego pisaka w trybie 8-bitowym zapisane są w trzech długich słowach (3×32 bity). Jednak po przeliczeniu ilości tak zapisanych barw wychodziło 3036 bajtów zamiast oczekiwanych 3072 co daje tylko 253 barwy. Na szczęście mówił o tym offset 0x010055 (65621). Po palecie barw pod offsetami 0x010C38 (68664), 0x010C3A (68666) znajdowały się dane 0x0280, 0x01E0 czyli w przeliczeniu na układ dziesiętny odpowiednio 640 oraz 480.
To mogła być wielkość obrazka a wiec analiza pliku szła w dobrym kierunku.
Za tymi danymi od offsetu 0x010C30 (68668) następowały kolejne nic już w sumie nie mówiące dane.
Skopiowałem te dane programem który napisałem bardzo dawno temu którego używam do dziś.
Pozwala on na skopiowanie dowolnej długości danych z danego pliku zaczynając od dowolnego miejsca.
Nazwałem go sobie Kopier. Programy tego typu prawdopodobnie można znaleźć na Aminecie.

Analiza wycinka wykazała że dane były skompresowane metoda RLE (Run-Length Encoding). W skrócie jest to metoda bezstratnej kompresji, która polega na tym że ciągi danych następujących po sobie które się powtarzają zastępuje się jednym plus informacje ile razy taki element się powtórzył. Elementy niepowtarzające się przepisuje się.
Dla przykładu: „AAAMIGAAA RULEZZZZ” można zapisać jako: „3A3MIG3A5 RULE4Z”.
Opis troszeczkę uprościłem gdyż w rzeczywistości trzeba rozróżnić które dane się powtarzają a które nie.
Wykorzystano tutaj znak liczby informacyjnej: jeśli jest dodatni to elementy nie powtarzają się, jeśli ujemny – powtarzają. Algorytm prymitywny ale w opisywanym przypadku wystarczający.
Osobom trochę bardziej obeznanym z Amigą przypomina to kompresję stosowaną w plikach ILBM. I tak w istocie jest.
Tyle tylko że w omawianym przypadku dane o samym obrazku są inaczej opisane, dane jednego piksela opisuje jeden bajt.

Wiedząc o tym, szybko napisałem w C program który zdekompresował mi te dane. Ilość informacji po dekompresji ilościowo zgadzała się z zakładaną jaka powinna być dla obrazka o rozmiarach 640 na 480 czyli 327200 bajtów.
Należało je tylko w jakiś sposób zweryfikować. Tutaj z pomocą przyszedł mi program Personal Paint i format graficzny BMP.
Format ten zapisuje dane wprost bez kompresji z tą różnicą że linie obrazu zapisuje zaczynając od ostatniej.
Jednak dla testu nie było to problemem. Stworzyłem w PPaincie pusty obrazek o wymiarach 640×480 z paletą jaka była ustawiona na starcie programu i zapisałem jako BMP.

Wiedząc że dane graficzne w takim pliku zaczynają się od offsetu 0x0436 (1078) aż do końca pliku, podmieniłem je poprzez odpowiednie pocięcie wyżej opisanym programem i doklejenie swoich danych poleceniem Join. Ponowne załadowanie takiego
pliku do PPainta i… BINGO!
Moim oczom ukazał się dobrze znany obrazek tyle że obrócony do góry nogami z niepoprawną paletą.
Teraz wszystko poszło z górki. Należało jeszcze podmienić paletę która oryginalnie była w 96 bitach na 0RBB (32 bity) gdyż taki zapis obowiązuje w formacie BMP. Do tego także napisałem własny program który mi to przekonwertował.
Paleta w pliku BMP zapisana jest od offsetu 0x0036 (54), wiedząc to wykonałem podmianę danych i ostatecznie dostałem to co liczyłem. Wystarczyło tylko obrócić obrazek wczytany do PPainta:

Podsumuję czego się dowiedziałem:
– obrazek ma rozmiar 640×480 w 8 bitach
– dane obrazka spakowane są metodą RLE
– offset gdzie zaczynają się dane obrazka to 0x010C30 (68668)
– całkowita długość spakowanych danych oryginalnego obrazka to 69741 bajtów
– paleta obrazka zapisana jest w 12 bajtach na kolor
– offset palety barw zaczyna się od 0x010058 (65624)
– wykorzystano tylko 253 barwy (3036 bajtów).

ETAP DRUGI – Obrazek własny.

Wiedząc w jaki sposób i gdzie dane są zapisane mogę spróbować podmienić je na swoje.
Najpierw napisałem algorytm który realizuje kompresję RLE. Do testów posłużył mi oryginalny obrazek który wyciągnąłem z pliku BootImage. Po jego napisaniu i przetestowaniu stwierdziłem że mój algorytm okazał się wydajniejszy i plik był o kilkanaście bajtów krótszy. Zaciekawiło mnie to. Jednak dekompresor który napisałem wcześniej odtwarzał obrazek bezbłędnie. Dodatkowo upewniłem że wszystko jest w porządku poprzez doklejenie moich danych do pliku BootImage gdzie brakujące bajty zastąpiłem wartością 0x80 (dekompresor napotykając takie dane ignoruje je). Obrazek przy starcie systemu OS4.1 pokazał się bez najmniejszych problemów a więc pełny sukces. Jednak nie do końca. Długość ta miała znaczenie ale o tym później.
Gdy stwierdziłem że wszystko działa jak należy, zacząłem poszukiwania na sieci jakiegoś obrazka którym mógłbym zastąpić ten oryginalny. Padło na:


Ponieważ jestem fanem Mangi/Anime ten właśnie obrazek jakoś bardzo mi się spodobał. Wczytałem go do PPainta. Ten przekonwertował mi go do 8 bit, dodatkowo przekolorowałem do 253 barw, oraz odpowiednio wykadrowałem. Zapisałem jako BMP. Następnie taki plik pociąłem oddzielając grafikę od palety. Dane obrazka skompresowałem, paletę przekonwertowałem. Następnie wszystko wkleiłem gdzie trzeba do pliku BootImage sprawdzając czy nigdzie się nie pomyliłem. Ponieważ plik po kompresji był znacznie krótszy dokleiłem odpowiednią ilość 0x80 jak poprzednio. Przegrałem plik gdzie trzeba. Odpaliłem Sam440 i moim oczom ukazał się… No właśnie nie wiem, bo w żaden sposób nie przedstawiało to tego czego oczekiwałem. Jednym słowem wojna mrówek bijąca się kaszkę mannę. Co się stało? Co poszło nie tak? Gdzie się pomyliłem? Długo się nad tym zastanawiałem sprawdzając po trzykroć algorytmy oraz umiejscowienie danych. Nic nie pomagało. Po pewnym czasie przypomniałem sobie o tej różnicy długości pliku testując mój kompresor i nie dawało mi to spokoju. Skądś ta różnica musiała wynikać. Po długich analizach dostałem olśnienia. Mój algorytm kompresował dane całościowo. I tu właśnie był błąd. Oryginalny plik każdą linię obrazu miał kompresowaną oddzielnie. Aby sprawdzić moją teorię nie przerabiałem algorytmu kompresora tylko dodałem do mojego obrazka szary gradient w postaci pionowych pasów.

Był on tak dobrany aby mieć pewność że kompresji zostanie poddana następna linia. Dlaczego to nie wyszło wcześniej? Oryginalny obrazek posiada napis nie na jednolitym tle tylko gradiencie kołowym. To on sprawił że dane kompresowały się w odpowiedni sposób. Po dodaniu gradientu w końcu mogłem się cieszyć własnym obrazkiem przy starcie systemu AmigaOS4.1.

Dla dalszych testów wykonałem kilka testów z różnymi obrazkami z czego dwa umieściłem na OS4 Depot.


Myślałem nad tym czy nie napisać programu z poprawionym algorytmem kompresji i konwerterem palety barw który wykonywałby plik Bootimage automatycznie z dowolnego obrazka. Jednak w trakcie prac wyszedł jeszcze jeden problem. Własny obrazek po kompresji musi zawierać się maksymalnie w takiej ilości bajtów jak obrazek oryginalny. Często przy przygotowywaniu innych obrazków okazywało się że po kompresji plik był dłuższy od zakładanego limitu. Im był bardziej szczegółowy tym bardziej działało to na niekorzyść. Należało go więc sztucznie modyfikować przez usuwanie pewnych fragmentów lub zmniejszanie ilości barw aż otrzyma się zadowalający wynik. Co prawie zawsze skutkowało tym, że obrazek po takich zabiegach nie wyglądał już jak bym chciał.

Myślę że każdy kto zna się choć trochę na programowaniu na podstawie informacji które tutaj przedstawiłem i chciałby taki program napisać zrobi to bez trudu. W razie czego mogę służyć pomocą.

’Phibrizzo’ – Amiga NG 1/2017

—> do spisu artykułów

Dodaj komentarz