Esempio n. 1
0
        private static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
        {
            CPpmd_State tmp = *t1;

            *t1 = *t2;
            *t2 = tmp;
        }
Esempio n. 2
0
        private static void RestartModel(CPpmd7 p)
        {
            uint i, k, m;

            //memset(p.FreeList, 0, sizeof(p.FreeList));
            for (i = 0; i < p.FreeList.Length; i++)
            {
                p.FreeList[i] = default(CPpmd_Void_Ref);
            }

            p.Text      = p.Base + p.AlignOffset;
            p.HiUnit    = p.Text + p.Size;
            p.LoUnit    = p.UnitsStart = p.HiUnit - p.Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
            p.GlueCount = 0;

            p.OrderFall   = p.MaxOrder;
            p.RunLength   = p.InitRL = -(Int32)((p.MaxOrder < 12) ? p.MaxOrder : 12) - 1;
            p.PrevSuccess = 0;

            p.MinContext           = p.MaxContext = (CPpmd7_Context *)(p.HiUnit -= UNIT_SIZE); /* AllocContext(p); */
            p.MinContext->Suffix   = default(CPpmd7_Context_Ref);
            p.MinContext->NumStats = 256;
            p.MinContext->SummFreq = 256 + 1;
            p.FoundState           = (CPpmd_State *)p.LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
            p.LoUnit           += U2B(256 / 2);
            p.MinContext->Stats = REF(p, p.FoundState);
            for (i = 0; i < 256; i++)
            {
                CPpmd_State *s = &p.FoundState[i];
                s->Symbol = (byte)i;
                s->Freq   = 1;
                SetSuccessor(s, default(CPpmd_Void_Ref));
            }

            for (i = 0; i < 128; i++)
            {
                for (k = 0; k < 8; k++)
                {
                    ushort *dest = p.BinSumm[i] + k;
                    ushort  val  = (ushort)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
                    for (m = 0; m < 64; m += 8)
                    {
                        dest[m] = val;
                    }
                }
            }

            for (i = 0; i < 25; i++)
            {
                for (k = 0; k < 16; k++)
                {
                    CPpmd_See *s = &p.See[i][k];
                    s->Summ  = (ushort)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
                    s->Count = 4;
                }
            }
        }
Esempio n. 3
0
        public static void Ppmd7_Update1(CPpmd7 p)
        {
            CPpmd_State *s = p.FoundState;

            s->Freq += 4;
            p.MinContext->SummFreq += 4;
            if (s[0].Freq > s[-1].Freq)
            {
                SwapStates(&s[0], &s[-1]);
                p.FoundState = --s;
                if (s->Freq > MAX_FREQ)
                {
                    Rescale(p);
                }
            }
            NextContext(p);
        }
