예제 #1
0
파일: rfx_rlgr.c 프로젝트: 10084462/FreeRDP
int rfx_rlgr_encode(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size)
{
	int k;
	int kp;
	int krp;
	RFX_BITSTREAM* bs;
	int processed_size;

	bs = (RFX_BITSTREAM*) malloc(sizeof(RFX_BITSTREAM));
	ZeroMemory(bs, sizeof(RFX_BITSTREAM));

	rfx_bitstream_attach(bs, buffer, buffer_size);

	/* initialize the parameters */
	k = 1;
	kp = 1 << LSGR;
	krp = 1 << LSGR;

	/* process all the input coefficients */
	while (data_size > 0)
	{
		int input;

		if (k)
		{
			int numZeros;
			int runmax;
			int mag;
			int sign;

			/* RUN-LENGTH MODE */

			/* collect the run of zeros in the input stream */
			numZeros = 0;
			GetNextInput(input);
			while (input == 0 && data_size > 0)
			{
				numZeros++;
				GetNextInput(input);
			}

			// emit output zeros
			runmax = 1 << k;
			while (numZeros >= runmax)
			{
				OutputBit(1, 0); /* output a zero bit */
				numZeros -= runmax;
				UpdateParam(kp, UP_GR, k); /* update kp, k */
				runmax = 1 << k;
			}

			/* output a 1 to terminate runs */
			OutputBit(1, 1);

			/* output the remaining run length using k bits */
			OutputBits(k, numZeros);

			/* note: when we reach here and the last byte being encoded is 0, we still
			   need to output the last two bits, otherwise mstsc will crash */

			/* encode the nonzero value using GR coding */
			mag = (input < 0 ? -input : input); /* absolute value of input coefficient */
			sign = (input < 0 ? 1 : 0);  /* sign of input coefficient */

			OutputBit(1, sign); /* output the sign bit */
			CodeGR(&krp, mag ? mag - 1 : 0); /* output GR code for (mag - 1) */

			UpdateParam(kp, -DN_GR, k);
		}
		else
		{
			/* GOLOMB-RICE MODE */

			if (mode == RLGR1)
			{
				UINT32 twoMs;

				/* RLGR1 variant */

				/* convert input to (2*magnitude - sign), encode using GR code */
				GetNextInput(input);
				twoMs = Get2MagSign(input);
				CodeGR(&krp, twoMs);

				/* update k, kp */
				/* NOTE: as of Aug 2011, the algorithm is still wrongly documented
				   and the update direction is reversed */
				if (twoMs)
				{
					UpdateParam(kp, -DQ_GR, k);
				}
				else
				{
					UpdateParam(kp, UQ_GR, k);
				}
			}
			else /* mode == RLGR3 */
			{
				UINT32 twoMs1;
				UINT32 twoMs2;
				UINT32 sum2Ms;
				UINT32 nIdx;

				/* RLGR3 variant */

				/* convert the next two input values to (2*magnitude - sign) and */
				/* encode their sum using GR code */

				GetNextInput(input);
				twoMs1 = Get2MagSign(input);
				GetNextInput(input);
				twoMs2 = Get2MagSign(input);
				sum2Ms = twoMs1 + twoMs2;

				CodeGR(&krp, sum2Ms);

				/* encode binary representation of the first input (twoMs1). */
				GetMinBits(sum2Ms, nIdx);
				OutputBits(nIdx, twoMs1);

				/* update k,kp for the two input values */

				if (twoMs1 && twoMs2)
				{
					UpdateParam(kp, -2 * DQ_GR, k);
				}
				else if (!twoMs1 && !twoMs2)
				{
					UpdateParam(kp, 2 * UQ_GR, k);
				}
			}
		}
	}

	processed_size = rfx_bitstream_get_processed_bytes(bs);
	free(bs);

	return processed_size;
}
예제 #2
0
int
rfx_rlgr1_encode(const sint16* data, int data_size, uint8* buffer, int buffer_size)
{
    int k;
    int kp;
    int krp;

    int input;
    int numZeros;
    int runmax;
    int mag;
    int sign;
    int processed_size;
    int lmag;

    RFX_BITSTREAM bs;

    uint32 twoMs;

    rfx_bitstream_attach(bs, buffer, buffer_size);

    /* initialize the parameters */
    k = 1;
    kp = 1 << LSGR;
    krp = 1 << LSGR;

    /* process all the input coefficients */
    while (data_size > 0)
    {
        if (k)
        {
            /* RUN-LENGTH MODE */

            /* collect the run of zeros in the input stream */
            numZeros = 0;
            GetNextInput(input);
            while (input == 0 && data_size > 0)
            {
                numZeros++;
                GetNextInput(input);
            }

            /* emit output zeros */
            runmax = 1 << k;
            while (numZeros >= runmax)
            {
                OutputBit(1, 0); /* output a zero bit */
                numZeros -= runmax;
                UpdateParam(kp, UP_GR, k); /* update kp, k */
                runmax = 1 << k;
            }

            /* output a 1 to terminate runs */
            OutputBit(1, 1);

            /* output the remaining run length using k bits */
            OutputBits(k, numZeros);

            /* note: when we reach here and the last byte being encoded is 0, we still
               need to output the last two bits, otherwise mstsc will crash */

            /* encode the nonzero value using GR coding */
            mag = (input < 0 ? -input : input); /* absolute value of input coefficient */
            sign = (input < 0 ? 1 : 0);  /* sign of input coefficient */

            OutputBit(1, sign); /* output the sign bit */
            lmag = mag ? mag - 1 : 0;
            CodeGR(krp, lmag); /* output GR code for (mag - 1) */

            UpdateParam(kp, -DN_GR, k);
        }
        else
        {
            /* GOLOMB-RICE MODE */

            /* RLGR1 variant */

            /* convert input to (2*magnitude - sign), encode using GR code */
            GetNextInput(input);
            twoMs = Get2MagSign(input);
            CodeGR(krp, twoMs);

            /* update k, kp */
            /* NOTE: as of Aug 2011, the algorithm is still wrongly documented
               and the update direction is reversed */
            if (twoMs)
            {
                UpdateParam(kp, -DQ_GR, k);
            }
            else
            {
                UpdateParam(kp, UQ_GR, k);
            }

        }
    }

    processed_size = rfx_bitstream_get_processed_bytes(bs);

    return processed_size;
}