Example #1
0
        private static void NextContext(CPpmd7 p)
        {
            CPpmd7_Context *c = CTX(p, SUCCESSOR(p.FoundState));

            if (p.OrderFall == 0 && (byte *)c > p.Text)
            {
                p.MinContext = p.MaxContext = c;
            }
            else
            {
                UpdateModel(p);
            }
        }
Example #2
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);
        }
Example #3
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);
        }
Example #4
0
 private static CPpmd7_Context *SUFFIX(CPpmd7 p, CPpmd7_Context *ctx) => CTX(p, ctx->Suffix);
Example #5
0
 private static CPpmd_State *ONE_STATE(CPpmd7_Context *ctx) => Ppmd7Context_OneState(ctx);
Example #6
0
 private static CPpmd_State *STATS(CPpmd7 p, CPpmd7_Context *ctx) => Ppmd7_GetStats(p, ctx);