
『Stable Diffusion』與GitHub倉庫同步更新.
- 係『C:\stable-diffusion-webui』新建『update.bat』.
- 文本編輯『update.bat』
- 填寫『git pull』
- 執行『update.bat』
www.bookcard.net

當睇到下面信息『Stable Diffusion』已装掂,但係缺『基礎模型』.
| No checkpoints found. When searching for checkpoints, looked at: |
| – file C:\stable-diffusion-webui\model.ckpt |
| – directory C:\stable-diffusion-webui\models\Stable-diffusion |
| Can’t run without a checkpoint. Find and place a .ckpt file into any of those locations. The program will exit. |
先去『civitai.com』下載模型
| https://civitai.com/ |
| https://huggingface.co/ |
係『Stable Diffusion』左上角揀基礎模型.擴展名『.safetensors』『.ckpt』, 大細係6GB~4GB之間. 『基礎模型』吾可叠加.
『基礎模型』擺係指定檔案夾.
| Model模型 | 檔案夾位置 |
| Checkpoint『.ckpt』 | C:\stable-diffusion-webui\models\Stable-diffusion |
| .safetensors | C:\stable-diffusion-webui\models\Stable-diffusion |
『基礎模型』添加封面,圖檔名與模型名壹致,同『基礎模型』模型擺係壹起,之後撳『refresh page』刷新.
| 基礎模型 | model.safetensors |
| 封面圖 | model.png |



『Stable Diffusion』開源AI划畫畵程式. 輕易係網络下載,部署係電腦行.
| https://github.com/AUTOMATIC1111/stable-diffusion-webui |
『提示詞』畀『Clip』解讀, 『Diffusion』逐步生成圖像.
| 『提示詞』->『Clip』->『Diffusion』->『VAE』->『畵』 |
硬件要求
部署運行環境.
部署Stable Diffusion
| git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui |
| “C:\Program Files\Python310\python.exe” |
| @echo off |
| set PYTHON=”C:\Program Files\Python310\python.exe” |
| set GIT= |
| set VENV_DIR= |
| set COMMANDLINE_ARGS=–xformers |
| call webui.bat |
| ERROR:Could not find a version that satisfies the requirement torch |
| ERROR:NO matching distribution found for torch |
| WARNING:There was an error checking the latest version of pip. |
| python -m pip install –upgrade pip |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install –upgrade pip |
| RuntimeError: Torch is not able to use GPU; add –skip-torch-cude-test to COMMANDLINE_ARGS variable to disable this check |
| set COMMANDLINE_ARGS=–xformers –skip-torch-cuda-test |
| RuntimeError: Couldn’t install gfpgan. |
| RuntimeError: Couldn’t install clip. |
| RuntimeError: Couldn’t install open_clip. |
| OSError: Can’t load tokenizer for ‘openai/clip-vit-large-patch14’. If you were trying to load it from ‘https://huggingface.co/models’, make sure you don’t have a local directory with the same name. Otherwise, make sure ‘openai/clip-vit-large-patch14’ is the correct path to a directory containing all relevant files for a CLIPTokenizer tokenizer. |
| TypeError: AsyncConnectionPool.__init__() got an unexpected keyword argument ‘socket_options’ |
| ImportError: cannot import name ‘_compare_version’ from ‘torchmetrics.utilities.imports’ (C:\stable-diffusion-webui\venv\lib\site-packages\torchmetrics\utilities\imports.py) |
| Downloading: “https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors” to C:\stable-diffusion-webui\models\Stable-diffusion\v1-5-pruned-emaonly.safetensors |
| C:\stable-diffusion-webui\venv |
| Running on local URL: http://127.0.0.1:7860 |

安裝『Stable Diffusion』時未有安裝『open-clip-torch』
| changing setting sd_model_checkpoint to v1-5-pruned-emaonly.safetensors [6ce0161689]: AttributeError
Traceback (most recent call last): |
| AttributeError: ‘NoneType’ object has no attribute ‘lowvram’ |
| pip install open-clip-torch==2.20.0 |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install open-clip-torch==2.20.0 |

『Stable Diffusion』冇自带模型,需自行下載,當妳睇到下面信息,下載『v1-5-pruned-emaonly.safetensors』, 之后擺係『C:\stable-diffusion-webui\models\Stable-diffusion\』資料夾.
| Downloading: “https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors” to C:\stable-diffusion-webui\models\Stable-diffusion\v1-5-pruned-emaonly.safetensors |
| https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors | Sour |
| C:\stable-diffusion-webui\models\Stable-diffusion\v1-5-pruned-emaonly.safetensors | dest |


當妳『Stable Diffusion』睇到下面信息,未有裝『transformers』模型分詞器.或版本舊.
| OSError: Can’t load tokenizer for ‘openai/clip-vit-large-patch14’. If you were trying to load it from ‘https://huggingface.co/models’, make sure you don’t have a local directory with the same name. Otherwise, make sure ‘openai/clip-vit-large-patch14’ is the correct path to a directory containing all relevant files for a CLIPTokenizer tokenizer. |
| pip install transformers |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install transformers |
| pip install –upgrade transformers |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install –upgrade transformers |

安裝『Stable Diffusion』時未有裝『torchmetrics』.
| ImportError: cannot import name ‘_compare_version’ from ‘torchmetrics.utilities.imports’ (C:\stable-diffusion-webui\venv\lib\site-packages\torchmetrics\utilities\imports.py) |
進入『命令行模式CMD』
查版本號
| pip show torchmetrics |
缷載
| pip uninstall torchmetrics |
下載0.11.4版本
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install torchmetrics==0.11.4 |

安裝『Stable Diffusion』時報錯
| TypeError: AsyncConnectionPool.__init__() got an unexpected keyword argument ‘socket_options’ |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install httpx==0.24.1 -force-reinstall |
| python.exe -m pip install httpx==0.24.1 -force-reinstall |

安裝『Stable Diffusion』時未裝『open_clip』. 其實亦係『clip』
| RuntimeError: Couldn’t install open_clip. |
進入『open_clip』
| https://github.com/mlfoundations/open_clip |
或者下載『open_clip』落『C:』碟
| git clone https://github.com/openai/open_clip.git |
下載『open_clip-main.zip』後解壓本地安裝
| https://codeload.github.com/mlfoundations/open_clip/zip/refs/heads/main |
复制『C:\open_clip』到『C:\stable-diffusion-webui\venv\Scripts』
| C:\open_clip | Sour |
| C:\stable-diffusion-webui\venv\Scripts | dest |
進入『命令行模式CMD』
CD去『CLIP』檔䅁夾, 作為本地路徑
| cd C:\stable-diffusion-webui\venv\Scripts\open_clip |
执行下列安裝指令
| C:\stable-diffusion-webui\venv\Scripts\python.exe setup.py build install |
常試通過pip指令安裝
| pip install open_clip_torch |













諗住買3090Ti點知連成萬,孖2080Ti送NVLink先陸千有找.
登入NVIDIA官網下載嘉時至新驅動
| https://www.nvidia.com/Download/index.aspx?lang=en-us |
| 填NVIDIA Driver Downloads | |
| NVIDIA Driver Downloads | 揀 |
| Product Type | GeForce |
| Product Series | GeForce RTX 40 Series |
| Product | GeForce RTX 4090 Ti |
| Operating System | Windows 10 64-bit |
| Download Type | NVIDIA Studio Driver |
撳Search下載驅動
| https://us.download.nvidia.com/Windows/552.22/552.22-desktop-win10-win11-64bit-international-nsd-dch-whql.exe |
新顯卡NVLINK金手指有封膜,撕左插入NVLINK桥即掂.冇使搞BIOS.
下載『NVLinkTestCUDA11』測試NVLINK桥造總線带寛
| https://www.pugetsystems.com/support/guides/how-to-enable-and-test-nvidia-nvlink-on-quadro-and-geforce-rtx-cards-in-windows-10-1266/ |
| https://puget.systems/go/NVLinkTestCUDA11 |
孖『NVIDIA GeForce RTX 2080 Ti』都插係PCIEx16,鋪頭送『GeForce NVLINK』桥造總線带寛得『48.08GB/S』, 可能要『Quadro Nvlink』先有『100GB/S』带寛.


『clip』建构圖像文字之間連系模型,安裝『Stable Diffusion』時未有安裝『clip』.
| RuntimeError: Couldn’t install clip. |
進入『clip』
| https://github.com/openai/clip/ |
下載『clip』落『C:』碟
| git clone https://github.com/openai/CLIP.git |
或者下載『CLIP-main.zip』後解壓
| https://codeload.github.com/openai/CLIP/zip/refs/heads/main |
复制『C:\CLIP』到『C:\stable-diffusion-webui\venv\Scripts』
| C:\CLIP | Sour |
| C:\stable-diffusion-webui\venv\Scripts | dest |
進入『命令行模式CMD』
CD去『CLIP』檔䅁夾, 作為本地路徑
| cd C:\stable-diffusion-webui\venv\Scripts\CLIP |
执行下列安裝指令
| C:\stable-diffusion-webui\venv\Scripts\python.exe setup.py build install |

安裝『Stable Diffusion』時未有安裝『gfpgan』人樣修复.
| RuntimeError: Couldn’t install gfpgan. |
進入『GFPGAN』
| https://github.com/TencentARC/GFPGAN |
下載『GFPGAN』落『C:』碟
| git clone https://github.com/TencentARC/GFPGAN.git |
复制『C:\GFPGAN』到『C:\stable-diffusion-webui\venv\Scripts』
| C:\GFPGAN | Sour |
| C:\stable-diffusion-webui\venv\Scripts | dest |
進入『命令行模式CMD』
CD去『GFPGAN』檔䅁夾, 作為本地路徑
| cd C:\stable-diffusion-webui\venv\Scripts\GFPGAN |
执行下列安裝指令
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install basicsr |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install facexlib |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install -r requirements.txt |
| C:\stable-diffusion-webui\venv\Scripts\python.exe setup.py develop |
| C:\stable-diffusion-webui\venv\Scripts\python.exe -m pip install realesrgan |


『Torch』基於神經網络人工智慧輵, 『PyTorch』係『Python』版本
首先确認NVIDIA顯卡支持CUDA版本. 下載最新顯卡驅動『552.22-desktop-win10-win11-64bit-international-nsd-dch-whql.exe』
網络安装『PyTorch』
| pip3 install torch torchvision torchaudio –index-url https://download.pytorch.org/whl/cu121 |
本地安装『PyTorch』
| https://download.pytorch.org/whl/torch/ |
| https://download.pytorch.org/whl/cu121/torch-2.3.0%2Bcu121-cp310-cp310-win_amd64.whl#sha256=002027d18a9c054f08fe9cf7a729e041229e783e065a71349015dcccc9a7137e |
| WARNING:There was an error checking the latest version of pip. |
| Defaulting to user installation because normal site-packages is not writeable |
| python -m pip install –upgrade pip |
測試『Pytorch』返回true,表示可調用GPU-CUDA指令, 進入『Pytho3.10』.
| import torch |
| print(torch.__version__) |
| torch.cuda.is_available() |
缷載tcrch
| Pip uninstall torch |
| Pip uninstall torchaudio torchvision |
| Pip uninstall torch-geometric torch-scatter torch-sparse torch-cluster torch-spline-conv |
| https://pytorch.org/get-started/locally/ |
| https://pytorch.org/get-started/previous-versions/ |















睇人AI繪畫,諗住買NVIDIA顯卡,中古RTX3060都要兩千幾,
可能係機房大批淘汰,Tesla P40-24GB係網大量焦拋售,柒百伍包郵,成色麻麻.配NVIDIA-8pin專用供電線,睇佢散熱槽,應該係風道式散熱. 係屎窟裝涡輪風扇, 點知電流大噪䡰大,再加30%降壓線壓低風.
使能PCIE-Above 4G
驅動下載
| 填NVIDIA Driver Downloads | |
| NVIDIA Driver Downloads | 揀 |
| Product Type | Data Center Tesla |
| Product Series | P-Series |
| Product | Tesla P40 |
| Operating System | Windows 10 64-bit |
『Tesla P40』裝驅動 默認係『TCC計算模式』, 需改為『WDDM圖形模式』.
| Computer \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318} |
| DriverDesc | |
| 0000 | NVIDIA Tesla P40 |
| 0001 | NVIDIA Quadro K6000 |
| NAME | TYPE | VALUE |
| AdapterType | REG_DWORD | 1 – DELETE |
| FeatureScore | REG_DWORD | 0Xcf->0Xd1 |
| GridLicensedFeatures | REG_DWORD | 7 (强制開啟GRID圖形模式) |
| EnableMsHybrid | REG_DWORD | 1 |
| NAME | TYPE | VALUE |
| EnableMsHybrid | REG_DWORD | 2 |
圖形設定指定-GPU: NVIDIA Tesla P40
NVIDIA GPU指定『Tesla P40』

『nvidia-smi.exe』, 係nvidia公司開發蒞睇gpu. 基於命令行界面, 而非圖形界面. 可能考慮兼容同稳定.随nvidia顯卡驅動安裝自動复制,路徑如下.
| C:\Windows\System32\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係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/ |



github
gitHub攻略
git系統等於『檔案伺服』外加『版本管理』,
『Linux』安裝git
通過SSH登入
| ssh username@ubuntu |
root@ubuntu’s password: 填密碼. 冇字符顯示, 撳Enter鍵.
安裝git架撑
| sudo apt update |
| sudo apt install git |
| sudo apt update git |
下載『Quectel_MHI』
| sudo git clone https://github.com/ChaingTsung/Quectel_MHI/ |
『OpenWRT』安装『git』從缺小http傳輸支
| git: ‘remote-https’ is not a git command. See ‘git –help’. |
安装『git-http』修复
| sudo apt install git-http |
| sudo apt install curl |
| sudo apt install libcurl4 |
| git –version | 版本號 |
『windows10』下載祗安裝『Git-2.45.0-64-bit.exe』,家時最新2.45.0版.
| 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) | 管理大型儲存庫 |
注册GitHub賬戶
| 賬戶信息 | |
| EMAIL電郵 | 電子郵箱, 用蒞收驗證電郵. |
| Username | 字母+字符 混合, 唯壹未被利用. |
| PASSWORD密碼 | 字母+數字+字符混合 |
下載GitHub卓面版『GitHubDesktopSetup-x64.exe』





『Python』其實係『虛擬機』, 先裝『.py』源碼編譯為字節碼『.pyc』. 『Python虛擬機』再執行『Python字節碼』. 同『java』壹樣.
登入『Python』官網『https://www.python.org/』.
| Documentation | 文檔 |
| Pip | (必揀)下載和管理python包 |
| Tcl/tk and IDLE | 裝IDLE包 |
| Python test suite | 裝測試包 |
| Py launcher For all users(requires admin privileges) | 裝‘py’啟動程式 |
| 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) | 下載調試庫 |
| C:\Users\bookc\AppData\Roaming\Python\Python310\ |
| C:\Users\bookc\AppData\Roaming\Python\Python310\Scripts\ |
| C:\Users\bookc\AppData\Roaming\Python\Python310\site-packages\ |
| C:\Program Files\Python310\Scripts\ |
| C:\Program Files\Python310\ |
檢查最新版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 |

| 龍飛鳳舞振家聲 |
| 招牌一出棟天庭 |
『龍飛鳳舞』指『喫夜粥練硬對拳頭』
『招牌』指『洪門』
『棟』指『棟穿』
『天庭』指『满清』
咸丰四年-儒略歷1854年,『陳開』白晝獄官, 夜晚洪門『洪順堂』大佬. 得知『洪秀全/全哥』係金田起義,之後仲係金陵建立『太平天國』.
『陳開』知道時機成熟,連仝 二花面『李文茂』, 『豐寧寺』主持『鄺能/和尚能』三人密謀 决定發動洪門起義. 『和尚能』議定作戰戰略『拜佛』『劏羊』『擒龍』.
『龍飛鳳舞振家聲 招牌一出棟天庭』.咸豐四年六月十一日即係1854年7月5日,主帥『陳開』領率『洪門子弟』,副帥『李文茂』領率『梨园子弟』,『和尚能』軍師.
首戰『拜佛』壹日 占領『佛山』, 『和尚能』以『塔坡寺』為本陳. 發動『劏羊』作戰.









買雜牌『B450-ITX』配『RYZEN5-1500X』砌臺ITX,摆係老竇屋企睇片.點知『BE200』WIFI吾認識. 早期版本,篮牙要更新BIOS.
壹年後……
平時冇點用,拎翻蒞諗住插支咪試下,壹插塊主板烧左,前后寄翻去3次,先肯换塊新RGBA版本,前後各壹條m.2磁碟,插4pin小喇叭著機BOOT.
以雜牌蒞講都算好,保养3年,壹年後烧左换新. 祗係記憶體吾兼容,間隙輕機. AID64記憶體測試報錯.舊版本返宜兼容記憶體.唯有降低頻率加大時序.
用『Ryzen DRAM Calculator』睇時序配置.
| 記憶體 | 默認值 | 修定後 |
| MEM FREQUENCY(Mhz) 頻率 | 2400 | 2133 |
| 主時序配置 | ||
| Tcl | 15 | 20 |
| Trcdrd | 15 | 20 |
| Trcdwr | 15 | 20 |
| Trp | 15 | 20 |
| Tras | 35 | 38 |
| 副時序配置 | ||
| Trc | 0 | |
| Trrds | 4 | |
| Trrdl | 6 | |
| Tfaw | 23 | |
| Twtrs | 3 |
休眠喚醒後顯示器黑屏,要撳『power』鍵重啟.BIOS 已UPADAE.『Win10/Linux』皆係.
| B450-ITX | RGBA版 |
| m.2磁碟 | 2 |
| BOOT-4pin | 1 |
| rgba燈 | 2 |
| 4pin風扇 | 2 |
| 3pin風扇 | 2 |
| DEBUG | 1 |



之前係老竇屋企砌臺ITX電腦愛蒞睇片,『BE200』新出買蒞試試, 點知係係『b450-itx』可以認藍牙,唔認WIFI.反而係『x99-itx』藍牙WIFI都認.
唯有『AX210』配『b450-itx』, 『BE200』配『x99-itx』.
下載最新Intel WiFi驅動.

係電腦發展初時定義左套『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; |

係電腦發展初時.定義左套『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; } |

『Android Studio』默認utf8編碼. 而『Visual Studio』按『地區設定』,轉本地字符編碼. 係VC6年代直頭吾直持『utf8』.
要强轉utf8可以係字加『u8』前缀
| char utf8[MAX_CHAR] = u8″abcdef屌㞗𡳞杘屄”; |
加『u8』前缀後,代碼移稙『Android Studio』繁鎖.可以加編譯詣令.
| #pragma execution_character_set(“utf-8”) |
适宜字符寫死係代碼. 若将字符保存係外部文檔,存為utf8即軟代碼.唔使諗編碼.
要强轉unicode係字加『L』前缀.USC2同USC4混埋.
| wchar_t unicode[MAX_CHAR] = L”屌㞗𡳞杘屄”; |

經緯度座標有叄種格式,『度分秒』『度分』『度』.
『度分秒』等於『時分秒』, 『1度=60分=3600秒』『1分=60秒』
| 經緯度座標 | |
| 度分秒DMS | DDD°MM’SS” |
| 度分DM | DDD°MM.MMM’ |
| 度D | DDD.DDDDD° |
| 度分秒 | 轉换 |
| 分轉度 | 除60 |
| 秒轉度 | 除3600 |
| 秒轉分 | 除60 |
| 度轉分 | 度小數乘60 |
| 分轉秒 | 分小數乘60 |
『度分秒』轉『度』
| 例『35°41′37.5″』即係『35度41分37.5秒』 |
| 41分轉度= 41/60 |
| 37.5秒轉度=37.5/3600 |
| 35 + 41/60 + 37.5/3600=35.69375度 |
| void DMS_TO_DD(float D,float M,float S,double * DD)
{ *DD = D + M/60.0f + S/3600.0f; } |
『度分』轉『度』
| 例『35°41.625』即係『35度41.625分』 |
| 41.625分轉度= 41/60 |
| 35 + 41.625/60 =35.69375度 |
| void DM_TO_DD(float D, float M, double* DD)
{ *DD = D + M / 60.0f; // 除60 } |
『度』轉『度分』
| 例『35.6937632°』即係『35度41.625792分』 |
| 『0.6937632°』度轉分 0.6937632*60=41.625792′ |
| 35 + 0.6937632*60=『35°41.625792’』=『35度41.625792分』 |
| void DD_TO_DM(double DD,int * D,float * M)
{ *D = (int)DD; // 度取整 *M = (DD – *D) * 60; // 度小數乘60 } |
『度』轉『度分秒』
| 例『35.6937632°』度即係『35度, 41分, 37.54秒』 |
| 取度小數『0.6937632°』度轉分 0.6937632°*60=41.625792′ |
| 取分小數『0.625792’』分轉秒 0.625792’*60=37.54752″ |
| 35°+ 0.6937632°*60 + 0.625792’*60=『35°41′37.5″』=『35度, 41分, 37.54秒』 |
| void DD_TO_DMS(double DD, float* D, float* M, float* S)
{ float MM; *D = (int)DD; // 度取整 MM = (DD – *D) * 60; // 度小數乘60 *M = (int)MM;// 分 *S = (*M – MM) * 60;// 分小數乘60 } |
| 1日 | 360度 |
| 1度 | 60分=3600秒 |
| 1分 | 60秒 |

係Windows拖拽或者縮放窗口, 會造成窗體閃爍, 啟用象筋拖放, 即係非實時拖放,可避免窗體閃爍.
| 進入像筋拖放 |
| SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, true, &drag_full_windows, NULL); |
| 退出像筋拖放 |
| SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, false, &drag_full_windows, NULL); |
通過監聽『WM_ENTERSIZEMOVE』進入拖拽, 『WM_EXITSIZEMOVE』退出像筋拖拽, 實施像筋象筋拖放
| LRESULT CALLBACK WindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ |
| if (msg == WM_ENTERSIZEMOVE)
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, true, &drag_full_windows, NULL);// 進入像筋拖放 else |
| if (msg == WM_EXITSIZEMOVE)
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, false, &drag_full_windows, NULL);// 退出像筋拖放 |
| return(DefWindowProc(hWnd, msg, wParam, lParam));
} |












WD BLACK AN1500原配两條SN730仲有ARGB燈,有人拆出蒞䶒賣殼.睇中佢自動组建Raid0,讀寫至高達『6500MB/S』,諗住買翻『SN730-1TB』, 睇到『PC300-1TB』特價,仲係『MLC SSD』. 1TB仲係1024GB.
打孖插入『PC300-1TB』自建Raid0. 温度高達65℃. 讀『3800 MB/S』,寫『2194MB/S』. 比『SN730』慢.
| WD BLACK AN1500-Raid0 | PC300 NVMe SK Hynix 1TB*2 |
| CrystalDiskMark讀 | 2800 MB/S |
| CrystalDiskMark寫 | 2194MB/S |
| CrystalDiskInfo | 69℃. |
| MLC SSD | SK Hynix H2702T8C0B3A |
| WD AN1500 | |
| 上行 | 6500MB/S |
| 下行 | 6500MB/S |
| 總線 | PCIe Gen3*4 SSD |




