summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite/src/generic/Util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite/src/generic/Util.cpp')
-rw-r--r--Build/source/libs/graphite/src/generic/Util.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/src/generic/Util.cpp b/Build/source/libs/graphite/src/generic/Util.cpp
new file mode 100644
index 00000000000..aabd6563d3e
--- /dev/null
+++ b/Build/source/libs/graphite/src/generic/Util.cpp
@@ -0,0 +1,261 @@
+
+#include "GrCommon.h"
+#include "GrDebug.h"
+
+
+namespace gr
+{
+
+/*----------------------------------------------------------------------------------------------
+ Swap two blocks of size cb starting at pv1 and pv2. Doesn't handle overlapping blocks.
+----------------------------------------------------------------------------------------------*/
+void SwapBytes(void * pv1, void * pv2, int cb)
+{
+ Assert((byte *)pv1 + cb <= (byte *)pv2 || (byte *)pv2 + cb <= (byte *)pv1);
+ AssertPtrSize(pv1, cb);
+ AssertPtrSize(pv2, cb);
+
+#ifdef NO_ASM
+
+ byte *pb1 = (byte *)pv1;
+ byte *pb2 = (byte *)pv2;
+ byte b;
+
+ while (--cb >= 0)
+ {
+ b = *pb1;
+ *pb1++ = *pb2;
+ *pb2++ = b;
+ }
+
+#else // !NO_ASM
+
+ __asm
+ {
+ // edi -> memory to swap, first pointer
+ // esi -> memory to swap, second pointer
+
+ mov edi,pv1
+ mov esi,pv2
+
+ mov ecx,cb
+ shr ecx,2
+ jz LBytes
+
+LIntLoop:
+ mov eax,[edi]
+ mov ebx,[esi]
+ mov [edi],ebx
+ mov [esi],eax
+
+ add edi,4
+ add esi,4
+ dec ecx
+ jnz LIntLoop;
+
+LBytes:
+ mov ecx,cb
+ and ecx,3
+ jz LDone
+
+LByteLoop:
+ mov al,[edi]
+ mov bl,[esi]
+ mov [edi],bl
+ mov [esi],al
+ inc edi
+ inc esi
+ dec ecx
+ jnz LByteLoop
+
+LDone:
+ }
+
+#endif //!NO_ASM
+}
+
+/*----------------------------------------------------------------------------------------------
+ Fills a block of memory with the given short value.
+----------------------------------------------------------------------------------------------*/
+void FillShorts(void * pv, short sn, int csn)
+{
+ AssertPtrSize(pv, csn * isizeof(short));
+
+#ifdef NO_ASM
+
+ short * psn = (short *)pv;
+ short * psnLim = psn + csn;
+
+ while (psn < psnLim)
+ *psn++ = sn;
+
+#else // !NO_ASM
+
+ __asm
+ {
+ // Setup the registers for using REP STOS instruction to set memory.
+ // NOTE: Alignment does not effect the speed of STOS.
+ //
+ // edi -> memory to set
+ // eax = value to store in destination
+ // direction flag is clear for auto-increment
+
+ mov edi,pv
+ mov ax,sn
+ mov ecx,csn
+
+ mov edx,ecx
+ and edx,1
+ jz LInts
+
+ // set 1 short
+ stosw
+
+LInts:
+ shr ecx,1
+ jz LDone
+
+ mov ebx,eax
+ shl eax,16
+ mov ax,bx
+
+ rep stosd
+LDone:
+ }
+
+#endif //!NO_ASM
+}
+
+/***********************************************************************************************
+ Integer utilities.
+***********************************************************************************************/
+
+/*
+ * table of powers of 2, and largest prime smaller than each power of 2
+ * n 2**n prime diff
+ * --- ---------- ---------- ----
+ * 2: 4 3 ( -1)
+ * 3: 8 7 ( -1)
+ * 4: 16 13 ( -3)
+ * 5: 32 31 ( -1)
+ * 6: 64 61 ( -3)
+ * 7: 128 127 ( -1)
+ * 8: 256 251 ( -5)
+ * 9: 512 509 ( -3)
+ * 10: 1024 1021 ( -3)
+ * 11: 2048 2039 ( -9)
+ * 12: 4096 4093 ( -3)
+ * 13: 8192 8191 ( -1)
+ * 14: 16384 16381 ( -3)
+ * 15: 32768 32749 (-19)
+ * 16: 65536 65521 (-15)
+ * 17: 131072 131071 ( -1)
+ * 18: 262144 262139 ( -5)
+ * 19: 524288 524287 ( -1)
+ * 20: 1048576 1048573 ( -3)
+ * 21: 2097152 2097143 ( -9)
+ * 22: 4194304 4194301 ( -3)
+ * 23: 8388608 8388593 (-15)
+ * 24: 16777216 16777213 ( -3)
+ * 25: 33554432 33554393 (-39)
+ * 26: 67108864 67108859 ( -5)
+ * 27: 134217728 134217689 (-39)
+ * 28: 268435456 268435399 (-57)
+ * 29: 536870912 536870909 ( -3)
+ * 30: 1073741824 1073741789 (-35)
+ * 31: 2147483648 2147483647 ( -1)
+ * 32: 4294967296 4294967291 ( -5)
+ */
+const static unsigned int g_rguPrimes[] = {
+ 3, 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071,
+ 262139, 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859,
+ 134217689, 268435399, 536870909, 1073741789, 2147483647, 4294967291U
+};
+
+
+/*----------------------------------------------------------------------------------------------
+ Returns the prime in g_rguPrimes that is closest to u.
+----------------------------------------------------------------------------------------------*/
+unsigned int GetPrimeNear(unsigned int u)
+{
+ int cu = isizeof(g_rguPrimes) / isizeof(unsigned int);
+ int iuMin;
+ int iuLim;
+ int iu;
+
+ for (iuMin = 0, iuLim = cu; iuMin < iuLim; )
+ {
+ iu = (iuMin + iuLim) / 2;
+ if (u > g_rguPrimes[iu])
+ iuMin = iu + 1;
+ else
+ iuLim = iu;
+ }
+ Assert(iuMin == cu || iuMin < cu && u <= g_rguPrimes[iuMin]);
+ Assert(iuMin == 0 || iuMin > 0 && u > g_rguPrimes[iuMin - 1]);
+
+ if (!iuMin)
+ return g_rguPrimes[0];
+ if (iuMin == cu)
+ return g_rguPrimes[cu - 1];
+ if (g_rguPrimes[iuMin] - u < u - g_rguPrimes[iuMin - 1])
+ return g_rguPrimes[iuMin];
+ return g_rguPrimes[iuMin - 1];
+}
+
+
+/*----------------------------------------------------------------------------------------------
+ Returns the prime in g_rguPrimes that is larger than u or is the largest in the list.
+----------------------------------------------------------------------------------------------*/
+unsigned int GetLargerPrime(unsigned int u)
+{
+ int cu = isizeof(g_rguPrimes) / isizeof(unsigned int);
+ int iuMin;
+ int iuLim;
+ int iu;
+
+ for (iuMin = 0, iuLim = cu; iuMin < iuLim; )
+ {
+ iu = (iuMin + iuLim) / 2;
+ if (u >= g_rguPrimes[iu])
+ iuMin = iu + 1;
+ else
+ iuLim = iu;
+ }
+ Assert(iuMin == cu || iuMin < cu && u < g_rguPrimes[iuMin]);
+ Assert(iuMin == 0 || iuMin > 0 && u >= g_rguPrimes[iuMin - 1]);
+
+ if (iuMin == cu)
+ return g_rguPrimes[cu - 1];
+ return g_rguPrimes[iuMin];
+}
+
+
+/*----------------------------------------------------------------------------------------------
+ Returns the prime in g_rguPrimes that is smaller than u or is the smallest in the list.
+----------------------------------------------------------------------------------------------*/
+unsigned int GetSmallerPrime(unsigned int u)
+{
+ int cu = isizeof(g_rguPrimes) / isizeof(unsigned int);
+ int iuMin;
+ int iuLim;
+ int iu;
+
+ for (iuMin = 0, iuLim = cu; iuMin < iuLim; )
+ {
+ iu = (iuMin + iuLim) / 2;
+ if (u > g_rguPrimes[iu])
+ iuMin = iu + 1;
+ else
+ iuLim = iu;
+ }
+ Assert(iuMin == cu || iuMin < cu && u <= g_rguPrimes[iuMin]);
+ Assert(iuMin == 0 || iuMin > 0 && u > g_rguPrimes[iuMin - 1]);
+
+ if (!iuMin)
+ return g_rguPrimes[0];
+ return g_rguPrimes[iuMin - 1];
+}
+
+}
+