Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / Win32

SWF Summary Shell Extension (PropertyPage for SWF files!)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
13 Jul 2010CPOL7 min read 35K   899   17  
This application adds a property page to show SWF properties in the Windows file properties window.
#include "stdafx.h"
#include "SWFReader.h"

// This code was written by Daniel Cohen Gindi (danielgindi@gmail.com)
// You can use it fo whatever needs, but please keep the credits :-)

// NOTE: The code is using a 'minimal' version of ZLIB, 
//       with only the unzip functionality

// IMPORTANT NOTE: The FILE passes must be opened in BINARY MODE!!!
//				   And for a good reason: 
//				   The fseek reliability is not guaranteed in text mode... (MSDN... And tests)

CSWFReader::CSWFReader(FILE * file/* = NULL */)
{
	m_bReadCompressed=FALSE;
	m_fFile=file;
	m_bHeaderRead=FALSE;
	m_iBitPos=0;
	m_bCurByte=0;
	memset(&m_header, 0, sizeof(m_header));
}

CSWFReader::~CSWFReader()
{
	if (m_bReadCompressed)
	{
		inflateEnd(&m_zStream);
		m_bReadCompressed=FALSE;
	}
}

void CSWFReader::SetFile(FILE * file)
{
	if (m_fFile==file) return;
	if (m_bReadCompressed)
	{
		inflateEnd(&m_zStream);
		m_bReadCompressed=FALSE;
	}
	m_fFile=file;
	m_bHeaderRead=FALSE;
	m_iBitPos=0;
	m_bCurByte=0;
	fseek(file, 0, SEEK_SET);
}

BOOL CSWFReader::ReadHeader()
{
	if (m_fFile==NULL) return FALSE;
	else
	{
		if (m_bReadCompressed)
		{
			inflateEnd(&m_zStream);
			m_bReadCompressed=FALSE;
		}

		fseek(m_fFile, 0, SEEK_SET);

		BOOL bSuccess=TRUE;

		char headerID[3]={0};
		UINT iTotalFileSize=0;

		bSuccess=ReadBytes((BYTE*)headerID, 3);

		if (bSuccess)
		{
			if ((headerID[0]=='F' || headerID[0]=='C') &&
				headerID[1]=='W' && headerID[2]=='S')
			{
				if (headerID[0]=='C') m_header.bCompressed=TRUE;
			}
			else bSuccess=FALSE;
		}

		if (bSuccess) bSuccess = ReadByte(m_header.bVer);
		if (bSuccess) bSuccess = ReadUI32(iTotalFileSize);

		if (m_header.bCompressed)
		{
			// When the SWF is compressed, everything after the first 8 bytes
			// is compressed.

			m_zStream.next_in = NULL;
			m_zStream.avail_in = (uInt)0;
			m_zStream.next_out = NULL;
			m_zStream.avail_out = 0;
			m_zStream.zalloc = (alloc_func)0;
			m_zStream.zfree = (free_func)0;

			if (inflateInit(&m_zStream)==Z_OK)
			{
				m_bReadCompressed=TRUE;
			}
			else
			{
				bSuccess=FALSE;
			}
		}

		BYTE bBits=0;
		if (bSuccess) bSuccess = ReadUB(bBits, 5);
		if (bSuccess) bSuccess = ReadSB(m_header.rcFrameSize.xMin, bBits);
		if (bSuccess) bSuccess = ReadSB(m_header.rcFrameSize.xMax, bBits);
		if (bSuccess) bSuccess = ReadSB(m_header.rcFrameSize.yMin, bBits);
		if (bSuccess) bSuccess = ReadSB(m_header.rcFrameSize.yMax, bBits);

		if (bSuccess) bSuccess = Read8_8(m_header.fFrameRate);
		if (bSuccess) bSuccess = ReadUI16(m_header.wFrameCount);

		if (bSuccess) m_bHeaderRead=TRUE;

		return bSuccess;
	}
}

SWF_HEADER& CSWFReader::GetHeader()
{
	return m_header;
}

BOOL CSWFReader::ReadByte(BYTE & bOut)
{
	return ReadBytes(&bOut, 1);
}

BOOL CSWFReader::ReadBytes(BYTE * bOut, UINT iCount)
{
	if (m_fFile==NULL) return FALSE;
	if (m_bReadCompressed)
	{
		int err=Z_OK;

		m_zStream.next_out=(Bytef*)bOut;
		m_zStream.avail_out=iCount;

		while (m_zStream.avail_out>0 && err==Z_OK)
		{
			if (m_zStream.avail_in>0) fseek(m_fFile, -(int)m_zStream.avail_in, SEEK_CUR);
			m_zStream.next_in=(Bytef*)m_zInBytes;
			m_zStream.avail_in=fread(m_zInBytes, 1, DECOMPRESS_BUFFER_SIZE, m_fFile);
			err = inflate(&m_zStream, Z_SYNC_FLUSH);
		}

		if (err==Z_STREAM_END) err=Z_OK;

		return err==Z_OK;
	}
	else
	{
		if (fread(bOut, 1, iCount, m_fFile)==iCount)
		{
			m_iBitPos=8;
			return TRUE;
		}
		else return FALSE;
	}
}

