示例#1
0
 public static void Ppmd7_UpdateBin(CPpmd7 p)
 {
     p.FoundState->Freq = (byte)(p.FoundState->Freq + (p.FoundState->Freq < 128 ? 1 : 0));
     p.PrevSuccess      = 1;
     p.RunLength++;
     NextContext(p);
 }
示例#2
0
        private static void *RemoveNode(CPpmd7 p, uint indx)
        {
            CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p.FreeList[indx]);

            p.FreeList[indx] = *node;
            return(node);
        }
示例#3
0
        private static void *AllocUnitsRare(CPpmd7 p, uint indx)
        {
            uint  i;
            void *retVal;

            if (p.GlueCount == 0)
            {
                GlueFreeBlocks(p);
                if (p.FreeList[indx].Value != 0)
                {
                    return(RemoveNode(p, indx));
                }
            }

            i = indx;

            do
            {
                if (++i == PPMD_NUM_INDEXES)
                {
                    uint numBytes = U2B(I2U(p, indx));
                    p.GlueCount--;
                    return(((uint)(p.UnitsStart - p.Text) > numBytes) ? (p.UnitsStart -= numBytes) : null);
                }
            }while (p.FreeList[i].Value == 0);

            retVal = RemoveNode(p, i);
            SplitBlock(p, retVal, i, indx);
            return(retVal);
        }
示例#4
0
        public static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 p, uint numMasked, uint *escFreq)
        {
            CPpmd_See *see;
            uint       nonMasked = p.MinContext->NumStats - numMasked;

            if (p.MinContext->NumStats != 256)
            {
                see = p.See[p.NS2Indx[nonMasked - 1]] +
                      (nonMasked < (uint)SUFFIX(p, p.MinContext)->NumStats - p.MinContext->NumStats ? 1 : 0) +
                      2 * (p.MinContext->SummFreq < 11 * p.MinContext->NumStats ? 1 : 0) +
                      4 * (numMasked > nonMasked ? 1 : 0) +
                      p.HiBitsFlag;
                {
                    uint r = ((uint)see->Summ >> see->Shift);
                    see->Summ = (ushort)(see->Summ - r);
                    *escFreq = r + ((r == 0) ? 1u : 0u);
                }
            }
            else
            {
                see = p.DummySee;
                *escFreq = 1;
            }
            return(see);
        }
示例#5
0
 public static void Ppmd7_Init(CPpmd7 p, uint maxOrder)
 {
     p.MaxOrder = maxOrder;
     RestartModel(p);
     p.DummySee->Shift = PPMD_PERIOD_BITS;
     p.DummySee->Summ  = 0;  /* unused */
     p.DummySee->Count = 64; /* unused */
 }
示例#6
0
        public static void Ppmd7_Construct(CPpmd7 p)
        {
            uint i, k, m;

            p.Base = null;

            for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
            {
                uint step = (i >= 12 ? 4 : (i >> 2) + 1);
                do
                {
                    p.Units2Indx[k++] = (byte)i;
                } while (--step != 0);
                p.Indx2Units[i] = (byte)k;
            }

            p.NS2BSIndx[0] = (0 << 1);
            p.NS2BSIndx[1] = (1 << 1);

            //memset(p.NS2BSIndx + 2, (2 << 1), 9);
            for (i = 0; i < 9; i++)
            {
                p.NS2BSIndx[i + 2] = 2 << 1;
            }

            //memset(p.NS2BSIndx + 11, (3 << 1), 256 - 11);
            for (i = 0; i < 256 - 11; i++)
            {
                p.NS2BSIndx[i + 11] = 3 << 1;
            }

            for (i = 0; i < 3; i++)
            {
                p.NS2Indx[i] = (byte)i;
            }

            for (m = i, k = 1; i < 256; i++)
            {
                p.NS2Indx[i] = (byte)m;

                if (--k == 0)
                {
                    k = (++m) - 2;
                }
            }

            //memset(p.HB2Flag, 0, 0x40);
            for (i = 0; i < 0x40; i++)
            {
                p.HB2Flag[i] = 0;
            }

            //memset(p.HB2Flag + 0x40, 8, 0x100 - 0x40);
            for (i = 0; i < 0x100 - 0x40; i++)
            {
                p.HB2Flag[i + 0x40] = 8;
            }
        }
