Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.26 KB | None | 0 0
  1. // <copyright file="YCbCrToRgbTables.cs" company="James Jackson-South">
  2. // Copyright (c) James Jackson-South and contributors.
  3. // Licensed under the Apache License, Version 2.0.
  4. // </copyright>
  5.  
  6. namespace ImageSharp.Formats.Jpeg.Components.Decoder
  7. {
  8. using System.Runtime.CompilerServices;
  9.  
  10. using ImageSharp.PixelFormats;
  11.  
  12. /// <summary>
  13. /// Provides lookup tables for converting from YCbCr to Rgb colorspace.
  14. /// Methods to build the tables are identical to libjpeg.
  15. /// </summary>
  16. internal struct YCbCrToRgbTables
  17. {
  18. private const int ScaleBits = 16;
  19.  
  20. private const int Half = 1 << (ScaleBits - 1);
  21.  
  22. private static readonly int[] CrRTable = new int[256];
  23.  
  24. private static readonly int[] CbBTable = new int[256];
  25.  
  26. private static readonly int[] CrGTable = new int[256];
  27.  
  28. private static readonly int[] CbGTable = new int[256];
  29.  
  30. /// <summary>
  31. /// Optimized method to pack bytes to the image from the YCbCr color space.
  32. /// </summary>
  33. /// <typeparam name="TPixel">The pixel format.</typeparam>
  34. /// <param name="packed">The packed pixel.</param>
  35. /// <param name="y">The y luminance component.</param>
  36. /// <param name="cb">The cb chroma component.</param>
  37. /// <param name="cr">The cr chroma component.</param>
  38. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  39. public void Pack<TPixel>(ref TPixel packed, byte y, byte cb, byte cr)
  40. where TPixel : struct, IPixel<TPixel>
  41. {
  42. byte r = (byte)(y + CrRTable[cr]).Clamp(0, 255);
  43.  
  44. // The values for the G calculation are left scaled up, since we must add them together before rounding.
  45. byte g = (byte)(y + RightShift(CbGTable[cb] + CrGTable[cr])).Clamp(0, 255);
  46. byte b = (byte)(y + CbBTable[cb]).Clamp(0, 255);
  47.  
  48. packed.PackFromBytes(r, g, b, byte.MaxValue);
  49. }
  50.  
  51. /// <summary>
  52. /// Initializes the YCbCr tables
  53. /// </summary>
  54. /// <returns>The intialized <see cref="YCbCrToRgbTables"/></returns>
  55. public YCbCrToRgbTables Init()
  56. {
  57. for (int i = 0, x = -128; i <= 255; i++, x++)
  58. {
  59. // i is the actual input pixel value, in the range 0..255
  60. // The Cb or Cr value we are thinking of is x = i - 128
  61. // Cr=>R value is nearest int to 1.402 * x
  62. CrRTable[i] = RightShift((Fix(1.402F) * x) + Half);
  63.  
  64. // Cb=>B value is nearest int to 1.772 * x
  65. CbBTable[i] = RightShift((Fix(1.772F) * x) + Half);
  66.  
  67. // Cr=>G value is scaled-up -0.714136286
  68. CrGTable[i] = (-Fix(0.714136286F)) * x;
  69.  
  70. // Cb => G value is scaled - up - 0.344136286 * x
  71. // We also add in Half so that need not do it in inner loop
  72. CbGTable[i] = ((-Fix(0.344136286F)) * x) + Half;
  73. }
  74.  
  75. return this;
  76. }
  77.  
  78. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  79. private static int Fix(float x)
  80. {
  81. return (int)((x * (1L << ScaleBits)) + 0.5F);
  82. }
  83.  
  84. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  85. private static int RightShift(int x)
  86. {
  87. return x >> ScaleBits;
  88. }
  89. }
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement