⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class1.cs

📁 mpeg4压缩算法程序
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.IO;
using System.Drawing;

namespace BitmapImage
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	public class MPEGFunctions
	{
		// Class of functions and variables needed to encode images
		// using the MPEG1 format
		// The MemoryStream ms is provided to store the bitstream 
		// produced by encoding the image's blocks
		private MemoryStream ms = new MemoryStream();
		private double[,] cosine = new double[8,8];
		private double SQRT2o2 = Math.Sqrt(2.0) / 2.0;

		// MPEG1 default quantization matrix
		private byte[,] defaultQ = new byte[8,8] {{8,16,19,22,26,27,29,34},
										{16,16,22,24,27,29,34,37},
										{19,22,26,27,29,34,34,38},
										{22,22,26,27,29,34,37,40},
										{22,26,27,29,32,35,40,48},
										{26,27,29,32,35,40,48,58},
										{26,27,29,34,38,46,56,69},
										{27,29,35,38,46,56,69,83}};

		// MPEG1 default DC Huffman codes 
		public int[] DCLumCode = new int[9] {4, 0, 1, 5, 6, 14, 30, 62, 126};
		public int[] DCLumSize = new int[9] {3, 2, 2, 3, 3, 4, 5, 6, 7};
		public int[] DCChromCode = new int[9] {0, 1, 2, 6, 14, 30, 62, 126, 254};
		public int[] DCChromSize = new int[9] {2, 2, 2, 3, 4, 5, 6, 7, 8};

		// MPEG1 default AC Huffman codes
		private int[] ACcode = new int[111] {
		6,6,10,14,12,14,10,8,14,10,78,70,68,64,28,26,16,	// AC=1, run=0->16    
		62,52,50,46,44,62,60,58,56,54,62,60,58,56,54,		// AC=1, run=17->31   
		8,12,8,72,30,18,60,42,34,34,32,52,50,48,46,44,42,	// AC=2, run=0->16   
		10,74,22,56,36,36,40,		// AC=3, run=0->6		
		12,24,40,38,				// AC=4, run=0->3	
		76,54,40,				// AC=5, run=0->2	
		66,44,					// AC=6	
		20,42,
		58,62,
		48,60,
		38,58,
		32,56,
		52,54,
		50,52,
		48,50,
		46,38,
		62,36,
		62,34,
		58,32,
		56,54,52,50,48,46,44,42,40,38,36,34,32,		// AC=19->31, run=0	
		48,46,44,42,40,38,36,34,32};			// AC=32->40, run=0

		private int[] ACsize = new int[111] {
		3,4,5,6,6,7,7,7,8,8,9,9,9,9,11,11,11,	// AC=1, run=0->16
		13,13,13,13,13,14,14,14,14,14,17,17,17,17,17,	// AC=1, run=17->31
		5,7,8,9,11,11,13,13,13,14,14,17,17,17,17,17,17,	// AC=2, run=0->16
		6,9,11,13,13,14,17,				// AC=3, run=0->6
		8,11,13,14,					// AC=4, run=0->3
		9,13,14,					
		9,14,
		11,14,
		13,16,
		13,16,
		13,16,
		13,16,
		14,16,
		14,16,
		14,16,
		14,17,
		15,17,
		15,17,
		15,17,
		15,15,15,15,15,15,15,15,15,15,15,15,15,				// AC=19->31, run=0
		16,16,16,16,16,16,16,16,16};					// AC=32->40, run=0	

		// MPEG1 sequence header
		public byte[] seqHeaderBits = new byte[100] 
				  {
						  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					  0,0,0,0,0,0,0,1,1,0,1,1,0,0,1,1,	// Sequence Header
					  0,0,0,1,0,1,1,0,0,0,0,0,		// HSize = 352
					  0,0,0,0,1,1,1,1,0,0,0,0,		// VSize = 240
					  1,1,0,0,0,1,0,0,		// Pel Shape=1.125,Picture Rate=29.97
					  0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,	// Bit Rate = 4096*400
					  1,						// Marker Bit
					  0,0,0,0,0,1,0,1,0,0,			// VBV Buffer Size = 20 * 16384
					  0,0,0,255,255,255,255};

		// MPEG1 GOP header
		public byte[] GOPHeaderBits = new byte[68]
				{
						0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0,	// GOP Header
					1,0,0,0,0,0,0,0,0,0,0,0,
					1,0,0,0,0,0,0,0,0,0,0,0,0,		// Time Code = 00:00:00
					1,0,0,0,0,0,0,255,255,255,255};		// Closed GOP, Broken Link
		
		// MPEG1 picture header
		public byte[] picHeaderBits = new byte[68]
				{
						0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,	// Picture Header
					0,0,0,0,0,0,0,0,0,0,			// Temporal Reference
					0,0,1,					// Picture Type = I Frame
					1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,	// VBV Delay = 32768
					0,0,0,255,255,255,255};
		
		// MPEG1 slice header
		public byte[] sliceHeaderBits = new byte[44]
				{
						0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,	// Slice Header
					0,1,0,0,0,					// Q Scale = 8
					0,255,255,255,255,255,255};				// Extra Slice Bit

		public byte[] EOPBits = new byte[8] {255,255,255,255,255,255,255,255};

		public MPEGFunctions()
		{
			int i, j;

			// Calculate frequently used cosine matrix
			for (i=0; i<8; i++)
				for (j=0; j<8; j++)
					cosine[j,i] = Math.Cos(Math.PI*j*(2.0*i + 1)/16.0);
		}

		//	The memory stream can be used to store the encoded picture
		//	by using the writeToMS function anytime a block is encoded
		public MemoryStream getMS()
		{
			return ms;
		}

		//	Perform the DCT on the A block
		//	See the JPEG DCT definition for the formula
		public double[,] calculateDCT (byte[,] A)
			{
			int k1, k2, i, j;
			double Cu, Cv;
			double[,] B = new double[8,8];

			for (k1=0; k1<8; k1++)
				for (k2=0; k2<8; k2++)
				{
					B[k1,k2] = 0.0;
					for (i=0; i<8; i++)
						for (j=0; j<8; j++)
							B[k1,k2] += A[i,j] * cosine[k1,i] * cosine[k2,j];

					if (k1==0)
						Cu = SQRT2o2;
					else
						Cu = 1.0;
					if (k2==0)
						Cv = SQRT2o2;
					else
						Cv= 1.0;
					
					B[k1,k2] *= (0.25*Cu*Cv);
				}
			return B;	// Return Frequency Component matrix
		}

		// Quantize the DCT coefficients using the defaultQ array
		// In MPEG, always divide the DC value by eight
		public int[,] Quantize (double[,] S)
		{
			int i, j;
			int[,] S1 = new int[8,8];

			for (i=0; i<8; i++)
				for (j=0; j<8; j++)
					S1[i,j] = (int) Math.Round((S[i,j] / (double) defaultQ[i,j]));

			return S1;	// Return quantized Frequency Component matrix
		}			

			
		// Quantize the DCT coefficients using the supplied Q array
		// In MPEG, always divide the DC value by eight
		public int[,] Quantize (double[,] S, double[,] Q)
		{
			int i, j;
			int[,] S1 = new int[8,8];

			for (i=0; i<8; i++)
				for (j=0; j<8; j++)
					S1[i,j] = (int) Math.Round((S[i,j] / Q[i,j]));

			return S1;	// Return quantized Frequency Component matrix
		}			


		//	Function to encode the DC values
		public byte[] DCHuffmanEncode(int DC, int[] eco, int[] esi)
		{
			byte[] DCbits = new byte[24];
			int cat, tempval, i;
			bool invert;
			int tempbits;

			for (i=0; i<24; i++)
				DCbits[i] = 255;

			// Set flag if DC is negative
			invert = false;
			if (DC<0)
				invert = true;
			DC = Math.Abs(DC);

			// Determine the number of bits needed to represent DC
			cat = 0;
			tempval = DC;
			while (tempval >= 1)
			{
				cat++;
				tempval >>= 1;
			}

			// Write bits for Huffman code into DCbits[] array
			tempval = (int) Math.Pow(2, esi[cat]-1);
			for (i=0; i<esi[cat]; i++)
			{
				tempbits = eco[cat] & tempval;
				DCbits[i] = (byte) (tempbits >> (esi[cat] - 1 - i));
				tempval >>= 1;
			}

			// Write bits for DC into DCbits[] array
			tempval = (int) Math.Pow(2, cat-1);
			for (i=esi[cat]; i<esi[cat]+cat; i++)
			{
				tempbits = DC & tempval;
				DCbits[i] = (byte) (tempbits >> (cat-1-i+esi[cat]));
				tempval >>= 1;
			}

			// If necessary, invert bits to represent negative DC
			if (invert)
				for (i=esi[cat]; i<esi[cat]+cat; i++)
				{
					if (DCbits[i] == 0)
						DCbits[i] = 1;
					else
						DCbits[i] = 0;
				}

			return DCbits;	// Return array of bits representing DC value
		}


		//	Re order all coefficients after DCT is performed
		public int[] Zigzag (int[,] S1)
		{
			int[] index = new int[64] {0,1,7,8,-7,-7,1,7,7,7,8,
							 -7,-7,-7,-7,1,7,7,7,7,7,8,
							 -7,-7,-7,-7,-7,-7,1,7,7,7,7,7,7,7,1,
							 -7,-7,-7,-7,-7,-7,8,7,7,7,7,7,1,
							 -7,-7,-7,-7,8,7,7,7,1,
							 -7,-7,8,7,1};
			int i;
			int[] zz = new int[64];
			int a, b;
			int S1pointer = 0;

			for (i=0; i<64; i++)
			{
				S1pointer += index[i];
				a = S1pointer/8;
				b = S1pointer%8;
				zz[i] = S1[a,b];
			}

			return zz;	// Return sorted array with DC value at position 0
		}


		//	This function takes the array pointed to by zz and encodes
		//	the values using the Huffman code pointed to by eco[].
		public byte[] ACHuffmanEncode(int[] zz)
		{
			int MAXACSIZE = 1764;	// 63 AC Values * 28 bits
			byte[] outBits = new byte[MAXACSIZE];
			int run, tempval;
			int ACindex = 0;
			int i, AC;
			int arrayPosition;
			int ACbits;
			int size;
			int code;
			int outbitsPosition;
			int tempbits;

			for (i=0; i<MAXACSIZE; i++)
				outBits[i] = 255;

			//	Start at zz[1] since don't want to include DC value
			//	Do this to the end of the zz array
			arrayPosition = 1;
			outbitsPosition = 0;
			while (ACindex < MAXACSIZE - 28)
			{
				// First figure out how many consecutive zeros
				run = 0;
				while ((zz[arrayPosition]==0) && (arrayPosition<63))
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -