NVIDIA TESLA P40

NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40
NVIDIA TESLA P40 GPU REGEDIT
NVIDIA TESLA P40 GPU REGEDIT
NVIDIA TESLA P40 GPU
NVIDIA TESLA P40 GPU
NVIDIA TESLA P40 GPUZ
NVIDIA TESLA P40 GPUZ
NVIDIA TESLA P40 NVIDIA-SMI
NVIDIA TESLA P40 NVIDIA-SMI
NVIDIA TESLA P40 NVIDIA GPU
NVIDIA TESLA P40 NVIDIA GPU
NVIDIA TESLA P40 NVIDIA GPU
NVIDIA TESLA P40 NVIDIA GPU

睇人AI繪畫,諗住買NVIDIA顯卡,中古RTX3060都要兩千幾,

可能係機房大批淘汰,Tesla P40-24GB係網大量焦拋售,柒百伍包郵,成色麻麻.配NVIDIA-8pin專用供電線,睇佢散熱槽,應該係風道式散熱. 係屎窟裝涡輪風扇, 點知電流大噪䡰大,再加30%降壓線壓低風.

 

使能PCIE-Above 4G

  1. 著機撳DEL鍵,BIOS
  2. ENABLED PCIE-Above 4G

 

驅動下載

  1. 登入https://www.nvidia.com/Download/index.aspx?lang=en-us
填NVIDIA Driver Downloads
NVIDIA Driver Downloads
Product Type Data Center Tesla
Product Series P-Series
Product Tesla P40
Operating System Windows 10 64-bit
  1. 撳Search
  2. 下載『33-data-center-tesla-desktop-win10-win11-64bit-dch-international.exe
  3. 重裝『Quadro K6000』驅動會自動裝埋『Tesla P40』
  4. 登入『命令行界面cmd』.
  5. 撳『nvidia-smi
  6. 分別係『Tesla P40』『Quadro K6000

 

『Tesla P40』裝驅動 默認係『TCC計算模式』, 需改為『WDDM圖形模式』.

  1. 撳『Win+r』鍵,著『exe』
  2. 左側展開
Computer \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}
  1. 展開左側
  DriverDesc
0000 NVIDIA Tesla P40
0001 NVIDIA Quadro K6000
  1. 修改『0000』-『NVIDIA Tesla P40』
NAME TYPE VALUE
AdapterType REG_DWORD 1  – DELETE
FeatureScore REG_DWORD 0Xcf->0Xd1
GridLicensedFeatures REG_DWORD 7   (强制開啟GRID圖形模式)
EnableMsHybrid REG_DWORD 1
  1. 修改『0001』-『NVIDIA Quadro K6000
NAME TYPE VALUE
EnableMsHybrid REG_DWORD 2
  1. 重啟電腦
  2. 登入『命令行界面cmd』.
  3. 撳『ctrl+alt+del』鍵, 入『工作管理員』
  4. 撳『效能』,睇到『GPU0-NVIDIA Tesla P40』同埋『GPU0-NVIDIA Quadro K6000』. 『掂』
  5. 撳『nvidia-smi
  6. 『NVIDIA Tesla P40』改為『WDDM圖形模式』
  7. 進入『GPU-Z』
  8. 下面框框冚辦闌打勾勾

 

圖形設定指定-GPU: NVIDIA Tesla P40

  1. 撳『設定』
  2. 撳『系统』->『顯示器』->『圖形設定』
  3. 『硬體加速GPU排程』撳『開啟』
  4. 揀『傅统型應用程式』
  5. 撳『瀏覧』揀『.EXE』
  6. 撳『選項』
  7. 勾『GPU: NVIDIA Tesla P40』

 

NVIDIA GPU指定『Tesla P40』

  1. 入『NVIDIA控制面板』
  2. 撳『3D設定』->『管理3D設定』
  3. 『廣域設定』
  4. 『CUDA-GPU』揀『Tesla P40』
  5. 『OpenGL呈現GPU』揀『Tesla P40』

 

 

 

nvidia-smi

nvidia-smi
nvidia-smi

『nvidia-smi.exe』, 係nvidia公司開發蒞睇gpu. 基於命令行界面, 而非圖形界面. 可能考慮兼容同稳定.随nvidia顯卡驅動安裝自動复制,路徑如下.

