I'm trying to hide a message in a PPM file, (p6). Awfully I just XOR'd my message with the red pixels. This worked, but left a very noticeable change to the image. I know a better way would be to use a bit mask, or just shift changing each LSB bit to a 1 or 0 if needed. I'm having trouble doing this in C.
my data structs...
typedef struct {
unsigned char red,green,blue;
} PPMPixel;
typedef struct {
int x, y;
PPMPixel *data;
} PPMImage;
and my embed function...
unsigned char * embBits(PPMImage *img, int messageLen, unsigned char*msgOne, unsigned char *encMsg)
{
int count = 0;
unsigned char eMsg[messageLen];
unsigned char bit;
for(int j = 0; j < messageLen; j++)
{
//bit = msgOne[j];
img->data[count].red = msgOne[j] ^ img->data[count].red;
// img->data[count].green = msgOne[j+1] ^ img->data[count].green;
// img->data[count].blue = msgOne[j+2] ^ img->data[count].blue;
eMsg[j] = img->data[count].red;
count++;
/*
// was thinking to look at each bit in RED / GREEN / BLUE
// 1. start at 100000 and go down to 000001
// 2. leave values that are the same / flip values that are different
for(int k=7; 0 < k; k--)
{
// bit & ( 1 << k);
}
*/
}
return encMsg = eMsg;
}
I know I need to just flip the LSB if they don't match, but I'm having a rough time thinking of how to do this in C. At first I was thinking about taking the first character stream - converting it to hex, converting that to binary, then taking the first bit and masking it into the red pixel, the 2nd bit with the green pixel and so forth. I know an easier solution exists with just a simple shift and bitwise &, but I've yet to figure out. Thanks for any help.
UPDATED:::: I haven't been able to test this yet, but I think this works by just looking at it. I'm going to just have to update my output of the function to catch the new values of what I'm changing.
unsigned char * embBits(PPMImage *img, int messageLen, unsigned char*msgOne, unsigned char *encMsg)
{
int count = 0;
unsigned char eMsg[messageLen];
unsigned char byte;
unsigned char mask;
unsigned char flipOne = 0x01;
unsigned char flipZero = 0x00;
for(int j = 0; j < messageLen; j++)
{
byte = msgOne[j];
mask = 0x80;
for(int k=7; 0 < k; k--)
{
byte = byte & mask;
if(byte == 0)
{
//red
if (mask == 0x80 || mask == 0x10 || mask == 0x02)
{
//check LSB and FLIP
img->data[count].red = img->data[count].red & flipZero;
}
//green
if (mask == 0x40 || mask == 0x08 || mask == 0x01)
{
//check LSB and FLIP
img->data[count].green = img->data[count].green & flipZero;
}
//blue
if (mask == 0x20 || mask == 0x03)
{
//check
LSB and FLIP
img->data[count].blue = img->data[count].blue & flipZero;
}
}
else
{
//flip bit
//red
if (mask == 0x80 || mask == 0x10 || mask == 0x02)
{
//check LSB and FLIP
img->data[count].red = img->data[count].red & flipOne;
}
//green
if (mask == 0x40 || mask == 0x08 || mask == 0x01)
{
//check LSB and FLIP
img->data[count].green = img->data[count].green & flipOne;
}
//blue
if (mask == 0x20 || mask == 0x03)
{
//check LSB and FLIP
img->data[count].blue = img->data[count].blue & flipOne;
}
}
mask = mask >> 1;
count++;
}
}
return encMsg = eMsg;
}