// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: AttemptThreadJoggingRequest.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//////////////////////////////////////////////////////////////////////////////////
// Paint.NET //
// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
// See src/Resources/Files/License.txt for full licensing and attribution //
// details. //
// . //
/////////////////////////////////////////////////////////////////////////////////
// Based on: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/colorquant.asp
using Tango.RemoteDesktop.Quantization;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Tango.RemoteDesktop.Quantization
{
internal unsafe abstract class Quantizer
{
/// <summary>
/// Flag used to indicate whether a single pass or two passes are needed for quantization.
/// </summary>
private bool singlePass;
protected int ditherLevel;
public int DitherLevel
{
get
{
return this.ditherLevel;
}
set
{
this.ditherLevel = value;
}
}
/// <summary>
/// Construct the quantizer
/// </summary>
/// <param name="singlePass">If true, the quantization only needs to loop through the source pixels once</param>
/// <remarks>
/// If you construct this class with a true value for singlePass, then the code will, when quantizing your image,
/// only call the 'QuantizeImage' function. If two passes are required, the code will call 'InitialQuantizeImage'
/// and then 'QuantizeImage'.
/// </remarks>
public Quantizer(bool singlePass)
{
this.singlePass = singlePass;
}
/// <summary>
/// Quantize an image and return the resulting output bitmap
/// </summary>
/// <param name="source">The image to quantize</param>
/// <returns>A quantized version of the image</returns>
public Bitmap Quantize(Image source)
{
// Get the size of the source image
int height = source.Height;
int width = source.Width;
// And construct a rectangle from these dimensions
Rectangle bounds = new Rectangle(0, 0, width, height);
// First off take a 32bpp version of the image
Bitmap img32bpp;
if (source is Bitmap && source.PixelFormat == PixelFormat.Format32bppArgb)
{
img32bpp = (Bitmap)source;
}
else
{
img32bpp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
// Now lock the bitmap into memory
using (Graphics g = Graphics.FromImage(img32bpp))
{
g.PageUnit = GraphicsUnit.Pixel;
// Draw the source image onto the copy bitmap,
// which will effect a widening as appropriate.
g.DrawImage(source, 0, 0, bounds.Width, bounds.Height);
}
}
// And construct an 8bpp version
Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
// Define a pointer to the bitmap data
BitmapData sourceData = null;
try
{
// Get the source image bits and lock into memory
sourceData = img32bpp.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Call the FirstPass function if not a single pass algorithm.
// For something like an octree quantizer, this will run through
// all image pixels, build a data structure, and create a palette.
if (!singlePass)
{
FirstPass(sourceData, width, height);
}
// Then set the color palette on the output bitmap. I'm passing in the current palette
// as there's no way to construct a new, empty palette.
output.Palette = this.GetPalette(output.Palette);
// Then call the second pass which actually does the conversion
SecondPass(sourceData, output, width, height, bounds);
}
finally
{
// Ensure that the bits are unlocked
img32bpp.UnlockBits(sourceData);
}
if (img32bpp != source)
{
img32bpp.Dispose();
img32bpp = null;
}
// Last but not least, return the output bitmap
return output;
}
/// <summary>
/// Execute the first pass through the pixels in the image
/// </summary>
/// <param name="sourceData">The source data</param>
/// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param>
protected virtual void FirstPass(BitmapData sourceData, int width, int height)
{
// Define the source data pointers. The source row is a byte to
// keep addition of the stride value easier (as this is in bytes)
byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer();
Int32* pSourcePixel;
// Loop through each row
for (int row = 0; row < height; row++)
{
// Set the source pixel to the first pixel in this row
pSourcePixel = (Int32*)pSourceRow;
// And loop through each column
for (int col = 0; col < width; col++, pSourcePixel++)
{
InitialQuantizePixel((ColorBgra *)pSourcePixel);
}
// Add the stride to the source row
pSourceRow += sourceData.Stride;
}
}
/// <summary>
/// Execute a second pass through the bitmap
/// </summary>
/// <param name="sourceData">The source bitmap, locked into memory</param>
/// <param name="output">The output bitmap</param>
/// <param name="width">The width in pixels of the image</param>
/// <param name="height">The height in pixels of the image</param>
/// <param name="bounds">The bounding rectangle</param>
protected virtual void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds)
{
BitmapData outputData = null;
Color[] pallete = output.Palette.Entries;
int weight = ditherLevel;
try
{
// Lock the output bitmap into memory
outputData = output.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
// Define the source data pointers. The source row is a byte to
// keep addition of the stride value easier (as this is in bytes)
byte* pSourceRow = (byte *)sourceData.Scan0.ToPointer();
Int32* pSourcePixel = (Int32 *)pSourceRow;
// Now define the destination data pointers
byte* pDestinationRow = (byte *)outputData.Scan0.ToPointer();
byte* pDestinationPixel = pDestinationRow;
int[] errorThisRowR = new int[width + 1];
int[] errorThisRowG = new int[width + 1];
int[] errorThisRowB = new int[width + 1];
for (int row = 0; row < height; row++)
{
int[] errorNextRowR = new int[width + 1];
int[] errorNextRowG = new int[width + 1];
int[] errorNextRowB = new int[width + 1];
int ptrInc;
if ((row & 1) == 0)
{
pSourcePixel = (Int32*)pSourceRow;
pDestinationPixel = pDestinationRow;
ptrInc = +1;
}
else
{
pSourcePixel = (Int32*)pSourceRow + width - 1;
pDestinationPixel = pDestinationRow + width - 1;
ptrInc = -1;
}
// Loop through each pixel on this scan line
for (int col = 0; col < width; ++col)
{
// Quantize the pixel
ColorBgra srcPixel = *(ColorBgra *)pSourcePixel;
ColorBgra target = new ColorBgra();
target.B = Utility.ClampToByte(srcPixel.B - ((errorThisRowB[col] * weight) / 8));
target.G = Utility.ClampToByte(srcPixel.G - ((errorThisRowG[col] * weight) / 8));
target.R = Utility.ClampToByte(srcPixel.R - ((errorThisRowR[col] * weight) / 8));
target.A = srcPixel.A;
byte pixelValue = QuantizePixel(&target);
*pDestinationPixel = pixelValue;
ColorBgra actual = ColorBgra.FromColor(pallete[pixelValue]);
int errorR = actual.R - target.R;
int errorG = actual.G - target.G;
int errorB = actual.B - target.B;
// Floyd-Steinberg Error Diffusion:
// a) 7/16 error goes to x+1
// b) 5/16 error goes to y+1
// c) 3/16 error goes to x-1,y+1
// d) 1/16 error goes to x+1,y+1
const int a = 7;
const int b = 5;
const int c = 3;
int errorRa = (errorR * a) / 16;
int errorRb = (errorR * b) / 16;
int errorRc = (errorR * c) / 16;
int errorRd = errorR - errorRa - errorRb - errorRc;
int errorGa = (errorG * a) / 16;
int errorGb = (errorG * b) / 16;
int errorGc = (errorG * c) / 16;
int errorGd = errorG - errorGa - errorGb - errorGc;
int errorBa = (errorB * a) / 16;
int errorBb = (errorB * b) / 16;
int errorBc = (errorB * c) / 16;
int errorBd = errorB - errorBa - errorBb - errorBc;
errorThisRowR[col + 1] += errorRa;
errorThisRowG[col + 1] += errorGa;
errorThisRowB[col + 1] += errorBa;
errorNextRowR[width - col] += errorRb;
errorNextRowG[width - col] += errorGb;
errorNextRowB[width - col] += errorBb;
if (col != 0)
{
errorNextRowR[width - (col - 1)] += errorRc;
errorNextRowG[width - (col - 1)] += errorGc;
errorNextRowB[width - (col - 1)] += errorBc;
}
errorNextRowR[width - (col + 1)] += errorRd;
errorNextRowG[width - (col + 1)] += errorGd;
errorNextRowB[width - (col + 1)] += errorBd;
// unchecked is necessary because otherwise it throws a fit if ptrInc is negative.
unchecked
{
pSourcePixel += ptrInc;
pDestinationPixel += ptrInc;
}
}
// Add the stride to the source row
pSourceRow += sourceData.Stride;
// And to the destination row
pDestinationRow += outputData.Stride;
errorThisRowB = errorNextRowB;
errorThisRowG = errorNextRowG;
errorThisRowR = errorNextRowR;
}
}
finally
{
// Ensure that I unlock the output bits
output.UnlockBits(outputData);
}
}
/// <summary>
/// Override this to process the pixel in the first pass of the algorithm
/// </summary>
/// <param name="pixel">The pixel to quantize</param>
/// <remarks>
/// This function need only be overridden if your quantize algorithm needs two passes,
/// such as an Octree quantizer.
/// </remarks>
protected virtual void InitialQuantizePixel(ColorBgra *pixel)
{
}
/// <summary>
/// Override this to process the pixel in the second pass of the algorithm
/// </summary>
/// <param name="pixel">The pixel to quantize</param>
/// <returns>The quantized value</returns>
protected abstract byte QuantizePixel(ColorBgra *pixel);
/// <summary>
/// Retrieve the palette for the quantized image
/// </summary>
/// <param name="original">Any old palette, this is overrwritten</param>
/// <returns>The new color palette</returns>
protected abstract ColorPalette GetPalette(ColorPalette original);
}
}