Tak to widzę (dla uproszczenia załóżmy, że obrazki są czarno białe i mają takie same wymiary):
a0) robisz sobie strukturę dla liczby zespolonej (pola img i real typu double)
a) odczytujesz plik pierwotnego obrazka (rozmiarów NxM) do jednowymiarowej tablicy o rozmiarze N*M, robisz na nim FFT z gotowej biblioteki (nie wiem jaka jest w C, w Pythonie jest numpy.fft), wynik zapisujesz w tablicy typu struktury którą sobie zadeklarowałeś w punkcie a0.
b ) to samo robisz z plikiem ukrywanym
c) ok, masz dwie tablice reprezentujące zapis obu obrazków po FFT, robisz z nich jedną, możesz po prostu dodać polami (img z img, real z real)
d) robisz odwrotną transformacje i zapisujesz do pliku graficznego o rozmiarach NxM.
Przy obrazku kolorowym zamiast jednej takiej operacji są trzy (dla kanału czerwonego, zielonego i niebieskiego), no ew. cztery, jeśli bierzesz pod uwagę kanał alfa. Taki obrazek będzie strasznie niepodobny, do oryginału IMHO, by to było w miarę ok, to chowany obrazek musi być mniejszy niż ten w którym go chowasz (wtedy zmieniasz np co czwarty piksel, a nie każdy). Ew. możesz zrobić FFT i operacje odwrotną na tablicy 2D wtedy efekt powinien być lepszy (chyba).
Operacja odwrotna to taka, że masz obrazek oryginalny oraz ten z ukryta treścią, robisz na obu FFT, a później odejmujesz wartości, później operacja odwrotna do FFT, zapis do piku i masz plik, który ukryłeś. Jeżeli przy dekodowaniu nie chcesz korzystać z pliku oryginalnego to można to zrobić tak, że (zakładając że obrazek ukrywany jest dużo mniejszy od tego w którym go ukrywasz), że piksele, które zmieniasz nie dodajesz, tylko zamieniasz wartościami (wtedy musisz mieć info, które piksele zamieniłeś, co sprowadza się do tego, że musisz wiedzieć jaki jest stosunek wielkości obu obrazków).