『ZLIB』係開源『壓縮』同『解壓』程式庫, 支持『DEFLATE』冇損壓縮算法,混合『LZ77算法』同『霍夫曼編碼』.
『Visual studio』冇內置『ZLIB』,下載『zlib-1.2.13.tar.gz』再編譯.
| http://www.zlib.net/ |
| http://www.zlib.net/zlib-1.2.13.tar.gz |
| 路徑 | 版本 |
| C:\Program Files (x86)\zlib-1.2.13\build\Debug | Debug |
| C:\Program Files (x86)\zlib-1.2.13\build\Release | Release |
| Debug調試版 | Release發行版 | |
| zlibstaticd.lib | zlibstatic.lib | 静態庫, 唔使dll |
| zlibd.lib | zlib.lib | 動態庫, 要dll |
| zlibd.dll | zlib.dll | 動態連结 |
| C:\Program Files\zlib\include\zconf.h | Zlib-API |
| C:\Program Files\zlib\include\zlib.h |
| #include <zlib.h> | Zlib-api |
| #include <zconf.h> |
| #if _DEBUG | |
| #pragma comment(lib, “..\\ZLIB\\zlibstaticd.lib”)
#else |
|
| #pragma comment(lib, “..\\ZLIB\\zlibstatic.lib”)
#endif |


『CMake』愛蒞生成makefile或project文件, 畀Visual studio編譯代碼.
登入『CMake官網』下載『cmake-3.27.7-windows-x86_64.msi』安装包.
驗証CMake安装
| https://cmake.org/ |
| https://cmake.org/download/ |
| cmake-3.28.0-rc3-windows-x86_64.msi |
| cmake-3.27.7-windows-x86_64.msi |




上次『USB3.0壹拆貳』插『SD讀卡機』冇反應,改買臺彎汤銘TERMINUS-FE2.1芯片,『USB2.0 壹拆肆』.聽講兼容冚辦闌USB2.0機體.
冇定位窿, 3D打印磁吸底座,吸係機槓壁.配線够長.
部『SD讀卡機』係USB3.0-19PIN,要轉9PIN.好彩識認.


華南X99-F8D Plus
臺X570冇定時輕機,睇翻佢本天書,要用『1R8/2R8-DDR4』記憶體,買两條32GB成千幾紋,索性買雜牌X99玩,開機慢到以為吾著. 壹分鐘先睇到bios logo
配置如下
雜牌X99-F8D Plus有捌條DDR4槽, 單條支持至高64GB.捌條槽最高512GB.DDR4-64GB依然偏貴.块X99話支持肆通道.買两條用住先.




買左雜牌『X99-F8D PLUS』, 睇岩『E5-2637 V4』支持雙U,頻率至高.『基頻3.5GHZ』畀『E5-1630V4』低200HZ.
用CPU-Z測單線程相若. 多線程跑分接近壹倍. 可能同雙CPU有關.
| INTEL XEON | E5-2637V4 | E5-1630V4 | E5-2630LV3 |
| CPU-Z單線程 | 462.4 | 470.7 | 233.2 |
| CPU-Z多線程 | 4368.2 | 2350.2 | 2136.7 |
| 主頻 | 3.5GHZ | 3.7GHZ | 1.8GHZ |
| 核心 | 4核 | 4核 | 8核 |
| 線程 | 8線程 | 8線程 | 16線程 |
| TDW | 140W | 140W | 55W |

買左雜牌『x99-EATX』,舊式ATX機槓要拆左光驅位支架.冇臺鉆拆拉釘驚拆爛.索性新買EATX機槓W100,分左右腔.10條PCIE槽位,有主板要11條PCIE槽位.
左腔裝主板同風扇,為左装『23030風扇』要移有機玻璃去門板外側.
右腔得86mm寬,装3.5寸機體同埋atx火牛都掹水,早知買W200吾使搞甘耐.

雜牌x99-eatx係登入Win10間謁會Te

eDriverW8x64.sys蓝屏. 心諗雜牌都係信唔過.
『TeeDriverW8x64.sys』係『Intel(R) Management Engine Interface』英特爾®管理引擎介面驅動程式.
『剷TeeDriverW8x64.sys』




新EATX機槓裝9把『200風扇』. BNFENIX-3PIN白色『230風扇』,為左装係『200扇位』削去两側. 9扇葉設計,扇速慢得800轉.9把『230風扇』要風扇集線器.
230扇葉大易斷扇軸,冇适合鐵網保謢扇葉.
| PC-FAN 23030 | 數值 |
| 尺碼 | 230*30mm |
| 電壓 | 12V |
| 電流 | 0.18A |
| Materials | PBT |
| Speed(R.P.M.) | 700~900轉/分 |
| 噪聲 | 20(dB-A) |
| 厚 | 25MM |
| 窿徑 | 4MM |




前幾日打印『SOCKET-2011風扁支架』,ABS打印90*90MM梗有壹角收縮翘邊.搞左幾日最後502黐死底座,要重黐美紋紙.
睇『噴砂磁鋼板平臺』分两層,下層磁貼底座,3M背胶黐住熱床. 上層係噴砂磁鋼,靠下層磁貼吸死.
厰家指南熱唔超80℃.事實比美紋紙仲衰,打印ABS只有熱床上到110℃,先睇到效果.等熱床降温後自動分離.









X99-EATX愛两正方SOCKET-2011散熱. 唔諗買『熱導管散熱』.學上次咁買两拆機銅散熱,正方『90mm*90mm』, 配两『AVC-9025-12V-0.13A』.風扇底座用3D打印. 尺寸太大ABS容易收縮變形.