BOOL CSWFReader::ReadBit(BOOL & bBit)
{
	if (m_fFile==NULL) return FALSE;
	else
	{
		if (m_iBitPos > 7)
		{
			if (!ReadByte(m_bCurByte)) return FALSE;
			m_iBitPos = 0;
		}
		bBit = (m_bCurByte & (1<<(7 - m_iBitPos))) != 0;
		m_iBitPos++;
		return TRUE;
	}
}

BOOL CSWFReader::ReadUI8(unsigned __int8 & value)
{
	return ReadByte((BYTE&)value);
}

BOOL CSWFReader::ReadSI8(signed __int8 & value)
{
	return ReadByte((BYTE&)value);
}

BOOL CSWFReader::ReadUI16(unsigned __int16 & value)
{
	return ReadBytes((BYTE*)&value, 2);
}

BOOL CSWFReader::ReadSI16(signed __int16 & value)
{
	return ReadBytes((BYTE*)&value, 2);
}

BOOL CSWFReader::ReadUI32(unsigned __int32 & value)
{
	return ReadBytes((BYTE*)&value, 4);
}

BOOL CSWFReader::ReadSI32(signed __int32 & value)
{
	return ReadBytes((BYTE*)&value, 4);
}

BOOL CSWFReader::Read8_8(float & value)
{
	BYTE b[2];
	if (!ReadBytes(b, 2)) return FALSE;
	value=((signed char)b[1])+b[0]/255.0f;
	return TRUE;
}

BOOL CSWFReader::Read16_16(float & value)
{
	signed __int16 iWhole;
	unsigned __int16 iDec;
	if (!ReadUI16(iDec)) return FALSE;
	if (!ReadSI16(iWhole)) return FALSE;
	value=iWhole+iDec/65535.0f;
	return TRUE;
}

BOOL CSWFReader::ReadUB(unsigned __int8 & value, int iBits)
{
	value = 0;

	if (iBits > 0)
	{
		BOOL bBit;
		for (int i = iBits - 1; i > -1; i--)
		{
			if (!ReadBit(bBit)) return FALSE;
			if (bBit) value |= 1<<i;
		}
	}

	return TRUE;
}

BOOL CSWFReader::ReadUB(unsigned __int16 & value, int iBits)
{
	value = 0;

	if (iBits > 0)
	{
		BOOL bBit;
		for (int i = iBits - 1; i > -1; i--)
		{
			if (!ReadBit(bBit)) return FALSE;
			if (bBit) value |= 1<<i;
		}
	}

	return TRUE;
}

BOOL CSWFReader::ReadUB(unsigned __int32 & value, int iBits)
{
	value = 0;

	if (iBits > 0)
	{
		BOOL bBit;
		for (int i = iBits - 1; i > -1; i--)
		{
			if (!ReadBit(bBit)) return FALSE;
			if (bBit) value |= 1<<i;
		}
	}

	return TRUE;
}

BOOL CSWFReader::ReadSB(signed __int8 & value, int iBits)
{
	value = 0;

	if (iBits > 0)
	{
		BOOL bBit;

		if (!ReadBit(bBit)) return FALSE;
		if (bBit) value -= 1 << (iBits-1);

		for (int i = iBits - 2; i > -1; i--)
		{
			if (!ReadBit(bBit)) return FALSE;
			if (bBit) value |= 1<<i;
		}
	}

	return TRUE;
}

BOOL CSWFReader::ReadSB(signed __int16 & value, int iBits)
{
	value = 0;

	if (iBits > 0)
	{
		BOOL bBit;

		if (!ReadBit(bBit)) return FALSE;
		if (bBit) value -= 1 << (iBits-1);

		for (int i = iBits - 2; i > -1; i--)
		{
			if (!ReadBit(bBit)) return FALSE;
			if (bBit) value |= 1<<i;
		}
	}

	return TRUE;
}

BOOL CSWFReader::ReadSB(signed __int32 & value, int iBits)
{
	value = 0;

	if (iBits > 0)
	{
		BOOL bBit;

		if (!ReadBit(bBit)) return FALSE;
		if (bBit) value -= 1 << (iBits-1);

		for (int i = iBits - 2; i > -1; i--)
		{
			if (!ReadBit(bBit)) return FALSE;
			if (bBit) value |= 1<<i;
		}
	}

	return TRUE;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions