Beispiel #1
0
        public void RenderColoredGray2(ColoredFrame frame)
        {
            SetPalette(frame.Palette, frame.PaletteIndex);

            var joinedFrame = FrameUtil.Join(DmdWidth, DmdHeight, frame.Planes);

            // send frame buffer to device
            RenderGray4(FrameUtil.ConvertGrayToGray(joinedFrame, new byte[] { 0x0, 0x1, 0x4, 0xf }));
        }
Beispiel #2
0
        public void RenderColoredGray2(byte[][] planes, Color[] palette)
        {
            SetPalette(palette);

            var frame = FrameUtil.Join(DmdWidth, DmdHeight, planes);

            // send frame buffer to device
            RenderGray4(FrameUtil.ConvertGrayToGray(frame, new byte[] { 0x0, 0x1, 0x4, 0xf }));
        }
Beispiel #3
0
 public void RenderGray2(byte[] frame)
 {
     // 2-bit frames are rendered as 4-bit
     RenderGray4(FrameUtil.ConvertGrayToGray(frame, new byte[] { 0x0, 0x1, 0x4, 0xf }));
 }
Beispiel #4
0
 public void RenderGray2(byte[] frame)
 {
     RenderGray4(FrameUtil.ConvertGrayToGray(frame, new byte[] { 0x0, 0x1, 0x4, 0xf }));
 }
