private void Enc(string inputPath, string outputPath, byte[] data) { var input = new jpeg_decompress_struct(); using (var fileStream = new FileStream(inputPath, FileMode.Open)) { input.jpeg_stdio_src(fileStream); input.jpeg_read_header(false); var coefficients = input.jpeg_read_coefficients(); var channels = coefficients.Take(3).Select(JpegHelper.GetBuffer).ToArray(); Encrypt(channels, data); var output = new jpeg_compress_struct(); using (var outfile = new FileStream(outputPath, FileMode.Create)) { output.jpeg_stdio_dest(outfile); input.jpeg_copy_critical_parameters(output); output.jpeg_write_coefficients(coefficients); output.jpeg_finish_compress(); } } }
/// <summary> /// The DCT coefficients are returned in a structure where the different components are separated in 2D arrays od shorts[][]. /// The first dimension of the array contains the Blocks and the second dimension the 64 values for that block. /// </summary> /// <returns></returns> public static DCTCoefficients GetDctCoefficients(string JpegFilePath) { jpeg_decompress_struct jpds = new jpeg_decompress_struct(); FileStream fileStreamImg = new FileStream(JpegFilePath, FileMode.Open, FileAccess.Read); jpds.jpeg_stdio_src(fileStreamImg); jpds.jpeg_read_header(true); // DCT coefficients var jBlock = jpds.jpeg_read_coefficients(); // Initialize the list for all the dct var dctFull = new List <short>(); var dctFullDc = new List <short>(); var dctFullAc = new List <short>(); // Get coeffs and fill the list _dctFull List <short[]> dctCr = readDctCoeffs(EnumStegoChannel.Cr, jBlock, dctFull, dctFullDc, dctFullAc); List <short[]> dctCb = readDctCoeffs(EnumStegoChannel.Cb, jBlock, dctFull, dctFullDc, dctFullAc); List <short[]> dctY = readDctCoeffs(EnumStegoChannel.Y, jBlock, dctFull, dctFullDc, dctFullAc); // Close decompress and filestream jpds.jpeg_finish_decompress(); fileStreamImg.Close(); // Return DCT coefficients DCTCoefficients dctCoeffs = new DCTCoefficients { DctY = dctY.ToArray(), DctCb = dctCb.ToArray(), DctCr = dctCr.ToArray(), DctFull = dctFull.ToArray(), DctFullDc = dctFullDc.ToArray(), DctFullAc = dctFullAc.ToArray() }; return(dctCoeffs); }
private byte[] Dec(string inputPath, int len) { var input = new jpeg_decompress_struct(); input.jpeg_stdio_src(new FileStream(inputPath, FileMode.Open)); input.jpeg_read_header(false); var coefficients = input.jpeg_read_coefficients(); var channels = coefficients.Take(3).Select(JpegHelper.GetBuffer).ToArray(); return(Decrypt(channels, len)); }
public byte[] DecodeJpeg(string inputPath, int len) { var input = new jpeg_decompress_struct(); using (var fs = new FileStream(inputPath, FileMode.Open)) { input.jpeg_stdio_src(fs); input.jpeg_read_header(false); var coefficients = input.jpeg_read_coefficients(); var channels = coefficients.Take(3).Select(JpegHelper.GetBuffer).ToArray(); input.jpeg_finish_decompress(); return(DecodeBlocks(channels, len)); } }
public static void ApplyQuantizationTable(string JpegFilePath, EnumStegoChannel Component = EnumStegoChannel.Y, int ScaleFactor = 50, int[] QuantizationTable = null) { var jpds = new jpeg_decompress_struct(); FileStream fileStreamImg = new FileStream(JpegFilePath, FileMode.Open, FileAccess.Read); jpds.jpeg_stdio_src(fileStreamImg); jpds.jpeg_read_header(true); // DCT coefficients var jBlock = jpds.jpeg_read_coefficients(); jpds.jpeg_finish_decompress(); fileStreamImg.Close(); if (null == QuantizationTable) { switch (Component) { case EnumStegoChannel.Y: QuantizationTable = _qLuminance; break; case EnumStegoChannel.Cb: case EnumStegoChannel.Cr: QuantizationTable = _qChromiance; break; } } // Get fle info FileInfo fInfo = new FileInfo(JpegFilePath); string dir = fInfo.DirectoryName; string fNane = fInfo.Name; string stegFName = $"steg_{DateTime.Now.ToString("yyyyMMddHHmm")}_{fNane}"; string stegJpegFilePath = Path.Combine(dir, stegFName); // Compress process FileStream fileStream = File.Create(stegJpegFilePath); jpeg_compress_struct jpcs = new jpeg_compress_struct(); jpcs.jpeg_stdio_dest(fileStream); jpds.jpeg_copy_critical_parameters(jpcs); jpcs.jpeg_write_coefficients(jBlock); jpcs.jpeg_finish_compress(); fileStream.Close(); jpds.jpeg_abort_decompress(); }
/// <summary> /// For bits 0-63 only the LSB of DCT coefficients is written (it takes the full length of the bits to read). From bit 64 every DCT coefficient is written with the last 2 LSBs. /// </summary> /// <param name="jpegFilePath"></param> /// <param name="bits"></param> /// <param name="securityLevel"></param> private static void changeDctCoefficients(string jpegFilePath, BitArray bits, int securityLevel) { var jpds = new jpeg_decompress_struct(); FileStream fileStreamImg = new FileStream(jpegFilePath, FileMode.Open, FileAccess.Read); jpds.jpeg_stdio_src(fileStreamImg); jpds.jpeg_read_header(true); // DCT coefficients var jBlock = jpds.jpeg_read_coefficients(); var bitsLen = bits.Length; int currentBit = 0; bool canIterate = true; int cntAcCoeffNotZero = 0; // Write on position 0 then 1 // Start with Cr component int component = (int)EnumStegoChannel.Cr; while ((component >= 0) && canIterate) { int z = 0; while (canIterate) { int countCrRows; try { countCrRows = jBlock[component].Access(z, 1)[0].Length; } catch { break; } int i = 0; while ((i < countCrRows) && canIterate) { // Skip DC coefficients j = 0 int j = 1; while ((j < 64) && canIterate) { short currentVal = jBlock[component].Access(z, 1)[0][i][j]; // Skip bits 0 and dct according to the security level (steps) if (0 != currentVal) // Set only 1 bit for the first 64 AC coefficients { // Define the step of bits to write after 64 bits if ((0 == cntAcCoeffNotZero % securityLevel) || (currentBit < 64)) { // Get the current bit bool bit = bits[currentBit]; // Write the new value in position 0 short newVal = getNewValForComponent(currentVal, bit, 0); jBlock[component].Access(z, 1)[0][i][j] = newVal; currentBit++; canIterate = currentBit < bitsLen; // Start writing on bit 1 after 64 bits to encode the content length if (canIterate && currentBit > 64) { // Get the current bit bit = bits[currentBit]; // Write the new value in position 1 newVal = getNewValForComponent(newVal, bit, 1); jBlock[component].Access(z, 1)[0][i][j] = newVal; currentBit++; canIterate = currentBit < bitsLen; } } cntAcCoeffNotZero++; } j++; } i++; } z++; } component--; } jpds.jpeg_finish_decompress(); fileStreamImg.Close(); // Get file info FileInfo fInfo = new FileInfo(jpegFilePath); string dir = fInfo.DirectoryName; string fName = fInfo.Name; var docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); var stegJpegFilePath = $@"{docPath}\StegImageUI\steg_{DateTime.Now.ToString("yyyyMMddHHmmss")}_{fName}"; // Compress process FileStream fileStream = File.Create(stegJpegFilePath); jpeg_compress_struct jpcs = new jpeg_compress_struct(); jpcs.jpeg_stdio_dest(fileStream); jpds.jpeg_copy_critical_parameters(jpcs); jpcs.jpeg_write_coefficients(jBlock); jpcs.jpeg_finish_compress(); fileStream.Close(); jpds.jpeg_abort_decompress(); }