C:\Windows\System32\nvidia-smi.exe
  1. 撳『win+r』, 填cmd, 登入『命令行界面』.
  2. 撳『nvidia-smi.exe』
講解
Nvidia-smi 程式版本號
Driver version 顯卡驅動版本號
CUDA Version CUDA至高支援版本號
GPU 顯卡編號, 0開如始編址,
FAN 風扇轉速(0~100%),冇風扇(N/A)
NAME 顯卡型號
Temp GPU温度,0C ~ 100C
Perf 性能, 至高p0級~至低p12級
Pwr: Usage/Cap 顯卡能耗,
『usage』
使用率,『Cap』能耗牆
Bus-ID 顯卡總線地埗
Disp.A 圖像顯示輸出,OFF閂, ON著
Memory-Usage 顯存使用率
GPU-Util GPU使用率
Compute M. 計算模式DEFAULT/EXCLUSIVE_PROCESS/PROHIBITED
ECC 顯存校驗糾錯

 

CUDA下載安装

CUDA下載安装
CUDA下載安装

CUDA係NVIDIA為GPU并行運算而開發,用C語言調用GPU-CUDA指令集進行大規模并行運行.

虽然上世紀以經有『INTEL-SEE』并行運算指令集,但係『NVIDIA-CUDA』青出於蓝.

『PyTorch』暫時至高支持『CUDA 12.1』.

登入『CUDA官網』, 下載『CUDA Toolkit 12.1.1

 

https://developer.nvidia.com/cuda-toolkit-archive/

 

git下載安裝

 

git系統等於『檔案伺服』外加『版本管理』,家時最新2.45.0版.

  1. 連入git官網
  2. 撳Download
  3. 撳Windows
  4. 下載最新版
  5. 執行『Git-2.45.0-64-bit.exe
  6. 走勾『only show new options』只顯示新選項,撳『next』
Additional icons on the Desktop 桌面捷徑
Windows Explorer integration Git Bash Here 右鍵菜單
Windows Explorer integration Git GUI Here 右鍵菜單
Git LFS (Large File Support) 支援大檔䅁
Associate .git* configuration files with the default text edito 配置檔䅁.git關聯edito
Associate .sh files to be run with Bash 關聯.sh檔䅁
Check daily for Git for Windows updates 日日檢查更新
Add a Git Bash Profile to Windows Terminal 將Git Bash設定檔新增到Windows終端
Scalar(Git add-on to manage large-scale repositories) 管理大型儲存庫

 

 

 

 

https://git-scm.com/
https://git-scm.com/download/win
https://github.com/git-for-windows/git/releases/download/v2.45.0.windows.1/Git-2.45.0-64-bit.exe

 

Python下載安裝

Python下載安裝
Python下載安裝
Python下載安装
Python下載安装
Python下載安装
Python下載安装
Python下載安裝
Python下載安裝
Python下載安裝
Python下載安裝

『Python』其實係『虛擬機』, 先裝『.py』源碼編譯為字節碼『.pyc』. 『Python虛擬機』再執行『Python字節碼』. 同『java』壹樣.

登入『Python』官網『https://www.python.org/』.

  1. Stable Diffusion需下載10.6版係『python-3.10.6-amd64.exe
  2. 勾『Use admin privileges when installing py.exe』管理帳號安装程式
  3. 勾『Add python.exe to PATH』将路徑加入『環境變量』
  4. 撳『Customize installation』定制安装.
  5. 『Optional features』選項
Documentation 文檔
Pip (必揀)下載和管理python包
Tcl/tk and IDLE 裝IDLE包
Python test suite 裝測試包
Py launcher For all users(requires admin privileges) 裝‘py’啟動程式
  1. 『Advanced Optionsa』高级選項
Install python 3.12 for all users 冚辦闌帳號裝python程式
Associate files with python(requires the ‘py’ launcher) 關聯‘py’文檔
Create shortcuts for installed applications 制作python捷徑檔
Add Python to environment variables 將Python路徑添加到環境變量
Precompile standard library 預編譯標準庫
Download debugging symbols 下載調試符號
Download debug binaries(requires VS 2017 or later) 下載調試庫

 

檢查最新版pip時出錯.

WARNING:There was an error checking the latest version of pip.

需手動升級pip至最新版.

python -m pip install –upgrade pip

 

