Esempio n. 1
0
////////////////////////////////////////////////////////
// Encode buffer of given size using bit plane coding.
// A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
// Following coding scheme is used: 
//		Buffer		::= <nPlanes>(5 bits) foreach(plane i): Plane[i]  
//		Plane[i]	::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
//		Sig1		::= 1 <codeLen>(15 bits) codedSigAndSignBits 
//		Sig2		::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits 
//		Sign1		::= 1 <codeLen>(15 bits) codedSignBits
//		Sign2		::= 0 <signLen>(15 bits) [DWORD alignment] signBits
void CEncoder::CMacroBlock::BitplaneEncode() {
	UINT8	nPlanes;
	UINT32	sigLen, codeLen = 0, wordPos, refLen, signLen;
	UINT32  sigBits[BufferLen] = { 0 }; 
	UINT32  refBits[BufferLen] = { 0 }; 
	UINT32  signBits[BufferLen] = { 0 }; 
	UINT32  planeMask;
	UINT32	bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
	bool	useRL;

#ifdef TRACE
	//printf("which thread: %d\n", omp_get_thread_num());
#endif 

	// clear significance vector
	for (UINT32 k=0; k < bufferSize; k++) {
		m_sigFlagVector[k] = false;
	}
	m_sigFlagVector[bufferSize] = true; // sentinel

	// clear output buffer
	for (UINT32 k=0; k < bufferSize; k++) {
		m_codeBuffer[k] = 0;
	}
	m_codePos = 0;

	// compute number of bit planes and split buffer into separate bit planes
	nPlanes = NumberOfBitplanes();

	// write number of bit planes to m_codeBuffer
	// <nPlanes>
	SetValueBlock(m_codeBuffer, 0, nPlanes, MaxBitPlanesLog);
	m_codePos += MaxBitPlanesLog;

	// loop through all bit planes
	if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
	planeMask = 1 << (nPlanes - 1);

	for (int plane = nPlanes - 1; plane >= 0; plane--) {
		// clear significant bitset
		for (UINT32 k=0; k < BufferLen; k++) {
			sigBits[k] = 0;
		}

		// split bitplane in significant bitset and refinement bitset
		sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);

		if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
			// set RL code bit
			// <1><codeLen>
			SetBit(m_codeBuffer, m_codePos++);

			// write length codeLen to m_codeBuffer
			SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);
			m_codePos += RLblockSizeLen + codeLen;
		} else {
		#ifdef TRACE
			//printf("new\n");
			//for (UINT32 i=0; i < bufferSize; i++) {
			//	printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
			//	if (i%120 == 119) printf("\n");
			//}
			//printf("\n");
		#endif // TRACE

			// run-length coding wasn't efficient enough
			// we don't use RL coding for sigBits
			// <0><sigLen>
			ClearBit(m_codeBuffer, m_codePos++);

			// write length sigLen to m_codeBuffer
			ASSERT(sigLen <= MaxCodeLen); 
			SetValueBlock(m_codeBuffer, m_codePos, sigLen, RLblockSizeLen);
			m_codePos += RLblockSizeLen;

			if (m_encoder->m_favorSpeed || signLen == 0) {
				useRL = false;
			} else {
				// overwrite m_codeBuffer
				useRL = true;
				// run-length encode m_sign and append them to the m_codeBuffer
				codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
			}

			if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
				// RL encoding of m_sign was efficient
				// <1><codeLen><codedSignBits>_
				// write RL code bit
				SetBit(m_codeBuffer, m_codePos++);
				
				// write codeLen to m_codeBuffer
				SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);

				// compute position of sigBits
				wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
				ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
			} else {
				// RL encoding of signBits wasn't efficient
				// <0><signLen>_<signBits>_
				// clear RL code bit
				ClearBit(m_codeBuffer, m_codePos++);

				// write signLen to m_codeBuffer
				ASSERT(signLen <= MaxCodeLen); 
				SetValueBlock(m_codeBuffer, m_codePos, signLen, RLblockSizeLen);

				// write signBits to m_codeBuffer
				wordPos = NumberOfWords(m_codePos + RLblockSizeLen);
				ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
				codeLen = NumberOfWords(signLen);

				for (UINT32 k=0; k < codeLen; k++) {
					m_codeBuffer[wordPos++] = signBits[k];
				}
			}

			// write sigBits
			// <sigBits>_
			ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
			refLen = NumberOfWords(sigLen);

			for (UINT32 k=0; k < refLen; k++) {
				m_codeBuffer[wordPos++] = sigBits[k];
			}
			m_codePos = wordPos << WordWidthLog;
		}

		// append refinement bitset (aligned to word boundary)
		// _<refBits>
		wordPos = NumberOfWords(m_codePos);
		ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
		refLen = NumberOfWords(bufferSize - sigLen);

		for (UINT32 k=0; k < refLen; k++) {
			m_codeBuffer[wordPos++] = refBits[k];
		}
		m_codePos = wordPos << WordWidthLog;
		planeMask >>= 1;
	}
	ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
}
Esempio n. 2
0
/////////////////////////////////////////////////////////////////////
// Write encoded macro block into stream.
// It might throw an IOException.
void CEncoder::WriteMacroBlock(CMacroBlock* block) {
	ASSERT(block);
#ifdef __PGFROISUPPORT__
	ROIBlockHeader h = block->m_header;
#endif
	UINT16 wordLen = UINT16(NumberOfWords(block->m_codePos)); ASSERT(wordLen <= CodeBufferLen);
	int count = sizeof(UINT16);

#ifdef TRACE
	//UINT32 filePos = (UINT32)m_stream->GetPos();
	//printf("EncodeBuffer: %d\n", filePos);
#endif

#ifdef PGF_USE_BIG_ENDIAN
	// write wordLen
	UINT16 wl = __VAL(wordLen);
	m_stream->Write(&count, &wl); ASSERT(count == sizeof(UINT16));

#ifdef __PGFROISUPPORT__
	// write ROIBlockHeader
	if (m_roi) {
		count = sizeof(ROIBlockHeader);
		h.val = __VAL(h.val);
		m_stream->Write(&count, &h.val); ASSERT(count == sizeof(ROIBlockHeader));
	}
#endif // __PGFROISUPPORT__

	// convert data
	for (int i=0; i < wordLen; i++) {
		block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
	}
#else
	// write wordLen
	m_stream->Write(&count, &wordLen); ASSERT(count == sizeof(UINT16));

#ifdef __PGFROISUPPORT__
	// write ROIBlockHeader
	if (m_roi) {
		count = sizeof(ROIBlockHeader);
		m_stream->Write(&count, &h.val); ASSERT(count == sizeof(ROIBlockHeader));
	}
#endif // __PGFROISUPPORT__
#endif // PGF_USE_BIG_ENDIAN

	// write encoded data into stream
	count = wordLen*WordBytes;
	m_stream->Write(&count, block->m_codeBuffer);

	// store levelLength
	if (m_levelLength) {
		// store level length
		// EncodeBuffer has been called after m_lastLevelIndex has been updated
		ASSERT(m_currLevelIndex < m_nLevels);
		m_levelLength[m_currLevelIndex] += (UINT32)ComputeBufferLength();
		m_currLevelIndex = block->m_lastLevelIndex + 1;

	}

	// prepare for next buffer
	SetBufferStartPos();

	// reset values
	block->m_valuePos = 0;
	block->m_maxAbsValue = 0;
}