Beispiel #5
0
		/// <summary>
		/// Connects a source with a destination and defines in which mode data is
		/// sent and received.
		/// </summary>
		/// <remarks>
		/// Note that render bitlength is enforced, i.e. even if the destination 
		/// supports the "from" bitlength, it will be converted to the given "to"
		/// bitlength.
		/// </remarks>
		/// <param name="source">Source to subscribe to</param>
		/// <param name="dest">Destination to send the data to</param>
		/// <param name="from">Data format to read from source (incompatible source will throw exception)</param>
		/// <param name="to">Data forma to send to destination (incompatible destination will throw exception)</param>
		private void Connect(ISource source, IDestination dest, FrameFormat from, FrameFormat to)
		{
			var destFixedSize = dest as IFixedSizeDestination;
			var destGray2 = dest as IGray2Destination;
			var destGray4 = dest as IGray4Destination;
			var destRgb24 = dest as IRgb24Destination;
			var destBitmap = dest as IBitmapDestination;
			var destColoredGray2 = dest as IColoredGray2Destination;
			var destColoredGray4 = dest as IColoredGray4Destination;
			var scheduler = Scheduler.Default;
			Logger.Info("Connecting {0} to {1} ({2} => {3})", source.Name, dest.Name, from.ToString(), to.ToString());

			switch (from) { 

				// source is gray2:
				case FrameFormat.Gray2:
					var sourceGray2 = source as IGray2Source;
					switch (to)
					{
						// gray2 -> gray2
						case FrameFormat.Gray2:
							AssertCompatibility(source, sourceGray2, dest, destGray2, from, to);
							_activeSources.Add(sourceGray2.GetGray2Frames()
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray2.RenderGray2));
							break;

						// gray2 -> gray4
						case FrameFormat.Gray4:
							throw new NotImplementedException("Cannot convert from gray2 to gray4 (every gray4 destination should be able to do gray2 as well).");

						// gray2 -> rgb24
						case FrameFormat.Rgb24:
							AssertCompatibility(source, sourceGray2, dest, destRgb24, from, to);
							_activeSources.Add(sourceGray2.GetGray2Frames()
								.Select(frame => ColorizeGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame))
								.Select(frame => TransformRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destRgb24.RenderRgb24));
							break;

						// gray2 -> bitmap
						case FrameFormat.Bitmap:
							AssertCompatibility(source, sourceGray2, dest, destBitmap, from, to);
							_activeSources.Add(sourceGray2.GetGray2Frames()
								.Select(frame => ImageUtil.ConvertFromRgb24(
									source.Dimensions.Value.Width,
									source.Dimensions.Value.Height,
									ColorizeGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame)
								))
								.Select(bmp => Transform(bmp, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destBitmap.RenderBitmap));
							break;

						// gray2 -> colored gray2
						case FrameFormat.ColoredGray2:
							throw new NotImplementedException("Cannot convert from gray2 to colored gray2 (doesn't make any sense, colored gray2 can also do gray2).");

						// gray2 -> colored gray4
						case FrameFormat.ColoredGray4:
							throw new NotImplementedException("Cannot convert from gray2 to colored gray2 (a colored gray4 destination should also be able to do gray2 directly).");

						default:
							throw new ArgumentOutOfRangeException(nameof(to), to, null);
					}
					break;

				// source is gray4:
				case FrameFormat.Gray4:
					var sourceGray4 = source as IGray4Source;
					switch (to) {
						// gray4 -> gray2
						case FrameFormat.Gray2:
							AssertCompatibility(source, sourceGray4, dest, destGray2, from, to);
							_activeSources.Add(sourceGray4.GetGray4Frames()
								.Select(frame => FrameUtil.ConvertGrayToGray(frame, new byte[] { 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3 }))
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray2.RenderGray2));
							break;

						// gray4 -> gray4
						case FrameFormat.Gray4:
							AssertCompatibility(source, sourceGray4, dest, destGray4, from, to);
							_activeSources.Add(sourceGray4.GetGray4Frames()
								.Select(frame => TransformGray4(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray4.RenderGray4));
							break;

						// gray4 -> rgb24
						case FrameFormat.Rgb24:
							AssertCompatibility(source, sourceGray4, dest, destRgb24, from, to);
							_activeSources.Add(sourceGray4.GetGray4Frames()
								.Select(frame => ColorizeGray4(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame))
								.Select(frame => TransformRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destRgb24.RenderRgb24));
							break;

						// gray4 -> bitmap
						case FrameFormat.Bitmap:
							AssertCompatibility(source, sourceGray4, dest, destBitmap, from, to);
							_activeSources.Add(sourceGray4.GetGray4Frames()
								.Select(frame => ImageUtil.ConvertFromRgb24(
									source.Dimensions.Value.Width,
									source.Dimensions.Value.Height,
									ColorizeGray4(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame)
								))
								.Select(bmp => Transform(bmp, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destBitmap.RenderBitmap));
							break;

						// gray4 -> colored gray2
						case FrameFormat.ColoredGray2:
							throw new NotImplementedException("Cannot convert from gray4 to colored gray2 (doesn't make any sense, colored gray2 can also do gray4).");

						// gray4 -> colored gray4
						case FrameFormat.ColoredGray4:
							throw new NotImplementedException("Cannot convert from gray2 to colored gray2 (doesn't make any sense, colored gray4 can also do gray4).");

						default:
							throw new ArgumentOutOfRangeException(nameof(to), to, null);
					}
					break;

				// source is rgb24:
				case FrameFormat.Rgb24:
					var sourceRgb24 = source as IRgb24Source;
					switch (to) {
						// rgb24 -> gray2
						case FrameFormat.Gray2:
							AssertCompatibility(source, sourceRgb24, dest, destGray2, from, to);
							_activeSources.Add(sourceRgb24.GetRgb24Frames()
								.Select(frame => ImageUtil.ConvertToGray(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, 4))
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray2.RenderGray2));
							break;

						// rgb24 -> gray4
						case FrameFormat.Gray4:
							AssertCompatibility(source, sourceRgb24, dest, destGray4, from, to);
							_activeSources.Add(sourceRgb24.GetRgb24Frames()
								.Select(frame => ImageUtil.ConvertToGray(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, 16))
								.Select(frame => TransformGray4(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray4.RenderGray4));
							break;

						// rgb24 -> rgb24
						case FrameFormat.Rgb24:
							AssertCompatibility(source, sourceRgb24, dest, destRgb24, from, to);
							_activeSources.Add(sourceRgb24.GetRgb24Frames()
								.Select(frame => TransformRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destRgb24.RenderRgb24));
							break;

						// rgb24 -> bitmap
						case FrameFormat.Bitmap:
							AssertCompatibility(source, sourceRgb24, dest, destBitmap, from, to);
							_activeSources.Add(sourceRgb24.GetRgb24Frames()
								.Select(frame => ImageUtil.ConvertFromRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame))
								.Select(bmp => Transform(bmp, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destBitmap.RenderBitmap));
							break;

						// rgb24 -> colored gray2
						case FrameFormat.ColoredGray2:
							throw new NotImplementedException("Cannot convert from rgb24 to colored gray2 (colored gray2 only has 4 colors per frame).");

						// rgb24 -> colored gray4
						case FrameFormat.ColoredGray4:
							throw new NotImplementedException("Cannot convert from rgb24 to colored gray2 (colored gray4 only has 16 colors per frame).");

						default:
							throw new ArgumentOutOfRangeException(nameof(to), to, null);
					}
					break;

				// source is bitmap:
				case FrameFormat.Bitmap:
					var sourceBitmap = source as IBitmapSource;
					switch (to) {
						// bitmap -> gray2
						case FrameFormat.Gray2:
							AssertCompatibility(source, sourceBitmap, dest, destGray2, from, to);
							_activeSources.Add(sourceBitmap.GetBitmapFrames()
								.Select(bmp => ImageUtil.ConvertToGray2(bmp))
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray2.RenderGray2));
							break;

						// bitmap -> gray4
						case FrameFormat.Gray4:
							AssertCompatibility(source, sourceBitmap, dest, destGray4, from, to);
							_activeSources.Add(sourceBitmap.GetBitmapFrames()
								.Select(bmp => ImageUtil.ConvertToGray4(bmp))
								.Select(frame => TransformGray4(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray4.RenderGray4));
							break;

						// bitmap -> rgb24
						case FrameFormat.Rgb24:
							AssertCompatibility(source, sourceBitmap, dest, destRgb24, from, to);
							_activeSources.Add(sourceBitmap.GetBitmapFrames()
								.Select(bmp => ImageUtil.ConvertToRgb24(bmp))
								.Select(frame => TransformRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destRgb24.RenderRgb24));
							break;

						// bitmap -> bitmap
						case FrameFormat.Bitmap:
							AssertCompatibility(Source, sourceBitmap, dest, destBitmap, from, to);
							_activeSources.Add(sourceBitmap.GetBitmapFrames()
								.Select(bmp => Transform(bmp, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destBitmap.RenderBitmap));
							break;

						// bitmap -> colored gray2
						case FrameFormat.ColoredGray2:
							throw new NotImplementedException("Cannot convert from bitmap to colored gray2 (colored gray2 only has 4 colors per frame).");

						// bitmap -> colored gray4
						case FrameFormat.ColoredGray4:
							throw new NotImplementedException("Cannot convert from bitmap to colored gray2 (colored gray4 only has 16 colors per frame).");

						default:
							throw new ArgumentOutOfRangeException(nameof(to), to, null);
					}
					break;

				// source is colored gray2:
				case FrameFormat.ColoredGray2:
					var sourceColoredGray2 = source as IColoredGray2Source;
					switch (to) {

						// colored gray2 -> gray2
						case FrameFormat.Gray2:
							AssertCompatibility(source, sourceColoredGray2, dest, destGray2, from, to);
							_activeSources.Add(sourceColoredGray2.GetColoredGray2Frames()
								.Select(x => FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1))
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray2.RenderGray2));
							break;

						// colored gray2 -> gray4
						case FrameFormat.Gray4:
							throw new NotImplementedException("Cannot convert from colored gray2 to gray4 (it's not like we can extract luminosity from the colors...)");

						// colored gray2 -> rgb24
						case FrameFormat.Rgb24:
							AssertCompatibility(source, sourceColoredGray2, dest, destRgb24, from, to);
							_activeSources.Add(sourceColoredGray2.GetColoredGray2Frames()
								.Select(x => ColorUtil.ColorizeFrame(
									source.Dimensions.Value.Width,
									source.Dimensions.Value.Height, 
									FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1), 
									x.Item2)
								)
								.Select(frame => TransformRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destRgb24.RenderRgb24));
							break;

						// colored gray2 -> bitmap
						case FrameFormat.Bitmap:
							AssertCompatibility(source, sourceColoredGray2, dest, destBitmap, from, to);
							_activeSources.Add(sourceColoredGray2.GetColoredGray2Frames()
								.Select(x => ColorUtil.ColorizeFrame(
									source.Dimensions.Value.Width,
									source.Dimensions.Value.Height,
									FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1),
									x.Item2)
								)
								.Select(frame => ImageUtil.ConvertFromRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame))
								.Select(bmp => Transform(bmp, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destBitmap.RenderBitmap));
							break;

						// colored gray2 -> colored gray2
						case FrameFormat.ColoredGray2:
							AssertCompatibility(source, sourceColoredGray2, dest, destColoredGray2, from, to);
							_activeSources.Add(sourceColoredGray2.GetColoredGray2Frames()
								.Select(x => TransformColoredGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1, x.Item2, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(x => destColoredGray2.RenderColoredGray2(x.Item1, x.Item2)));
							break;

						// colored gray2 -> colored gray4
						case FrameFormat.ColoredGray4:
							throw new NotImplementedException("Cannot convert from colored gray2 to colored gray4 (if a destination can do colored gray4 it should be able to do colored gray2 directly).");

						default:
							throw new ArgumentOutOfRangeException(nameof(to), to, null);
					}
					break;

				// source is colored gray4:
				case FrameFormat.ColoredGray4:
					var sourceColoredGray4 = source as IColoredGray4Source;
					switch (to) {

						// colored gray4 -> gray2
						case FrameFormat.Gray2:
							AssertCompatibility(source, sourceColoredGray4, dest, destGray2, from, to);
							_activeSources.Add(sourceColoredGray4.GetColoredGray4Frames()
								.Select(x => FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1))
								.Select(frame => FrameUtil.ConvertGrayToGray(frame, new byte[] { 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3 }))
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray2.RenderGray2));
							break;

						// colored gray4 -> gray4
						case FrameFormat.Gray4:
							AssertCompatibility(source, sourceColoredGray4, dest, destGray4, from, to);
							_activeSources.Add(sourceColoredGray4.GetColoredGray4Frames()
								.Select(x => FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1))
								.Select(frame => TransformGray2(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destGray4.RenderGray4));
							break;

						// colored gray4 -> rgb24
						case FrameFormat.Rgb24:
							AssertCompatibility(source, sourceColoredGray4, dest, destRgb24, from, to);
							_activeSources.Add(sourceColoredGray4.GetColoredGray4Frames()
								.Select(x => ColorUtil.ColorizeFrame(
									source.Dimensions.Value.Width,
									source.Dimensions.Value.Height,
									FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1),
									x.Item2)
								)
								.Select(frame => TransformRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destRgb24.RenderRgb24));
							break;

						// colored gray4 -> bitmap
						case FrameFormat.Bitmap:
							AssertCompatibility(source, sourceColoredGray4, dest, destBitmap, from, to);
							_activeSources.Add(sourceColoredGray4.GetColoredGray4Frames()
								.Select(x => ColorUtil.ColorizeFrame(
									source.Dimensions.Value.Width,
									source.Dimensions.Value.Height,
									FrameUtil.Join(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1),
									x.Item2)
								)
								.Select(frame => ImageUtil.ConvertFromRgb24(source.Dimensions.Value.Width, source.Dimensions.Value.Height, frame))
								.Select(bmp => Transform(bmp, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(destBitmap.RenderBitmap));
							break;

						// colored gray4 -> colored gray2
						case FrameFormat.ColoredGray2:
							throw new NotImplementedException("Cannot convert from colored gray4 to colored gray2 (use rgb24 instead of down-coloring).");

						// colored gray4 -> colored gray4
						case FrameFormat.ColoredGray4:
							AssertCompatibility(source, sourceColoredGray4, dest, destColoredGray4, from, to);
							_activeSources.Add(sourceColoredGray4.GetColoredGray4Frames()
								.Select(x => TransformColoredGray4(source.Dimensions.Value.Width, source.Dimensions.Value.Height, x.Item1, x.Item2, destFixedSize))
								.ObserveOn(scheduler)
								.Subscribe(x => destColoredGray4.RenderColoredGray4(x.Item1, x.Item2)));
							break;
						default:
							throw new ArgumentOutOfRangeException(nameof(to), to, null);
					}
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}
		}