https://www.python.org/
https://www.python.org/downloads/windows/
https://www.python.org/ftp/python/3.10.6/python-3.10.6-amd64.exe
https://www.python.org/ftp/python/3.12.3/python-3.12.3-amd64.exe

 

B450-ITX

B450-ITX
B450-ITX
B450-ITX
B450-ITX
B450-ITX
B450-ITX
B450-ITX
B450-ITX

買雜牌『B450-ITX』配『RYZEN5-1500X』砌臺ITX,摆係老竇屋企睇片.

點知『BE200』WIFI吾認識.篮牙要更新BIOS.

SSD磁盤冇法指盤符,要装最新版Windows10-22H2.

 

Intel Wi-Fi 7 BE200

Intel Wi-Fi 7 BE200
Intel Wi-Fi 7 BE200
Intel Wi-Fi 7 BE200
Intel Wi-Fi 7 BE200
Intel Wi-Fi 7 BE200
Intel Wi-Fi 7 BE200

之前係老竇屋企砌臺ITX電腦愛蒞睇片,『BE200』新出買蒞試試, 點知係係『b450-itx』可以認藍牙,唔認WIFI.反而係『x99-itx』藍牙WIFI都認.

唯有『AX210』配『b450-itx』, 『BE200』配『x99-itx』.

下載最新Intel WiFi驅動.

https://downloadmirror.intel.com/812774/WiFi-23.20.0-Driver64-Win10-Win11.exe
https://downloadmirror.intel.com/812775/WiFi-23.20.0-Driver64-Win10-Win11.zip
https://downloadmirror.intel.com/794069/BT-23.10.0-64UWD-Win10-Win11.exe
https://downloadmirror.intel.com/794708/BT-23.10.0-64UWD-Win10-Win11.zip

 

X99-EATX禁CPU-C3 Report /CPU-C6 Report

X99-EATX禁CPU-C3 Report /CPU-C6 Report
X99-EATX禁CPU-C3 Report /CPU-C6 Report

登入Win10間謁會TeeDriverW8x64.sys蓝屏, 聽聞禁節能模式可修复,『CPU C3 report』『CPU C6 report』.

  1. 著機logo,撳『del』鍵登入BIOS
  2. 撳『IntelRCSetup』
  3. 撳『CPU C3 Report』揀『Disabled』
  4. 撳『CPU C6 Report』揀『Disabled』

UTF8/BIG5/Shift-JIS/EUC-KR/GB2312判定

UTF8/BIG5/Shift-JIS/EUC-KR/GB2312判定
UTF8/BIG5/Shift-JIS/EUC-KR/GB2312判定

係電腦發展初時定義左套『ASCII碼』,得128字符,英文加數字用單字節BYTE. 後蒞各國皆自定『字符編碼』,『Shift-JIS/EUC-KR/BIG5/GB2312』皆占两字節WORD,结果係編碼重叠.所以先有亂碼.

Low 8bit Height 8bit
ASCII-128 0 ~ 0x7F N/A
BIG5漢字 0xA1 ~ 0xF9 0x40 ~ 0x7E

0xA1 ~ 0xFE

SHIFT-JIS日字 0x81~0x9f

0xe0~0xef

0x40~0x7e

0x80~0xfc

EUC-KR韓字 0xA1~0xFE 0xA1~0xFE
GB2312中字 0xA1 ~ 0xF7 0xA1 ~ 0xFE
GBK中字 0x81 ~ 0xFE 0x40 ~ 0xFE

『UTF-8』係Unicode『萬國碼』變體,首byte前缀標記字符長度.前缀0長度1, 前缀110長度2, 前缀1110長度3.以此类推.尾随byte前缀皆標記01.

『UTF-8』bin 長度
bin:0xxxxxxx 1
bin:110xxxxx 10xxxxxx 2
bin:1110xxxx 10xxxxxx 10xxxxxx 3
bin:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4
bin:111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 5
bin:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6

UTF-8判定

if ((utf8[0] & 0x80) == 0x00)

return 1;

值小於0x80的ASCII字元
if ((utf8[0] & 0xE0) == 0xC0  &&

(utf8[1] & 0xC0) == 0x80)

return 2;

2字節UTF-8字符
if ((utf8[0] & 0xF0) == 0xE0 &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80)

return 3;

