예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Get the Quantization tables using reflection per component
        /// </summary>
        /// <returns></returns>
        public static short[][] GetQuantizationTables(string JpegFilePath)
        {
            FileStream             objFileStreamMegaMap = File.Create(JpegFilePath);
            jpeg_decompress_struct jpds = new jpeg_decompress_struct();
            jpeg_compress_struct   jpcs = new jpeg_compress_struct();

            jpcs.jpeg_stdio_dest(objFileStreamMegaMap);
            jpds.jpeg_copy_critical_parameters(jpcs);
            jpds.jpeg_finish_decompress();
            objFileStreamMegaMap.Close();
            JQUANT_TBL[] jpeg_quant_tables = jpcs.Quant_tbl_ptrs;
            int          qCount            = jpeg_quant_tables.Length;

            short[][]    qt        = new short[qCount][];
            BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
            int          idx       = 0;

            while (null != jpeg_quant_tables[idx])
            {
                Type      type     = jpeg_quant_tables[idx].GetType();
                object    instance = jpeg_quant_tables[idx];
                FieldInfo field    = type.GetField("quantval", bindFlags);
                qt[idx] = field.GetValue(instance) as short[];
                ++idx;
            }
            var qTables = qt.Where(tab => null != tab).ToArray();

            return(qTables);
        }
예제 #3
0
        /// <summary>
        /// Get the Huffman tables using reflection for a specific component (AC, DC)
        /// </summary>
        /// <returns></returns>
        public static HuffmanTable[] GetHuffmanTables(string JpegFilePath)
        {
            FileStream             objFileStreamMegaMap = File.Create(JpegFilePath);
            jpeg_decompress_struct jpds = new jpeg_decompress_struct();
            jpeg_compress_struct   jpcs = new jpeg_compress_struct();

            jpcs.jpeg_stdio_dest(objFileStreamMegaMap);
            jpds.jpeg_copy_critical_parameters(jpcs);
            jpds.jpeg_finish_decompress();
            objFileStreamMegaMap.Close();

            // DC Huffman tables
            JHUFF_TBL[] jpeg_dc_huffman_tables = jpcs.Dc_huff_tbl_ptrs;
            var         comp = HuffmanTable.EnumComponent.DC;
            var         htdc = getHTables(jpeg_dc_huffman_tables, comp);

            // AC Huffman tables
            JHUFF_TBL[] jpeg_ac_huffman_tables = jpcs.Ac_huff_tbl_ptrs;
            comp = HuffmanTable.EnumComponent.AC;
            var htac = getHTables(jpeg_ac_huffman_tables, comp);

            HuffmanTable[] hts = new HuffmanTable[htdc.Length + htac.Length];
            Array.Copy(htdc, hts, htdc.Length);
            Array.Copy(htac, 0, hts, htdc.Length, htac.Length);

            return(hts);
        }
예제 #4
0
        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();
        }
예제 #5
0
        /// <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();
        }