System.Windows.Forms.Cursor.InitFromStream C# (CSharp) Method

InitFromStream() private method

private InitFromStream ( System.Stream stream ) : void
stream System.Stream
return void
		private void InitFromStream (Stream stream)
		{
			ushort		entry_count;
			CursorEntry	ce;
			uint		largest;

			//read the cursor header
			if (stream == null || stream.Length == 0) 
				throw new ArgumentException ("The argument 'stream' must be a picture that can be used as a cursor", "stream");
			
			BinaryReader reader = new BinaryReader (stream);
            
			cursor_dir = new CursorDir ();
			cursor_dir.idReserved = reader.ReadUInt16();
			cursor_dir.idType = reader.ReadUInt16();
			if (cursor_dir.idReserved != 0 || !(cursor_dir.idType == 2 || cursor_dir.idType == 1))
				throw new ArgumentException ("Invalid Argument, format error", "stream");

			entry_count = reader.ReadUInt16();
			cursor_dir.idCount = entry_count;
			cursor_dir.idEntries = new CursorEntry[entry_count];
			cursor_data = new CursorImage[entry_count];

			//now read in the CursorEntry structures
			for (int i=0; i < entry_count; i++){
				ce = new CursorEntry();

				ce.width = reader.ReadByte();
				ce.height = reader.ReadByte();
				ce.colorCount = reader.ReadByte();
				ce.reserved = reader.ReadByte();
				ce.xHotspot = reader.ReadUInt16();
				ce.yHotspot = reader.ReadUInt16();
				if (cursor_dir.idType == 1) {
					ce.xHotspot = (ushort)(ce.width / 2);
					ce.yHotspot = (ushort)(ce.height / 2);
				}
				ce.sizeInBytes = reader.ReadUInt32();
				ce.fileOffset = reader.ReadUInt32();

				cursor_dir.idEntries[i] = ce;
			}

			// If we have more than one pick the largest cursor
			largest = 0;
			for (int j = 0; j < entry_count; j++){
				if (cursor_dir.idEntries[j].sizeInBytes >= largest)	{
					largest = cursor_dir.idEntries[j].sizeInBytes;
					this.id = (ushort)j;
					this.size.Height = cursor_dir.idEntries[j].height;
					this.size.Width = cursor_dir.idEntries[j].width;
				}
			}

			//now read in the cursor data
			for (int j = 0; j < entry_count; j++) {
				CursorImage		curdata;
				CursorInfoHeader	cih;
				byte[]			buffer;
				BinaryReader		cih_reader;
				int			num_colors;
				int			cursor_height;
				int			bytes_per_line;
				int			xor_size;
				int			and_size;

				curdata = new CursorImage();
				cih = new CursorInfoHeader();
				
				stream.Seek (cursor_dir.idEntries[j].fileOffset, SeekOrigin.Begin);
				buffer = new byte [cursor_dir.idEntries[j].sizeInBytes];
				stream.Read (buffer, 0, buffer.Length);

				cih_reader = new BinaryReader(new MemoryStream(buffer));

				cih.biSize = cih_reader.ReadUInt32 ();
				if (cih.biSize != 40) {
					throw new ArgumentException ("Invalid cursor file", "stream");
				}
				cih.biWidth = cih_reader.ReadInt32 ();
				cih.biHeight = cih_reader.ReadInt32 ();
				cih.biPlanes = cih_reader.ReadUInt16 ();
				cih.biBitCount = cih_reader.ReadUInt16 ();
				cih.biCompression = cih_reader.ReadUInt32 ();
				cih.biSizeImage = cih_reader.ReadUInt32 ();
				cih.biXPelsPerMeter = cih_reader.ReadInt32 ();
				cih.biYPelsPerMeter = cih_reader.ReadInt32 ();
				cih.biClrUsed = cih_reader.ReadUInt32 ();
				cih.biClrImportant = cih_reader.ReadUInt32 ();

				curdata.cursorHeader = cih;

				//Read the number of colors used and corresponding memory occupied by
				//color table. Fill this memory chunk into rgbquad[]
				switch (cih.biBitCount){
					case 1: num_colors = 2; break;
					case 4: num_colors = 16; break;
					case 8: num_colors = 256; break;
					default: num_colors = 0; break;
				}
				
				curdata.cursorColors = new uint[num_colors];
				for (int i = 0; i < num_colors; i++) {
					curdata.cursorColors[i] = cih_reader.ReadUInt32 ();
				}

				//XOR mask is immediately after ColorTable and its size is 
				//icon height* no. of bytes per line
				
				//cursor height is half of BITMAPINFOHEADER.biHeight, since it contains
				//both XOR as well as AND mask bytes
				cursor_height = cih.biHeight/2;
				
				//bytes per line should should be uint aligned
				bytes_per_line = ((((cih.biWidth * cih.biPlanes * cih.biBitCount)+ 31)>>5)<<2);
				
				//Determine the XOR array Size
				xor_size = bytes_per_line * cursor_height;
				curdata.cursorXOR = new byte[xor_size];
				for (int i = 0; i < xor_size; i++) {
					curdata.cursorXOR[i] = cih_reader.ReadByte();
				}
				
				//Determine the AND array size
				and_size = (int)(cih_reader.BaseStream.Length - cih_reader.BaseStream.Position);
				curdata.cursorAND = new byte[and_size];
				for (int i = 0; i < and_size; i++) {
					curdata.cursorAND[i] = cih_reader.ReadByte();
				}
				
				cursor_data[j] = curdata;
				cih_reader.Close();
			}			

			reader.Close();
		}