Esempio n. 4
0
        private static void UpdateModel(CPpmd7 p)
        {
            CPpmd_Void_Ref  successor, fSuccessor = SUCCESSOR(p.FoundState);
            CPpmd7_Context *c;
            uint            s0, ns;

            if (p.FoundState->Freq < MAX_FREQ / 4 && p.MinContext->Suffix.Value != 0)
            {
                c = SUFFIX(p, p.MinContext);

                if (c->NumStats == 1)
                {
                    CPpmd_State *s = ONE_STATE(c);
                    if (s->Freq < 32)
                    {
                        s->Freq++;
                    }
                }
                else
                {
                    CPpmd_State *s = STATS(p, c);
                    if (s->Symbol != p.FoundState->Symbol)
                    {
                        do
                        {
                            s++;
                        } while (s->Symbol != p.FoundState->Symbol);
                        if (s[0].Freq >= s[-1].Freq)
                        {
                            SwapStates(&s[0], &s[-1]);
                            s--;
                        }
                    }
                    if (s->Freq < MAX_FREQ - 9)
                    {
                        s->Freq     += 2;
                        c->SummFreq += 2;
                    }
                }
            }

            if (p.OrderFall == 0)
            {
                p.MinContext = p.MaxContext = CreateSuccessors(p, true);
                if (p.MinContext == null)
                {
                    RestartModel(p);
                    return;
                }
                SetSuccessor(p.FoundState, REF(p, p.MinContext));
                return;
            }

            *p.Text++ = p.FoundState->Symbol;
            successor = REF(p, p.Text);
            if (p.Text >= p.UnitsStart)
            {
                RestartModel(p);
                return;
            }

            if (fSuccessor.Value != 0)
            {
                if (fSuccessor.Value <= successor.Value)
                {
                    CPpmd7_Context *cs = CreateSuccessors(p, false);
                    if (cs == null)
                    {
                        RestartModel(p);
                        return;
                    }
                    fSuccessor = REF(p, cs);
                }
                if (--p.OrderFall == 0)
                {
                    successor = fSuccessor;
                    p.Text   -= (p.MaxContext != p.MinContext) ? 1 : 0;
                }
            }
            else
            {
                SetSuccessor(p.FoundState, successor);
                fSuccessor = REF(p, p.MinContext);
            }

            s0 = p.MinContext->SummFreq - (ns = p.MinContext->NumStats) - (p.FoundState->Freq - 1u);

            for (c = p.MaxContext; c != p.MinContext; c = SUFFIX(p, c))
            {
                uint ns1;
                uint cf, sf;
                if ((ns1 = c->NumStats) != 1)
                {
                    if ((ns1 & 1) == 0)
                    {
                        /* Expand for one UNIT */
                        uint oldNU = ns1 >> 1;
                        uint i     = U2I(p, oldNU);
                        if (i != U2I(p, oldNU + 1))
                        {
                            void *ptr = AllocUnits(p, i + 1);
                            void *oldPtr;
                            if (ptr == null)
                            {
                                RestartModel(p);
                                return;
                            }
                            oldPtr = STATS(p, c);
                            MyMem12Cpy(ptr, oldPtr, oldNU);
                            InsertNode(p, oldPtr, i);
                            c->Stats = STATS_REF(p, ptr);
                        }
                    }
                    c->SummFreq = (ushort)(c->SummFreq + (2 * ns1 < ns ? 1u : 0u) + 2 * ((4 * ns1 <= ns ? 1u : 0u) & (c->SummFreq <= 8 * ns1 ? 1u : 0u)));
                }
                else
                {
                    CPpmd_State *s = (CPpmd_State *)AllocUnits(p, 0);
                    if (s == null)
                    {
                        RestartModel(p);
                        return;
                    }
                    *s = *ONE_STATE(c);
                    c->Stats = REF(p, s);
                    if (s->Freq < MAX_FREQ / 4 - 1)
                    {
                        s->Freq <<= 1;
                    }
                    else
                    {
                        s->Freq = MAX_FREQ - 4;
                    }
                    c->SummFreq = (ushort)(s->Freq + p.InitEsc + (ns > 3 ? 1u : 0u));
                }
                cf = 2 * (uint)p.FoundState->Freq * (c->SummFreq + 6u);
                sf = (uint)s0 + c->SummFreq;
                if (cf < 6 * sf)
                {
                    cf           = 1 + (cf > sf ? 1u : 0u) + (cf >= 4 * sf ? 1u : 0u);
                    c->SummFreq += 3;
                }
                else
                {
                    cf          = 4 + (cf >= 9 * sf ? 1u : 0u) + (cf >= 12 * sf ? 1u : 0u) + (cf >= 15 * sf ? 1u : 0u);
                    c->SummFreq = (ushort)(c->SummFreq + cf);
                }
                {
                    CPpmd_State *s = STATS(p, c) + ns1;
                    SetSuccessor(s, successor);
                    s->Symbol   = p.FoundState->Symbol;
                    s->Freq     = (byte)cf;
                    c->NumStats = (ushort)(ns1 + 1);
                }
            }
            p.MaxContext = p.MinContext = CTX(p, fSuccessor);
        }
