bitMapMiXer

Jedną z najprostszych metod ukrycia wiadomości jest zaszycie jej w pliku graficznym. Polega ona na manipulowaniu najmniej znaczącymi bitami poszczególnych pikseli, tak by z jednej strony zawierały pożądaną wiadomość, a z drugiej strony by powodowało to niezauważalną dla postronnego obserwtora zmianę samego obrazka.

Proszę napisać program umożliwiający ukrycie inforamcji w pliku graficznym, a potem jej ponowne odczytanie. Program ma być wywoływany z dwoma lub trzema argumentami. Gdy są trzy argumenty, to wykonywane jest ukrywanie i argumenty oznaczają kolejno: nazwa wejściowego pliku graficznego, nazwa pliku z informacją do ukrycia, nazwa wyjściowego pliku graficznego. Gdy są dwa argumenty, to wykonywane jest odczytywanie ukrytej informacji i argumenty oznaczają: nazwa pliku graficznego z ukrytą informacją, nazwa odtwarzanego pliku informacyjnego. Ukrywanie informacji w pliku graficznym nie powinno zmieniać jego rozmiaru. Po wykonaniu operacji ukrycia i odtworzenia pliki ukrywany i odtworzony muszą być identyczne. Plik z informacją do ukrycia może być dowolnym plikiem, niekoniecznie tekstowym. Zakładamy, że plik ten jest wystarczająco mały, aby dał się rozproszyć w pliku graficznym bez istotnych zmian w jego wyglądzie, ale na tyle duży, aby zadanie nie było trywialne. Ponadto zakładamy, że oba pliki razem mieszczą się w pamięci operacyjnej. Sposób rozproszenia bitów ukrywanej informacji w pliku graficznym jest dowolny.

Program może być napisany w C i/lub asemblerze. Program powinien zaalokować pamięć mieszczącą w całości pliki wejściowe, wczytać zawartość plików wejściowych do pamięci, wykonać na pamięci ukrywanie lub odczytywanie danych, a na koniec zapisać plik wyjściowy. Wszystkie operacje na danych wejściowych i wyjściowych w pamięci powinny być zrealizowane za pomocą instrukcji SIMD (mmx, sse, sse2, ...). Należy też zadbać, aby instrukcje SIMD, odwołując się do pamięci, używały adresów wyrównanych, tzn. będących wielokrotnością 8 dla mmx a 16 dla sse. Używanie instrukcji skalarnych dopuszczalne jest jedynie w celu organizownia pętli, manipulowania argumentami programu, alokowania i zwalniania pamięci oraz do operacji plikowych. Proszę zauważyć, że nie wszystkie instrukcje SIMD asemblera mają swoje odpowiedniki w postaci funkcji wbudowanych.

Ocenie będzie podlegać głównie pomysłowość użycia instrukcji SIMD i będzie to ocena subiektywna.

Można użyć dowolnego formatu graficznego. Trzeba sobie wyszukać jego opis w Internecie. Jeśli komuś nie chce się szukać, to może użyć tego pliku. Jego format jest przedstawiony w poniższej tabli. Program powinien radzić sobie nie tylko z przykładowym plikiem ale też z dowolnym plikiem w tym samym formacie.

liczba bajtów zawartość
Nagłówek pliku
2 litery BM
4 całkowita długość pliku w bajtach
4 zarezerwowane, zawsze 0
4 odległość w bajtach od początku pliku do początku tablicy pikseli (mapy bitowej)
Definicja formatu
4 rozmiar definicji formatu w bajtach
4 szerokość obrazka w pikselach
4 wysokość obrazka w pikselach
2 liczba płaszczyzn, zawsze 1
2 liczba bitów na piksel (tutaj 24 = True Color)
4 rodzaj kompresji, 0 = brak kompresji
4 całkowity rozmiar tablicy pikseli w bajtach
4 rozdzielczość pozioma w pikselach na metr
4 rozdzielczość pionowa w pikselach na metr
4 zawsze 0
4 zawsze 0
Tablica kolorów (nieobecna, jeśli True Color)
Tablica pikseli
Tablica ta zawiera kolejne piksele obrazka, ułożone wierszami. Wiersz zawiera piksele w kolejności od lewej do prawej i uzupełniony jest pustymi bajtami, tak aby jego rozmiar był wielokrotnością 4 bajtów. Wiersze ułożone są w kolejności od dołu do góry. W formacie True Color pojedynczy piksel opisywany jest za pomocą trzech bajtów, które określają odpowiednio intensywność składowych kolorów podstawowych RGB.