舊時『游戲紋理』再用『.bmp格式』, 冇壓缩即使256色盤依然佔用吉間.
『.PNG格式』利LZ77且冇失真壓縮. 且壓縮極高, 配合256色盤,适宜作『游戲紋理』.
| 數據塊 | 數值 |
| PNG圖檔標誌 | 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A |
| 圖檔頭 | IHDR |
| 调色板 | PLTE |
| 图像数据 | IDAT |
| 图像结束 | IEND |
PNG數據塊基本結构.
| 數據塊結构 | size | 簡介 |
| LENGTH | 整數4字節 | 數據長度 |
| CHUNK TYPE | 整數4字節 | 類型標記 |
| CHUNK DATA | 0~2^32字節 | 數據 |
| CRC32 | 整數4字節 | CRC32校驗 |
两字節肆字節數據,冚辦闌用『網络字節』存儲,需轉『主機字節』.
| 『網络字節』轉『主機字節』 |
| #define PNG_VALUE32(v) ((v & 0xff000000) >> 24 | (v & 0x00ff0000) >> 8 | (v & 0x0000ff00) << 8 | (v & 0x000000ff) << 24) |
| #define PNG_VALUE16(v) ((v & 0xff00) >> 8 | (v & 0x00ff) << 8) |
游戲引擎需讀PNG 伍個數據塊
| PNG數據塊 | 功能簡介 |
| IHDR | 文檔頭 |
| PLTE | 色盤 |
| IDAT | 圖像數值 |
| IEND | 結束 |
| tRNS | 圖像透明 |
| bKGD | 背景色 |
PNG圖檔頭捌字節標記,愛蒞識别PNG
| 0x89 | 0x50 | 0x4E | 0x47 | 0x0D | 0x0A | 0x1A | 0x0A |
| 137 | P | N | G | \r | \n | 26 | \n |
對比PNG標識
| if(memcmp(data, 0x0A1A0A0D474E5089, 8) != 0)
return false;// 非png圖檔 |
CRC32計算必需計『CHUNK TYPE + CHUNK DATA』, 長度『length + 4』而得.
| DWORD length = PNG_VALUE32(chunk->length) + 4; | 長 |
| DWORD64 crc = CRC32((PBYTE)(chunk) + 4,length); | CRC32計算 |
| DWORD64 crc_ = PNG_VALUE32(chunk->crc_); | 轉主機字節 |
| if(crc_ == crc)
return true;
|
比較crc值 |
首先定義PNG結构
| typedef struct PNG_TAG{ | |
| int width; | 圖宽 |
| int height; | 圖高 |
| int bitCount; | 位圖像素bits 8位,16位,24位,32位 |
| PNG_RGBA palette[256]; | 调色板 |
| PBYTE buffer; | 圖像数据 |
| int buffer_size; | 圖像数据長度 |
| int length; | 临時變量 |
| z_stream stream; | ZLIB解壓 |
| } PNG, *PNG_PTR; |
文檔頭結构 IHDR
| typedef struct PNG_IHDR_TAG{ | 文檔頭 IHDR |
| int length; | Data長度 |
| DWORD type; | 標記’IHDR’ |
| DWORD width; | 像素寬 |
| DWORD height; | 像素高 |
| BYTE BitDepth; | 圖像深度 |
| BYTE ColorType; | 顏色類型 |
| BYTE Compression; | LZ77派生演算法 ,壹定係0 |
| BYTE Filter; | 濾波,止值定0. 事實『0,1,2,3,4』伍種濾波 |
| BYTE Interlace; | 隔行掃描0=冇掃描,1=(Adam7 interlace) |
| DWORD CRC32; | CRC32校驗 |
| }PNG_IHDR,*PNG_IHDR_PTR; |
PNG支緩伍款顏色類型
| ColorType | 顏色類型 | 像素 |
| 0=Greyscale | 灰度圖像 | 1,2,4,8,16bit |
| 2=Truecolour | 真彩色圖像 | 8,16bit |
| 3=Indexed-colour | 索引彩色圖像 | 1,2,4,8bit |
| 4=Greyscale with alpha | 帶α通道資料灰度圖像 | 8,16bit |
| 6=Truecolour with alpha | 帶α通道資料真彩色圖像 | 8,16bit |
像素排列
| ColorType | 像素排列 |
| Greyscale | Y |
| Truecolour | RGB |
| Indexed-colour | i |
| Greyscale with alpha | RGBA |
| Truecolour with alpha | YA |
解析文檔頭 IHDR, 分配圖像時分, 每行像素多壹字節,記錄『Filter』濾波值,『0,1,2,3,4』伍種濾波;
| if(IHDR->ColorType == 0)
png->bitCount = IHDR->BitDepth; |
0:Greyscale:灰度圖像,1,2,4,8,16bit |
| if(IHDR->ColorType == 2)
png->bitCount = IHDR->BitDepth * 3; |
2:Truecolour:真彩色圖像,8,16bit |
| if(IHDR->ColorType == 3)
png->bitCount = IHDR->BitDepth; |
3:Indexed-colour:索引彩色圖像,1,2,4,8bit |
| if(IHDR->ColorType == 4)
png->bitCount = IHDR->BitDepth * 2; |
4:Greyscale with alpha:帶α通道資料灰度圖像,8,16bit |
| if(IHDR->ColorType == 6)
png->bitCount = IHDR->BitDepth * 4; |
6:Truecolour with alpha:帶α通道資料真彩色圖像,8,16bit |
| png->width = PNG_VALUE32(IHDR->width); | 像素寬 |
| png->height = PNG_VALUE32(IHDR->height); | 像素高 |
| int byte_count = (float)png->bitCount / 8.0f; | 像素大小 BIT to BYTE |
| png->buffer_size = (png->width * png->height * byte_count) + (png->height * 1); | 圖像数据長度,每行多壹字節 |
| png->buffer = (PBYTE)malloc(png->buffer_size); | 圖像数据 |
定義色盤RGB
| typedef struct PNG_RGB_TYP { | 色盤3字節 |
| BYTE red; | 紅 |
| BYTE green; | 錄 |
| BYTE blue; | 蓝 |
| } PNG_RGB, *PNG_RGB_PTR; |
定義色盤RGBA
| typedef struct PNG_RGBA_TYP { | 色盤4字節 |
| BYTE red; | 紅 |
| BYTE green; | 錄 |
| BYTE blue; | 蓝 |
| BYTE alpha; | 透明混合,透明0x00~實體0xFF |
| } PNG_RGBA, *PNG_RGBA_PTR; |
定義PNG色盤結构 ‘PLTE’
| typedef struct PNG_PLTE_TYP { | |
| int length; | Data長度 |
| DWORD type; | 標記’PLTE’ |
| PNG_RGB palette[256]; | 至多256色盤 |
| DWORD CRC32; | CRC32校驗 |
| } PNG_PLTE, *PNG_PLTE_PTR; |
分析PNG色盤 ‘PLTE’
| int length = PNG_VALUE32(chunk->length); | 長度 |
| int count = length / 3; | 色盤量 |
| for(int index = 0; index < count; ++index){ | |
| png->palette[index].red = PLTE->palette[index].red ; | 紅 |
| png->palette[index].green = PLTE->palette[index].green ; | 錄 |
| png->palette[index].blue = PLTE->palette[index].blue ; | 蓝 |
| png->palette[index].alpha = 0xff; } | 透明0x00~實體0xFF |
定義透明像素結构’tRNS’
| typedef struct PNG_tRNS_TYP{ | |
| int length; | 數據長度 |
| DWORD type; | 標記’tRNS’ |
| union { | |
| WORD grey; | 顏色類型 0 |
| struct {WORD Red,Green,Blue;}; | 顏色類型 2 |
| BYTE palette[256]; | 顏色類型 3 |
| DWORD CRC32; | CRC32校驗 |
| }PNG_tRNS,*PNG_tRNS_PTR; |
分析透明像素
| PNG_tRNS_PTR tRNS; | 透明像素 |
| tRNS->length = PNG_VALUE32(tRNS->length); | 數據長度 |
| if(IHDR->ColorType == 0 )
tRNS->grey = PNG_VALUE16(tRNS->grey); |
0:Greyscale:灰度圖像,1,2,4,8,16bit |
| if(IHDR->ColorType == 2 ) {
tRNS->Red = PNG_VALUE16(tRNS->Red); tRNS->Green = PNG_VALUE16(tRNS->Green); tRNS->Blue = PNG_VALUE16(tRNS->Blue); } |
2:Truecolour:真彩色圖像,8,16bit |
| if(IHDR->ColorType == 3) {
length = tRNS->length; for(int i = 0; i < length; ++i) { index = tRNS->palette[i]; png->palette[index].alpha = 0x00; } |
3:Indexed-colour:索引彩色圖像,1,2,4,8bit
透明0x00~實體0xFF |
定義背景色結构 ‘bKGD’
| typedef struct PNG_bKGD_TYP{ | |
| int length; | Data長度 |
| DWORD type; | 標記’bKGD’ |
| union { | |
| WORD Greyscale; | 顏色類型0 and 4灰度 |
| struct{WORD Red,Green,Blue;}; | 顏色類型2 and 6 -RGB三色 |
| BYTE Palette_Index;}; | 顏色類型3色盤索引 |
| DWORD CRC32; | CRC32校驗 |
| }PNG_bKGD,*PNG_bKGD_PTR; |
分析背景色’bKGD’
| int length = PNG_VALUE32(bKGD->length); | 長度 |
| if(IHDR->ColorType == 0 || IHDR->ColorType == 4)
bKGD->Greyscale = PNG_VALUE16(bKGD->Greyscale); |
灰度圖像 – 帶α通道資料灰度圖像 |
| if(IHDR->ColorType == 2 || IHDR->ColorType == 6) {
bKGD->Red = PNG_VALUE16(bKGD->Red); bKGD->Green = PNG_VALUE16(bKGD->Green); bKGD->Blue = PNG_VALUE16(bKGD->Blue); } |
真彩色圖像 – 帶α通道資料真彩色圖像 |
| if(IHDR->ColorType == 3)
bKGD->Palette_Index = bKGD->Palette_Index; |
索引彩色圖像 |
定義圖像數值結构 ‘IDAT’, 止數據塊可能有多個.
| typedef struct PNG_IDAT_TYP { | |
| int length; | Data長度 |
| DWORD type; | 標記’PLTE’ |
| BYTE data[1]; | 經壓縮圖像數據 |
| DWORD CRC32; | CRC32校驗 |
| } PNG_IDAT, *PNG_IDAT_PTR; |
每行像素多壹字節,記錄『Filter』濾波值,『0,1,2,3,4』伍種濾波;
| int length = PNG_VALUE32(IDAT->length); | 長度 |
| int size = png->buffer_size – png->length; | 剩余記憶體 |
| Uncompress_Data_gZip(png->buffer + png->length, &size,
IDAT->data,length, &png->stream); |
解压 |
| png->length = png->length + size; | 累積積數據長度 |
結束 IEND,檢測到’IEND’數據塊,己到文檔未端.
| typedef struct PNG_IEND_TAG{ | |
| int length; | Data長度0 |
| DWORD type; | 標記’IEND’ |
| DWORD CRC32; | CRC32校驗 |
| }PNG_IEND, *PNG_IEND_PTR; |
以顏色類型分別進行『反濾波』, 係每行像素首字節『濾波』值,有『0,1,2,3,4』伍款濾波, 以每粒像素單獨『復位』,帶α通道真彩色圖像8bit為例.
以cbax像素排列支缓伍款濾波
| c | b |
| a | x |
濾波算法
| filter濾波 | 濾波 | 復位 |
| 0= None | Filt(x) = Orig(x) | Recon(x) = Filt(x) |
| 1= Sub | Filt(x) = Orig(x) – Orig(a) | Recon(x) = Filt(x) + Recon(a) |
| 2= Up | Filt(x) = Orig(x) – Orig(b) | Recon(x) = Filt(x) + Recon(b) |
| 3= Average | Filt(x) = Orig(x) – floor((Orig(a) + Orig(b)) / 2) | Recon(x) = Filt(x) + floor((Recon(a) + Recon(b)) / 2) |
| 4= Paeth | Filt(x) = Orig(x) – PaethPredictor(Orig(a), Orig(b), Orig(c)) | Recon(x) = Filt(x) + PaethPredictor(Recon(a), Recon(b), Recon(c)) |
復位算法
| int byte_count = 4; | 每粒像素4字節 |
| int pixel_size = png->width * png->height; | 總像素量 |
| int buffer_size = png->width * png->height * byte_count; | 總字節量 |
| PBYTE buffer = (PBYTE)malloc(buffer_size); | 反濾波影像數據 |
| int col_size_recon = (png->width * 4) ; | 復位後每行字節量 |
| int col_size_filt = (png->width * 4) + 1; | 濾波後每行字節量 |
| for(int j = 0; j < png->height ; ++j) | 每行像素 |
| int filter = png->buffer[col_size_filt * j]; | 行首濾波=1 byte |
處理filter濾波0= None
| if(filter == 0) { | None |
| for(int i = 0; i < png->width; ++i){ | 逐像素復位 |
| Red = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 0]; | x像素紅色 |
| Green = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 1]; | x像素藍色 |
| Blue = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 2]; | x像素錄色 |
| Alpha = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 3]; | x像素透明 |
| buffer[(col_size_recon * j) + (i * 4) + 0] = Red; | 復位像素紅色 |
| buffer[(col_size_recon * j) + (i * 4) + 1] = Green; | 復位像素藍色 |
| buffer[(col_size_recon * j) + (i * 4) + 2] = Blue; | 復位像素綠色 |
| buffer[(col_size_recon * j) + (i * 4) + 3] = Alpha; }} | 復位像素透明 |
處理filter濾波1 =Sub
| if(filter == 1) { | Sub |
| for(int i = 0; i < png->width; ++i){ | 逐像素復位 |
| Red = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 0]; | x像素紅色 |
| Green = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 1]; | x像素藍色 |
| Blue = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 2]; | x像素錄色 |
| Alpha = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 3]; | x像素透明 |
| aRed = aGreen = aBlue = aAlpha = 0; | 清零 |
| if(i > 0) { | |
| aRed = buffer[(col_size_recon * j) + ((i-1) * 4) + 0]; | a像素紅色 |
| aGreen = buffer[(col_size_recon * j) + ((i-1) * 4) + 1]; | a像素藍色 |
| aBlue = buffer[(col_size_recon * j) + ((i-1) * 4) + 2]; | a像素綠色 |
| aAlpha = buffer[(col_size_recon * j) + ((i-1) * 4) + 3]; } | a像素透明 |
| buffer[(col_size_recon * j) + (i * 4) + 0] = Red + aRed; | 復位像素紅色 |
| buffer[(col_size_recon * j) + (i * 4) + 1] = Green + aGreen; | 復位像素藍色 |
| buffer[(col_size_recon * j) + (i * 4) + 2] = Blue + aBlue; | 復位像素綠色 |
| buffer[(col_size_recon * j) + (i * 4) + 3] = Alpha + aAlpha; }} | 復位像素透明 |
處理filter濾波2 =Up
| if(filter == 2){ | Up |
| for( i = 0; i < png->width; ++i){ | 逐像素復位 |
| Red = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 0]; | x像素紅色 |
| Green = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 1]; | x像素藍色 |
| Blue = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 2]; | x像素錄色 |
| Alpha = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 3]; | x像素透明 |
| bRed = bGreen = bBlue = bAlpha = 0; | 清零 |
| if(j > 0) { | |
| bRed = buffer[(col_size_recon * (j-1)) + (i * 4) + 0]; | b像素紅色 |
| bGreen = buffer[(col_size_recon * (j-1)) + (i * 4) + 1]; | b像素藍色 |
| bBlue = buffer[(col_size_recon * (j-1)) + (i * 4) + 2]; | b像素綠色 |
| bAlpha = buffer[(col_size_recon * (j-1)) + (i * 4) + 3];} | b像素透明 |
| buffer[(col_size_recon * j) + (i * 4) + 0] = Red + bRed; | 復位像素紅色 |
| buffer[(col_size_recon * j) + (i * 4) + 1] = Green + bGreen; | 復位像素藍色 |
| buffer[(col_size_recon * j) + (i * 4) + 2] = Blue + bBlue; | 復位像素綠色 |
| buffer[(col_size_recon * j) + (i * 4) + 3] = Alpha + bAlpha; }} | 復位像素透明 |
處理filter濾波3 = Average
| if(filter == 3) { | Average |
| for( i = 0; i < png->width; ++i){ | 逐像素復位 |
| Red = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 0]; | x像素紅色 |
| Green = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 1]; | x像素藍色 |
| Blue = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 2]; | x像素錄色 |
| Alpha = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 3]; | x像素透明 |
| aRed = aGreen = aBlue = aAlpha = 0; | 清零 |
| bRed = bGreen = bBlue = bAlpha = 0; | 清零 |
| if(i > 0) { | |
| aRed = buffer[(col_size_recon * j) + ((i-1) * 4) + 0]; | a像素紅色 |
| aGreen = buffer[(col_size_recon * j) + ((i-1) * 4) + 1]; | a像素藍色 |
| aBlue = buffer[(col_size_recon * j) + ((i-1) * 4) + 2]; | a像素綠色 |
| aAlpha = buffer[(col_size_recon * j) + ((i-1) * 4) + 3]; } | a像素透明 |
| if(j > 0) { | |
| bRed = buffer[(col_size_recon * (j-1)) + (i * 4) + 0]; | b像素紅色 |
| bGreen = buffer[(col_size_recon * (j-1)) + (i * 4) + 1]; | b像素藍色 |
| bBlue = buffer[(col_size_recon * (j-1)) + (i * 4) + 2]; | b像素綠色 |
| bAlpha = buffer[(col_size_recon * (j-1)) + (i * 4) + 3];} | b像素透明 |
| buffer[(col_size_recon * j) + (i * 4) + 0] = Red + ((aRed+bRed)/2); | 復位像素紅色 |
| buffer[(col_size_recon * j) + (i * 4) + 1] = Green + ((aGreen+bGreen)/2); | 復位像素藍色 |
| buffer[(col_size_recon * j) + (i * 4) + 2] = Blue + ((aBlue+bBlue)/2); | 復位像素綠色 |
| buffer[(col_size_recon * j) + (i * 4) + 3] = Alpha + ((aAlpha+bAlpha)/2); }} | 復位像素透明 |
Paeth預測函式
| BYTE PaethPredictor_PNG(BYTE a,BYTE b,BYTE c){ | 預測函式 |
| int p; | |
| int pa,pb,pc; | |
| p = a + b – c; | |
| pa = abs(p – a); | |
| pb = abs(p – b); | |
| pc = abs(p – c); | |
| if (pa <= pb && pa <= pc ) return a; | |
| else if (pb <= pc ) return b; | |
| else return c;} |
處理filter濾波4 =Paeth預測
| if(filter == 3) { | Average |
| for( i = 0; i < png->width; ++i){ | 逐像素復位 |
| Red = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 0]; | x像素紅色 |
| Green = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 1]; | x像素藍色 |
| Blue = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 2]; | x像素錄色 |
| Alpha = png->buffer[(col_size_filt * j) + 1 + (i * 4) + 3]; | x像素透明 |
| aRed = aGreen = aBlue = aAlpha = 0; | 清零 |
| bRed = bGreen = bBlue = bAlpha = 0; | 清零 |
| cRed = cGreen = cBlue = cAlpha = 0; | 清零 |
| if(i > 0) { | |
| aRed = buffer[(col_size_recon * j) + ((i-1) * 4) + 0]; | a像素紅色 |
| aGreen = buffer[(col_size_recon * j) + ((i-1) * 4) + 1]; | a像素藍色 |
| aBlue = buffer[(col_size_recon * j) + ((i-1) * 4) + 2]; | a像素綠色 |
| aAlpha = buffer[(col_size_recon * j) + ((i-1) * 4) + 3]; } | a像素透明 |
| if(j > 0) { | |
| bRed = buffer[(col_size_recon * (j-1)) + (i * 4) + 0]; | b像素紅色 |
| bGreen = buffer[(col_size_recon * (j-1)) + (i * 4) + 1]; | b像素藍色 |
| bBlue = buffer[(col_size_recon * (j-1)) + (i * 4) + 2]; | b像素綠色 |
| bAlpha = buffer[(col_size_recon * (j-1)) + (i * 4) + 3];} | b像素透明 |
| if(i > 0 && j > 0) { | |
| cRed = buffer[(col_size_recon * (j-1)) + ((i-1) * 4) + 0]; | c像素紅色 |
| cGreen = buffer[(col_size_recon * (j-1)) + ((i-1) * 4) + 1]; | c像素藍色 |
| cBlue = buffer[(col_size_recon * (j-1)) + ((i-1) * 4) + 2]; | c像素綠色 |
| cAlpha = buffer[(col_size_recon * (j-1)) + ((i-1) * 4) + 3];} | c像素透明 |
| buffer[(col_size_recon * j) + (i * 4) + 0] = Red + PaethPredictor_PNG(aRed,bRed,cRed); | 復位像素紅色 |
| buffer[(col_size_recon * j) + (i * 4) + 1] = Green + PaethPredictor_PNG(aGreen,bGreen,cGreen); | 復位像素藍色 |
| buffer[(col_size_recon * j) + (i * 4) + 2] = Blue + PaethPredictor_PNG(aBlue,bBlue,cBlue); | 復位像素綠色 |
| buffer[(col_size_recon * j) + (i * 4) + 3] = Alpha + PaethPredictor_PNG(aAlpha,bAlpha,cAlpha);}} | 復位像素透明 |
释放圖像
| free(png->buffer); | 释放 |
| png->buffer = buffer; | 替换復位圖像 |
| png->bitCount = 32; | rgba |
| png->buffer_size = buffer_size; |

