예제 #1
0
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
	ISeqOutStream *outStream, ISeqInStream *inStream,
	const CXzProps *props, ICompressProgress *progress)
{
	xz->flags = (Byte)props->checkId;

	RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props));
	RINOK(Xz_WriteHeader(xz->flags, outStream));

	{
	CSeqCheckInStream checkInStream;
	CSeqSizeOutStream seqSizeOutStream;
	CXzBlock block;
	int filterIndex = 0;
	CXzFilter *filter = NULL;
	const CXzFilterProps *fp = props->filterProps;

	XzBlock_ClearFlags(&block);
	XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0));

	if (fp)
	{
		filter = &block.filters[filterIndex++];
		filter->id = fp->id;
		filter->propsSize = 0;
		if (fp->id == XZ_ID_Delta)
		{
		filter->props[0] = (Byte)(fp->delta - 1);
		filter->propsSize = 1;
		}
		else if (fp->ipDefined)
		{
		SetUi32(filter->props, fp->ip);
		filter->propsSize = 4;
		}
	}

	{
		CXzFilter *f = &block.filters[filterIndex++];
		f->id = XZ_ID_LZMA2;
		f->propsSize = 1;
		f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2);
	}

	seqSizeOutStream.p.Write = MyWrite;
	seqSizeOutStream.realStream = outStream;
	seqSizeOutStream.processed = 0;

	RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));

	checkInStream.p.Read = SeqCheckInStream_Read;
	checkInStream.realStream = inStream;
	SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));

	if (fp)
	{
		#ifdef USE_SUBBLOCK
		if (fp->id == XZ_ID_Subblock)
		{
		lzmaf->sb.inStream = &checkInStream.p;
		RINOK(SbEncInStream_Init(&lzmaf->sb));
		}
		else
		#endif
		{
		lzmaf->filter.realStream = &checkInStream.p;
		RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
		}
	}

	{
		UInt64 packPos = seqSizeOutStream.processed;
		SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
		fp ?
		#ifdef USE_SUBBLOCK
		(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
		#endif
		&lzmaf->filter.p:
		&checkInStream.p,
		progress);
		RINOK(res);
		block.unpackSize = checkInStream.processed;
		block.packSize = seqSizeOutStream.processed - packPos;
	}

	{
		unsigned padSize = 0;
		Byte buf[128];
		while((((unsigned)block.packSize + padSize) & 3) != 0)
		buf[padSize++] = 0;
		SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
		RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
		RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc));
	}
	}
	return Xz_WriteFooter(xz, outStream);
}
예제 #2
0
static SRes Xz_Compress(CXzStream *xz,
    CLzma2WithFilters *lzmaf,
    ISeqOutStream *outStream,
    ISeqInStream *inStream,
    const CLzma2EncProps *lzma2Props,
    Bool useSubblock,
    ICompressProgress *progress)
{
  xz->flags = XZ_CHECK_CRC32;

  RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));
  RINOK(Xz_WriteHeader(xz->flags, outStream));

  {
    CSeqCheckInStream checkInStream;
    CSeqSizeOutStream seqSizeOutStream;
    CXzBlock block;
    int filterIndex = 0;
    
    XzBlock_ClearFlags(&block);
    XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));
    
    if (useSubblock)
    {
      CXzFilter *f = &block.filters[filterIndex++];
      f->id = XZ_ID_Subblock;
      f->propsSize = 0;
    }

    {
      CXzFilter *f = &block.filters[filterIndex++];
      f->id = XZ_ID_LZMA2;
      f->propsSize = 1;
      f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2);
    }

    seqSizeOutStream.p.Write = MyWrite;
    seqSizeOutStream.realStream = outStream;
    seqSizeOutStream.processed = 0;
    
    RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p));
    
    checkInStream.p.Read = SeqCheckInStream_Read;
    checkInStream.realStream = inStream;
    SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
    
    #ifdef USE_SUBBLOCK
    if (useSubblock)
    {
      lzmaf->sb.sb.inStream = &checkInStream.p;
      SubblockEnc_Init(&lzmaf->sb.sb);
    }
    #endif
    
    {
      UInt64 packPos = seqSizeOutStream.processed;
      SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
        #ifdef USE_SUBBLOCK
        useSubblock ? &lzmaf->sb.p:
        #endif
        &checkInStream.p,
        progress);
      RINOK(res);
      block.unpackSize = checkInStream.processed;
      block.packSize = seqSizeOutStream.processed - packPos;
    }

    {
      unsigned padSize = 0;
      Byte buf[128];
      while((((unsigned)block.packSize + padSize) & 3) != 0)
        buf[padSize++] = 0;
      SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
      RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
      RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc));
    }
  }
  return Xz_WriteFooter(xz, outStream);
}