public RunLengthTwoParts RunLengthEncodeForDvd(Color background, Color pattern, Color emphasis1, Color emphasis2) { byte[] backgroundBuffer = new byte[4]; backgroundBuffer[0] = (byte)background.B; backgroundBuffer[1] = (byte)background.G; backgroundBuffer[2] = (byte)background.R; backgroundBuffer[3] = (byte)background.A; byte[] patternBuffer = new byte[4]; patternBuffer[0] = (byte)pattern.B; patternBuffer[1] = (byte)pattern.G; patternBuffer[2] = (byte)pattern.R; patternBuffer[3] = (byte)pattern.A; byte[] emphasis1Buffer = new byte[4]; emphasis1Buffer[0] = (byte)emphasis1.B; emphasis1Buffer[1] = (byte)emphasis1.G; emphasis1Buffer[2] = (byte)emphasis1.R; emphasis1Buffer[3] = (byte)emphasis1.A; byte[] emphasis2Buffer = new byte[4]; emphasis2Buffer[0] = (byte)emphasis2.B; emphasis2Buffer[1] = (byte)emphasis2.G; emphasis2Buffer[2] = (byte)emphasis2.R; emphasis2Buffer[3] = (byte)emphasis2.A; byte[] bufferEqual = new byte[Width * Height]; byte[] bufferUnEqual = new byte[Width * Height]; int indexBufferEqual = 0; int indexBufferUnEqual = 0; bool indexHalfNibble = false; int lastColor = -1; int count = -1; _pixelAddress = -4; for (int y = 0; y < Height; y++) { int index; byte[] buffer; if (y % 2 == 0) { index = indexBufferEqual; buffer = bufferEqual; } else { index = indexBufferUnEqual; buffer = bufferUnEqual; } indexHalfNibble = false; lastColor = -1; count = 0; for (int x = 0; x < Width; x++) { int color = GetDvdColor(x, y, backgroundBuffer, patternBuffer, emphasis1Buffer, emphasis2Buffer); if (lastColor == -1) { lastColor = color; count = 1; } else if (lastColor == color && count < 64) // only allow up to 63 run-length (for SubtitleCreator compatibility) { count++; } else { WriteRLE(ref indexHalfNibble, lastColor, count, ref index, buffer); lastColor = color; count = 1; } } if (count > 0) { WriteRLE(ref indexHalfNibble, lastColor, count, ref index, buffer); } if (indexHalfNibble) { index++; } if (y % 2 == 0) { indexBufferEqual = index; bufferEqual = buffer; } else { indexBufferUnEqual = index; bufferUnEqual = buffer; } } var twoParts = new RunLengthTwoParts(); twoParts.Buffer1 = new byte[indexBufferEqual]; Buffer.BlockCopy(bufferEqual, 0, twoParts.Buffer1, 0, indexBufferEqual); twoParts.Buffer2 = new byte[indexBufferUnEqual + 2]; Buffer.BlockCopy(bufferUnEqual, 0, twoParts.Buffer2, 0, indexBufferUnEqual); return(twoParts); }
public RunLengthTwoParts RunLengthEncodeForDvd(Color background, Color pattern, Color emphasis1, Color emphasis2) { byte[] backgroundBuffer = new byte[4]; backgroundBuffer[0] = (byte)background.B; backgroundBuffer[1] = (byte)background.G; backgroundBuffer[2] = (byte)background.R; backgroundBuffer[3] = (byte)background.A; byte[] patternBuffer = new byte[4]; patternBuffer[0] = (byte)pattern.B; patternBuffer[1] = (byte)pattern.G; patternBuffer[2] = (byte)pattern.R; patternBuffer[3] = (byte)pattern.A; byte[] emphasis1Buffer = new byte[4]; emphasis1Buffer[0] = (byte)emphasis1.B; emphasis1Buffer[1] = (byte)emphasis1.G; emphasis1Buffer[2] = (byte)emphasis1.R; emphasis1Buffer[3] = (byte)emphasis1.A; byte[] emphasis2Buffer = new byte[4]; emphasis2Buffer[0] = (byte)emphasis2.B; emphasis2Buffer[1] = (byte)emphasis2.G; emphasis2Buffer[2] = (byte)emphasis2.R; emphasis2Buffer[3] = (byte)emphasis2.A; byte[] bufferEqual = new byte[Width * Height]; byte[] bufferUnEqual = new byte[Width * Height]; int indexBufferEqual = 0; int indexBufferUnEqual = 0; bool indexHalfNibble = false; int lastColor = -1; int count = -1; _pixelAddress = -4; for (int y = 0; y < Height; y++) { int index; byte[] buffer; if (y % 2 == 0) { index = indexBufferEqual; buffer = bufferEqual; } else { index = indexBufferUnEqual; buffer = bufferUnEqual; } indexHalfNibble = false; lastColor = -1; count = 0; for (int x = 0; x < Width; x++) { int color = GetDvdColor(x, y, backgroundBuffer, patternBuffer, emphasis1Buffer, emphasis2Buffer); if (lastColor == -1) { lastColor = color; count = 1; } else if (lastColor == color && count < 64) // only allow up to 63 run-length (for SubtitleCreator compatibility) { count++; } else { WriteRLE(ref indexHalfNibble, lastColor, count, ref index, buffer); lastColor = color; count = 1; } } if (count > 0) WriteRLE(ref indexHalfNibble, lastColor, count, ref index, buffer); if (indexHalfNibble) index++; if (y % 2 == 0) { indexBufferEqual = index; bufferEqual = buffer; } else { indexBufferUnEqual = index; bufferUnEqual = buffer; } } var twoParts = new RunLengthTwoParts(); twoParts.Buffer1 = new byte[indexBufferEqual]; Buffer.BlockCopy(bufferEqual, 0, twoParts.Buffer1, 0, indexBufferEqual); twoParts.Buffer2 = new byte[indexBufferUnEqual+2]; Buffer.BlockCopy(bufferUnEqual, 0, twoParts.Buffer2, 0, indexBufferUnEqual); return twoParts; }
/// <summary> /// The run length encode for dvd. /// </summary> /// <param name="background"> /// The background. /// </param> /// <param name="pattern"> /// The pattern. /// </param> /// <param name="emphasis1"> /// The emphasis 1. /// </param> /// <param name="emphasis2"> /// The emphasis 2. /// </param> /// <returns> /// The <see cref="RunLengthTwoParts"/>. /// </returns> public RunLengthTwoParts RunLengthEncodeForDvd(Color background, Color pattern, Color emphasis1, Color emphasis2) { var backgroundBuffer = new byte[4]; backgroundBuffer[0] = background.B; backgroundBuffer[1] = background.G; backgroundBuffer[2] = background.R; backgroundBuffer[3] = background.A; var patternBuffer = new byte[4]; patternBuffer[0] = pattern.B; patternBuffer[1] = pattern.G; patternBuffer[2] = pattern.R; patternBuffer[3] = pattern.A; var emphasis1Buffer = new byte[4]; emphasis1Buffer[0] = emphasis1.B; emphasis1Buffer[1] = emphasis1.G; emphasis1Buffer[2] = emphasis1.R; emphasis1Buffer[3] = emphasis1.A; var emphasis2Buffer = new byte[4]; emphasis2Buffer[0] = emphasis2.B; emphasis2Buffer[1] = emphasis2.G; emphasis2Buffer[2] = emphasis2.R; emphasis2Buffer[3] = emphasis2.A; var bufferEqual = new byte[this.Width * this.Height]; var bufferUnEqual = new byte[this.Width * this.Height]; int indexBufferEqual = 0; int indexBufferUnEqual = 0; this._pixelAddress = -4; for (int y = 0; y < this.Height; y++) { int index; byte[] buffer; if (y % 2 == 0) { index = indexBufferEqual; buffer = bufferEqual; } else { index = indexBufferUnEqual; buffer = bufferUnEqual; } var indexHalfNibble = false; var lastColor = -1; var count = 0; for (int x = 0; x < this.Width; x++) { int color = this.GetDvdColor(patternBuffer, emphasis1Buffer, emphasis2Buffer); if (lastColor == -1) { lastColor = color; count = 1; } else if (lastColor == color && count < 64) { // only allow up to 63 run-length (for SubtitleCreator compatibility) count++; } else { WriteRle(ref indexHalfNibble, lastColor, count, ref index, buffer); lastColor = color; count = 1; } } if (count > 0) { WriteRle(ref indexHalfNibble, lastColor, count, ref index, buffer); } if (indexHalfNibble) { index++; } if (y % 2 == 0) { indexBufferEqual = index; bufferEqual = buffer; } else { indexBufferUnEqual = index; bufferUnEqual = buffer; } } var twoParts = new RunLengthTwoParts { Buffer1 = new byte[indexBufferEqual] }; Buffer.BlockCopy(bufferEqual, 0, twoParts.Buffer1, 0, indexBufferEqual); twoParts.Buffer2 = new byte[indexBufferUnEqual + 2]; Buffer.BlockCopy(bufferUnEqual, 0, twoParts.Buffer2, 0, indexBufferUnEqual); return twoParts; }