/// \file // RAN 2014-06-10: // -- Simplified the changeMask function. // -- Simplified the masking in the EmbbedMessage function. // -- Changed EmbbedMessage so that only the pixels needed to embbed the message // are changed. Previously, all pixels were masked. This involved hardcoding a // postfix into the encodded message that repeats ASCII code 0 ten times. // RAN 2014-06-14: // -- Simplified the end of message encoding and decoding. Now it just encodes one '\0' // char at the end of the string. Also, its stops decoding when it finds a '\0' // RAN 2015-06-30 // -- In the functions binaryStringToMessage and ExtractMessage, changed // string additions to character push_back. #include "steganography.h" #include Steganography::Steganography() { } /// \fn int cbtoi(char c) /// \~English /// \brief Converts a character bit to integer. /// \param c a character ('0' or '1'), the char that will be converted /// \return An integer 1 or 0 /// \~Spanish /// \brief Convierte un bit en caracter a entero. /// \param c un caracter ('0' o '1'), el caracter que se va a convertir. /// \return Un entero 1 o 0 /// int cbtoi(char c){ if(c == '0') return 0; else return 1 ; } /// \fn string decToBin(int num, int pad) /// \~English /// \brief Converts an decimal number to a string in base 2. /// \param num a non-negative integer, the number that will be converted /// \param pad a non-negative integer, the number of digits /// in the resulting string /// \return A string of length pad of 0's and/or 1's. /// \~Spanish /// \brief Convierte un numero entero a una cadena de caracteres /// en base 2. /// \param num un entero positivo, el numero que se va a convertir. /// \param pad un entero positivo, el numero de digitos en la cadena de /// caracteres resultante. /// \return Una cadena de caracteres de largo pad de 0's y/o 1's /// string decToBin(int num, int pad) { int r = 0; // residue // residuo int q = -1; // quotient // cociente string b = ""; // string to containt the result // cadena de caracteres para contener el resultado while(q != 0) { r = num%2; q = num/2; num = q; if (r) b.insert(0, "1"); else b.insert(0, "0"); } // if letter has less than pad bits, insert 0s at the beginning until length = pad // si letter tiene menos que pad bits, insertar 0s al principio hasta que el // length = pad while(b.length() < (unsigned long) pad) b.insert(0, "0"); return b; } /// \fn string messageToBinaryString(string str) /// \~English /// \brief Converts a string to a string of 1's and 0's /// that represent the ASCII codes of the characters in the original string. /// For example, "AB" results in "10000011000010". /// [-----][-----] /// ^ ^ /// ASCII code of A | | /// ASCII code of B --------+ /// /// \param str a string of characters to be converted to their ASCII representations /// \return A string of 0's and/or 1's. /// \~Spanish /// \brief Convierte una caena de caracteres a una cadena de 1's y 0's /// que representa el codigo ASCII de los caracteren en la cadena original. /// Por ejemplo, "AB" resulta in "10000011000010". /// [-----][-----] /// ^ ^ /// Codigo ASCII de A | | /// Codigo ASCII de B --------+ /// \param str una cadena de caracteres a ser convertido a su representacion ASCII /// \return Una cadena de 0's y/o 1's. /// string messageToBinaryString(string str){ string binStr = ""; int temp; //converting message to binary string //convirtiendo un mensaje a una cadena de caracteres binarios for(unsigned int i = 0; i(str[i]); binStr.append(decToBin(temp, bitsPerLetter)); } return binStr ; } /// \fn char binStringToChar(string str) /// \~English /// \brief binStringToChar: Converts a string of 0's and 1's to an caracter /// Example, with str="0011", returns the caracter 3./// /// \param str: a string of 0's and 1's /// \return A character whose binary representation is equivalent /// to the string. /// \~Spanish /// \brief Convierte una cadena de 0's y 1's a un caracter. /// Ejemplo, con str="00000011", devuelve el caracter 3. /// \param str una cadena de 0's y 1's /// \return Un caracter ASCII cuya representacion binaria es equivalente a la cadena str. /// char binStringToChar(string str){ int value = 0 ; for(unsigned int i = 0; i < str.length(); i++){ value = value << 1 ; if(str[i] == '1') value = value | 1 ; } return static_cast(value) ; } /// \fn int createMask(int lbits) /// \~English /// \brief Creates a mask of lbit 1's in the least significant positions. /// Example, with lbits=4, returns the integer 15, which is mask 0x1111. /// \param lbits a non-negative integer, the number of bits to set to one /// \return An integer with lbit 1's in the least signicant positions. /// \~Spanish /// \brief Crea una mascara de lbit 1's en las posiciones menos significativas. /// Ejemplo, con lbits=4, devuelve el entero 15, cuya mascara es 0x1111. /// \param lbits un entero no negativo, el numero de bits a poner en uno. /// \return Un entero con lbit 1's en las posiciones menos significativas. /// int createMask(int lbits){ return (1 << lbits) - 1; } /// \fn EmbbedMessage(const QImage & origImage, QImage & newImage, string msg) /// \~English /// \brief Given an image (origImage) will create a new image (&newImage) by /// embedding the bits of the msg into the least significant bits of /// pixel colors of the original image. /// \param origImage the original image will not be modified /// \param newImage the image that is created /// \param msg the string that will be embedded /// \return By reference, the newImage is returned, containing the embedded message /// \~Spanish /// \brief Dada una imagen (origImage) creara una imagen nueva(&newImage) /// empotrando los bits de el mensaje msg en los bits menos significativos de los /// colores de la imagen original. /// \param origImage la imagen original no va a ser modificada /// \param newImage la imagen que se crea /// \param msg la cadena que va a ser empotrada /// \return Por referencia, es devuelta newImage, conteniendo el mensaje empotrado. /// void EmbbedMessage(const QImage & origImage, QImage & newImage, string msg){ string binMsg ; // To store the message in binary. // Para almacenar el mensaje en binario. unsigned long msg_index = 0 ; // Will be used to pass through binStr // Sera utilizado para pasar atraves de binStr int red, green, blue ; // Will store the integer representation of the colors. // Va a guardar la representacion entera de los colores int mask = createMask(1); QRgb p; binMsg = messageToBinaryString(msg); // We will include this postfix, so that the decoder will // know when the embedded message ends. It consists of 1 char // whose ASCII is 0. // Vamos a incluir este sufijo, tal que el decodificador sepa // cuando el mensaje embedido termina. Este consiste de 1 caracter // cuyo ASCII es 0. binMsg.append(2*bitsPerLetter,'0'); //for each pixel in image //por cada pixel. for(int i = 0; i < origImage.width(); i++) { for(int j = 0; j