3字節UTF-8字符
if ((utf8[0] & 0xF8) == 0xF0 &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80 &&

(utf8[3] & 0xC0) == 0x80)

return 4;

4字節UTF-8字符
if ((utf8[0] & 0xFC) == 0xF8 &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80 &&

(utf8[3] & 0xC0) == 0x80 &&

(utf8[4] & 0xC0) == 0x80)

return 5;

5字節UTF-8字符
if ((utf8[0] & 0xFE) == 0xFC &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80 &&

(utf8[3] & 0xC0) == 0x80 &&

(utf8[4] & 0xC0) == 0x80 &&

(utf8[5] & 0xC0) == 0x80)

return 6;

6字节UTF-8字符

值小於0x80係ASCII字符集

if ((string[0] & 0x80) == 0x00)

return 1;

BIG5漢字符集編碼范圍

if ((string[0] >= 0xA1 && string[0] <= 0xF9) &&

(string[1] >= 0x40 && string[1] <= 0x7E ||

string[1] >= 0xA1 && string[1] <= 0xFE) )

return 2;

SHIFT-JIS日字符集編碼范圍

if ((string[0] >= 0x81 && string[0] <= 0xF9 ||

string[0] >= 0xe0 && string[0] <= 0xef) &&

(string[1] >= 0x40 && string[1] <= 0x7E ||

string[1] >= 0xA1 && string[1] <= 0xFE) )

return 2;

EUC-KR韓字符集編碼范圍

if ((string[0] >= 0xA1 && string[0] <= 0xFE) &&

(string[1] >= 0xA1 && string[1] <= 0xFE))

return 2;

GB2312中字符集編碼范圍

if ((string[0] >= 0xA1 && string[0] <= 0xF7) &&

(string[1] >= 0XA1 && string[1] <= 0XFE) )

return 2;

GBK中字符集編碼范圍

if ((string[0] >= 0x81 && string[0] <= 0xFE) &&

(string[1] >= 0XA0 && string[1] <= 0XFE) )

return 2;

 

UNICODE-UTF8轉換

UNICODE-UTF8轉換
UNICODE-UTF8轉換

係電腦發展初時.定義左套『ASCII碼』,得128字符,英文加數字用單字節BYTE. 後蒞各國皆自定『字符編碼』,『BIG5/GB2312』皆占两字節WORD,结果係編碼重叠.所以先有亂碼.

UNICODE『萬國碼』,各國各自有獨立編碼段,吾重叠,同『ASCII碼』兼容.

『UNICODE』係設計之初每字符占『2 BYTE』即『USC2』字符集. 但係『2 BYTE』够支持65535字符.所以後蒞有『USC4』占『4 BYTE』.

係同壹字符串USC2同USC4會混合出現.

但係『ASCII碼』只需單字節『1 BYTE』. 所以發明左『UTF-8』以節約地方.

『UTF-8』同『UNICODE』按照下表互為轉换.

Unicode『USC2』字符集HEX 『UTF-8』bin
0x0000~0x007F 0xxxxxxx
0x0080~0x07FF 110xxxxx 10xxxxxx
0x0800~0xFFFF 1110xxxx 10xxxxxx 10xxxxxx

為左係同壹字符串『USC2』同『USC4』混合出現.係『USC4』字符『低16bit』同『高16bit』分別加前缀標記.

『低16bit』加『0xD800』,『高16bit』加『0xDC00』,再加壹區域0x10000.

前缀標記『0xD800』『0xDC00』各占6bit,各净低10bit加埋有『20bit』.够支持 『1048576』字符

USC4-低16bit前缀標記 0xD800 BIN:110110 00000 00000
USC4-高16bit前缀標記 0xDC00 BIN:110111 00000 00000

 

USC4 前缀標記 USC4=前缀標記+字符
低16bit 0xD800 BIN:110110 00000 00000 + BIN:xxxxxxxxxx
高16bit 0xDC00 BIN:110111 00000 00000 + BIN:xxxxxxxxxx

utf8 轉 usc4

首字節 value = utf8[sour] & (0xFF >> (bytes + 1));

++sour;

尾随字節 for (int i = 1; i < bytes; ++i) {

value = value << 6;

value = value | (utf8[sour] & 0x3f);// 提低6bit

++sour;

}