『Adobe』同『Google』合作,制作『日月韓漢』矢量字庫,目前支缓65535『日月韓漢』字.以字量蒞睇依然有大量異體字未收納.
1. 官網下載『源界明朝』字庫,
2. 解壓
3. 將『SuperOTC\SourceHanSerif.ttc』复制到『C:\Windows\Fonts』
|
https://github.com/adobe-fonts/source-han-serif/archive/1.001R.zip |
|
https://typekit.com/fonts/source-han-sans-traditional-chinese |

随著『Android studio』更新版本,『Gradle』需升級.
| https://services.gradle.org/distributions/gradle-8.2.1-bin.zip |
| C:\Users\admin\.gradle\wrapper\dists\gradle-8.2.1-bin\5hap6b9n41hkg4jeh2au2pllh\gradle-8.2.1-bin.zip |
| Connection timed out: no further information. If you are behind an HTTP proxy, please configure the proxy settings either in IDE or Gradle. |

Android studio近日彈出gradle版本晤兼容.修改工程配置. 如果唔得重裝『Android Studio』.
| Android Studio版本 | Android Gradle Plugin Version插件版本 |
| Hedgehog | 2023.1.1 | 3.2~8.2 |
| Giraffe | 2022.3.1 | 3.2~8.1 |
| Flamingo | 2022.2.1 | 3.2~8.0 |
| Electric Eel | 2022.1.1 | 3.2~7.4 |
| Dolphin | 2021.3.1 | 3.2~7.3 |
| Android Gradle Plugin Version插件版本 | Gradle Version |
| 8.1 | 8.0 |
| 8.0 | 8.0 |
| 7.4 | 7.5 |
| 7.4 | 7.4 |
| 7.2 | 7.3.3 |
| 7.1 | 7.2 |
| 7.0 | 7.0 |
| 4.2.0+ | 6.7.1 |
| The project is using an incompatible version (AGP 8.1.0) of the Android Gradle plugin. Latest supported version is AGP 8.0.0 |