示例#7
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;
                }
            }
        }
示例#8
0
 public static void Ppmd7_Update2(CPpmd7 p)
 {
     p.MinContext->SummFreq += 4;
     if ((p.FoundState->Freq += 4) > MAX_FREQ)
     {
         Rescale(p);
     }
     p.RunLength = p.InitRL;
     UpdateModel(p);
 }
示例#9
0
        private static void SplitBlock(CPpmd7 p, void *ptr, uint oldIndx, uint newIndx)
        {
            uint i;
            uint nu = (uint)I2U(p, oldIndx) - (uint)I2U(p, newIndx);

            ptr = (byte *)ptr + U2B(I2U(p, newIndx));
            if (I2U(p, i = U2I(p, nu)) != nu)
            {
                uint k = I2U(p, --i);
                InsertNode(p, ((byte *)ptr) + U2B(k), nu - k - 1);
            }
            InsertNode(p, ptr, i);
        }
示例#10
0
        public static void Ppmd7_Update1_0(CPpmd7 p)
        {
            var bit = (2 * p.FoundState->Freq > p.MinContext->SummFreq) ? (byte)1 : (byte)0;

            p.PrevSuccess           = bit;
            p.RunLength            += bit;
            p.MinContext->SummFreq += 4;
            if ((p.FoundState->Freq += 4) > MAX_FREQ)
            {
                Rescale(p);
            }
            NextContext(p);
        }
示例#11
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);
            }
        }
示例#12
0
 public static bool Ppmd7_Alloc(CPpmd7 p, uint size, ISzAlloc alloc)
 {
     if (p.Base == null || p.Size != size)
     {
         Ppmd7_Free(p, alloc);
         p.AlignOffset = 4 - (size & 3);
         if ((p.Base = (byte *)alloc.Alloc(alloc, p.AlignOffset + size + UNIT_SIZE)) == null)
         {
             return(false);
         }
         p.Size = size;
     }
     return(true);
 }
示例#13
0
        private static void *AllocUnits(CPpmd7 p, uint indx)
        {
            uint numBytes;

            if (p.FreeList[indx].Value != 0)
            {
                return(RemoveNode(p, indx));
            }
            numBytes = U2B(I2U(p, indx));
            if (numBytes <= (uint)(p.HiUnit - p.LoUnit))
            {
                void *retVal = p.LoUnit;
                p.LoUnit += numBytes;
                return(retVal);
            }
            return(AllocUnitsRare(p, indx));
        }
示例#14
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);
        }
示例#15
0
        private static void *ShrinkUnits(CPpmd7 p, void *oldPtr, uint oldNU, uint newNU)
        {
            uint i0 = U2I(p, oldNU);
            uint i1 = U2I(p, newNU);

            if (i0 == i1)
            {
                return(oldPtr);
            }

            if (p.FreeList[i1].Value != 0)
            {
                void *ptr = RemoveNode(p, i1);
                MyMem12Cpy(ptr, oldPtr, newNU);
                InsertNode(p, oldPtr, i0);
                return(ptr);
            }

            SplitBlock(p, oldPtr, i0, i1);
            return(oldPtr);
        }
示例#16
0
 private static CPpmd_State *STATS(CPpmd7 p, CPpmd7_Context *ctx) => Ppmd7_GetStats(p, ctx);
示例#17
0
 private static byte I2U(CPpmd7 p, uint indx) => p.Indx2Units[indx];
示例#18
0
 private static byte U2I(CPpmd7 p, uint nu) => p.Units2Indx[nu - 1];