减壹區域 value = value – 0x10000
低16bit unicode[dest] = 0xD800 | ((value >> 10) & 0x3ff );
高16bit unicode[dest+1] = 0xDC00 | ((value) & 0x3ff);

dest = dest + 2;

utf8 轉 usc2

首字節 value = utf8[sour] & (0xFF >> (bytes + 1));

++sour;

尾随字節 for (int i = 1; i < bytes; ++i) {

value = value << 6;

value = value | (utf8[sour] & 0x3f);

++sour;

}

反轉字節 v = (value >> 24) & 0xFF;

unicode[dest] = v;

v = (value >> 16) & 0xFF;

if (v != 0) {

unicode[dest] = (unicode[dest] << 8) + v;

++dest;

}

反轉字節 v = (value >> 8) & 0xFF;

unicode[dest] = v;

v = value & 0xFF;

if (v != 0) {

unicode[dest] = (unicode[dest] << 8) + v;

++dest;

}

Usc4轉utf8

提取字符 value = (unicode[sour] – 0xD800) << 10 | (unicode[sour + 1] – 0xDC00);
加壹區域 value = value + 0x10000;

Usc2轉utf8

提取字符 value = unicode[sour];
首字節 utf8[dest] = (0xFF << (8 – bytes)) | (value >> ((bytes – 1) * 6));

++dest;

尾随字節 for (int i = 1; i < bytes; ++i) {

utf8[dest] = 0x80 | (value >> ((bytes – i – 1) * 6) & 0x3F);

++dest;

}

++sour;

『UTF-8』首byte,前缀標記字符長度. 前缀0長度1, 前缀110長度2, 前缀1110長度3. 以此类推.尾随byte前缀皆標記01.

『UTF-8』bin 長度
bin:0xxxxxxx 1
bin:110xxxxx 10xxxxxx 2
bin:1110xxxx 10xxxxxx 10xxxxxx 3
bin:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4
bin:111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 5
bin:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6

按首BIT符號,計算UTF8字符長度,返回0非UFT8字符.

『UTF-8』字符
if ((utf8[0] & 0x80) == 0x00)

return 1;

0xxxxxxx
if ((utf8[0] & 0xE0) == 0xC0  &&

(utf8[1] & 0xC0) == 0x80)

return 2;

110xxxxx 10xxxxxx
if ((utf8[0] & 0xF0) == 0xE0 &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80)

return 3;

1110xxxx

10xxxxxx

10xxxxxx

if ((utf8[0] & 0xF8) == 0xF0 &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80 &&

(utf8[3] & 0xC0) == 0x80)

return 4;

11110xxx

10xxxxxx

10xxxxxx

10xxxxxx

if ((utf8[0] & 0xFC) == 0xF8 &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80 &&

(utf8[3] & 0xC0) == 0x80 &&

(utf8[4] & 0xC0) == 0x80)

return 5;

111110xx

10xxxxxx

10xxxxxx

10xxxxxx

10xxxxxx

if ((utf8[0] & 0xFE) == 0xFC &&

(utf8[1] & 0xC0) == 0x80 &&

(utf8[2] & 0xC0) == 0x80 &&

(utf8[3] & 0xC0) == 0x80 &&

(utf8[4] & 0xC0) == 0x80 &&

(utf8[5] & 0xC0) == 0x80)

return 6;

1111110x

10xxxxxx

10xxxxxx

10xxxxxx

10xxxxxx

10xxxxxx

unicode轉utf8 , ASCII碼相等.

 int UnicodeToUTF8(char * utf8, const wchar_t * unicode)

