private static unsafe void FillBitmapFromImageData(byte[] imageData, Color32[] colorsTable, BitmapData bitmapData)
		{
			var p = (Color32*) bitmapData.Scan0.ToPointer();

			var i = 0;
			while (i < imageData.Length)
			{
				*p++ = colorsTable[imageData[i++]];
			}
		}
		private static unsafe void FillBitmapFromInterlacedImageData(byte[] imageData, Color32[] colorsTable, BitmapData bitmapData)
		{
			var p = (Color32*) bitmapData.Scan0.ToPointer();

			var rates = new[] { 8, 8, 4, 2, 1 };
			var startPosition = p;
			var offset = 0;

			var i = 0;
			var pass = 0;

			while (pass < 4)
			{
				if (pass > 0)
				{
					var diff = rates[pass + 1] * bitmapData.Width;
					p = startPosition + diff;
					offset += diff;
				}

				var rate = rates[pass];

				while (i < imageData.Length)
				{
					*p++ = colorsTable[imageData[i++]];
					offset++;

					if (i % bitmapData.Width != 0)
					{
						continue;
					}

					p += bitmapData.Width * (rate - 1);
					offset += bitmapData.Width * (rate - 1);

					if (offset >= imageData.Length)
					{
						pass++;
						offset = 0;
						break;
					}
				}
			}
		}
		private static Bitmap CreateBitmap(byte[] imageData, Color32[] colorsTable, bool interlaceFlag, int imageWidth, int imageHeight)
		{
			var result = new Bitmap(imageWidth, imageHeight);

			var rectangle = new Rectangle(0, 0, imageWidth, imageHeight);
			var bitmapData = result.LockBits(rectangle, ImageLockMode.ReadWrite, result.PixelFormat);

			if (interlaceFlag)
			{
				FillBitmapFromInterlacedImageData(imageData, colorsTable, bitmapData);
			}
			else
			{
				FillBitmapFromImageData(imageData, colorsTable, bitmapData);
			}

			result.UnlockBits(bitmapData);
			return result;
		}