/// <summary>
        /// Run-length decode ( RLE blocks -> zigzaged image blocks -> inverse zigzag -> origin image block )
        /// </summary>
        /// <param name="source">source data bits</param>
        /// <returns></returns>
        public List <Matrix <double> > Decode(IEnumerable <RLEBlock> source)
        {
            List <Matrix <double> > result = new List <Matrix <double> >();
            int latestDc = 0;

            foreach (RLEBlock rleBlock in source)
            {
                List <double> array = new List <double>();
                DCElement     dc    = rleBlock.DC;
                array.Add(dc.Diff + latestDc);
                latestDc = dc.Diff + latestDc;

                foreach (ACElement ac in rleBlock.ACs)
                {
                    for (int i = 0; i < ac.Length; i++)
                    {
                        array.Add(0);
                    }
                    array.Add(ac.Value);
                }

                if (array.Count < 64)
                {
                    int numOfZero = 64 - array.Count;
                    for (int i = 0; i < numOfZero; i++)
                    {
                        array.Add(0);
                    }
                }
                result.Add(ZigZagEncoder.IZigZag(array));
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Construct code word from RLE
        /// </summary>
        /// <param name="blocks"></param>
        /// <returns></returns>
        public static bool[] ConstructCodeWord(List <RLEBlock> blocks)
        {
            string codeword = string.Empty;

            foreach (RLEBlock block in blocks)
            {
                DCElement dc = block.DC;
                codeword += GetDCCodeWord(dc.Diff);
                foreach (ACElement ac in block.ACs)
                {
                    codeword += GetACCodeWord(ac.Length, ac.Value);
                }
                codeword += "1010";
            }

            return(Utility.StringToBoolArray(codeword));
        }
        /// <summary>
        /// Run-length encode , ( origin image blocks -> zigzaged image blocks -> RLE blocks )
        /// </summary>
        /// <param name="source">image blocks</param>
        /// <returns></returns>
        public List <RLEBlock> Encode(List <Matrix <double> > source)
        {
            List <RLEBlock> blocks    = new List <RLEBlock>();
            int             lastesrDC = 0;
            int             run       = 0;

            foreach (Matrix <double> matrix in source)
            {
                run = 0;
                List <double>    list = ZigZagEncoder.ZigZag(matrix);
                List <ACElement> acs  = new List <ACElement>();
                int diff = (int)list[0] - lastesrDC;
                lastesrDC = (int)list[0];
                DCElement     dc     = new DCElement(diff);
                List <double> listac = list.Skip(1).ToList();
                foreach (double data in listac)
                {
                    if (data == 0)
                    {
                        run++;
                    }
                    else
                    {
                        if (run >= 16)
                        {
                            int times = run / 16;
                            run %= 16;
                            for (int i = 0; i < times; i++)
                            {
                                acs.Add(new ACElement(15, 0));
                            }
                        }
                        acs.Add(new ACElement(run, (int)data));
                        run = 0;
                    }
                }
                blocks.Add(new RLEBlock(dc, acs));
            }

            return(blocks);
        }
Beispiel #4
0
        /// <summary>
        /// Construct RLE from code words
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List <RLEBlock> ReconstructRleBlocks(string source)
        {
            List <RLEBlock> result = new List <RLEBlock>();
            RLEBlock        block  = null;
            string          temp   = string.Empty;
            bool            isDc   = true;

            for (int i = 0; i < source.Length; i++)
            {
                // dc decode first
                if (isDc)
                {
                    if (block == null)
                    {
                        block = new RLEBlock();
                    }
                    temp += source[i];
                    string diff = string.Empty;
                    if (DcCategoryHashTable.Contains(temp))
                    {
                        int category = Convert.ToInt32(DcCategoryHashTable[temp]);
                        int nextBits = category == 0 ? 1 : category;
                        for (int j = 1; j <= nextBits; j++)
                        {
                            diff += source[i + j];
                        }

                        i += nextBits;

                        DCElement dc;
                        if (category == 0 && diff == "0")
                        {
                            dc = new DCElement(0);
                        }
                        else
                        {
                            dc = new DCElement(FindDiffValue(category, diff));
                        }

                        block.DC = dc;
                        isDc     = false;
                        temp     = string.Empty;
                    }
                }
                // then ac
                else
                {
                    temp += source[i];
                    if (AcCategoryHashTable.Contains(temp))
                    {
                        string           value   = string.Empty;
                        Tuple <int, int> runSize = (Tuple <int, int>)AcCategoryHashTable[temp];

                        if (runSize.Item1 == 0 && runSize.Item2 == 0)
                        {
                            isDc = true;
                            result.Add(block);
                            temp  = string.Empty;
                            block = null;
                            continue;
                        }

                        int category = runSize.Item2;
                        int nextBits = category == 0 ? 1 : category;
                        for (int j = 1; j <= nextBits; j++)
                        {
                            value += source[i + j];
                        }

                        i += nextBits;

                        ACElement ac = new ACElement(runSize.Item1, FindDiffValue(runSize.Item2, value));
                        block.ACs.Add(ac);
                        temp = string.Empty;
                    }
                }
            }

            return(result);
        }
 public RLEBlock(DCElement dc, List <ACElement> acs)
 {
     DC  = dc;
     ACs = acs;
 }