Add the ChameleonMan PowerVR sample.
BUG=14598298
Change-Id: Id6dcaebe793cf3d3a10af571348f461023d2a9d2
Reviewed-on: https://swiftshader-review.googlesource.com/1090
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/tests/third_party/PowerVR/Tools/PVRTUnicode.cpp b/tests/third_party/PowerVR/Tools/PVRTUnicode.cpp
new file mode 100644
index 0000000..b96b95a
--- /dev/null
+++ b/tests/third_party/PowerVR/Tools/PVRTUnicode.cpp
@@ -0,0 +1,349 @@
+/******************************************************************************
+
+ @File PVRTUnicode.cpp
+
+ @Title PVRTUnicode
+
+ @Version @Version
+
+ @Copyright Copyright (c) Imagination Technologies Limited.
+
+ @Platform All
+
+ @Description A small collection of functions used to decode Unicode formats to
+ individual code points.
+
+******************************************************************************/
+#include "PVRTUnicode.h"
+#include <string.h>
+
+/****************************************************************************
+** Constants
+****************************************************************************/
+const PVRTuint32 c_u32ReplChar = 0xFFFD;
+
+#define VALID_ASCII 0x80
+#define TAIL_MASK 0x3F
+#define BYTES_PER_TAIL 6
+
+#define UTF16_SURG_H_MARK 0xD800
+#define UTF16_SURG_H_END 0xDBFF
+#define UTF16_SURG_L_MARK 0xDC00
+#define UTF16_SURG_L_END 0xDFFF
+
+#define UNICODE_NONCHAR_MARK 0xFDD0
+#define UNICODE_NONCHAR_END 0xFDEF
+#define UNICODE_RESERVED 0xFFFE
+#define UNICODE_MAX 0x10FFFF
+
+#define MAX_LEN 0x8FFF
+
+/****************************************************************************
+** A table which allows quick lookup to determine the number of bytes of a
+** UTF8 code point.
+****************************************************************************/
+const PVRTuint8 c_u8UTF8Lengths[256] =
+{
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,
+};
+
+/****************************************************************************
+** A table which allows quick lookup to determine whether a UTF8 sequence
+** is 'overlong'.
+****************************************************************************/
+const PVRTuint32 c_u32MinVals[4] =
+{
+ 0x00000000, // 0 tail bytes
+ 0x00000080, // 1 tail bytes
+ 0x00000800, // 2 tail bytes
+ 0x00010000, // 3 tail bytes
+};
+
+/*!***************************************************************************
+ @Function CheckGenericUnicode
+ @Input c32 A UTF32 character/Unicode code point
+ @Returns Success or failure.
+ @Description Checks that the decoded code point is valid.
+*****************************************************************************/
+static bool CheckGenericUnicode(PVRTuint32 c32)
+{
+ // Check that this value isn't a UTF16 surrogate mask.
+ if(c32 >= UTF16_SURG_H_MARK && c32 <= UTF16_SURG_L_END)
+ return false;
+ // Check non-char values
+ if(c32 >= UNICODE_NONCHAR_MARK && c32 <= UNICODE_NONCHAR_END)
+ return false;
+ // Check reserved values
+ if((c32 & UNICODE_RESERVED) == UNICODE_RESERVED)
+ return false;
+ // Check max value.
+ if(c32 > UNICODE_MAX)
+ return false;
+
+ return true;
+}
+
+/*!***************************************************************************
+ @Function PVRTUnicodeUTF8ToUTF32
+ @Input pUTF8 A UTF8 string, which is null terminated.
+ @Output aUTF32 An array of Unicode code points.
+ @Returns Success or failure.
+ @Description Decodes a UTF8-encoded string in to Unicode code points
+ (UTF32). If pUTF8 is not null terminated, the results are
+ undefined.
+*****************************************************************************/
+EPVRTError PVRTUnicodeUTF8ToUTF32(const PVRTuint8* const pUTF8, CPVRTArray<PVRTuint32>& aUTF32)
+{
+ unsigned int uiTailLen, uiIndex;
+ unsigned int uiBytes = (unsigned int) strlen((const char*)pUTF8);
+ PVRTuint32 c32;
+
+ const PVRTuint8* pC = pUTF8;
+ while(*pC)
+ {
+ // Quick optimisation for ASCII characters
+ while(*pC && *pC < VALID_ASCII)
+ {
+ aUTF32.Append(*pC++);
+ }
+ // Done
+ if(!*pC)
+ break;
+
+ c32 = *pC++;
+ uiTailLen = c_u8UTF8Lengths[c32];
+
+ // Check for invalid tail length. Maximum 4 bytes for each UTF8 character.
+ // Also check to make sure the tail length is inside the provided buffer.
+ if(uiTailLen == 0 || (pC + uiTailLen > pUTF8 + uiBytes))
+ return PVR_OVERFLOW;
+
+ c32 &= (TAIL_MASK >> uiTailLen); // Get the data out of the first byte. This depends on the length of the tail.
+
+ // Get the data out of each tail byte
+ uiIndex = 0;
+ while(uiIndex < uiTailLen)
+ {
+ if((pC[uiIndex] & 0xC0) != 0x80)
+ return PVR_FAIL; // Invalid tail byte!
+
+ c32 = (c32 << BYTES_PER_TAIL) + (pC[uiIndex] & TAIL_MASK);
+ uiIndex++;
+ }
+
+ pC += uiIndex;
+
+ // Check overlong values.
+ if(c32 < c_u32MinVals[uiTailLen])
+ return PVR_FAIL;
+
+ if(!CheckGenericUnicode(c32))
+ return PVR_FAIL;
+
+ // OK
+ aUTF32.Append(c32);
+ }
+
+ return PVR_SUCCESS;
+}
+
+/*!***************************************************************************
+ @Function PVRTUnicodeUTF16ToUTF32
+ @Input pUTF16 A UTF16 string, which is null terminated.
+ @Output aUTF32 An array of Unicode code points.
+ @Returns Success or failure.
+ @Description Decodes a UTF16-encoded string in to Unicode code points
+ (UTF32). If pUTF16 is not null terminated, the results are
+ undefined.
+*****************************************************************************/
+EPVRTError PVRTUnicodeUTF16ToUTF32(const PVRTuint16* const pUTF16, CPVRTArray<PVRTuint32>& aUTF32)
+{
+ const PVRTuint16* pC = pUTF16;
+
+ // Determine the number of shorts
+ while(*++pC && (pC - pUTF16) < MAX_LEN);
+ unsigned int uiBufferLen = (unsigned int) (pC - pUTF16);
+
+ if(uiBufferLen == MAX_LEN)
+ return PVR_OVERFLOW; // Probably not NULL terminated.
+
+ // Reset to start.
+ pC = pUTF16;
+
+ PVRTuint32 c32;
+ while(*pC)
+ {
+ // Straight copy. We'll check for surrogate pairs next...
+ c32 = *pC++;
+
+ // Check surrogate pair
+ if(c32 >= UTF16_SURG_H_MARK && c32 <= UTF16_SURG_H_END)
+ {
+ // Make sure the next 2 bytes are in range...
+ if(pC + 1 > pUTF16 + uiBufferLen || *pC == 0)
+ return PVR_OVERFLOW;
+
+ // Check that the next value is in the low surrogate range
+ if(*pC < UTF16_SURG_L_MARK || *pC > UTF16_SURG_L_END)
+ return PVR_FAIL;
+
+ // Decode
+ c32 = ((c32 - UTF16_SURG_H_MARK) << 10) + (*pC - UTF16_SURG_L_MARK) + 0x10000;
+ pC++;
+ }
+
+ if(!CheckGenericUnicode(c32))
+ return PVR_FAIL;
+
+ // OK
+ aUTF32.Append(c32);
+ }
+
+ return PVR_SUCCESS;
+}
+
+/*!***************************************************************************
+ @Function PVRTUnicodeUTF8Length
+ @Input pUTF8 A UTF8 string, which is null terminated.
+ @Returns The length of the string, in Unicode code points.
+ @Description Calculates the length of a UTF8 string. If pUTF8 is
+ not null terminated, the results are undefined.
+*****************************************************************************/
+unsigned int PVRTUnicodeUTF8Length(const PVRTuint8* const pUTF8)
+{
+ const PVRTuint8* pC = pUTF8;
+
+ unsigned int charCount = 0;
+ unsigned int mask;
+ while(*pC)
+ {
+ // Quick optimisation for ASCII characters
+ const PVRTuint8* pStart = pC;
+ while(*pC && *pC < VALID_ASCII)
+ pC++;
+
+ charCount += (unsigned int) (pC - pStart);
+
+ // Done
+ if(!*pC)
+ break;
+
+ mask = *pC & 0xF0;
+ switch(mask)
+ {
+ case 0xF0: pC++;
+ case 0xE0: pC++;
+ case 0xC0: pC++;
+ break;
+ default:
+ _ASSERT(!"Invalid tail byte!");
+ return 0;
+ }
+
+ pC++;
+ charCount++;
+ }
+
+ return charCount;
+}
+
+/*!***************************************************************************
+ @Function PVRTUnicodeUTF16Length
+ @Input pUTF16 A UTF16 string, which is null terminated.
+ @Returns The length of the string, in Unicode code points.
+ @Description Calculates the length of a UTF16 string.
+ If pUTF16 is not null terminated, the results are
+ undefined.
+*****************************************************************************/
+unsigned int PVRTUnicodeUTF16Length(const PVRTuint16* const pUTF16)
+{
+ const PVRTuint16* pC = pUTF16;
+ unsigned int charCount = 0;
+ while(*pC && (pC - pUTF16) < MAX_LEN)
+ {
+ if( pC[0] >= UTF16_SURG_H_MARK && pC[0] <= UTF16_SURG_H_END
+ && pC[1] >= UTF16_SURG_L_MARK && pC[0] <= UTF16_SURG_L_END)
+ {
+ pC += 2;
+ }
+ else
+ {
+ pC += 1;
+ }
+
+ charCount++;
+ }
+
+ return charCount;
+}
+
+/*!***************************************************************************
+ @Function PVRTUnicodeValidUTF8
+ @Input pUTF8 A UTF8 string, which is null terminated.
+ @Returns true or false
+ @Description Checks whether the encoding of a UTF8 string is valid.
+ If pUTF8 is not null terminated, the results are undefined.
+*****************************************************************************/
+bool PVRTUnicodeValidUTF8(const PVRTuint8* const pUTF8)
+{
+ unsigned int uiTailLen, uiIndex;
+ unsigned int uiBytes = (unsigned int) strlen((const char*)pUTF8);
+ const PVRTuint8* pC = pUTF8;
+ while(*pC)
+ {
+ // Quick optimisation for ASCII characters
+ while(*pC && *pC < VALID_ASCII) pC++;
+ // Done?
+ if(!*pC)
+ break;
+
+ PVRTuint32 c32 = *pC++;
+ uiTailLen = c_u8UTF8Lengths[c32];
+
+ // Check for invalid tail length. Maximum 4 bytes for each UTF8 character.
+ // Also check to make sure the tail length is inside the provided buffer.
+ if(uiTailLen == 0 || (pC + uiTailLen > pUTF8 + uiBytes))
+ return false;
+
+ // Get the data out of each tail byte
+ uiIndex = 0;
+ while(uiIndex < uiTailLen)
+ {
+ if((pC[uiIndex] & 0xC0) != 0x80)
+ return false; // Invalid tail byte!
+
+ c32 = (c32 << BYTES_PER_TAIL) + (pC[uiIndex] & TAIL_MASK);
+ uiIndex++;
+ }
+
+ pC += uiIndex;
+
+ // Check overlong values.
+ if(c32 < c_u32MinVals[uiTailLen])
+ return false;
+ if(!CheckGenericUnicode(c32))
+ return false;
+ }
+
+ return true;
+}
+
+/*****************************************************************************
+ End of file (PVRTUnicode.cpp)
+*****************************************************************************/
+