Ejemplo n.º 1
0
void StringTable::CompressStart(int bpp, int width)
{
	m_bpp = bpp;
	m_slack = (8 - ((width * bpp) % 8)) % 8;

	m_partial |= m_clearCode << m_partialSize;
	m_partialSize += m_codeSize;
	ClearCompressorTable();
}
Ejemplo n.º 2
0
void StringTable::Initialize(int minCodeSize)
{
	m_done = false;

	m_bpp = 8;
	m_minCodeSize = minCodeSize;
	m_clearCode = 1 << m_minCodeSize;
	m_endCode = m_clearCode + 1;

	m_partial = 0;
	m_partialSize = 0;

	m_bufferSize = 0;
	ClearCompressorTable();
	ClearDecompressorTable();
}
Ejemplo n.º 3
0
bool StringTable::Compress(BYTE *buf, int *len)
{
	if( m_bufferSize == 0 || m_done ) {
		return false;
	}

	int mask = (1 << m_bpp) - 1;
	BYTE *bufpos = buf;
	while( m_bufferPos < m_bufferSize ) {
		//get the current pixel value
		char ch = (char)((m_buffer[m_bufferPos] >> m_bufferShift) & mask);

		// The next prefix is : 
		// <the previous LZW code (on 12 bits << 8)> | <the code of the current pixel (on 8 bits)>
		int nextprefix = (((m_prefix)<<8)&0xFFF00) + (ch & 0x000FF);
		if(firstPixelPassed) {
			
			if( m_strmap[nextprefix] > 0) {
				m_prefix = m_strmap[nextprefix];
			} else {
				m_partial |= m_prefix << m_partialSize;
				m_partialSize += m_codeSize;
				//grab full bytes for the output buffer
				while( m_partialSize >= 8 && bufpos - buf < *len ) {
					*bufpos++ = (BYTE)m_partial;
					m_partial >>= 8;
					m_partialSize -= 8;
				}

				//add the code to the "table map"
				m_strmap[nextprefix] = m_nextCode;

				//increment the next highest valid code, increase the code size
				if( m_nextCode == (1 << m_codeSize) ) {
					m_codeSize++;
				}
				m_nextCode++;

				//if we're out of codes, restart the string table
				if( m_nextCode == MAX_LZW_CODE ) {
					m_partial |= m_clearCode << m_partialSize;
					m_partialSize += m_codeSize;
					ClearCompressorTable();
				}

				// Only keep the 8 lowest bits (prevent problems with "negative chars")
				m_prefix = ch & 0x000FF;
			}

			//increment to the next pixel
			if( m_bufferShift > 0 && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack) ) {
				m_bufferShift -= m_bpp;
			} else {
				m_bufferPos++;
				m_bufferShift = 8 - m_bpp;
			}

			//jump out here if the output buffer is full
			if( bufpos - buf == *len ) {
				return true;
			}
		
		} else {
			// Specific behavior for the first pixel of the whole image

			firstPixelPassed=1;
			// Only keep the 8 lowest bits (prevent problems with "negative chars")
			m_prefix = ch & 0x000FF;

			//increment to the next pixel
			if( m_bufferShift > 0 && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack) ) {
				m_bufferShift -= m_bpp;
			} else {
				m_bufferPos++;
				m_bufferShift = 8 - m_bpp;
			}

			//jump out here if the output buffer is full
			if( bufpos - buf == *len ) {
				return true;
			}
		}
	}
Ejemplo n.º 4
0
bool StringTable::Compress(BYTE *buf, int *len)
{
	if( m_bufferSize == 0 || m_done ) {
		return false;
	}

	int mask = (1 << m_bpp) - 1;
	BYTE *bufpos = buf;
	while( m_bufferPos < m_bufferSize ) {
		//get the current pixel value
		char ch = (m_buffer[m_bufferPos] >> m_bufferShift) & mask;

		std::string nextprefix = m_prefix + ch;
		if( m_strmap.find(nextprefix) != m_strmap.end() ) {
			m_prefix = nextprefix;
		} else {
			m_partial |= m_strmap[m_prefix] << m_partialSize;
			m_partialSize += m_codeSize;
			//grab full bytes for the output buffer
			while( m_partialSize >= 8 && bufpos - buf < *len ) {
				*bufpos++ = (BYTE)m_partial;
				m_partial >>= 8;
				m_partialSize -= 8;
			}

			//add the string to the table map
			m_strmap[nextprefix] = m_nextCode;

			//increment the next highest valid code, increase the code size
			if( m_nextCode == (1 << m_codeSize) ) {
				m_codeSize++;
			}
			m_nextCode++;

			//if we're out of codes, restart the string table
			if( m_nextCode == MAX_LZW_CODE ) {
				m_partial |= m_clearCode << m_partialSize;
				m_partialSize += m_codeSize;
				ClearCompressorTable();
			}

			m_prefix = ch;
		}

		//increment to the next pixel
		if( m_bufferShift > 0 && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack) ) {
			m_bufferShift -= m_bpp;
		} else {
			m_bufferPos++;
			m_bufferShift = 8 - m_bpp;
		}

		//jump out here if the output buffer is full
		if( bufpos - buf == *len ) {
			return true;
		}
	}

	m_bufferSize = 0;
	*len = bufpos - buf;

	return true;
}