My problem is as follows :
My problem is that even after doing LSB replacement after the quantization step I still get errors and changes on the detection side. for strings, letters get changed but for bitmaps the image isn't readable as deduced from getting "Parameters no valid". I've tried a lot of debugging and I just can't figure it out.
My goal is pretty simple, insert a set of bits (before string or Bitmap) into a JPEG image, save it and be able to detect and extract said set of bits to its original form. I've been successful with BMP and PNG as there is no compression there, but JPEG is another story. Btw I'm doing LSB replacement.
I understand what I need to do, apply the LSB replacement after the DCT coefficients have been quantized. For that purpose I have been using a JPEG Encoder and modified what I needed in the appropriate spot.
I modified the method EncodeImageBufferToJpg
to convert a string or bitmap into a bit array (int[]) and then do LSB replacement to one Coefficient per block for each channel Y, Cb, Cr.
This here is my modified method for EncodeImageBufferToJpg
, plus the Detection+Process method I use to reconstruct the message: Link Here.
For the Y channel for example :
In encoding :
Int16[] DCT_Quant_Y = Do_FDCT_Quantization_And_ZigZag(Y_Data, Tables.FDCT_Y_Quantization_Table); if (!StegoEncodeDone) { // We clear the LSB to 0 DCT_Quant_Y[DCIndex] -= Convert.ToInt16(DCT_Quant_Y[DCIndex] % 2); // We add the bit to the LSB DCT_Quant_Y[DCIndex] += Convert.ToInt16(MsgBits[MsgIndx]); // Ys for debug print Ys.Add(DCT_Quant_Y[DCIndex]); MsgIndx++; if (MsgIndx >= MsgBits.Length) StegoEncodeDone = true; } DoHuffmanEncoding(DCT_Quant_Y, ref prev_DC_Y, Tables.Y_DC_Huffman_Table, Tables.Y_AC_Huffman_Table, OutputStream);
and in detection :
Int16[] DCT_Quant_Y = Do_FDCT_Quantization_And_ZigZag(Y_Data, Tables.FDCT_Y_Quantization_Table); // SteganoDecode ********************************************* if (!StegoDecodeDone) { int Dtt = Math.Abs(DCT_Quant_Y[DCIndex] % 2); int DYY = Y_Data[DCIndex]; int DDCTYYB = DCT_Quant_Y[DCIndex]; Ys.Add(DCT_Quant_Y[DCIndex]); // Si le DCT Coefficient est negatif le % retournais un -1 mais binaire => 0,1 => positif charValue = charValue * 2 + Math.Abs(DCT_Quant_Y[DCIndex] % 2); ProcessStaganoDecode(); } // End ********************************************************* DCT_Quant_Y.CopyTo(Y, index); public void ProcessStaganoDecode() { Counter++; cc++; if (IDFound) MsgBits.Add(charValue % 2); else IDBits.Add(charValue % 2); if (Counter == 8) { // If we find a '-' we inc, else we set to 0. because they have to be 3 consecutive "---" char ccs = (char)reverseBits(charValue); if (((char)reverseBits(charValue)) == '-') { SepCounter++; } else SepCounter = 0; if (SepCounter >= 3) { if (IDFound) { MsgBits.RemoveRange(MsgBits.Count - 3 * 8, 3 * 8); StegoDecodeDone = MarqueFound = true; } else { IDFound = true; IDBits.RemoveRange(IDBits.Count - 3 * 8, 3 * 8); string ID = BitToString(IDBits); IDNum = Convert.ToInt16(BitToString(IDBits)); Console.WriteLine("ID Found : " + IDNum); } SepCounter = 0; } charValue = 0; Counter = 0; } }
All the code is in the class: BaseJPEGEncoder
.
Here's the VS 2015 C# project for you to check the rest of the classes etc. I can only put 2 links, so sorry couldn't put the original: Here. I got the original encoder from "A simple JPEG encoder in C#" at CodeProject
I've read some answers to other questions from these two people, and I would love to get their attention to give me some help if they can: Sneftel and Reti43. Couldn't find a way to contact them.