Esempio n. 5
0
        private static CPpmd7_Context *CreateSuccessors(CPpmd7 p, bool skip)
        {
            CPpmd_State     upState;
            CPpmd7_Context *c        = p.MinContext;
            CPpmd_Byte_Ref  upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p.FoundState);

            CPpmd_State *[] ps    = new CPpmd_State *[PPMD7_MAX_ORDER];
            uint            numPs = 0;

            if (!skip)
            {
                ps[numPs++] = p.FoundState;
            }

            while (c->Suffix.Value != 0)
            {
                CPpmd_Void_Ref successor;
                CPpmd_State *  s;
                c = SUFFIX(p, c);
                if (c->NumStats != 1)
                {
                    for (s = STATS(p, c); s->Symbol != p.FoundState->Symbol; s++)
                    {
                        ;
                    }
                }
                else
                {
                    s = ONE_STATE(c);
                }

                successor = SUCCESSOR(s);

                if (successor != upBranch)
                {
                    c = CTX(p, successor);
                    if (numPs == 0)
                    {
                        return(c);
                    }

                    break;
                }

                ps[numPs++] = s;
            }

            upState.Symbol = *(byte *)Ppmd7_GetPtr(p, upBranch);
            SetSuccessor(&upState, new CPpmd_Byte_Ref(upBranch.Value + 1));

            if (c->NumStats == 1)
            {
                upState.Freq = ONE_STATE(c)->Freq;
            }
            else
            {
                uint         cf, s0;
                CPpmd_State *s;
                for (s = STATS(p, c); s->Symbol != upState.Symbol; s++)
                {
                    ;
                }
                cf           = s->Freq - 1u;
                s0           = (uint)c->SummFreq - (uint)c->NumStats - cf;
                upState.Freq = (byte)(1 + ((2 * cf <= s0)
                    ? (5 * cf > s0 ? 1u : 0u)
                    : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
            }

            do
            {
                /* Create Child */
                CPpmd7_Context *c1; /* = AllocContext(p); */
                if (p.HiUnit != p.LoUnit)
                {
                    c1 = (CPpmd7_Context *)(p.HiUnit -= UNIT_SIZE);
                }
                else if (p.FreeList[0].Value != 0)
                {
                    c1 = (CPpmd7_Context *)RemoveNode(p, 0);
                }
                else
                {
                    c1 = (CPpmd7_Context *)AllocUnitsRare(p, 0);
                    if (c1 == null)
                    {
                        return(null);
                    }
                }
                c1->NumStats = 1;
                *ONE_STATE(c1) = upState;
                c1->Suffix = REF(p, c);
                SetSuccessor(ps[--numPs], REF(p, c1));
                c = c1;
            }while (numPs != 0);

            return(c);
        }
Esempio n. 6
0
 private static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
 {
     (p)->SuccessorLow  = (ushort)v.Value;
     (p)->SuccessorHigh = (ushort)(v.Value >> 16);
 }
Esempio n. 7
0
 private static CPpmd_Void_Ref SUCCESSOR(CPpmd_State *p) => new CPpmd_Void_Ref((uint)p->SuccessorLow | ((uint)p->SuccessorHigh << 16));
Esempio n. 8
0
        private static void Rescale(CPpmd7 p)
        {
            uint         i, adder, sumFreq, escFreq;
            CPpmd_State *stats = STATS(p, p.MinContext);
            CPpmd_State *s     = p.FoundState;

            {
                CPpmd_State tmp = *s;
                for (; s != stats; s--)
                {
                    s[0] = s[-1];
                }
                *s = tmp;
            }
            escFreq  = (uint)p.MinContext->SummFreq - s->Freq;
            s->Freq += 4;
            adder    = (p.OrderFall != 0) ? 1u : 0u;
            s->Freq  = (byte)((s->Freq + adder) >> 1);
            sumFreq  = s->Freq;

            i = (uint)p.MinContext->NumStats - 1;
            do
            {
                escFreq -= (++s)->Freq;
                s->Freq  = (byte)((s->Freq + adder) >> 1);
                sumFreq += s->Freq;
                if (s[0].Freq > s[-1].Freq)
                {
                    CPpmd_State *s1  = s;
                    CPpmd_State  tmp = *s1;
                    do
                    {
                        s1[0] = s1[-1];
                    }while (--s1 != stats && tmp.Freq > s1[-1].Freq);
                    *s1 = tmp;
                }
            }while (--i != 0);

            if (s->Freq == 0)
            {
                uint numStats = p.MinContext->NumStats;
                uint n0, n1;
                do
                {
                    i++;
                } while ((--s)->Freq == 0);
                escFreq += i;
                p.MinContext->NumStats = (ushort)(p.MinContext->NumStats - i);
                if (p.MinContext->NumStats == 1)
                {
                    CPpmd_State tmp = *stats;
                    do
                    {
                        tmp.Freq  = (byte)(tmp.Freq - (tmp.Freq >> 1));
                        escFreq >>= 1;
                    }while (escFreq > 1);
                    InsertNode(p, stats, U2I(p, ((numStats + 1) >> 1)));
                    *(p.FoundState = ONE_STATE(p.MinContext)) = tmp;
                    return;
                }
                n0 = (numStats + 1) >> 1;
                n1 = ((uint)p.MinContext->NumStats + 1) >> 1;
                if (n0 != n1)
                {
                    p.MinContext->Stats = STATS_REF(p, ShrinkUnits(p, stats, n0, n1));
                }
            }
            p.MinContext->SummFreq = (ushort)(sumFreq + escFreq - (escFreq >> 1));
            p.FoundState           = STATS(p, p.MinContext);
        }