PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Effects/PosterizeAdjustment.cs

https://bitbucket.org/tuldok89/openpdn
C# | 208 lines | 144 code | 34 blank | 30 comment | 5 complexity | 985c9ba29693980a8dae5b62bb679836 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Paint.NET //
  3. // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
  4. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
  5. // See src/Resources/Files/License.txt for full licensing and attribution //
  6. // details. //
  7. // . //
  8. /////////////////////////////////////////////////////////////////////////////////
  9. // Copyright (c) 2007,2008 Ed Harvey
  10. //
  11. // MIT License: http://www.opensource.org/licenses/mit-license.php
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining a copy
  14. // of this software and associated documentation files (the "Software"), to deal
  15. // in the Software without restriction, including without limitation the rights
  16. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  17. // copies of the Software, and to permit persons to whom the Software is
  18. // furnished to do so, subject to the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be included in
  21. // all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  24. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  26. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  27. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  28. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  29. // THE SOFTWARE.
  30. //
  31. using System.Collections.Generic;
  32. using System.Drawing;
  33. using PaintDotNet.Base.PropertySystem;
  34. using PaintDotNet.IndirectUI;
  35. namespace PaintDotNet.Effects
  36. {
  37. [EffectCategory(EffectCategory.Adjustment)]
  38. public sealed class PosterizeAdjustment
  39. : InternalPropertyBasedEffect
  40. {
  41. private class PosterizePixelOp
  42. : UnaryPixelOp
  43. {
  44. private readonly byte[] _redLevels;
  45. private readonly byte[] _greenLevels;
  46. private readonly byte[] _blueLevels;
  47. public PosterizePixelOp(int red, int green, int blue)
  48. {
  49. _redLevels = CalcLevels(red);
  50. _greenLevels = CalcLevels(green);
  51. _blueLevels = CalcLevels(blue);
  52. }
  53. private static byte[] CalcLevels(int levelCount)
  54. {
  55. var t1 = new byte[levelCount];
  56. for (int i = 1; i < levelCount; i++)
  57. {
  58. t1[i] = (byte)((255 * i) / (levelCount - 1));
  59. }
  60. var levels = new byte[256];
  61. int j = 0;
  62. int k = 0;
  63. for (int i = 0; i < 256; i++)
  64. {
  65. levels[i] = t1[j];
  66. k += levelCount;
  67. if (k <= 255) continue;
  68. k -= 255;
  69. j++;
  70. }
  71. return levels;
  72. }
  73. public override ColorBgra Apply(ColorBgra color)
  74. {
  75. return ColorBgra.FromBgra(_blueLevels[color.B], _greenLevels[color.G], _redLevels[color.R], color.A);
  76. }
  77. public unsafe override void Apply(ColorBgra* ptr, int length)
  78. {
  79. while (length > 0)
  80. {
  81. ptr->B = _blueLevels[ptr->B];
  82. ptr->G = _greenLevels[ptr->G];
  83. ptr->R = _redLevels[ptr->R];
  84. ++ptr;
  85. --length;
  86. }
  87. }
  88. public unsafe override void Apply(ColorBgra* dst, ColorBgra* src, int length)
  89. {
  90. while (length > 0)
  91. {
  92. dst->B = _blueLevels[src->B];
  93. dst->G = _greenLevels[src->G];
  94. dst->R = _redLevels[src->R];
  95. dst->A = src->A;
  96. ++dst;
  97. ++src;
  98. --length;
  99. }
  100. }
  101. }
  102. private UnaryPixelOp _op;
  103. public PosterizeAdjustment()
  104. : base(PdnResources.GetString("PosterizeAdjustment.Name"),
  105. PdnResources.GetImageResource("Icons.PosterizeEffectIcon.png").Reference,
  106. null,
  107. EffectFlags.Configurable)
  108. {
  109. }
  110. public enum PropertyNames
  111. {
  112. RedLevels = 0,
  113. GreenLevels = 1,
  114. BlueLevels = 2,
  115. LinkLevels = 3
  116. }
  117. protected override PropertyCollection OnCreatePropertyCollection()
  118. {
  119. var props = new List<Property>
  120. {
  121. new Int32Property(PropertyNames.RedLevels, 16, 2, 64),
  122. new Int32Property(PropertyNames.GreenLevels, 16, 2, 64),
  123. new Int32Property(PropertyNames.BlueLevels, 16, 2, 64),
  124. new BooleanProperty(PropertyNames.LinkLevels, true)
  125. };
  126. var rules = new List<PropertyCollectionRule>
  127. {
  128. new LinkValuesBasedOnBooleanRule<int, Int32Property>(
  129. new object[]
  130. {PropertyNames.RedLevels, PropertyNames.GreenLevels, PropertyNames.BlueLevels},
  131. PropertyNames.LinkLevels,
  132. false)
  133. };
  134. return new PropertyCollection(props, rules);
  135. }
  136. protected override ControlInfo OnCreateConfigUI(PropertyCollection props)
  137. {
  138. ControlInfo info = CreateDefaultConfigUI(props);
  139. info.SetPropertyControlValue(
  140. PropertyNames.RedLevels,
  141. ControlInfoPropertyNames.DisplayName,
  142. PdnResources.GetString("PosterizeAdjustment.ConfigDialog.RedLevels.DisplayName"));
  143. info.SetPropertyControlValue(
  144. PropertyNames.GreenLevels,
  145. ControlInfoPropertyNames.DisplayName,
  146. PdnResources.GetString("PosterizeAdjustment.ConfigDialog.GreenLevels.DisplayName"));
  147. info.SetPropertyControlValue(
  148. PropertyNames.BlueLevels,
  149. ControlInfoPropertyNames.DisplayName,
  150. PdnResources.GetString("PosterizeAdjustment.ConfigDialog.BlueLevels.DisplayName"));
  151. info.SetPropertyControlValue(
  152. PropertyNames.LinkLevels,
  153. ControlInfoPropertyNames.DisplayName,
  154. string.Empty);
  155. info.SetPropertyControlValue(
  156. PropertyNames.LinkLevels,
  157. ControlInfoPropertyNames.Description,
  158. PdnResources.GetString("PosterizeAdjustment.ConfigDialog.LinkLevels.Description"));
  159. return info;
  160. }
  161. protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs)
  162. {
  163. int red = newToken.GetProperty<Int32Property>(PropertyNames.RedLevels).Value;
  164. int green = newToken.GetProperty<Int32Property>(PropertyNames.GreenLevels).Value;
  165. int blue = newToken.GetProperty<Int32Property>(PropertyNames.BlueLevels).Value;
  166. _op = new PosterizePixelOp(red, green, blue);
  167. base.OnSetRenderInfo(newToken, dstArgs, srcArgs);
  168. }
  169. protected override void OnRender(Rectangle[] renderRects, int startIndex, int length)
  170. {
  171. _op.Apply(DstArgs.Surface, SrcArgs.Surface, renderRects, startIndex, length);
  172. }
  173. }
  174. }