commit f93b275e6074ba4bbad229204ef3036ddf385150 Author: ranchuan Date: Wed Nov 22 18:02:53 2023 +0800 huffman数据压缩算法验证成功 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..f3679c6 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,23 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**", + "C:/MinGW/include/" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE", + "__WIN32__", + "DLL_EXPORT" + ], + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "windows-gcc-x64", + "compilerPath": "C:/MinGW/bin/gcc.exe" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..018b3b0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "coder_lib.h": "c" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1a1dd1f --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ + + +CC = gcc + + +SRCS = $(wildcard *.c) + + +STR = $(subst from,to,from your heart) + +all: + $(CC) $(SRCS) -o hello + +clean: + rm -rf *.exe diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..af09aaa --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,10 @@ + + + + +使用gcc编译一个文件 +gcc hello.c -o hello + + +2023.11.22 + huffman数据压缩算法验证成功 diff --git a/bytearray.c b/bytearray.c new file mode 100644 index 0000000..30c1d22 --- /dev/null +++ b/bytearray.c @@ -0,0 +1,219 @@ +#include "bytearray.h" +#include "stdlib.h" +#include "string.h" +#include "stdio.h" +// #include "board.h" +// #include "mystdlib.h" +// #include "debug.h" +// #include "rtthread.h" + + + +#define ARR_MAX_PRINT_LEN 200 + +#define ARRAY_APPEND_SKIP 2048 + +#define rt_mutex_t void * + +// 使用时保证不要在不同线程同时修改,可以不用保护以提高速度 +#define rt_mutex_create(...) 0 +#define rt_mutex_delete(...) +#define rt_mutex_take(...) +#define rt_mutex_release(...) + + + + + +struct _array_def{ + int32_t all; + int32_t used; + rt_mutex_t mutex; + uint8_t data[0]; +}; + + + + + +array_def *arr_creat(void) +{ + array_def *a; + static uint16_t count=0; + char s1[16]={0}; + sprintf(s1,"arr_mut#%d",count); + int size=0; + size+=sizeof(array_def); + size+=ARRAY_APPEND_SKIP; + a=malloc(size); + param_check(a); + a->all=ARRAY_APPEND_SKIP; + a->used=0; + a->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO); + count++; + return a; +} + + + +static array_def *arr_expend(array_def *a) +{ + array_def *r; + int size=0; + int cpysize=0; + size+=sizeof(array_def); + size+=a->all+ARRAY_APPEND_SKIP; + r=malloc(size); + param_check(r); + cpysize=sizeof(array_def)+a->used; + memcpy(r,a,cpysize); + r->all+=ARRAY_APPEND_SKIP; + free(a); + return r; +} + + + + +array_def *_arr_append(array_def **a,uint8_t d) +{ + param_check(a); + param_check(*a); + array_def *r=*a; + rt_mutex_take(r->mutex,RT_WAITING_FOREVER); + if((*a)->used>=(*a)->all) + { + r=arr_expend(*a); + } + r->data[r->used]=d; + r->used++; + rt_mutex_release(r->mutex); + *a=r; + return r; +} + + +uint8_t arr_get(array_def *a,int index) +{ + uint8_t ret=0; + param_check(a); + rt_mutex_take(a->mutex,RT_WAITING_FOREVER); + if(index<0) index=a->used+index; + if((index>=0&&indexused)==0) ret=0; + else ret=a->data[index]; + rt_mutex_release(a->mutex); + return ret; +} + + +void arr_reset(array_def *a,uint8_t d,int index) +{ + param_check(a); + rt_mutex_take(a->mutex,RT_WAITING_FOREVER); + if(index<0) index=a->used+index; + if((index>=0&&indexused)==0){} + else a->data[index]=d; + rt_mutex_release(a->mutex); +} + + +uint8_t *arr_data(array_def *a) +{ + param_check(a); + return a->data; +} + + +int arr_length(array_def *a) +{ + param_check(a); + return a->used; +} + + +// 截取数组 +array_def *arr_mid(array_def *a,int start,int len) +{ + param_check(a); + array_def *r; + r=arr_creat(); + if(start<0) start=a->used+start; + if((start>=0&&startused)==0) + { + return r; + } + if(start+len>a->used) + { + len=a->used-start; + } + for(int i=0;idata[i+start]); + } + //return tappend(r,0); + return r; +} + +// 移除一些数据,返回实际移除的数据长度 +int arr_remove(array_def *a,int start,int len) +{ + param_check(a); + if(start<0) start=a->used+start; + if((start>=0&&startused)==0) + { + return 0; + } + if(start+len>a->used) + { + len=a->used-start; + } + int move_len=a->used-(start+len); + memcpy(&a->data[start],&a->data[start+len],move_len); + a->used-=len; + return len; +} + +// 输出打印字符串 +char *arr_string(array_def *a) +{ + param_check(a); + array_def *d=arr_creat(); + param_check(d); + // DBG_LOG("d=%08x,a=%08x",d,a); + // DBG_LOG("%s:length(a)==%d.",__func__,arr_length(a)); + int len=0; + char s[20]; + int index=0; + arr_append(d,'['); + for(int i=0;i=ARR_MAX_PRINT_LEN){ + // 超过20字节的 只打印前20字节 + sprintf(s,"...(%d)",arr_length(a)); + len=strlen(s); + arr_appends(d,s,len); + break; + } + } + arr_append(d,']'); + len=arr_length(d); + char *ptr=malloc(len+1); + param_check(ptr); + memcpy(ptr,arr_data(d),len); + arr_delete(d); + ptr[len]=0; + return ptr; +} + + + + + + diff --git a/bytearray.h b/bytearray.h new file mode 100644 index 0000000..f8e0c8c --- /dev/null +++ b/bytearray.h @@ -0,0 +1,47 @@ +#ifndef bytearray_h__ +#define bytearray_h__ + +#include "stdint.h" + +struct _array_def; +typedef struct _array_def array_def; + + + +array_def *arr_creat(void); +uint8_t arr_get(array_def *a,int index); +void arr_reset(array_def *a,uint8_t d,int index); +array_def *arr_mid(array_def *a,int start,int len); +uint8_t *arr_data(array_def *a); +int arr_length(array_def *a); +int arr_remove(array_def *a,int start,int len); +char *arr_string(array_def *a); + + +#define arr_delete(a) {free(a);a=0;} +#define arr_append(a,d) _arr_append(&a,d) +#define arr_appends(a,d,len) for(int i=0;i年月日(hex) +年(y),月(m),日(d) +time=((((y[0]-'0')*10)+(y[1]-'0'))<<9)|\ + ((((m[0]-'0')*10)+(m[1]-'0'))<<5)|\ + (((d[0]-'0')*10)+(d[1]-'0')) + +特征码盒号序号(ascii)->特征码盒号序号(hex) +特征码(c),盒号(b),序号(i) +code=c*10000+((b[0]-'0')*100+(b[1]-'0')*10+(b[2]-'0'))*100+\ + ((i[1]-'0')*10+(i[2]-'0')) + + +*/ + + + + + +// 根据管壳码和年份信息生成uid的年份信息 +static int coder_calc_year(const char *year,const char shell_year,char *uid_year) +{ + int y=0; + for(int i=0;i<4;i++) + { + y*=10;y+=year[i]-'0'; + } + // year是实时数据,鉴于12月31生产的雷管,year可能不同 + // 此时year-1来保证与uid码上的相同 + if(year[3]!=shell_year) + y--; + uid_year[0]=y%100/10+'0'; + uid_year[1]=y%10+'0'; + if(uid_year[1]==shell_year) + return 0; + else + return -1; +} + + + +// 管壳码转uid码 +int coder_shell_to_uid(const char *year,const char *shell_code,char *uid_code) +{ + int ret=0; + memset(uid_code,0,16); + // 添加芯片企业代号(2byte) + memcpy(&uid_code[0],"AD",2); + // 添加年份(2y=byte) + ret=coder_calc_year(year,shell_code[2],&uid_code[2]); + // 添加雷管厂代号(2byte) + memcpy(&uid_code[4],&shell_code[0],2); + // 添加月日特征码流水号 + memcpy(&uid_code[6], &shell_code[3],10); + + return ret; +} + + + +// 转换hex字符串为一个byte +static int coder_strhex_to_byte(const char *str_hex) +{ + char buff[3]={0}; + buff[0]=str_hex[0]; + buff[1]=str_hex[1]; + return str_ahextoi(buff); +} +// 转换int字符串为一个整形 +static int coder_strint_to_byte(const char *str_int,int len) +{ + char buff[10]={0}; + if(len>10) return 0; + memcpy(buff,str_int,len); + return str_atoi(buff); +} + +// uid码转存储码 +int coder_uid_to_save(const char *uid_code,uint8_t *save_code) +{ + uint16_t ymd=0; + uint32_t feature=0; + save_code[0]=coder_strhex_to_byte(&uid_code[0]); + save_code[1]=coder_strhex_to_byte(&uid_code[4]); + ymd=coder_strint_to_byte(&uid_code[2],2)<<9; + ymd|=coder_strint_to_byte(&uid_code[6],2)<<5; + ymd|=coder_strint_to_byte(&uid_code[8],2); + save_code[2]=ymd>>8; + save_code[3]=ymd&0xff; + feature=uid_code[10]*100000; + feature+=coder_strint_to_byte(&uid_code[11],3)*100; + feature+=coder_strint_to_byte(&uid_code[14],2); + save_code[4]=feature>>16; + save_code[5]=feature>>8; + save_code[6]=feature&0xff; + save_code[7]=crc_crc8(save_code,7); + return 0; +} + +// 转换byte为hex字符串 +static int coder_byte_to_strhex(const uint8_t byte,char *str_hex) +{ + char buff[10]={0}; + sprintf(buff,"%02X",byte); + str_hex[0]=buff[0]; + str_hex[1]=buff[1]; + return 0; +} +// 转换int为int字符串 +static int coder_int_to_strint(const int n,char *str_int,int len) +{ + char buff[10]={0}; + sprintf(buff,"%05d",n); + memcpy(str_int,buff+(strlen(buff)-len),len); + return 0; +} + +// 存储码转uid +int coder_save_to_uid(const uint8_t *save_code,char *uid_code) +{ + uint16_t ymd=0; + uint32_t feature=0; + int ret=0; + if(save_code[7]!=crc_crc8(save_code,7)) + { + return -1; + } + ret|=coder_byte_to_strhex(save_code[0],&uid_code[0]); + ret|=coder_byte_to_strhex(save_code[1],&uid_code[4]); + ymd=(save_code[2]<<8)|save_code[3]; + feature=(save_code[4]<<16)|(save_code[5]<<8)|(save_code[6]); + ret|=coder_int_to_strint(ymd>>9,&uid_code[2],2); + ret|=coder_int_to_strint((ymd>>5)&0x0f,&uid_code[6],2); + ret|=coder_int_to_strint((ymd)&0x1f,&uid_code[8],2); + uid_code[10]=feature/100000; + ret|=coder_int_to_strint(feature%100000/100,&uid_code[11],3); + ret|=coder_int_to_strint(feature%100,&uid_code[14],2); + return ret; +} + + + +// uid码转管壳码 +int coder_uid_to_shell(const char *uid_code,char *shell_code) +{ + memset(shell_code,0,13); + // 添加雷管厂代号 + memcpy(&shell_code[0],&uid_code[4],2); + // 添加生产年份 + memcpy(&shell_code[2],&uid_code[3],1); + // 添加月日特征码流水号 + memcpy(&shell_code[3],&uid_code[6],10); + + return 0; +} + + + + + diff --git a/coder_lib.h b/coder_lib.h new file mode 100644 index 0000000..4dcabb5 --- /dev/null +++ b/coder_lib.h @@ -0,0 +1,36 @@ +#ifndef coder_lib_h__ +#define coder_lib_h__ + + +#include "stdint.h" + + + + + + + +// 管壳码转uid码 +int coder_shell_to_uid(const char *year,const char *shell_code,char *uid_code); + +// uid码转存储码 +int coder_uid_to_save(const char *uid_code,uint8_t *save_code); + +// 存储码转uid +int coder_save_to_uid(const uint8_t *save_code,char *uid_code); + +// uid码转管壳码 +int coder_uid_to_shell(const char *uid_code,char *shell_code); + + + + + + + + + + + +#endif + diff --git a/crc.c b/crc.c new file mode 100644 index 0000000..366a85b --- /dev/null +++ b/crc.c @@ -0,0 +1,109 @@ +#include "crc.h" + + + + + + + +uint8_t crc_crc8(const uint8_t *data,int num) +{ + uint8_t crc = 0; + uint16_t j,i; + for (j = 0; j < num; j++) + { + crc ^= *(data+j); + for ( i = 0; i < 8; i++) + { + if ((crc & 0x01) != 0) + { + crc >>= 1; + crc ^= 0x8c; + } + else + { + crc >>= 1; + } + } + } + return crc; +} + + + + + +void crc_crc16(const uint8_t *data, int len,uint8_t *lb,uint8_t *hb) +{ + if (len > 0) + { + uint16_t crc = 0xFFFF; + int i = 0; + for (; i < len; i++) + { + crc = (uint16_t)(crc ^ (data[i])); + for (int j = 0; j < 8; j++) + { + crc = (crc & 1) != 0 ? (uint16_t)((crc >> 1) ^ 0xA001) : (uint16_t)(crc >> 1); + } + } + uint8_t hi = (uint8_t)((crc & 0xFF00) >> 8); //高位置 + uint8_t lo = (uint8_t)(crc & 0x00FF); //低位置 + *lb=lo;*hb=hi; + } +} + + + +uint32_t crc_crc32(const uint8_t *data,int size) +{ + uint32_t temp,crc=0xffffffff; + int i=0,j=0; + if((size%4)!=0) + { + return 0; + } + while(ihm_calc_value_of_tree(item)) + { + table[i]=table[j]; + table[j]=item; + item=table[i]; + } + } + } +} + + + +// 打印index_table +static void hm_index_table_print(huffman_def *h){ + DBG_LOG("-----index_table-----\n"); + for(int i=0;iindex_table_index;i++){ + DBG_LOG("index:%d,data:%02x,count:%d\n",i,h->index_table[i]->data,h->index_table[i]->count); + } +} + + +// 打印数据的编码 +static void hm_data_code_print(huffman_def *h){ + huff_tree *t; + DBG_LOG("------data code------\n"); + for(int i=0;iindex_table_index;i++){ + t=h->index_table[i]; + DBG_LOG("%c:",t->data); + while(t->parant){ + DBG_LOG("%d",t->pos); + t=t->parant; + } + DBG_LOG("\n"); + } +} + + + +static void hm_calc_count(huffman_def *h,array_def *d) +{ + int num=arr_length(d); + int index; + memset(h->count_table,0,256); + // DBG_LOG("calc count_table\n"); + for(int i=0;icount_table[arr_get(d,i)]++; + } + // DBG_LOG("calc index_table\n"); + for(int i=0;i<256;i++) + { + if(h->count_table[i]>0){ + index=h->index_table_index; + h->index_table[index]=calloc(1,sizeof(huff_tree)); + h->index_table[index]->count=h->count_table[i]; + h->index_table[index]->data=i; + h->index_table_index++; + } + } + // DBG_LOG("sort index_table\n"); + hm_sort_index_table(h->index_table,h->index_table_index); + // hm_index_table_print(h); +} + + + +// 计算树的值 +static int hm_calc_value_of_tree(huff_tree *t) +{ + int sum=0; + if(t->left&&t->right) + sum=hm_calc_value_of_tree(t->left)+hm_calc_value_of_tree(t->right); + else + sum=t->count; + // DBG_LOG("tree sum:%d\n",sum); + return sum; +} + + + +// 打印huffman树 +static void hm_tree_print(huff_tree *t) +{ + if(t->left&&t->right){ + DBG_LOG("point:,count:%d\n",hm_calc_value_of_tree(t)); + hm_tree_print(t->left); + hm_tree_print(t->right); + }else{ + DBG_LOG("data:%d,count:%d\n",t->data,t->count); + } + +} + + + + +// 建立huffman树 +static void hm_creat_tree(huffman_def *h) +{ + int tail=h->index_table_index; + huff_tree *sub1,*sub2; + huff_tree **table=calloc(tail,sizeof(huff_tree *)); + for(int i=0;iindex_table[i]; + } + while(tail>1){ + huff_tree *temp; + sub1=table[tail-1]; + sub2=table[tail-2]; + // 大在左,小在右 + temp=calloc(1,sizeof(huff_tree)); + sub1->parant=temp; + sub2->parant=temp; + // 左为1,右为0 + if(hm_calc_value_of_tree(sub1)>hm_calc_value_of_tree(sub2)){ + temp->left=sub1; + sub1->pos=1; + temp->right=sub2; + sub2->pos=0; + }else{ + temp->left=sub2; + sub2->pos=1; + temp->right=sub1; + sub1->pos=0; + } + table[tail-2]=temp; + tail--; + hm_sort_index_table(table,tail); + // DBG_LOG("-----table-----\n"); + // for(int i=0;itree=table[0]; + free(table); +} + + +// 删除树 +static void hm_del_tree(huff_tree *t) +{ + if(t->left&&t->right){ + hm_del_tree(t->left); + hm_del_tree(t->right); + } + free(t); +} + +// 数据中添加一个bit +static void hm_add_bit(array_def *d,int bit,int *index) +{ + int len=arr_length(d); + if(*indexindex_table_index;i++) + { + t=h->index_table[i]; + if(t->data==d) + break; + } + if(t->data!=d){ + DBG_WARN("can not encode.\n"); + exit(-1); + } + + while(t->parant){ + hm_add_bit(h->out,t->pos,&h->arr_bit_index); + t=t->parant; + } + // char *str=arr_string(h->out); + // DBG_LOG("index:%d,out data:%s\n",h->arr_bit_index,str); + // free(str); + return 0; +} + +// 生成索引 +static array_def *hm_creat_index_table(huffman_def *h) +{ + array_def *a=arr_creat(); + int temp; + int diff; + arr_append(a,h->index_table_index); + hm_index_table_print(h); + for(int i=0;iindex_table_index;i++) + { + arr_append(a,h->index_table[i]->data); + temp=h->index_table[i]->count; + while(temp>0){ + if(temp>=255) diff=255; + else diff=temp; + arr_append(a,diff); + temp-=diff; + } + } + // 填充0个数 + temp=arr_length(h->out)*8-h->arr_bit_index; + arr_append(a,temp); + // char *str=arr_string(a); + // DBG_LOG("arr index table:%s\n",str); + // free(str); + return arr_temp(a); +} + +// huffman编码 +/* +压缩后数据格式 +data[0]:索引表长度 +data[1~n]:索引表,每个索引由值(1byte)和频次(1byte,小于255)(2byte,大于等于255,频次由两个字节相加) +data[n+1]:数据中填充0个数 +data[n+2~m]:压缩后的数据 + +*/ +array_def *hm_encode(array_def *data) +{ + int input_len=arr_length(data); + huffman_def *h=calloc(1,sizeof(huffman_def)); + array_def *ret=0; + h->out=arr_creat(); + // DBG_LOG("calc count\n"); + hm_calc_count(h,data); + // DBG_LOG("creat tree\n"); + hm_creat_tree(h); + // DBG_LOG("encode byte\n"); + for(int i=0;itree); + arr_appends_from(ret,h->out); + arr_delete(h->out); + free(h); + + DBG_LOG("lenth_in:%d,length_encode:%d\n",input_len,arr_length(ret)); + return arr_temp(ret); +} + + +// 读取编码表,返回数据开始的位置 +static int hm_unpack_count(huffman_def *h,array_def *d) +{ + int num=arr_get(d,0); + int index=1; + uint8_t temp; + for(int i=0;iindex_table[i]=calloc(1,sizeof(huff_tree)); + h->index_table[i]->data=arr_get(d,index);index++; + do{ + temp=arr_get(d,index);index++; + h->index_table[i]->count+=temp; + }while(temp==0xff); + h->index_table_index++; + } + temp=arr_get(d,index);index++; + h->in_bit_count=(arr_length(d)-index)*8-temp; + h->in=arr_mid(d,index,arr_length(d)-index); + // hm_index_table_print(h); + printf("bitcount:%d,\n",h->in_bit_count); + return index; +} + + +// 获取指定index的bit值 +static inline int hm_get_bit(array_def *d,int index) +{ + uint8_t t=arr_get(d,index/8); + return t&(1<<(index%8))?1:0; +} + + +// 对比树节点,匹配返回bit数,不匹配返回0 +static inline int hm_cmp_bits(huffman_def *h,huff_tree *t) +{ + int count=0; + // DBG_LOG("tree pos:",t->pos); + while(t){ + // DBG_LOG("%d",t->pos); + if(hm_get_bit(h->in,h->arr_bit_index+count)!=t->pos){ + // DBG_LOG(" |failed\n"); + return 0; + } + else{ + count++; + t=t->parant; + } + } + h->arr_bit_index+=count; + // DBG_LOG(" |ok,\n"); + return count; +} + + +static uint8_t hm_decode_byte(huffman_def *h) +{ + huff_tree *t=h->tree; + int bit; + // DBG_LOG("decode:"); + while(t->left&&t->right){ + bit=hm_get_bit(h->in,h->arr_bit_index-1); + // DBG_LOG("%d",bit); + if(bit==t->left->pos) + t=t->left; + else + t=t->right; + h->arr_bit_index--; + } + // DBG_LOG(" | decode byte:%c\n",t->data); + return t->data; +} + + + +static int hm_calc_decode_len(huffman_def *h) +{ + int sum=0; + for(int i=0;iindex_table_index;i++){ + sum+=h->index_table[i]->count; + } + DBG_LOG("data len for decode:%d\n",sum); + return sum; +} + + + +// huffman解码 +/* +*/ +array_def *hm_decode(array_def *data) +{ + huffman_def *h=calloc(1,sizeof(huffman_def)); + int decode_len,decode_index; + array_def *ret=arr_creat(); + uint8_t *decode_data=0; + uint8_t c; + hm_unpack_count(h,data); + hm_creat_tree(h); + // hm_data_code_print(h); + // hm_tree_print(h->tree); + decode_len=hm_calc_decode_len(h); + decode_index=decode_len; + decode_data=calloc(decode_len+1,sizeof(uint8_t)); + h->arr_bit_index=h->in_bit_count; + while(h->arr_bit_index>0){ + c=hm_decode_byte(h); + decode_data[decode_index-1]=c; + decode_index--; + } + DBG_LOG("del tree\n"); + hm_del_tree(h->tree); + DBG_LOG("del h->in\n"); + //arr_delete(h->in); + DBG_LOG("free h\n"); + free(h); + // arr_appends(ret,decode_data,decode_len); + DBG_LOG("decode:%s\n",decode_data); + free(decode_data); + return arr_temp(ret); +} + + + + + + + diff --git a/huffman.h b/huffman.h new file mode 100644 index 0000000..2dcedb8 --- /dev/null +++ b/huffman.h @@ -0,0 +1,19 @@ + +#ifndef huffman_h__ +#define huffman_h__ + +#include "bytearray.h" + +// huffman编码的实现 + +array_def *hm_encode(array_def *data); + +array_def *hm_decode(array_def *data); + + + + +#endif + + + diff --git a/mystring.c b/mystring.c new file mode 100644 index 0000000..1f31f8e --- /dev/null +++ b/mystring.c @@ -0,0 +1,74 @@ + +/* +* +* 把整数字符串传化为int,直到遇到非数字字符 +* +*/ +static int str_ainttoi(const char *s) +{ + int ret=0; + int sig=1; + if(*s=='-'){ + s++; + sig=-1; + } + while(*s) + { + if(*s>='0'&&*s<='9') + { + ret*=10; + ret+=*s-'0'; + } + else return ret; + s++; + } + return ret*sig; +} + + + + +int str_ahextoi(const char *s) +{ + int ret=0; + while(*s) + { + if(*s>='0'&&*s<='9') + { + ret*=16; + ret+=*s-'0'; + } + else if(*s>='a'&&*s<='f') + { + ret*=16; + ret+=*s-'a'+10; + } + else if(*s>='A'&&*s<='F') + { + ret*=16; + ret+=*s-'A'+10; + } + else return ret; + s++; + } + return ret; +} + + + + + +int str_atoi(const char *s) +{ + if(s[0]=='0'&&((s[1]=='x')||(s[1]=='X'))){ + return str_ahextoi(&s[2]); + }else{ + return str_ainttoi(s); + } +} + + + + + + diff --git a/mystring.h b/mystring.h new file mode 100644 index 0000000..9039f59 --- /dev/null +++ b/mystring.h @@ -0,0 +1,29 @@ + +#ifndef mystring_h__ +#define mystring_h__ + + +#include "stdint.h" + + + +int str_ahextoi(const char *s); + +int str_atoi(const char *s); + + + + + + + + + + +#endif + + + + + + diff --git a/sdl/.vscode/c_cpp_properties.json b/sdl/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..f3679c6 --- /dev/null +++ b/sdl/.vscode/c_cpp_properties.json @@ -0,0 +1,23 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**", + "C:/MinGW/include/" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE", + "__WIN32__", + "DLL_EXPORT" + ], + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "windows-gcc-x64", + "compilerPath": "C:/MinGW/bin/gcc.exe" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/sdl/.vscode/settings.json b/sdl/.vscode/settings.json new file mode 100644 index 0000000..236a91b --- /dev/null +++ b/sdl/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "sdl.h": "c" + } +} \ No newline at end of file diff --git a/sdl/hello_sdl.c b/sdl/hello_sdl.c new file mode 100644 index 0000000..9c16442 --- /dev/null +++ b/sdl/hello_sdl.c @@ -0,0 +1,62 @@ + + + +//使用 SDL 和 标准 IO +#include +#include + +//定义屏幕尺寸常量 +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; + + +int main( int argc, char* args[] ) +{ + //将要渲染的窗口 + SDL_Window* window = NULL; + + //窗口含有的surface + SDL_Surface* screenSurface = NULL; + + //初始化SDL + if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) + { + printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() ); + } + else + { + //创建 window + window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); + if( window == NULL ) + { + printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); + } + else + { + //获取 window surface + screenSurface = SDL_GetWindowSurface( window ); + + //用白色填充surface + SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF ) ); + + //更新surface + SDL_UpdateWindowSurface( window ); + + //延迟两秒 + SDL_Delay( 2000 ); + } + } + //销毁 window + SDL_DestroyWindow( window ); + + //退出 SDL subsystems + SDL_Quit(); + + return 0;} + + + + + + +