TFT_eSPI/Tools/Create_Smooth_Font/Compress_font/vlwcompress.c

210 lines
4.1 KiB
C

/*
VLW Compress v0.0.1 16/7/21
Used to transform 8bit VLW file into 4bit VLW file with no padding support.
Note: The program is made by pure C ;it has no dependence.
License:See license in root directory.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
FILE* fin;
FILE* fout;
struct {
uint32_t gCount;
uint32_t gVer; //0xB(11) = unCompressed,0xC(12)=compressed.
uint32_t fSize;
uint32_t mboxY;
uint32_t ascent;
uint32_t descent;
uint8_t* gX;
uint8_t* gY;
} fInfo;
uint32_t readu32(){
uint32_t temp=0;
uint8_t tmp[4]={0};
fread(tmp,1,4,fin);
temp |= tmp[0] << 24;
temp |= tmp[1] << 16;
temp |= tmp[2] << 8;
temp |= tmp[3] << 0;
return temp;
}
uint8_t readu8(){
uint8_t temp[1];
fread(temp,1,1,fin);
return temp[0];
}
int writeu32(uint32_t in){
uint8_t tmp[4]={0};
tmp[0]=in>>24;
tmp[1]=(in & 0x00ff0000 )>>16;
tmp[2]=(in & 0x0000ff00 )>>8;
tmp[3]=(in & 0x000000ff );
if(fwrite(tmp,1,4,fout)==4){
return 0;
}
return 1;
}
int writeu16(uint16_t in){
uint8_t tmp[2]={0};
tmp[0]=in>>8;
tmp[1]=(in & 0x00ff );
if(fwrite(tmp,1,2,fout)==2){
return 0;
}
return 1;
}
int writeu8(uint8_t in){
if(fwrite(&in,1,1,fout)==1){
return 0;
}
return 1;
}
uint8_t combine2u8(uint8_t H,uint8_t L){
return (H & 0xf0 ) | (L >> 4); //All get High bits and combine
}
int getFontInfo(){
fInfo.gCount=readu32();
fInfo.gVer=readu32();
fInfo.fSize=readu32();
fInfo.mboxY=readu32();
fInfo.ascent=readu32();
fInfo.descent=readu32();
return 0;
}
int writeHeader(){
writeu32(fInfo.gCount);
writeu32(12ULL);
writeu32(fInfo.fSize);
writeu32(fInfo.mboxY);
writeu32(fInfo.ascent);
writeu32(fInfo.descent);
return 0;
}
int compressCharsTable(){
for(uint32_t i=0;i<fInfo.gCount;i++){
uint16_t unicode=(uint16_t)readu32();
uint8_t bh=(uint8_t)readu32();
uint8_t bw=(uint8_t)readu32();
uint8_t ga=(uint8_t)readu32();
int16_t dy=(int16_t)readu32();
int8_t dx=(int8_t)readu32();
readu32(); //ignore padding
fInfo.gX[i]=bw;
fInfo.gY[i]=bh;
writeu16(unicode);
writeu8(bh);
writeu8(bw);
writeu8(ga);
writeu16(dy);
writeu8(dx);
}
return 0;
}
int compressCharsBitmap(){
for(uint32_t i=0;i<fInfo.gCount;i++){
if((fInfo.gX[i] & 1) !=0){//not fix 2
for(uint8_t j=0;j<fInfo.gY[i];j++){
for(uint8_t k=0;k<fInfo.gX[i]-1;k+=2){
uint8_t t1=(uint8_t)readu8();
uint8_t t2=(uint8_t)readu8();
writeu8(combine2u8(t1,t2));
}
//process the last pixel of each line with 0 as low bits
uint8_t t1=(uint8_t)readu8();
writeu8(combine2u8(t1,0));
}
}else{
for(uint16_t j=0;j<fInfo.gX[i] * fInfo.gY[i];j+=2){
uint8_t t1=(uint8_t)readu8();
uint8_t t2=(uint8_t)readu8();
writeu8(combine2u8(t1,t2));
}
}
}
}
int main(int argc,char* argv[]){
printf("\n=== VLWCompress - 4bpp by Lucy2003 v0.0.1 === \n\n");
if(argc<=2){
printf(" usage: %s [input_path] [output_path]\n\n",argv[0]);
return 0;
}
printf("Input file: %s\nOutput file: %s\n",argv[1],argv[2]);
fin=fopen(argv[1],"rb");
if(fin == NULL){
printf("\nError: Can't open input file. \n\n");
return 1;
}
fseek(fin,0,SEEK_SET);
fout=fopen(argv[2],"w+b");
if(fout==NULL){
printf("\nError: Can't open output file. \n\n");
return 2;
}
getFontInfo();
printf("Font file info:\n");
printf(" Char count: %d\n",fInfo.gCount);
printf(" Font version: %d\n",fInfo.gVer);
printf(" Font size: %d Bytes\n",fInfo.fSize);
printf(" mboxY: %d\n ascent:%d\n descent:%d\n",fInfo.mboxY,fInfo.ascent,fInfo.descent);
if(fInfo.gVer==12){
printf("\nError: Input file already compressed.\n\n");
return 3;
}
if(fInfo.gVer!=11){
printf("\nError: Unsupport font version.\n\n");
return 4;
}
fInfo.gX=NULL;
fInfo.gY=NULL;
fInfo.gX=(uint8_t*)calloc(fInfo.gCount,sizeof(uint8_t));
fInfo.gY=(uint8_t*)calloc(fInfo.gCount,sizeof(uint8_t));
if(fInfo.gX==NULL || fInfo.gY==NULL){
printf("\nError: Malloc memory failed.\n\n");
return 5;
}
//Compress
writeHeader();
compressCharsTable();
compressCharsBitmap();
free(fInfo.gX);
free(fInfo.gY);
while(!feof(fin)){
writeu8(readu8());
}
fclose(fin);
fclose(fout);
printf("\nCompress Font successfully!\n\n");
return 0;
}