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[Width * Height]; var bufferUnEqual = new byte[Width * Height]; int indexBufferEqual = 0; int indexBufferUnEqual = 0; _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; } var indexHalfNibble = false; var lastColor = -1; var count = 0; for (int x = 0; x < Width; x++) { int color = 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); }
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[Width * Height]; var bufferUnEqual = new byte[Width * Height]; int indexBufferEqual = 0; int indexBufferUnEqual = 0; _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; } var indexHalfNibble = false; var lastColor = -1; var count = 0; for (int x = 0; x < Width; x++) { int color = 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; }