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> /// Read DCT per component and return an array list of short. It fills the flat list of short with all coefficients order by Cr, Cb, Y. The list prameters are by ref. /// </summary> /// <param name="component"></param> /// <param name="jBlock"></param> /// <param name="dctFull"></param> /// <param name="dctFullDc"></param> /// <param name="dctFullAc"></param> /// <returns></returns> private static List <short[]> readDctCoeffs(EnumStegoChannel component, jvirt_array <JBLOCK>[] jBlock, List <short> dctFull, List <short> dctFullDc, List <short> dctFullAc) { var dct = new List <short[]>(); var u = 0; while (true) { int countBlocks = 0; JBLOCK[][] jblk = null; try { jblk = jBlock[(int)component].Access(u, 1); // accessing the block countBlocks = jblk[0].Length; } catch { break; } for (int i = 0; i < countBlocks; i++) { var arrTmp = new short[64]; for (int j = 0; j < 64; j++) { arrTmp[j] = jblk[0][i][j]; dctFull.Add(arrTmp[j]); // Flat list for all DC coefficients if (0 == j) { dctFullDc.Add(arrTmp[j]); } else // Flat list for all AC coefficients { dctFullAc.Add(arrTmp[j]); } } // ADD ARRAY TO LIST dct.Add(arrTmp); } ++u; } return(dct); }