示例#19
0
 private static CPpmd_Void_Ref REF(CPpmd7 p, void *ptr) => new CPpmd_Void_Ref((uint)((byte *)ptr - p.Base));
示例#20
0
        private static void GlueFreeBlocks(CPpmd7 p)
        {
            CPpmd7_Node_Ref head = new CPpmd7_Node_Ref(p.AlignOffset + p.Size);
            CPpmd7_Node_Ref n    = head;
            uint            i;

            p.GlueCount = 255;

            /* create doubly-linked list of free blocks */
            for (i = 0; i < PPMD_NUM_INDEXES; i++)
            {
                ushort          nu   = I2U(p, i);
                CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p.FreeList[i];
                p.FreeList[i] = default(CPpmd_Void_Ref);
                while (next.Value != 0)
                {
                    CPpmd7_Node *node = NODE(p, next);
                    node->Next  = n;
                    n           = NODE(p, n)->Prev = next;
                    next        = *(CPpmd7_Node_Ref *)node;
                    node->Stamp = 0;
                    node->NU    = (ushort)nu;
                }
            }
            NODE(p, head)->Stamp = 1;
            NODE(p, head)->Next  = n;
            NODE(p, n)->Prev     = head;
            if (p.LoUnit != p.HiUnit)
            {
                ((CPpmd7_Node *)p.LoUnit)->Stamp = 1;
            }

            /* Glue free blocks */
            while (n != head)
            {
                CPpmd7_Node *node = NODE(p, n);
                uint         nu   = (uint)node->NU;
                for (;;)
                {
                    CPpmd7_Node *node2 = NODE(p, n) + nu;
                    nu += node2->NU;
                    if (node2->Stamp != 0 || nu >= 0x10000)
                    {
                        break;
                    }
                    NODE(p, node2->Prev)->Next = node2->Next;
                    NODE(p, node2->Next)->Prev = node2->Prev;
                    node->NU = (ushort)nu;
                }
                n = node->Next;
            }

            /* Fill lists of free blocks */
            for (n = NODE(p, head)->Next; n != head;)
            {
                CPpmd7_Node *   node = NODE(p, n);
                uint            nu;
                CPpmd7_Node_Ref next = node->Next;
                for (nu = node->NU; nu > 128; nu -= 128, node += 128)
                {
                    InsertNode(p, node, PPMD_NUM_INDEXES - 1);
                }
                if (I2U(p, i = U2I(p, nu)) != nu)
                {
                    uint k = I2U(p, --i);
                    InsertNode(p, node + k, nu - k - 1);
                }
                InsertNode(p, node, i);
                n = next;
            }
        }
示例#21
0
 private static CPpmd_State_Ref STATS_REF(CPpmd7 p, void *ptr) => REF(p, ptr);
示例#22
0
 private static void InsertNode(CPpmd7 p, void *node, uint indx)
 {
     *((CPpmd_Void_Ref *)node) = p.FreeList[indx];
     p.FreeList[indx]          = REF(p, node);
 }
示例#23
0
 private static CPpmd7_Context *CTX(CPpmd7 p, CPpmd7_Context_Ref r) => Ppmd7_GetContext(p, r);
示例#24
0
 public static void Ppmd7_Free(CPpmd7 p, ISzAlloc alloc)
 {
     alloc.Free(alloc, (IntPtr)p.Base);
     p.Size = 0;
     p.Base = null;
 }
示例#25
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);
        }
示例#26
0
 private static CPpmd7_Context *SUFFIX(CPpmd7 p, CPpmd7_Context *ctx) => CTX(p, ctx->Suffix);
示例#27
0
 private static CPpmd7_Node *NODE(CPpmd7 p, CPpmd7_Node_Ref offs) => (CPpmd7_Node *)(p.Base + offs.Value);
示例#28
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);
        }
示例#29
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);
        }