コード例 #1
0
ファイル: Squeeze.cs プロジェクト: Tisit/zopfli-csharp
 static void ZopfliCopyLZ77Store(
     ZopfliLZ77Store source, ZopfliLZ77Store dest)
 {
     dest.ResetStore(source.data);
     dest.litlens   = new List <ushort>(source.litlens);
     dest.ll_counts = new List <ulong>(source.ll_counts);
     dest.d_counts  = new List <ulong>(source.d_counts);
     dest.ll_symbol = new List <ushort>(source.ll_symbol);
     dest.d_symbol  = new List <ushort>(source.d_symbol);
     dest.pos       = new List <ulong>(source.pos);
     dest.dists     = new List <ushort>(source.dists);
     dest.size      = source.size;
 }
コード例 #2
0
ファイル: Squeeze.cs プロジェクト: Tisit/zopfli-csharp
        static void ZopfliLZ77Optimal(ZopfliBlockState s,
                                      byte[] InFile, int instart, int inend,
                                      int numiterations,
                                      ZopfliLZ77Store store)
        {
            /* Dist to get to here with smallest cost. */
            int blocksize = inend - instart;

            ushort[]        length_array = new ushort[blocksize + 1];
            List <ushort>   path         = new List <ushort>();
            ZopfliLZ77Store currentstore = new ZopfliLZ77Store(InFile);
            ZopfliHash      h            = new ZopfliHash();
            SymbolStats     stats        = new SymbolStats();
            SymbolStats     beststats    = new SymbolStats();
            SymbolStats     laststats    = new SymbolStats();
            int             i;

            float[] costs = new float [blocksize + 1];
            double  cost;
            double  bestcost = ZOPFLI_LARGE_FLOAT;
            double  lastcost = 0;
            /* Try randomizing the costs a bit once the size stabilizes. */
            RanState ran_state      = new RanState();
            int      lastrandomstep = -1;

            /* Do regular deflate, then loop multiple shortest path runs, each time using
             * the statistics of the previous run. */

            /* Initial run. */
            ZopfliLZ77Greedy(s, InFile, instart, inend, currentstore, h);
            GetStatistics(currentstore, stats);

            /* Repeat statistics with each time the cost model from the previous stat
             * run. */
            for (i = 0; i < numiterations; i++)
            {
                currentstore.ResetStore(InFile);
                LZ77OptimalRun(s, InFile, instart, inend, path, length_array, stats,
                               currentstore, h, costs, false);
                cost = ZopfliCalculateBlockSize(currentstore, 0, currentstore.size, 2);
                if (Globals.verbose_more > 0 || (Globals.verbose > 0 && cost < bestcost))
                {
                    Console.WriteLine("Iteration " + i + ": " + cost + " bit");
                }
                if (cost < bestcost)
                {
                    /* Copy to the output store. */
                    ZopfliCopyLZ77Store(currentstore, store);
                    CopyStats(stats, ref beststats);
                    bestcost = cost;
                }
                CopyStats(stats, ref laststats);
                ClearStatFreqs(stats);
                GetStatistics(currentstore, stats);
                if (lastrandomstep != -1)
                {
                    /* This makes it converge slower but better. Do it only once the
                     * randomness kicks in so that if the user does few iterations, it gives a
                     * better result sooner. */
                    AddWeighedStatFreqs(stats, 1.0, laststats, 0.5, stats);
                    stats.CalculateStatistics();
                }
                if (i > 5 && cost == lastcost)
                {
                    CopyStats(beststats, ref stats);
                    RandomizeStatFreqs(ran_state, stats);
                    stats.CalculateStatistics();
                    lastrandomstep = i;
                }
                lastcost = cost;
            }
        }