换『臺達FLEX-500W火牛』後,『X99i』唔識認『TOSHIBA XG3 1TB』同『Seagate XM1440 960Gb』仲試過藍屏死機.
睇蒞都係要買翻『益衡FLEX-600W』, 貴係貴D, 勝在稳定唔死機.

visual_studio_ZLIB
Visual Studio-ZLIB壓縮同解壓
『ZLIB』開源『壓縮』同『解壓』程式庫, 支持『DEFLATE』冇損壓縮演算法,佢混合『LZ77演算法』同『霍夫曼編碼』.
『DEFLATE』壓縮演算法冇專利權.畀人大量應用係『網絡』『圖檔』『文檔』『影片』.
| .PNG/ Libpng | 圖檔解壓 |
| .ZIP | 壓縮檔 |
| .tar | 壓縮檔 |
| .gz | 壓縮檔 |
| HTTP | 壓縮傅送 |
| FFmpeg | 影片解壓 |
下載『ZLIB』
| http://www.zlib.net/ |
| http://www.zlib.net/zlib-1.2.13.tar.gz |
『Android studio』內置『ZLIB』, 唔使下載.但要係『CMakeLists.txt』增添『zlib』庫.
| CMakeLists.txt文檔 | |
| find_library( z-lib z ) | 搜索zlib |
| target_link_libraries( ${z-lib} ) | 連接zlib |
包含『ZLIB』頭文檔
| #include <zlib.h> | Zlib-api |
| #include <zconf.h> |
『z_stream』壓縮同解壓皆需此結構體
| z_stream stream; | zlib流結構體 |
| stream.zalloc = Z_NULL; | NULL用默認記憶體分配函數 |
| stream.zfree = Z_NULL; | NULL用默認記憶體釋放函數 |
| stream.opaque = Z_NULL; | |
| stream.next_in = (Bytef*)sour; | 蒞源 |
| stream.avail_in = (uInt)sour_length; | 蒞源長 |
| stream.next_out = dest; | 輸出 |
| stream.avail_out = (uInt)*dest_length; | 輸出長 |
『ZLIB』壓縮分三步
| 壓縮 | |
| deflateInit(&stream, level) | 分配記憶體,level壓縮等級 |
| deflate(&stream, flush); | 壓縮數據, flush設0 |
| deflateEnd(&stream); | 釋放記憶體 |
| int deflateInit2( | deflateInit()加強版 |
| z_streamp strm, | zlib流結構體 |
| int level, | level壓縮等級0~9.
0:速度快,唔壓縮. 9:速度慢,壓縮率高. |
| int method, | 壓縮演算法僅支緩Z_DEFLATED |
| int windowBits, | 處理RAW DEFLATE手法. |
| int memLevel, | 指定記憶體分配MAX_MEM_LEVEL |
| int strategy)); | 壓縮策略,僅影響壓縮比.默認Z_DEFAULT_STRATEGY |
| level | 壓縮等級 |
| #define Z_NO_COMPRESSION 0 | 唔壓縮 |
| #define Z_BEST_SPEED 1 | 高速,低壓縮率 |
| #define Z_BEST_COMPRESSION 9 | 高壓縮率, 慢速 |
| #define Z_DEFAULT_COMPRESSION (-1) | 默認壓縮 |
| windowBits | 處理RAW DEFLATE手法. |
| 8~15: | 純deflate壓縮 |
| -8~-15: | zlib頭 + deflate + zlib尾 |
| > 16: | Gzip頭+ deflate + Gzip尾 |
| method | 壓縮演算法 |
| #define Z_DEFLATED 8 | DEFLATE冇損壓縮 |
| memLevel | 記憶體分配 |
| MemLevel=1 | 最小記憶體,速度慢壓縮比低 |
| MemLevel=9
#define MAX_MEM_LEVEL 9 |
最大記憶體,最佳速度 |
| MemLevel=8 | 默認值 |
| strategy | 壓縮演算法設定 |
| #define Z_FILTERED 1 | 僅FILTERED生成數據 |
| #define Z_HUFFMAN_ONLY 2 | 僅霍夫曼編碼 |
| #define Z_RLE 3 | 匹配長度=1 |
| #define Z_FIXED 4 | 禁霍夫曼編碼 |
| #define Z_DEFAULT_STRATEGY 0 | 默認壓縮設定 |
| int deflate(z_stream *strm, int flush); | 壓縮/解壓 |
| strm: | z_stream 結構 |
| flush: | 操作標誌 |
| 返回值 |
| flush | 操作標誌 |
| Z_NO_FLUSH: | 標准壓縮操作 |
| Z_SYNC_FLUSH: | 同步刷新操作 |
| Z_FULL_FLUSH: | 完全刷新操作 |
| Z_FINISH: | 結束操作, 壓縮完成後返回 |
| deflate()返回值 | |
| Z_OK: | 壓縮操作成功 |
| Z_STREAM_END: | 輸入資料釋數壓縮, 壓縮器處於結束狀態 |
| Z_BUF_ERROR: | 緩衝吾够 |
| Z_STREAM_ERROR: | 內部錯誤 |
『ZLIB』解壓分三步
| 解壓 | |
| inflateInit(&stream) | 分配記憶體 |
| inflate(&stream, Z_NO_FLUSH); | 解壓數據 |
| inflateEnd(stream); | 釋放記憶體 |
| 返回碼 | |
| #define Z_OK 0 | 壓縮操作成功 |
| #define Z_STREAM_END 1 | 輸入資料已經被完全壓縮,並且壓縮器處於結束狀態。 |
| #define Z_NEED_DICT 2 | 愛密碼 |
| #define Z_ERRNO (-1) | |
| #define Z_STREAM_ERROR (-2) | |
| #define Z_DATA_ERROR (-3) | 加密數據損壞壞,或缺失. |
| #define Z_MEM_ERROR (-4) | 唔夠記憶體 |
| #define Z_BUF_ERROR (-5) | 唔夠緩存 |
| #define Z_VERSION_ERROR (-6) |
解壓示例
int Uncompress_Data_gZip(PBYTE dest,int * dest_length,PBYTE sour,int sour_length)
{
z_stream stream;
int ret;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
stream.next_in = (Bytef*)sour;
stream.avail_in = (uInt)sour_length;
stream.next_out = dest;
stream.avail_out = (uInt)*dest_length;
MAX_MEM_LEVEL
ret = inflateInit2(&stream, 16+MAX_WBITS);
if (ret != Z_OK)
return ret;
ret = inflate(&stream, Z_NO_FLUSH);// 解壓
*dest_length = stream.total_out;
inflateEnd(&stream);
return ret;
}
壓縮示例
bool Compress_Data_gZip(PBYTE dest,int * dest_length,PBYTE sour,int sour_length, int level)
{
int ret;
int flush;
//int sour_offset,dest_offset;
//int have;
z_stream stream;
//BYTE in[ZIP_CHUNK];
//BYTE out[ZIP_CHUNK];
stream.zalloc = Z_NULL;// 記憶體分配函數
stream.zfree = Z_NULL;// 記憶體釋放函數
stream.opaque = Z_NULL;
stream.next_in = (Bytef*)sour; // 輸入
stream.avail_in = (uInt)sour_length;
stream.next_out = dest;//輸出
stream.avail_out = (uInt)*dest_length;
ret = deflateInit(&stream, level);// 内存分配
if (ret != Z_OK)
return false;
flush = Z_FINISH;
//flush = Z_NO_FLUSH;// 允許壓縮演算法決定累積多少資料再產生輸出,以達到壓縮效率最高.
while (ret == Z_OK) {
ret = deflate(&stream, flush); // 進行壓縮
if (ret == Z_STREAM_END)
break;
else
if (ret == Z_BUF_ERROR)//緩衝吾够
break;
else
if (ret == Z_STREAM_ERROR)// 內部錯誤
break;
}
*dest_length = stream.total_out;
deflateEnd(&stream);// 釋放記憶體
return Z_OK;
}




『Gigabyte-X570 AORUS MASTER』成日間歇藍屏重啟.耳聞『EVGA 1000 G2』火牛質量嘛嘛,唯有試换火牛,睇中古台達『火牛GM1300』.冚模块設計.
買翻蒞壹直冇装機.

『CRC32』同『MD5』『SHA1』壹樣,計『貳进制』數值『指紋』,佢速度快,HASH校验值肆字節.两DWORD值相等比較. 适宜網络數據傳輸, 校驗數據係咪完璧.
DWORD CRC32_Table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
DWORD CRC32(PBYTE buf, int len){
int i;
DWORD crc;
crc = 0xffffffffL;
for (i = 0; i < len; ++i )
crc = CRC32_Table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
crc = crc ^ 0xffffffffL;
return crc;
}




『TOSHIBA XG3 1TB』冇拉拉唔識認,後蒞『Seagate XM1440 960Gb』都唔識認.睇蒞係中古『臺達FLEX-500』造工嘛嘛.
上次買『Seagate XM1440 960Gb』係22110規格.『x99-itx』係2280規格且係主板背面.
『M.2槽2280轉22110』.卡高啱啱好利用機箱托板散热,『XM1440』維持係50℃,基本冇跌速.