Ejemplo n.º 1
0
size_t HuffDecompressor::decompress(ZLInputStream &stream, char *targetBuffer, size_t compressedSize, size_t maxUncompressedSize) {
	if (compressedSize == 0 || myErrorCode == ERROR_CORRUPTED_FILE) {
		return 0;
	}
	if (targetBuffer != 0) {
		unsigned char *sourceBuffer = new unsigned char[compressedSize];
		myTargetBuffer = targetBuffer;
		myTargetBufferEnd = targetBuffer + maxUncompressedSize;
		myTargetBufferPtr = targetBuffer;
		if (stream.read((char*)sourceBuffer, compressedSize) == compressedSize) {
			const size_t trailSize = sizeOfTrailingEntries(sourceBuffer, compressedSize);
			if (trailSize < compressedSize) {
				bitsDecompress(BitReader(sourceBuffer, compressedSize - trailSize));
			} else {
				myErrorCode = ERROR_CORRUPTED_FILE;
			}
		}
		delete[] sourceBuffer;
	} else {
		myTargetBuffer = 0;
		myTargetBufferEnd = 0;
		myTargetBufferPtr = 0;
	}

	return myTargetBufferPtr - myTargetBuffer;
}
Ejemplo n.º 2
0
void HuffDecompressor::bitsDecompress(BitReader bits, size_t depth) {
	if (depth > 32) {
		myErrorCode = ERROR_CORRUPTED_FILE;
		return;
	}

	while (bits.left()) {
		const unsigned long dw = (unsigned long)bits.peek(32);
		const unsigned long v = myCacheTable[dw >> 24];
		unsigned long codelen = v & 0x1F;
		//if ((codelen == 0) || (codelen > 32)) {
		//	return false;
		//}
		unsigned long code = dw >> (32 - codelen);
		unsigned long r = (v >> 8);
		if ((v & 0x80) == 0) {
			while (code < myBaseTable[(codelen - 1) * 2]) {
				codelen += 1;
				code = dw >> (32 - codelen);
			}
			r = myBaseTable[(codelen - 1) * 2 + 1];
		}
		r -= code;
		//if (codelen == 0) {
		//	return false;
		//}
		if (!bits.eat(codelen)) {
			return;
		}
		const unsigned long dicno = r >> myEntryBits;
		const unsigned long off1 = 16 + (r - (dicno << myEntryBits)) * 2;
		const unsigned char* dict = myDicts[dicno];							//TODO need index check
		const unsigned long off2 = 16 + dict[off1] * 256 + dict[off1 + 1];	//TODO need index check
		const unsigned long blen = dict[off2] * 256 + dict[off2 + 1];		//TODO need index check
		const unsigned char* slice = dict + off2 + 2;
		const unsigned long sliceSize = blen & 0x7fff;
		if (blen & 0x8000) {
			if (myTargetBufferPtr + sliceSize < myTargetBufferEnd) {
				memcpy(myTargetBufferPtr, slice, sliceSize);
				myTargetBufferPtr += sliceSize;
			} else {
				return;
			}
		} else {
			bitsDecompress(BitReader(slice, sliceSize), depth + 1);
		}
	}
}
Ejemplo n.º 3
0
bool DtsHeaderParser::parseHeader(const uint8_t *hdr, HeaderInfo *hinfo)
{
  DtsFrameInfo dtsFi;
  int bsType;
  bool isBigEndian(true);

  if ( dtsFi.init(BitReader(hdr, 16, true)) )
      bsType = dtsFi.getIs14Bit() ? BITSTREAM_14BE : BITSTREAM_16BE;
  else if ( dtsFi.init(BitReader(hdr, 16, false)) )
  {
      bsType = dtsFi.getIs14Bit() ? BITSTREAM_14LE : BITSTREAM_16LE;
      isBigEndian = false;
  }
  else
    return false;

  /////////////////////////////////////////////////////////
  // Constraints

  if ( dtsFi.getSampleBlocks() < 6 ) // constraint
    return false;
  else if ( dtsFi.getChannelLayout() > 0xc ) // we don't work with more than 6 channels
    return false;
  else if ( dtsFi.getSampleRate() == 0 ) // constraint
    return false;
  else if ( dtsFi.getLfe() == 3 ) // constraint
    return false;

  DtsHdFrameInfo dtsHdFrameInfo(BitReader(hdr+dtsFi.getFrameSize(), 16, isBigEndian));

  if ( hinfo )
  {
    const int layout2MaskTable[] = {
      MODE_MONO,   MODE_STEREO,  MODE_STEREO,  MODE_STEREO,  MODE_STEREO,
      MODE_3_0,    MODE_2_1,     MODE_3_1,     MODE_2_2,     MODE_3_2
    };

    const int layout2RelationTable[] =
    {
      NO_RELATION,   NO_RELATION,  NO_RELATION,  RELATION_SUMDIFF, RELATION_DOLBY,
      NO_RELATION,   NO_RELATION,  NO_RELATION,  NO_RELATION,      NO_RELATION,
    };

    int mask(layout2MaskTable[dtsFi.getChannelLayout()]);
    const int relation(layout2RelationTable[dtsFi.getChannelLayout()]);

    if ( dtsFi.getLfe() )
    {
      mask |= CH_MASK_LFE;
    }

    hinfo->setSpeakers(Speakers(FORMAT_DTS, mask, dtsFi.getSampleRate(), 1.0, relation));
    hinfo->setFrameSize(dtsFi.getFrameSize() + dtsHdFrameInfo.getHdSize());
    hinfo->setDtsHdSize(dtsHdFrameInfo.getHdSize());
    hinfo->setScanSize(16384); // always scan up to maximum DTS frame size
    hinfo->setSampleCount(dtsFi.getSampleCount());
    hinfo->setBsType(bsType);

    switch ( hinfo->getSampleCount() )
    {
      case 512:
        hinfo->setSpdifType(11);
        break;
      case 1024:
        hinfo->setSpdifType(12);
        break;
      case 2048:
        hinfo->setSpdifType(13);
        break;
      default:
        hinfo->setSpdifType(0); // cannot do SPDIF passthrough
        break;
    }
  }

  return true;
}