圖檔-PNG解析

圖檔-PNG解析
圖檔-PNG解析

舊時『游戲紋理』再用『.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;  

 

SolidWorks改單位系統MMGS

SolidWorks改單位系統MMGS
SolidWorks改單位系統MMGS

SolidWorks望記或填錯英制單位, 改翻MM單位.

  1. 打開『新檔/舊檔』『.SLDPRT』
  2. 『工具』->『選項』
  3. 『文件屬性』->『單位』
  4. 『單位系統』->勾『MMGS(毫米, 公克, 秒)』
  5. 撳『確定』

Font-源界明朝

Font-源界明朝
Font-源界明朝

 

Adobe』同『Google』合作,制作『日月韓漢』矢量字庫,目前支缓65535『日月韓漢』字.以字量蒞睇依然有大量異體字未收納.

1.          官網下載源界明朝字庫,

2.          解壓

3.          將『SuperOTC\SourceHanSerif.ttc』复制到『C:\Windows\Fonts

https://source.typekit.com/source-han-serif/tw/

https://github.com/adobe-fonts/source-han-serif/archive/1.001R.zip

https://typekit.com/fonts/source-han-sans-traditional-chinese

 

Samsung開發人員模式

Samsung開發人員模式
Samsung開發人員模式
Samsung開發人員模式
Samsung開發人員模式

問老友借samsung平板程式調試, 首先著『開發人員模式』.

  1. 撳『設定』->『關於平板電腦』->『軟件資訊』
  2. 撳『內部版本號』柒下
  3. 撳『設定』->『開發人員模式』
  4. 著『USB偵錯』

Android Studio-Gradle連缐超時

Android Studio-Gradle連缐超時
Android Studio-Gradle連缐超時

随著『Android studio』更新版本,『Gradle』需升級.

  1. 『File』->『project Structure』
  2. 『Gradle version』揀新版本
  3. 撳右下角『Apply』自動下載.點知彈出『Connection timed out:』連缐超時.
  4. 编輯『Project\gradle\wrapper\gradle-wrapper.properties』
  5. 『distributionUrl』係『Gradle』升級包下載路徑.
https://services.gradle.org/distributions/gradle-8.2.1-bin.zip
  1. 『zipStorePath』係升級包擺放點『wrapper/dists』
  2. 下載後將『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-gradle版本異常
Android studio-gradle版本異常

Android studio近日彈出gradle版本晤兼容.修改工程配置. 如果唔得重裝『Android Studio』.

  1. 撳『HELP』->『ABOUT』. 『Android Studio版本』确定『Gradle插件版本』
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
  1. 撳『File』->『project Structure』
  2. 『Gradle version』揀版本
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
  1. 撳右下角『Apply』自動下載.
The project is using an incompatible version (AGP 8.1.0) of the Android Gradle plugin. Latest supported version is AGP 8.0.0

 

Windows10-解除更新

Windows10-解除更新
Windows10-解除更新
Windows10-解除更新
Windows10-解除更新

『Win10』自動更新後頻頻輕機,舊时『Win9x/WinXP』係著機果陣『F8鍵』入『安全模式』修復系统.係『Win10』時代入『修復』卸載更新.

  1. 著機睇見『Win10-logo』後撳『reset鍵』.重复三次登入『修復』
  2. 『高級選項』->『疑难解答』->『高級選項』->『解除更新』
  3. 解除更新.
  4. 入『Win10』
  5. 『設定』->『Windows Update』
  6. 連繼撳『將更新暫停7天』,

Android Studio-ZLIB壓縮同解壓

Android Studio-ZLIB壓縮同解壓
Android 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 默認壓縮設定

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(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(PBYTE dest,int * dest_length,PBYTE sour,int sour_length, int level)

{

int ret, 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;

 

ret = deflate(&stream, flush);  // 进行压缩

*dest_length = stream.total_out;

 

deflateEnd(&stream);// 释放内存

return ret;

}