示例#1
0
void CJOCh264bitstream::addexpgolombunsigned (unsigned long lval)
{
	//it implements unsigned exp golomb coding

	unsigned long lvalint = lval + 1;
	int nnumbits = log2 (lvalint) + 1;

	for (int n = 0; n < (nnumbits-1); n++)
		addbits(0,1);

	addbits(lvalint,nnumbits);
}
示例#2
0
void main() {

	char str1[] = "1100101";
	char str2[] = "101";

	printf("res is %s \n", addbits(str1, str2));
	printf("res is %s \n", addbits2(str1, str2));
}
示例#3
0
int Unpack::DecodeNumber(struct Decode *Dec)
{
	unsigned int Bits;
	unsigned int BitField=getbits() & 0xfffe;
	if (BitField<Dec->DecodeLen[8])
		if (BitField<Dec->DecodeLen[4])
			if (BitField<Dec->DecodeLen[2])
				if (BitField<Dec->DecodeLen[1])
					Bits=1;
				else
					Bits=2;
			else
				if (BitField<Dec->DecodeLen[3])
					Bits=3;
				else
					Bits=4;
		else
			if (BitField<Dec->DecodeLen[6])
				if (BitField<Dec->DecodeLen[5])
					Bits=5;
				else
					Bits=6;
			else
				if (BitField<Dec->DecodeLen[7])
					Bits=7;
				else
					Bits=8;
	else
		if (BitField<Dec->DecodeLen[12])
			if (BitField<Dec->DecodeLen[10])
				if (BitField<Dec->DecodeLen[9])
					Bits=9;
				else
					Bits=10;
			else
				if (BitField<Dec->DecodeLen[11])
					Bits=11;
				else
					Bits=12;
		else
			if (BitField<Dec->DecodeLen[14])
				if (BitField<Dec->DecodeLen[13])
					Bits=13;
				else
					Bits=14;
			else
				Bits=15;

	unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits));
	if (N>=Dec->MaxNum)
		N=0;
	// do after reading values, to allow better instruction scheduling
	addbits(Bits);
	return(Dec->DecodeNum[N]);
}
示例#4
0
_forceinline uint Unpack::DecodeNumber(DecodeTable *Dec)
{
  // Left aligned 15 bit length raw bit field.
  uint BitField=getbits() & 0xfffe;

  if (BitField<Dec->DecodeLen[Dec->QuickBits])
  {
    uint Code=BitField>>(16-Dec->QuickBits);
    addbits(Dec->QuickLen[Code]);
    return Dec->QuickNum[Code];
  }
示例#5
0
void CJOCh264bitstream::addbyte (unsigned char cByte)
{
	//Byte alignment optimization
	if ((m_nLastbitinbuffer % 8)  == 0)
	{
		addbytetostream (cByte);
	}
	else
	{
		addbits (cByte, 8);
	}
}
示例#6
0
void dcpr_comm(INT comm_size)
{
   SHORT hash[comm_cpr_hf(255, 255) + 1];
   INT  dpos = 0,
        c,
        pos,
        len,
        hs;

   memset(&hash, 0, sizeof(hash));
   if (comm_cpr_size)
   {
      dcpr_comm_init();
      len = code_rd >> (32 - 15);
      addbits(15);
      if (len >= comm_size)
         len = comm_size - 1;
      if (read_wd(maxwd_mn, dcpr_code_mn, dcpr_wd_mn, max_cd_mn))
         do
         {
            if (dpos > 1)
            {
               pos = hash[hs = comm_cpr_hf(comm[dpos - 1], comm[dpos - 2])];
               hash[hs] = dpos;
            }
            addbits(dcpr_wd_mn[(c = dcpr_code_mn[code_rd >> (32 - maxwd_mn)])]);
            if (rpos == size_rdb - 3)
               rpos = 0;
            if (c > 255)
            {
               c -= 256;
               c += 2;
               while (c--)
                  comm[dpos++] = comm[pos++];
            }
            else
            {
               comm[dpos++] = c;
            }
         }
         while (dpos < len);
      comm[len] = 0;
   }
}
示例#7
0
void decompress(void)
{
   INT  c,
        lg,
        i,
        k;
   ULONG dist;

   while (dcpr_do < dcpr_do_max)
   {
      if (!blocksize)
         if (!calc_dectabs())
            return;

      addbits(dcpr_wd_mn[(c = dcpr_code_mn[code_rd >> (32 - maxwd_mn)])]);
      blocksize--;
      if (c > 255)
      {
         if (c > 259)
         {
            if ((c -= 260) > 1)
            {
               dist = (code_rd >> (33 - c)) + (1L << (c - 1));
               addbits(c - 1);
            }
            else
               dist = c;
            dcpr_olddist[(dcpr_oldnum = (dcpr_oldnum + 1) & 3)] = dist;
            i = 2;
            if (dist > maxdis2)
            {
               i++;
               if (dist > maxdis3)
                  i++;
            }
         }
         else
         {
//Creates and saves the NAL SLICE (one per frame)
void CJOCh264encoder::create_slice_header(unsigned long lFrameNum)
{
	add4bytesnoemulationprevention (0x000001); // NAL header
	addbits (0x0,1); // forbidden_bit
	addbits (0x3,2); // nal_ref_idc
	addbits (0x5,5); // nal_unit_type : 5 ( Coded slice of an IDR picture  )
	addexpgolombunsigned(0); // first_mb_in_slice
	addexpgolombunsigned(7); // slice_type
	addexpgolombunsigned(0); // pic_param_set_id

	unsigned char cFrameNum = lFrameNum % 16; //(2⁴)
	addbits (cFrameNum,4); // frame_num ( numbits = v = log2_max_frame_num_minus4 + 4)

	unsigned long lidr_pic_id = lFrameNum % 512;
	//idr_pic_flag = 1
	addexpgolombunsigned(lidr_pic_id); // idr_pic_id
	addbits(0x0,4); // pic_order_cnt_lsb (numbits = v = log2_max_fpic_order_cnt_lsb_minus4 + 4)
	addbits(0x0,1); //no_output_of_prior_pics_flag
	addbits(0x0,1); //long_term_reference_flag
	addexpgolombsigned(0); //slice_qp_delta

	//Probably NOT byte aligned!!!
}
示例#9
0
void Unpack::Unpack20(bool Solid)
{
  static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
  static unsigned char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};
  static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
  static unsigned char DBits[]=  {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,  6,  6,  7,  7,  8,  8,   9,   9,  10,  10,  11,  11,  12,   12,   13,   13,    14,    14,   15,   15,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16};
  static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
  static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};
  unsigned int Bits;

  if (Suspended)
    UnpPtr=WrPtr;
  else
  {
    UnpInitData(Solid);
    if (!UnpReadBuf())
      return;
    if (!Solid)
      if (!ReadTables20())
        return;
    --DestUnpSize;
  }

  while (DestUnpSize>=0)
  {
    UnpPtr&=MAXWINMASK;

    if (InAddr>ReadTop-30)
      if (!UnpReadBuf())
        break;
    if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
    {
      OldUnpWriteBuf();
      if (Suspended)
        return;
    }
    if (UnpAudioBlock)
    {
      int AudioNumber=DecodeNumber(&MD[UnpCurChannel]);

      if (AudioNumber==256)
      {
        if (!ReadTables20())
          break;
        continue;
      }
      Window[UnpPtr++]=DecodeAudio(AudioNumber);
      if (++UnpCurChannel==UnpChannels)
        UnpCurChannel=0;
      --DestUnpSize;
      continue;
    }

    int Number=DecodeNumber(&LD);
    if (Number<256)
    {
      Window[UnpPtr++]=(byte)Number;
      --DestUnpSize;
      continue;
    }
    if (Number>269)
    {
      int Length=LDecode[Number-=270]+3;
      if ((Bits=LBits[Number])>0)
      {
        Length+=getbits()>>(16-Bits);
        addbits(Bits);
      }

      int DistNumber=DecodeNumber(&DD);
      unsigned int Distance=DDecode[DistNumber]+1;
      if ((Bits=DBits[DistNumber])>0)
      {
        Distance+=getbits()>>(16-Bits);
        addbits(Bits);
      }
示例#10
0
void BitInput::faddbits(int Bits)
{
	addbits(Bits);
}
示例#11
0
void Unpack::Unpack29(bool Solid)
{
	// tables moved outside function
	
	unsigned int Bits;

	FileExtracted=true;

	if (!Suspended)
	{
		UnpInitData(Solid);
		if (!UnpReadBuf())
			return;
		if ((!Solid || !TablesRead) && !ReadTables())
			return;
	}

	while (true)
	{
		UnpPtr&=MAXWINMASK;

		if (InAddr>ReadBorder)
		{
			if (!UnpReadBuf())
				break;
		}
		if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
		{
			UnpWriteBuf();
			if (WrittenFileSize>DestUnpSize)
				return;
			if (Suspended)
			{
				FileExtracted=false;
				return;
			}
		}
		if (UnpBlockType==BLOCK_PPM)
		{
			int Ch=PPM.DecodeChar();
			if (Ch==-1)
			{
				PPM.CleanUp();

				// turn off PPM compression mode in case of error, so UnRAR will
				// call PPM.DecodeInit in case it needs to turn it on back later.
				UnpBlockType=BLOCK_LZ;
				break;
			}
			if (Ch==PPMEscChar)
			{
				int NextCh=PPM.DecodeChar();
				if (NextCh==0)
				{
					if (!ReadTables())
						break;
					continue;
				}
				if (NextCh==2 || NextCh==-1)
					break;
				if (NextCh==3)
				{
					if (!ReadVMCodePPM())
						break;
					continue;
				}
				if (NextCh==4)
				{
					unsigned int Distance=0,Length;
					Length = 0; // avoids warning
					bool Failed=false;
					for (int I=0;I<4 && !Failed;I++)
					{
						int Ch=PPM.DecodeChar();
						if (Ch==-1)
							Failed=true;
						else
							if (I==3)
								Length=(byte)Ch;
							else
								Distance=(Distance<<8)+(byte)Ch;
					}
					if (Failed)
						break;

#ifdef _MSC_VER
	// avoid a warning about uninitialized 'Length' variable
	#pragma warning( disable : 4701 )
#endif
					CopyString(Length+32,Distance+2);
					continue;
				}
				if (NextCh==5)
				{
					int Length=PPM.DecodeChar();
					if (Length==-1)
						break;
					CopyString(Length+4,1);
					continue;
				}
			}
			Window[UnpPtr++]=Ch;
			continue;
		}

		int Number=DecodeNumber((struct Decode *)&LD);
		if (Number<256)
		{
			Window[UnpPtr++]=(byte)Number;
			continue;
		}
		if (Number>=271)
		{
			int Length=LDecode[Number-=271]+3;
			if ((Bits=LBits[Number])>0)
			{
				Length+=getbits()>>(16-Bits);
				addbits(Bits);
			}

			int DistNumber=DecodeNumber((struct Decode *)&DD);
			unsigned int Distance=DDecode[DistNumber]+1;
			if ((Bits=DBits[DistNumber])>0)
			{
				if (DistNumber>9)
				{
					if (Bits>4)
					{
						Distance+=((getbits()>>(20-Bits))<<4);
						addbits(Bits-4);
					}
					if (LowDistRepCount>0)
					{
						LowDistRepCount--;
						Distance+=PrevLowDist;
					}
					else
					{
						int LowDist=DecodeNumber((struct Decode *)&LDD);
						if (LowDist==16)
						{
							LowDistRepCount=LOW_DIST_REP_COUNT-1;
							Distance+=PrevLowDist;
						}
						else
						{
							Distance+=LowDist;
							PrevLowDist=LowDist;
						}
					}
				}
				else
				{
//Creates and saves the NAL SPS (including VUI) (one per file)
void CJOCh264encoder::create_sps (int nImW, int nImH, int nMbW, int nMbH, int nFps, int nSARw, int nSARh)
{
	add4bytesnoemulationprevention (0x000001); // NAL header
	addbits (0x0,1); // forbidden_bit
	addbits (0x3,2); // nal_ref_idc
	addbits (0x7,5); // nal_unit_type : 7 ( SPS )
	addbits (0x42,8); // profile_idc = baseline ( 0x42 )
	addbits (0x0,1); // constraint_set0_flag
	addbits (0x0,1); // constraint_set1_flag
	addbits (0x0,1); // constraint_set2_flag
	addbits (0x0,1); // constraint_set3_flag
	addbits (0x0,1); // constraint_set4_flag
	addbits (0x0,1); // constraint_set5_flag
	addbits (0x0,2); // reserved_zero_2bits /* equal to 0 */
	addbits (0x0a,8); // level_idc: 3.1 (0x0a)
	addexpgolombunsigned(0); // seq_parameter_set_id
	addexpgolombunsigned(0); // log2_max_frame_num_minus4
	addexpgolombunsigned(0); // pic_order_cnt_type
	addexpgolombunsigned(0); // log2_max_pic_order_cnt_lsb_minus4
	addexpgolombunsigned(0); // max_num_refs_frames
	addbits(0x0,1); // gaps_in_frame_num_value_allowed_flag

	int nWinMbs = nImW / nMbW;
	addexpgolombunsigned(nWinMbs-1); // pic_width_in_mbs_minus_1
	int nHinMbs = nImH / nMbH;
	addexpgolombunsigned(nHinMbs-1); // pic_height_in_map_units_minus_1

	addbits(0x1,1); // frame_mbs_only_flag
	addbits(0x0,1); // direct_8x8_interfernce
	addbits(0x0,1); // frame_cropping_flag
	addbits(0x1,1); // vui_parameter_present

	//VUI parameters (AR, timming)
	addbits(0x1,1); //aspect_ratio_info_present_flag
	addbits(0xFF,8); //aspect_ratio_idc = Extended_SAR

	//AR
	addbits(nSARw, 16); //sar_width
	addbits(nSARh, 16); //sar_height

	addbits(0x0,1); //overscan_info_present_flag
	addbits(0x0,1); //video_signal_type_present_flag
	addbits(0x0,1); //chroma_loc_info_present_flag
	addbits(0x1,1); //timing_info_present_flag

	unsigned int nnum_units_in_tick = TIME_SCALE_IN_HZ / (2*nFps);
	addbits(nnum_units_in_tick,32); //num_units_in_tick
	addbits(TIME_SCALE_IN_HZ,32); //time_scale
	addbits(0x1,1);  //fixed_frame_rate_flag

	addbits(0x0,1);  //nal_hrd_parameters_present_flag
	addbits(0x0,1);  //vcl_hrd_parameters_present_flag
	addbits(0x0,1);  //pic_struct_present_flag
	addbits(0x0,1);  //bitstream_restriction_flag
	//END VUI

	addbits(0x0,1); // frame_mbs_only_flag
	addbits(0x1,1); // rbsp stop bit

	dobytealign();
}
//Creates and saves the SLICE footer (one per SLICE)
void CJOCh264encoder::create_slice_footer()
{
	addbits(0x1,1); // rbsp stop bit
}
//Creates and saves the NAL PPS (one per file)
void CJOCh264encoder::create_pps ()
{
	add4bytesnoemulationprevention (0x000001); // NAL header
	addbits (0x0,1); // forbidden_bit
	addbits (0x3,2); // nal_ref_idc
	addbits (0x8,5); // nal_unit_type : 8 ( PPS )
	addexpgolombunsigned(0); // pic_parameter_set_id
	addexpgolombunsigned(0); // seq_parameter_set_id
	addbits (0x0,1); // entropy_coding_mode_flag
	addbits (0x0,1); // bottom_field_pic_order_in frame_present_flag
	addexpgolombunsigned(0); // nun_slices_groups_minus1
	addexpgolombunsigned(0); // num_ref_idx10_default_active_minus
	addexpgolombunsigned(0); // num_ref_idx11_default_active_minus
	addbits (0x0,1); // weighted_pred_flag
	addbits (0x0,2); // weighted_bipred_idc
	addexpgolombsigned(0); // pic_init_qp_minus26
	addexpgolombsigned(0); // pic_init_qs_minus26
	addexpgolombsigned(0); // chroma_qp_index_offset
	addbits (0x0,1); //deblocking_filter_present_flag
	addbits (0x0,1); // constrained_intra_pred_flag
	addbits (0x0,1); //redundant_pic_ent_present_flag
	addbits(0x1,1); // rbsp stop bit

	dobytealign();
}
示例#15
0
文件: unpack.cpp 项目: djondjoe/xbmc
void Unpack::Unpack29(bool Solid)
{
  static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
  static unsigned char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};
  static int DDecode[DC];
  static byte DBits[DC];
  static unsigned int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
  static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
  static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};
  unsigned int Bits;

  if (DDecode[1]==0)
  {
    int Dist=0,BitLength=0,Slot=0;
    for (unsigned int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
      for (unsigned int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
      {
        DDecode[Slot]=Dist;
        DBits[Slot]=BitLength;
      }
  }

  FileExtracted=true;

  if (!Suspended)
  {
    UnpInitData(Solid);
    if (!UnpReadBuf())
      return;
    if (!TablesRead)
      if (!ReadTables())
        return;
//    if (!TablesRead && Solid)
  //    if (!ReadTables())
  //      return;
    //if ((!Solid || !TablesRead) && !ReadTables())
    //  return;
  }

  if (PPMError)
    return;

  while (true)
  {
    if (UnpIO->bQuit) 
    {
      FileExtracted=false;
      return;
    }

    UnpPtr&=MAXWINMASK;

    if (InAddr>ReadBorder)
    {
      if (!UnpReadBuf())
        break;
    }
    if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
    {
      UnpWriteBuf();
      if (WrittenFileSize>DestUnpSize)
        return;
      if (Suspended)
      {
        FileExtracted=false;
        return;
      }
    }
    if (UnpBlockType==BLOCK_PPM)
    {
      int Ch=PPM.DecodeChar();
      if (Ch==-1)
      {
        PPMError=true;
        break;
      }
      if (Ch==PPMEscChar)
      {
        int NextCh=PPM.DecodeChar();
        if (NextCh==0)
        {
          if (!ReadTables())
            break;
          continue;
        }
        if (NextCh==2 || NextCh==-1)
          break;
        if (NextCh==3)
        {
          if (!ReadVMCodePPM())
            break;
          continue;
        }
        if (NextCh==4)
        {
          unsigned int Distance=0,Length=0;
          bool Failed=false;
          for (int I=0;I<4 && !Failed;I++)
          {
            int Ch=PPM.DecodeChar();
            if (Ch==-1)
              Failed=true;
            else
              if (I==3)
                Length=(byte)Ch;
              else
                Distance=(Distance<<8)+(byte)Ch;
          }
          if (Failed)
            break;
          CopyString(Length+32,Distance+2);
          continue;
        }
        if (NextCh==5)
        {
          int Length=PPM.DecodeChar();
          if (Length==-1)
            break;
          CopyString(Length+4,1);
          continue;
        }
      }
      Window[UnpPtr++]=Ch;
      continue;
    }

    int Number=DecodeNumber((struct Decode *)&LD);
    if (Number<256)
    {
      Window[UnpPtr++]=(byte)Number;
      continue;
    }
    if (Number>=271)
    {
      int Length=LDecode[Number-=271]+3;
      if ((Bits=LBits[Number])>0)
      {
        Length+=getbits()>>(16-Bits);
        addbits(Bits);
      }

      int DistNumber=DecodeNumber((struct Decode *)&DD);
      unsigned int Distance=DDecode[DistNumber]+1;
      if ((Bits=DBits[DistNumber])>0)
      {
        if (DistNumber>9)
        {
          if (Bits>4)
          {
            Distance+=((getbits()>>(20-Bits))<<4);
            addbits(Bits-4);
          }
          if (LowDistRepCount>0)
          {
            LowDistRepCount--;
            Distance+=PrevLowDist;
          }
          else
          {
            int LowDist=DecodeNumber((struct Decode *)&LDD);
            if (LowDist==16)
            {
              LowDistRepCount=LOW_DIST_REP_COUNT-1;
              Distance+=PrevLowDist;
            }
            else
            {
              Distance+=LowDist;
              PrevLowDist=LowDist;
            }
          }
        }
        else
        {
示例#16
0
void BitInput::faddbits(uint Bits)
{
    // Function wrapped version of inline addbits to save code size.
    addbits(Bits);
}
示例#17
0
void Unpack::Unpack29(bool Solid)
{
  static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
  static unsigned char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};
  static int DDecode[DC];
  static byte DBits[DC];
  static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
  static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
  static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};
  unsigned int Bits;

  if (DDecode[1]==0)
  {
    int Dist=0,BitLength=0,Slot=0;
    for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
      for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
      {
        DDecode[Slot]=Dist;
        DBits[Slot]=BitLength;
      }
  }

  FileExtracted=true;

  if (!Suspended)
  {
    UnpInitData(Solid);
    if (!UnpReadBuf())
      return;
    if ((!Solid || !TablesRead) && !ReadTables())
      return;
  }

  while (true)
  {
    UnpPtr&=MAXWINMASK;

    if (InAddr>ReadBorder)
    {
      if (!UnpReadBuf())
        break;
    }
    if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
    {
      UnpWriteBuf();
      if (WrittenFileSize>DestUnpSize)
        return;
      if (Suspended)
      {
        FileExtracted=false;
        return;
      }
    }
    if (UnpBlockType==BLOCK_PPM)
    {
      // Here speed is critical, so we do not use SafePPMDecodeChar,
      // because sometimes even the inline function can introduce
      // some additional penalty.
      int Ch=PPM.DecodeChar();
      if (Ch==-1)              // Corrupt PPM data found.
      {
        PPM.CleanUp();         // Reset possibly corrupt PPM data structures.
        UnpBlockType=BLOCK_LZ; // Set faster and more fail proof LZ mode.
        break;
      }
      if (Ch==PPMEscChar)
      {
        int NextCh=SafePPMDecodeChar();
        if (NextCh==0)  // End of PPM encoding.
        {
          if (!ReadTables())
            break;
          continue;
        }
        if (NextCh==-1) // Corrupt PPM data found.
          break;
        if (NextCh==2)  // End of file in PPM mode..
          break;
        if (NextCh==3)  // Read VM code.
        {
          if (!ReadVMCodePPM())
            break;
          continue;
        }
        if (NextCh==4) // LZ inside of PPM.
        {
          unsigned int Distance=0,Length;
          bool Failed=false;
          for (int I=0;I<4 && !Failed;I++)
          {
            int Ch=SafePPMDecodeChar();
            if (Ch==-1)
              Failed=true;
            else
              if (I==3)
                Length=(byte)Ch;
              else
                Distance=(Distance<<8)+(byte)Ch;
          }
          if (Failed)
            break;

          CopyString(Length+32,Distance+2);
          continue;
        }
        if (NextCh==5) // One byte distance match (RLE) inside of PPM.
        {
          int Length=SafePPMDecodeChar();
          if (Length==-1)
            break;
          CopyString(Length+4,1);
          continue;
        }
        // If we are here, NextCh must be 1, what means that current byte
        // is equal to our 'escape' byte, so we just store it to Window.
      }
      Window[UnpPtr++]=Ch;
      continue;
    }

    int Number=DecodeNumber((struct Decode *)&LD);
    if (Number<256)
    {
      Window[UnpPtr++]=(byte)Number;
      continue;
    }
    if (Number>=271)
    {
      int Length=LDecode[Number-=271]+3;
      if ((Bits=LBits[Number])>0)
      {
        Length+=getbits()>>(16-Bits);
        addbits(Bits);
      }

      int DistNumber=DecodeNumber((struct Decode *)&DD);
      unsigned int Distance=DDecode[DistNumber]+1;
      if ((Bits=DBits[DistNumber])>0)
      {
        if (DistNumber>9)
        {
          if (Bits>4)
          {
            Distance+=((getbits()>>(20-Bits))<<4);
            addbits(Bits-4);
          }
          if (LowDistRepCount>0)
          {
            LowDistRepCount--;
            Distance+=PrevLowDist;
          }
          else
          {
            int LowDist=DecodeNumber((struct Decode *)&LDD);
            if (LowDist==16)
            {
              LowDistRepCount=LOW_DIST_REP_COUNT-1;
              Distance+=PrevLowDist;
            }
            else
            {
              Distance+=LowDist;
              PrevLowDist=LowDist;
            }
          }
        }
        else
        {