{

int unicodeLength = 0;

int bytes;

int dest, sour;

DWORD value;

unicodeLength = Unicode_Length(unicode) ;

sour = dest = 0;

while (sour < unicodeLength)

{

bytes = 1;

if (unicode[sour] >= 0xD800 && unicode[sour + 1] >= 0xDC00)

bytes = 4;

else

if (unicode[sour] >= 0x00 && unicode[sour] <= 0x7F)

bytes = 1;

else

if (unicode[sour] >= 0x80 && unicode[sour] <= 0x7FF)

bytes = 2;

else

if (unicode[sour] >= 0x800 && unicode[sour] <= 0xFFFF)

bytes = 3;

else

if (((unicode[sour + 1] << 16) | unicode[sour]) >= 0x10000 &&

((unicode[sour + 1] << 16) | unicode[sour]) <= 0x1FFFFF)

bytes = 4;

else

if (((unicode[sour + 1] << 16) | unicode[sour]) >= 0x200000 &&

((unicode[sour + 1] << 16) | unicode[sour]) <= 0x3FFFFFF)

bytes = 5;

else

if (((unicode[sour + 1] << 16) | unicode[sour]) >= 0x4000000 &&

((unicode[sour + 1] << 16) | unicode[sour]) <= 0x7FFFFFFF)

bytes = 6;

else

if (((unicode[sour + 1] << 16) | unicode[sour]) >= 0x80000000)

bytes = 7;

 

if (bytes == 1)

{

utf8[dest] = unicode[sour];

++dest;

++sour;

}

else

if (unicode[sour] >= 0xD800 && unicode[sour + 1] >= 0xDC00)

{

value = (unicode[sour] – 0xD800) << 10   |  (unicode[sour + 1] – 0xDC00);

value = value + 0x10000;

utf8[dest] = (0xFF << (8 – bytes)) | (value >> ((bytes – 1) * 6));

++dest;

for (int i = 1; i < bytes; ++i) {

utf8[dest] = 0x80 | (value >> ((bytes – i – 1) * 6) & 0x3F);

++dest;

}

sour = sour + 2;

}

else

if (bytes == 2 || bytes == 3)

{

value = unicode[sour];

utf8[dest] = (0xFF << (8 – bytes)) | (value >> ((bytes – 1) * 6));

++dest;

for (int i = 1; i < bytes; ++i) {

utf8[dest] = 0x80 | (value >> ((bytes – i – 1) * 6) & 0x3F);

++dest;

}

++sour;

}

else

if (bytes >= 4)

{

value = (unicode[sour + 1] << 16) | unicode[sour];

utf8[dest] = (0xFF << (8 – bytes)) | (value >> ((bytes – 1) * 6));

++dest;

for (int i = 1; i < bytes; ++i) {

utf8[dest] = 0x80 | (value >> ((bytes – i – 1) * 6) & 0x3F);

++dest;

}

sour = sour + 2;

}

}

utf8[dest] = NULL;

return dest;

}

utf8 轉 unicode

 int UTF8ToUnicode(wchar_t * unicode, const char* utf8)

{

int utf8Length;

int sour, dest;

int bytes;

dest = sour = 0;

DWORD value;

BYTE v;

utf8Length = strlen(utf8);

while (sour < utf8Length)

{

if ((utf8[sour] & 0x80) == 0x00)

bytes = 1;

else

if ((utf8[sour] & 0xE0) == 0xC0)

bytes = 2;

else

if ((utf8[sour] & 0xF0) == 0xE0)

bytes = 3;

else

if ((utf8[sour] & 0xF8) == 0xF0)

bytes = 4;

else

if ((utf8[sour] & 0xFC) == 0xF8)

bytes = 5;

else

if ((utf8[sour] & 0xFE) == 0xFC)

bytes = 6;

else

bytes = 7;

if (bytes == 1)

{

unicode[dest] = utf8[sour];

++dest;

++sour;

}

else

if (bytes == 2 || bytes == 3)

{

value = utf8[sour] & (0xFF >> (bytes + 1));

++sour;

for (int i = 1; i < bytes; ++i) {

value = value << 6;

value = value | (utf8[sour] & 0x3f);

++sour;

}

 

v = (value >> 24) & 0xFF;

unicode[dest] = v;

v = (value >> 16) & 0xFF;

if (v != 0) {

unicode[dest] = (unicode[dest] << 8) + v;

++dest;

}

 

v = (value >> 8) & 0xFF;

unicode[dest] = v;

v = value & 0xFF;

if (v != 0) {

unicode[dest] = (unicode[dest] << 8) + v;

++dest;

}

}

else

if (bytes >= 4 )

{

value = utf8[sour] & (0xFF >> (bytes + 1));

++sour;

for (int i = 1; i < bytes; ++i) {

value = value << 6;

value = value | (utf8[sour] & 0x3f);

++sour;

}

value = value – 0x10000;

unicode[dest] = 0xD800 | ((value >> 10) & 0x3ff );

unicode[dest+1] = 0xDC00 | ((value) & 0x3ff);

dest = dest + 2;

}

}

 

unicode[dest] = NULL;

return dest;

}