AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
TextureScale.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 // See http://wiki.unity3d.com/index.php/TextureScale
5 
6 using System.Threading;
7 using UnityEngine;
8 
9 namespace HoloToolkit.Unity
10 {
11  public static class TextureScale
12  {
13  private class ThreadData
14  {
15  public readonly int Start;
16  public readonly int End;
17 
18  public ThreadData(int s, int e)
19  {
20  Start = s;
21  End = e;
22  }
23  }
24 
25  private static Color[] texColors;
26  private static Color[] newColors;
27  private static int w;
28  private static float ratioX;
29  private static float ratioY;
30  private static int w2;
31  private static int finishCount;
32  private static Mutex mutex;
33 
34  public static void Point(Texture2D tex, int newWidth, int newHeight)
35  {
36  ThreadedScale(tex, newWidth, newHeight, false);
37  }
38 
39  public static void Bilinear(Texture2D tex, int newWidth, int newHeight)
40  {
41  ThreadedScale(tex, newWidth, newHeight, true);
42  }
43 
44  private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear)
45  {
46  texColors = tex.GetPixels();
47  newColors = new Color[newWidth * newHeight];
48  if (useBilinear)
49  {
50  ratioX = 1.0f / ((float)newWidth / (tex.width - 1));
51  ratioY = 1.0f / ((float)newHeight / (tex.height - 1));
52  }
53  else
54  {
55  ratioX = (float)tex.width / newWidth;
56  ratioY = (float)tex.height / newHeight;
57  }
58  w = tex.width;
59  w2 = newWidth;
60  var cores = Mathf.Min(SystemInfo.processorCount, newHeight);
61  var slice = newHeight / cores;
62 
63  finishCount = 0;
64 
65  if (mutex == null)
66  {
67  mutex = new Mutex(false);
68  }
69 
70  if (cores > 1)
71  {
72  int i;
73  ThreadData threadData;
74 
75  for (i = 0; i < cores - 1; i++)
76  {
77  threadData = new ThreadData(slice * i, slice * (i + 1));
78  ParameterizedThreadStart ts = useBilinear ? BilinearScale : new ParameterizedThreadStart(PointScale);
79  var thread = new Thread(ts);
80  thread.Start(threadData);
81  }
82 
83  threadData = new ThreadData(slice * i, newHeight);
84  if (useBilinear)
85  {
86  BilinearScale(threadData);
87  }
88  else
89  {
90  PointScale(threadData);
91  }
92 
93  while (finishCount < cores)
94  {
95  Thread.Sleep(1);
96  }
97  }
98  else
99  {
100  var threadData = new ThreadData(0, newHeight);
101 
102  if (useBilinear)
103  {
104  BilinearScale(threadData);
105  }
106  else
107  {
108  PointScale(threadData);
109  }
110  }
111 
112  tex.Resize(newWidth, newHeight, TextureFormat.ARGB32, false);
113  tex.SetPixels(newColors);
114  tex.Apply();
115 
116  texColors = null;
117  newColors = null;
118  }
119 
120  public static void BilinearScale(object obj)
121  {
122  var threadData = (ThreadData)obj;
123  for (var y = threadData.Start; y < threadData.End; y++)
124  {
125  int yFloor = (int)Mathf.Floor(y * ratioY);
126  var y1 = yFloor * w;
127  var y2 = (yFloor + 1) * w;
128  var yw = y * w2;
129 
130  for (var x = 0; x < w2; x++)
131  {
132  int xFloor = (int)Mathf.Floor(x * ratioX);
133  var xLerp = x * ratioX - xFloor;
134  newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor + 1], xLerp),
135  ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor + 1], xLerp),
136  y * ratioY - yFloor);
137  }
138  }
139 
140  mutex.WaitOne();
141  finishCount++;
142  mutex.ReleaseMutex();
143  }
144 
145  public static void PointScale(object obj)
146  {
147  var threadData = (ThreadData)obj;
148  for (var y = threadData.Start; y < threadData.End; y++)
149  {
150  var thisY = (int)(ratioY * y) * w;
151  var yw = y * w2;
152  for (var x = 0; x < w2; x++)
153  {
154  newColors[yw + x] = texColors[(int)(thisY + ratioX * x)];
155  }
156  }
157 
158  mutex.WaitOne();
159  finishCount++;
160  mutex.ReleaseMutex();
161  }
162 
163  private static Color ColorLerpUnclamped(Color c1, Color c2, float value)
164  {
165  return new Color(c1.r + (c2.r - c1.r) * value,
166  c1.g + (c2.g - c1.g) * value,
167  c1.b + (c2.b - c1.b) * value,
168  c1.a + (c2.a - c1.a) * value);
169  }
170  }
171 }
static void Point(Texture2D tex, int newWidth, int newHeight)
Definition: TextureScale.cs:34
static void PointScale(object obj)
static void Bilinear(Texture2D tex, int newWidth, int newHeight)
Definition: TextureScale.cs:39
static void BilinearScale(object obj)