diff --git a/lab3/report/report.tex b/lab3/report/report.tex index 3ed2e8c..9a86ee8 100644 --- a/lab3/report/report.tex +++ b/lab3/report/report.tex @@ -270,6 +270,41 @@ bitsToInt bits = Для работы с изображениями использовалась библиотека \texttt{JuicyPixels}~\cite{JuicyPixels}. С её помощью можно как прочитать изображение в любом популярном формате, так и сохранить его. В частности в работе использовались функции: \texttt{readImage} -- для чтения изображения из указанного файла, \texttt{saveBmpImage} -- для сохранения изображения в формате bmp. + + \subsection{Сохранение зашифрованных данных в изображении} + + Код функций для создания изображения с закодированными данными представлен в листинге~\ref{lst:genImg}. Функция \texttt{encodePixel} отвечает за кодирование последовательности бит в определённый пиксель изображения. Она принимает количество бит данных, которое будет сохранено в каждый байт изображения, исходное изображение, вектор бит зашифрованных данных, координаты пикселя (\(x, y\)) и возвращает новый пиксель с закодированными данными. Для этого функция вычисляет индекс пикселя в изображении, извлекает соответствующую часть вектора бит данных, преобразует её в целые числа, накладывает битовую маску, которая соответствует количество изменяемых бит в байте, и записывает закодированные данные. Для создания маски используется вспомогательная функция \texttt{createMask}. + + Функция \texttt{encodePixel} затем используется вместе с функцией \texttt{generateImage} из библиотеки JuicyPixels для генерации нового изображения. + + При сохранении изображения в файл, в его названии сохраняется смещение шифра Цезаря и количество бит в байте, отведённых для хранения зашифрованных данных. Например, название изображения \texttt{david\_2\_10.bmp} означает, что при кодировании использовался код Цезаря со смещением 10, а для хранения закодированных данных в каждом байте изображения использовалось 2 бита. + +\begin{lstlisting}[caption={Функции для создания изображения с закодированными данными.}, label={lst:genImg}] +createMask :: Int -> Int +createMask shift = shiftL (complement 0) shift .&. complement 0 + +encodePixel :: Int -> Image PixelRGB8 -> VU.Vector Int -> Int -> Int -> PixelRGB8 +encodePixel bitsPerByte img bits x y = PixelRGB8 newR newG newB + where + width = imageWidth img + + index = x + y * width + startPos = index * 3 * bitsPerByte + pixelBits = VU.slice startPos (3 * bitsPerByte) bits + + bitsIntR = bitsToInt $ VU.slice 0 bitsPerByte pixelBits + bitsIntG = bitsToInt $ VU.slice bitsPerByte bitsPerByte pixelBits + bitsIntB = bitsToInt $ VU.slice (2 * bitsPerByte) bitsPerByte pixelBits + + mask = createMask bitsPerByte + + PixelRGB8 r g b = pixelAt img x y + newR = intToWord8 $ ((word8ToInt r) .&. mask) .|. bitsIntR + newG = intToWord8 $ ((word8ToInt g) .&. mask) .|. bitsIntG + newB = intToWord8 $ ((word8ToInt b) .&. mask) .|. bitsIntB +\end{lstlisting} + + \newpage \section {Результаты работы программы}