Translate

Unlocking the Power: Compiler Optimization and Testing in C/C++ vs Python

Compiler optimization and testing:
After compiler optimization, the performance of C/C++ is greatly improved, with some steps even requiring 10 billion executions before results can be obtained due to the speed being too fast. Cxxdroid uses CLang with only the -O3 parameter, which automatically uses the acceleration instruction set. Termux uses g++ with support for a large number of parameters and initial tests show that it is much faster than Cxxdroid. However, there are still many areas that need to be researched and tested.
Under the same optimization conditions, it is impossible to compare the performance of Python with that of C because the use of many advanced types working together incurs a significant cost.

#include "mylib.h"
using namespace std;
int testPerformance (int ts = 10000 * 1000){
//	print_ulimit_a();

	printf("Testing Performance for %ld Millions times:\n",ts/1000/1000);
	clock_t start, finish;
	long double total_time;
	map<int , long double> omap;
	unordered_map<int,long double> umap;
	unordered_map<string, string> kmap;
	vector<int> vlist;
	string strpp;
	myChar mychar;
	 char *cst=(char*)malloc(ts*sizeof(char));
	vector<int> ls;
int *ls1=(int*)malloc(ts*sizeof(int));
	string str;


char testC[]="123456";


start = clock();
int lenC=strlen(testC);
	for (long long i = 0; i <ts; i++)
	{
		mychar.cat(testC,lenC);
	}
	
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("myChar cat : %Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	
charsView(mychar,10,32);

start = clock();
	for (long long  i = 0; i <ts*100; i++)
	{
		
		char temps=mychar.chars[i%ts];
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("myChar get for 100X %d M times : %Lf secs,%Lf  M/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000);


start = clock();
	for (long long i = 0; i <ts; i++)
	{
		strpp+=testC;
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("C++ string add ;%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();
	for (long long  i = 0; i <ts; i++)
	{
		char temps=strpp.at(i);
	
	}

	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("C++ string get ;%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);
start = clock();
	for (long long i = 0; i <ts; i++)
	{
		vlist.push_back(i);
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::vector push back ;%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();
	for (long long i = 0; i <ts*100; i++)
	{
		 int temp=vlist[i%ts];
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::vector get for 100X %d M times : %Lf secs,%Lf  M/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000);	


//return 0;
start = clock();
	for (long long i = 0; i <ts; i++)
	{
		umap[i]=i;
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::unordered_map set :%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();
	for (long long i = 0; i <ts; i++)
	{
	long double temp=umap[i];
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::unordered_map get :%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000.0);	
			
	start = clock();
	for (long long i = 0; i <ts; i++)
	{
		ls1[i] = i;
		//ls.push_back(i);
		//str+="g";
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("C int array set :%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0/ 1000);
	
start = clock();
	for (long long i = 0; i <ts*100;i++)
	{
		int v = ls1[i%ts];
		//int v=ls[i];
		//str+="g";
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("C int array 100X %d M times : %Lf secs,%Lf  M/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000);
	start = clock();
	for (long long i = 0; i <ts; i++)
	{
		cst[i]=i%256;
		//ls.push_back(i);
		//str+="g";
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("C char array set : %Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);
	
start = clock();
	for (long long i = 0; i <ts*100;i++)
	{
		char v = cst[i%ts];
		//int v=ls[i];
		//str+="g";
	}
	finish = clock();
	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;
	printf("C char array 100X %d M times : %Lf secs,%Lf  M/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000);	

free(mychar.chars);		
free(ls1);
ls1=NULL;
free(cst);
cst=NULL;
printf("Testing Python 3.1.1 ,run loop for 1,000,000 Times:\n");
system("python test2.py");
return 0;	
	}
	

int main()
{	

testPerformance(10000*10000);
long double t0,t;	
char url[]="http://localhost:8000/static/test.mp3";
char url1[]="http://localhost:8000/static/chat.js";
char url2[]="http://localhost:8000/static/in.mp4";

printf("Testing download file from  localhost and write to File with myChar:\n");
char *uri=url2;
t0=clock();
myChar uc=readURL(uri);
t=(clock()-t0)/CLOCKS_PER_SEC;
printf("Downloaed %s in %Lf secs,%Lf MB/sec\n",uri,t,uc.length/t/1000/1000);
charsView(uc,10,16);


/*

t0=clock();
char path[]="o.mp4";
writeToFile(path,uc.chars,uc.length);
t=(clock()-t0)/CLOCKS_PER_SEC;
printf("Data written  to File %s  in %Lf secs,%Lf MB/sec\n",path,t,uc.length/t/1000/1000);
*/
free(uc.chars);
return 0;

	
}

The C language's is incredibly fast! 😱
If the same task was done in Python, it would take days to get the same results.
The test.cpp:


#include "mylib.h"

using namespace std;

int testPerformance (int ts = 10000 * 1000){

//	print_ulimit_a();

	printf("Testing Performance for %ld Millions times:\n",ts/1000/1000);

	clock_t start, finish;

	long double total_time;

	map<int , long double> omap;

	unordered_map<int,long double> umap;

	unordered_map<string, string> kmap;

	vector<int> vlist;

	string strpp;

	myChar mychar;

	 char *cst=(char*)malloc(ts*sizeof(char));

	vector<int> ls;

int *ls1=(int*)malloc(ts*sizeof(int));

	string str;

char testC[]="123456";

 myChar s;

s.cat("Hello ");

 s.cat("world ");

myChar s1=s*1000*1000;

 s1.cat("!");

char *p1=strstr(s1.chars,"Hello world !");

long long p1p=(long long)(p1-s1.chars+1);

printf("muChar for search test:\n");

printf("\n");

charsView(s1,20,11);

start=clock();

for (long long i =0;i<ts;i++){

	if (p1p!=s1.find("Hello world !")){

		printf("Test failed: %ld,,%ld\n",p1p,s1.find("world !"));

		break;

	}

}

finish=clock();

total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("myChar search  str with length=%ld for %d Millions times : %Lf secs,%Lf  Billions/sec\n", s1.length,ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000/1000);	 

start = clock();

int lenC=strlen(testC);

	for (long long i = 0; i <ts; i++)

	{

		mychar.cat(testC,lenC);

	}

	

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("myChar cat : %Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

charsView(mychar,10,32);

start = clock();

	for (long long  i = 0; i <ts*100; i++)

	{

	

		char temps=mychar.chars[i%ts];

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("myChar get for 100X %d M times : %Lf secs,%Lf  Billions/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000/1000);

start = clock();

	for (long long i = 0; i <ts; i++)

	{

		strpp+=testC;

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("C++ string add ;%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();

	for (long long  i = 0; i <ts; i++)

	{

		char temps=strpp.at(i);

	

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("C++ string get ;%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);

start = clock();

	for (long long i = 0; i <ts; i++)

	{

		vlist.push_back(i);

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("STD::vector push back ;%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();

	for (long long i = 0; i <ts*100; i++)

	{

		 int temp=vlist[i%ts];

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("STD::vector get for 100X %d M times : %Lf secs,%Lf  Billions/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000/1000);	

//return 0;

start = clock();

	for (long long i = 0; i <ts; i++)

	{

		umap[i]=i;

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("STD::unordered_map set :%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();

	for (long long i = 0; i <ts; i++)

	{

	long double temp=umap[i];

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("STD::unordered_map get :%Lf secs,%Lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000.0);	

			

	start = clock();

	for (long long i = 0; i <ts; i++)

	{

		ls1[i] = i;

		//ls.push_back(i);

		//str+="g";

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("C int array set :%Lf secs,%Lf  Billions/sec\n", total_time, ts / total_time / 1000.0/ 1000/1000);

	

start = clock();

	for (long long i = 0; i <ts*100;i++)

	{

		int v = ls1[i%ts];

		//int v=ls[i];

		//str+="g";

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("C int array 100X %d M times : %Lf secs,%Lf  Billions/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 / 1000/1000);

	start = clock();

	for (long long i = 0; i <ts; i++)

	{

		cst[i]=i%256;

		//ls.push_back(i);

		//str+="g";

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("C char array set : %Lf secs,%Lf  Billions/sec\n", total_time, ts / total_time / 1000.0 /1000/ 1000);

	

start = clock();

	for (long long i = 0; i <ts*100;i++)

	{

		char v = cst[i%ts];

		//int v=ls[i];

		//str+="g";

	}

	finish = clock();

	total_time = (long double)(finish - start) / CLOCKS_PER_SEC;

	printf("C char array 100X %d M times : %Lf secs,%Lf  Billions/sec\n", ts/1000/1000,total_time, ts / total_time / 1000.0 /1000/ 1000);	

//free(mychar.chars);		

free(ls1);

ls1=NULL;

free(cst);

cst=NULL;

printf("Testing Python 3.1.1 ,run loop for 1,000,000 Times:\n");

system("python test2.py");

return 0;	

	}

		

int main()

{

testPerformance(10000*10000);

long double t0,t;	

char url[]="http://localhost:8000/static/test.mp3";

char url1[]="http://localhost:8000/static/chat.js";

char url2[]="http://localhost:8000/static/in.mp4";

printf("Testing download file from  localhost and write to File with myChar:\n");

char *uri=url2;

t0=clock();

myChar uc=readURL(uri);

t=(clock()-t0)/CLOCKS_PER_SEC;

printf("Downloaed %s in %Lf secs,%Lf MB/sec\n",uri,t,uc.length/t/1000/1000);

charsView(uc,20,16);

/*

t0=clock();

char path[]="o.mp4";

writeToFile(path,uc.chars,uc.length);

t=(clock()-t0)/CLOCKS_PER_SEC;

printf("Data written  to File %s  in %Lf secs,%Lf MB/sec\n",path,t,uc.length/t/1000/1000);

//*/

//free(uc.chars);

return 0;

	

}

The test results on Termux:


(fast) brian@localhost:/sdcard/Documents/Cxxdroid$

Testing Performance for 100 Millions times:

muChar for search test:

Size :12.000000 M,   20 sample slices with witdth=11:

Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- Hello world  -...- ![0][0][0][0][0][0][0][0][0][0]  -...-

myChar search  str with length=12000001 for 100 Millions times : 0.002188 secs,45.703839  Billions/sec

myChar cat : 0.323255 secs,309.353297  M/sec

Size :600.000000 M,   10 sample slices with witdth=32:

12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...-

myChar get for 100X 100 M times : 0.000001 secs,100000.000000  Billions/sec

C++ string add ;0.918199 secs,108.908853  M/sec

C++ string get ;0.022508 secs,4442.864759  M/sec

STD::vector push back ;0.421409 secs,237.299156  M/sec

STD::vector get for 100X 100 M times : 0.000000 secs,inf  Billions/sec

STD::unordered_map set :9.055981 secs,11.042426  M/sec

STD::unordered_map get :0.368186 secs,271.601853  M/sec

C int array set :0.167584 secs,0.596716  Billions/sec

C int array 100X 100 M times : 0.000001 secs,100000.000000  Billions/sec

C char array set : 0.047238 secs,2.116940  Billions/sec

C char array 100X 100 M times : 0.000001 secs,100000.000000  Billions/sec

Testing Python 3.1.1 ,run loop for 1,000,000 Times:

Run  testPythonStrAdd  loop for  1000000 times in 0.039954 secs, 25.028816 M/secs

Run  testPythonStrGet  loop for  1000000 times in 0.035021 secs, 28.554242 M/secs

Run  testNumpyArrayPut  loop for  1000000 times in 0.074087 secs, 13.497619 M/secs

Run  testNumpyArrayGet  loop for  1000000 times in 0.106379 secs, 9.400370 M/secs

Run  testPythonListAppend  loop for  1000000 times in 0.051809 secs, 19.301728 M/secs

Run  testPythonListGet  loop for  1000000 times in 0.026272 secs, 38.062907 M/secs

Run  testPythonDictSet  loop for  1000000 times in 0.814699 secs, 1.227448 M/secs

Run  testPythonDictGet  loop for  1000000 times in 0.586921 secs, 1.703806 M/secs

Run  testFileDictSet  loop for  1000000 times in 4.468566 secs, 0.223785 M/secs

Run  testFileDictGet  loop for  1000000 times in 4.197674 secs, 0.238227 M/secs

Testing download file from  localhost and write to File with myChar:

Downloaed http://localhost:8000/static/in.mp4 in 0.969424 secs,188.828987 MB/sec

Size :183.055000 M,   20 sample slices with witdth=16:

[0][0][0][18]ftypmp42[0][0][0][0]  -...- [F7][D][C6][B1]m[9F][CC][BE][93][82][E3]<[E9]vb[BB]  -...- [6][9E][D1][A1][A9][DA][D3][7]A[19][A6][FE][D1][C8][8A][F7]  -...- [7F][E1][E]:[A4][C0][D5]~[13][CF][B3][BA][A6]q[C9][A2]  -...- [D8][83]D=[A5][CB][98]Qw[C4][EA]c[AC])[91][F4]  -...- .n%"[E7]8]%[10]>[CD]r[DF][7].[B7]  -...- [E0][EE]K[6][B9][1F][10][FC][D6][[9E]([B1][1B][9E][E2]  -...- [AB][EE][E4]65[C5][B1]8[EC][99][97]~[E2][EF]0t  -...- [B1][DF][83][EB][E3][D6]xXv[CF][F8][86][F9][D4]T!  -...- [80][F2]<k[E7]^[9C][7]@[DF]_[9F][1B][D3]qI  -...- w[C7][AD][4]qq[A0]p[1E][9B][8C]5J#[E4][CF]  -...-  ;;[D5][8C][E1][15][FC])[D6][DF][A3]=[DA]Q[80]  -...- [DE][BA][8B][E5][8A]J[E5][E5]g6[9C]0^[AB][D1]/  -...- '[96]%P[B5]~[EF]g[FA][C0]5p[87][97]'j  -...- pqT[B0][CC]:[F7][1C][B2]+Q[88][FE]f b  -...- v[82][1F]wY[B3][DF]C%[8F][0]m^[19][FB][98]  -...-  [F9][1A]+[D3][D9][DA][9B]?[90][CF][1F][DC]l[C6]q  -...- [D9][AF]J[93][E3]a[E]H@8[83][18][F2][DF]#C  -...- [F2][9B]Zq[9B]a[E8]][BC][9D][18][FB][AE]Sk[D1]  -...- P[CE][83][D][CD][94]Y[B4][E0][8E][C][B7][CF][B][F4]6  -...- Rs[16]d[AA]c[C4][B2][13]#[A9]o[0][0][0][0]  -...-

improved it by doubling the horizontal resolution and enabling the display of RGB images in Termux.

Referring to a project on GitHub that implements similar functionality using RUST (https://github.com/nabijaczleweli/termimage), I have improved it by doubling the horizontal resolution and enabling the display of RGB images in Termux.


	void printMatrixC()
	{
		// Allocate memory for the output buffer
		char *output = (char *)malloc((getWidth() + 1) * getHeight() * 16 * sizeof(char)); // Width + 1 to include the newline character

		// Build the output buffer
		char *p = output;
			for (int y = 0; y < getHeight(); y+=2)
		{
			for (int x = 0; x < getWidth(); x++)
			{
				//Point2D point = {(double)x, (double)y};
				unsigned char value = get(x, y);

				// Choose the background color based on the value
				int backgroundColor = (int)value;

				// Set the background color and print a space
				p += sprintf(p, "\033[48;5;%dm ", backgroundColor);
			}
			p += sprintf(p, "\033[0m\n");
		}

		// Print the output buffer and free memory
		printf("%s", output);
		free(output);
	}
	

	void printMatrix()
	{
		float avg=0;
		float maxC=0;
		float minC=256;
		for (int i=0;i<height*width;i++) {
			int c=array[i];
		//	float rgb=colorMap[c][0]+colorMap[c][1]+colorMap[c][2];
		float rgb=colorMap[c][0]*0.299+colorMap[c][1]*0.587+colorMap[c][2]*0.114;
			avg+=rgb;
			if (rgb>=maxC) maxC=rgb;
			if (rgb<=minC) minC=rgb;
			
		}
		   avg=avg/height/width;
		   maxC=maxC-minC;
		   //maxC=232*3;
			for (int y = 0; y < getHeight(); y+=2)
		{
			for (int x = 0; x < getWidth(); x++)
			{
				//Point2D point = {(double)x, (double)y};
				unsigned char value = get(x, y);
				//Y = 0.299 R + 0.587 G + 0.114 B
			//	float rgb=colorMap[value][0]+colorMap[value][1]+colorMap[value][2];
		float rgb=16+colorMap[value][0]*0.299+colorMap[value][1]*0.587+colorMap[value][2]*0.114;
				
			//	if (value>=avg*3)printf("@@");
if (value>=minC+maxC*30/32)printf("§");
else if (value>=minC+maxC*29/32)printf("€");
else if (value>=minC+maxC*29/32)printf("¥");
else if (value>=minC+maxC*28/32)printf("@");
else if (value>=minC+maxC*27/32)printf("&");
else if (value>=minC+maxC*27/32)printf("¥");
else if (value>=minC+maxC*26/32)printf("$");
else if (value>=minC+maxC*25/32)printf("#");
else if (value>=minC+maxC*24/32)printf("W");
else if (value>=minC+maxC*23/32)printf("B");
else if (value>=minC+maxC*22/32)printf("G");
else if (value>=minC+maxC*21/32)printf("R");
else if (value>=minC+maxC*20/32)printf("N");
else if (value>=minC+maxC*19/32)printf("F");
else if (value>=minC+maxC*18/32)printf("H");
else if (value>=minC+maxC*17/32)printf("K");
else if (value>=minC+maxC*16/32)printf("N");
else if (value>=minC+maxC*15/32)printf("U");
else if (value>=minC+maxC*14/32)printf("V");
else if (value>=minC+maxC*13/32)printf("L");
else if (value>=minC+maxC*12/32)printf("J");
else if (value>=minC+maxC*11/32)printf("O");
else if (value>=minC+maxC*10/32)printf("C");
else if (value>=minC+maxC*9/32)printf("I");
else if (value>=minC+maxC*8/32)printf("i");
else if (value>=minC+maxC*7/32)printf("-");
else if (value>=minC+maxC*6/32)printf(";");
else if (value>=minC+maxC*5/32)printf(":");
else if (value>=minC+maxC*4/32)printf(".");
else if (value>=minC+maxC*3/32)printf(" ");
else if (value>=minC+maxC*2/32)printf(" ");
else printf(" ");
			}
			printf("\n");
		}
		return;
	}


//RGB:



void printMatrixC()
	{
		// Allocate memory for the output buffer
		char *output = (char *)malloc((getWidth() + 1) * getHeight() * 24 * sizeof(char)); // Width + 1 to include the newline character

		// Build the output buffer
		char *p = output;
		for (int y = 0; y < getHeight(); y+=2)
		{
			for (int x = 0; x < getWidth(); x++)
			{
				//Point2D point = {(double)x, (double)y};
				Color bg = getPoint({(double)x,(double)y});

				// Choose the background color based on the value

				// Set the background color and print a space
				p += sprintf(p, "\033[48;2;%d;%d;%dm ", bg.r,bg.g,bg.b);
			}
			p += sprintf(p, "\033[0m\n");
		}

		// Print the output buffer and free memory
		printf("%s", output);
		free(output);
	}

Testing glyph data extraction using FreeType:

Similar methods can be used to achieve many interesting ideas!


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <ft2build.h>

#include FT_FREETYPE_H

#include <wchar.h>

#include <sys/time.h>

#include <time.h>

#include <unistd.h>

#include <sys/ioctl.h>

FT_Bitmap getBitMap(FT_Library library, FT_Face face, int charIndex) {

    FT_Bitmap bitmap;

    FT_GlyphSlot slot;

    FT_Error error;

    error = FT_Load_Glyph(face, charIndex, FT_LOAD_DEFAULT);

    if (error) {

        printf("Failed to load glyph\n");

        exit(1);

    }

    slot = face->glyph;

    error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);

    if (error) {

        printf("Failed to render glyph\n");

        exit(1);

    }

    bitmap.buffer = slot->bitmap.buffer;

    bitmap.width = slot->bitmap.width;

    bitmap.rows = slot->bitmap.rows;

    return bitmap;

}

void print_bitmap(FT_Bitmap *bitmap) {

    int x, y;

    for (y = 0; y < bitmap->rows; y++) {

        for (x = 0; x < bitmap->width; x++) {

            printf(bitmap->buffer[x + bitmap->width * y] ? "##" : "  ");

        }

        printf("\n");

    }

}

int main() {

    struct winsize sSize;

	ioctl(STDOUT_FILENO, TIOCGWINSZ, &sSize);

    FT_Library library;

    FT_Face face;

    FT_Error error;

    FT_UInt charIndex;

    

  const  char font_file[] = "./SysSans-Hans-Regular.ttf";

    int font_size = (sSize.ws_row-3)/3;

    

    error = FT_Init_FreeType(&library);

    if (error) {

        printf("Failed to initialize FreeType library\n");

        return 1;

    }

    error = FT_New_Face(library, font_file, 0, &face);

    if (error == FT_Err_Unknown_File_Format) {

        printf("Unsupported font file format\n");

        return 1;

    } else if (error) {

        printf("Failed to open font file\n");

        return 1;

    }

    error = FT_Set_Pixel_Sizes(face, 0, font_size);

    if (error) {

        printf("Failed to set font size\n");

        return 1;

    }

    

    for (int i = 0; i < 100; i++) {

        system("clear");

        srand(clock());

        int k=rand()%(127-33);

        //0x4e00 -0x9fff Chinese

      

            charIndex = FT_Get_Char_Index(face, k+34);

            FT_Bitmap bitmap = getBitMap(library, face, charIndex);

            print_bitmap(&bitmap);

            printf("\n");

           

            

            

            

            srand(clock());

        k=rand()%(218-166);

       

            charIndex = FT_Get_Char_Index(face, k+166);

            bitmap = getBitMap(library, face, charIndex);

            print_bitmap(&bitmap);

            printf("\n");

            

            

            srand(clock());

        k=rand()%(0x9fff-0x4e00);

       

            charIndex = FT_Get_Char_Index(face, k+0x4e00);

            bitmap = getBitMap(library, face, charIndex);

            print_bitmap(&bitmap);

            printf("\n");

            

            sleep(1);

         

        

    }

    

    FT_Done_Face(face);

    FT_Done_FreeType(library);

    return 0;

}

A simple test for Python, C, and C++:

A simple test for Python, C, and C++:
After some trying, it was found that it is difficult to achieve various ideas in a short time using only C language. However, if it is compiled into CPP, there are fewer restrictions, and one can mix various languages and create their own struct and methods. Now I have tested the performance of various commonly used basic types and also explored better usage methods. The test results can serve as reference data for solving various problems with suitable data types in the future. In the process, I also wrote a mixed C language type called myChar and automatically allocated memory through a buffer mechanism, with a length attribute to record the length. It not only considers performance but also adds various new functions continuously, including automatic memory release mechanism, so that the data processing process can meet the intended conception without wasting time on complicated problems.
Some types and methods, such as ordered map and Python str addition operation, are too slow to be tested together for too long without results, and are therefore not considered to be used.
In actual development, I tend to mix various languages as much as possible, reusing all tested code, first developing a version that can work correctly in the shortest possible time, and then improving it slowly during usage.
t1.cpp:

#include "mylib.h"
using namespace std;
int testPerformance (int ts = 10000 * 1000){
//	print_ulimit_a();

	printf("Testing Performance for %ld Millions times:\n",ts/1000/1000);
	clock_t start, finish;
	double total_time;
	map<int , double> omap;
	unordered_map<int,double> umap;
	unordered_map<string, string> kmap;
	vector<int> vlist;
	string strpp;
	myChar mychar;
	 char *cst=(char*)malloc(ts*sizeof(cst));
	vector<int> ls;
int *ls1=(int*)malloc(ts*sizeof(int));
	string str;



char testC[]="123456";

start = clock();

	for (int  i = 0; i <ts; i++)
	{
		mychar.cat(testC,6);
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("myChar cat : %lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);	
charsView(mychar,10,32);

start = clock();
	for (int  i = 0; i <ts; i++)
	{
		
		char temps=mychar.chars[i];
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("myChar get : %lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);


start = clock();
	for (int  i = 0; i <ts; i++)
	{
		strpp+=testC;
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("C++ string add ;%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);	

start = clock();
	for (int  i = 0; i <ts; i++)
	{
		char temps=strpp.at(i);
	
	}

	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("C++ string get ;%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);





start = clock();
	for (int  i = 0; i <ts; i++)
	{
		vlist.push_back(i);
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::vector push back ;%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);	

start = clock();
	for (int  i = 0; i <ts; i++)
	{
		 int temp=vlist[i];
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::vector get ;%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);	



//return 0;
start = clock();
	for (int  i = 0; i <ts; i++)
	{
		umap[i]=i;
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::unordered_map set :%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);	

start = clock();
	for (int  i = 0; i <ts; i++)
	{
		double temp=umap[i];
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::unordered_map get :%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000.0);		
		


start = clock();
	for (int  i = 0; i <ts; i++)
	{
		kmap[to_string(i)]="s";
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD::unordered_map string  set :%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000.0 / 1000);	

start = clock();
	for (int  i = 0; i <ts; i++)
	{
		string temp1=kmap[to_string(i)];
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("STD :: unordered_map string get : %lf secs,%lf  M/sec\n", total_time, ts / total_time /1000.0 / 1000);	


	
			

	
	start = clock();
	for (int  i = 0; i <ts; i++)
	{
		ls1[i] = i;
		//ls.push_back(i);
		//str+="g";
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("C int array set :%lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);
	
start = clock();
	for (int i = 0; i <ts;i++)
	{
		int v = ls1[i];
		//int v=ls[i];
		//str+="g";
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("C int array get :%lf secs,%lf  M/sec,\n", total_time, ts / total_time / 1000 / 1000);
	start = clock();
	for (int  i = 0; i <ts; i++)
	{
		cst[i]=i%256;
		//ls.push_back(i);
		//str+="g";
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("C char array set : %lf secs,%lf  M/sec\n", total_time, ts / total_time / 1000 / 1000);
	
start = clock();
	for (int i = 0; i <ts;i++)
	{
		char v = cst[i];
		//int v=ls[i];
		//str+="g";
	}
	finish = clock();
	total_time = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("C char array get :%lf secs,%lf  M/sec,\n", total_time, ts / total_time / 1000 / 1000);
	
free(mychar.chars);		
free(ls1);
ls1=NULL;
free(cst);
cst=NULL;
printf("Testing Python 3.1.1 ,run loop for 1,000,000 Tines:\n");
system("python test2.py");
return 0;	
	}
int main()
{	
testPerformance();
double t0,t;	
char url[]="http://localhost:8000/static/test.mp3";
char url1[]="http://localhost:8000/static/chat.js";
char url2[]="http://localhost:8000/static/in.mp4";

printf("Testing download file from  localhost and write to File with myChar:\n");
t0=clock();
myChar uc=readURL(url2);
t=(clock()-t0)/CLOCKS_PER_SEC;
printf("Downloaed %s in %lf secs,%lf MB/sec\n",url2,t,uc.length/t/1000/1000);
charsView(uc,20,16);




t0=clock();
char path[]="o.mp4";
writeToFile(path,uc.chars,uc.length);
t=(clock()-t0)/CLOCKS_PER_SEC;
printf("Data written  to File %s  in %lf secs,%lf MB/sec\n",path,t,uc.length/t/1000/1000);


free(uc.chars);

return 0;

}

test2.py:

import  time
from  fileDict3 import FileDict
import numpy

def timIt(f,ts):
	t0=time.time()
	f(ts)
	t=(time.time()-t0)
	print("Run  %s  loop for  %d times in %f secs, %f M/secs  " %(f.__name__,ts,t,ts/t/1000/1000))

ts=10000*100
fileDict=FileDict(":memory:")
pythonDict=dict()
pythonList=list()
pythonStr=str()
numpyArray=numpy.empty(0)
def testFileDictSet(ts=ts):
	for i in range(ts):
		fileDict["%d"%i]="%d"%i
def testFileDictGet(ts=ts):
	for i in range(ts):
		trmp=fileDict["%d"%i]
def testSQLFileDict(ts=ts):
    timIt(testFileDictSet,ts)
    timIt(testFileDictGet,ts)

def testPythonDictSet(ts=ts):
	for i in range(ts):
		pythonDict["%d"%i]="%d"%i
def testPythonDictGet(ts=ts):
	for i in range(ts):
		trmp=pythonDict["%d"%i]
def testPythonDict(ts=ts):
    timIt(testPythonDictSet,ts)
    timIt(testPythonDictGet,ts)

def testPythonListAppend(ts=ts):
	for i in range(ts):
		pythonList.append(i)
def testPythonListGet(ts=ts):
	for i in range(ts):
		trmp=pythonList[i]
def testPythonList(ts=ts):
    timIt(testPythonListAppend,ts)
    timIt(testPythonListGet,ts)

def testPythonStrAdd(ts=ts):
	global pythonStr
	pythonStr="".join(["s" for x in range(ts)])
def testPythonStrGet(ts=ts):
	global pythonStr
	for i in range(ts):
		trmp=pythonStr[i]
def testPythonStr(ts=ts):
    timIt(testPythonStrAdd,ts)
    timIt(testPythonStrGet,ts)

def testNumpyArrayPut(ts=ts):
	global numpyArray
	numpyArray=numpy.array(range(ts))
def testNumpyArrayGet(ts=ts):
	global numpyArray
	for i in range(ts):
		temp=numpyArray[i]
	
def testNumpyArray(ts=ts):
    timIt(testNumpyArrayPut,ts)
    timIt(testNumpyArrayGet,ts)

testPythonStr()
testNumpyArray()
testPythonList()
testPythonDict()
testSQLFileDict()
Test results on Termux:

cat t1.sh
g++  -g -std=c++17 t1.cpp -o ~/bin/t1 -l stdc++  -l z -l ncurses  -l jpeg  -l m -l png -l sqlite3(fast) brian@localhost:/sdcard/Documents/Cxxdroibash t1.sh
(fast) brian@localhost:/sdcard/Documents/Cxxdroid$ ~/bin/t1
Testing Performance for 10 Millions times:
myChar cat : 0.109706 secs,91.152717  M/sec
Size :60.000000 M,   10 sample slices with witdth=32:
12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...-
myChar get : 0.029256 secs,341.810227  M/sec
C++ string add ;0.148384 secs,67.392711  M/sec
C++ string get ;0.031740 secs,315.059861  M/sec
STD::vector push back ;0.145763 secs,68.604516  M/sec
STD::vector get ;0.029890 secs,334.560054  M/sec
STD::unordered_map set :3.308387 secs,3.022621  M/sec
STD::unordered_map get :0.980168 secs,10.202333  M/sec
STD::unordered_map string  set :14.202366 secs,0.704108  M/sec
STD :: unordered_map string get : 8.273668 secs,1.208654  M/sec
C int array set :0.043568 secs,229.526258  M/sec
C int array get :0.031669 secs,315.766207  M/sec,
C char array set : 0.037155 secs,269.142780  M/sec
C char array get :0.031384 secs,318.633699  M/sec,
Testing Python 3.1.1 ,run loop for 1,000,000 Tines:
Run  testPythonStrAdd  loop for  1000000 times in 0.037662 secs, 26.551942 M/secs
Run  testPythonStrGet  loop for  1000000 times in 0.031914 secs, 31.334215 M/secs
Run  testNumpyArrayPut  loop for  1000000 times in 0.067665 secs, 14.778615 M/secs
Run  testNumpyArrayGet  loop for  1000000 times in 0.102062 secs, 9.797990 M/secs
Run  testPythonListAppend  loop for  1000000 times in 0.044594 secs, 22.424756 M/secs
Run  testPythonListGet  loop for  1000000 times in 0.028341 secs, 35.284205 M/secs
Run  testPythonDictSet  loop for  1000000 times in 0.748319 secs, 1.336329 M/secs
Run  testPythonDictGet  loop for  1000000 times in 0.579722 secs, 1.724966 M/secs
Run  testFileDictSet  loop for  1000000 times in 4.431511 secs, 0.225657 M/secs
Run  testFileDictGet  loop for  1000000 times in 4.278479 secs, 0.233728 M/secs
Testing download file from  localhost and write to File with myChar:
Downloaed http://localhost:8000/static/in.mp4 in 2.554132 secs,71.670279 MB/sec
Size :183.055000 M,   20 sample slices with witdth=16:
Ʊm�̾���<�vb�  -...- �ѡ���A���Ȋ�  -...- �:���~ϳ��qɢ  -...- ؃D=�˘Qw��c�)��  -...- .n%"�8]%>�r�.�  -...- ��K���[�(��  -...- ���65ű8왗~��0t  -...- �߃���xXv�����T!  -...- ��<k�^�@�_��I  -...- wǭqq�p��5J#��  -...-  ;;Ռ��)�ߣ=�Q�  -...- ���J��g6�0^��/  -...- '�%P�~�g��5p��'j  -...- pqT��:��+Q��f b  -...- v�wY��C%�m^��  -...-  �+��ڛ?���l�q  -...- ٯJ��aH@8���#C  -...- �Zq�a�]����Sk�  Y��.- P�
   ��
     �6  -...- Rsd�cIJ#�o  -...-
174.574219 MB Data written to o.mp4
Data written  to File o.mp4  in 0.091976 secs,1990.251283 MB/sec
(fast) brian@localhost:/sdcard/Documents/Cxxdroid$
Test results on Cxxdroid

Testing Performance for 10 Millions times:
myChar cat : 0.147278 secs,67.898804  M/sec
Size :60.000000 M,   10 sample slices with witdth=32:
12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...- 12345612345612345612345612345612  -...-
myChar get : 0.030455 secs,328.353308  M/sec
C++ string add ;0.129566 secs,77.180742  M/sec
C++ string get ;0.028515 secs,350.692618  M/sec
STD::vector push back ;0.498145 secs,20.074476  M/sec
STD::vector get ;0.028672 secs,348.772321  M/sec
STD::unordered_map set :5.756297 secs,1.737228  M/sec
STD::unordered_map get :1.829963 secs,5.464591  M/sec
STD::unordered_map string  set :20.736899 secs,0.482232  M/sec
STD :: unordered_map string get : 11.860119 secs,0.843162  M/sec
C int array set :0.045866 secs,218.026425  M/sec
C int array get :0.031573 secs,316.726317  M/sec,
C char array set : 0.036120 secs,276.854928  M/sec
C char array get :0.031741 secs,315.049935  M/sec,
Testing Python 3.1.1 ,run loop for 1,000,000 Tines:
sh: python: not found
Testing download file from  localhost and write to File with myChar:
Downloaed http://localhost:8000/static/in.mp4 in 0.657549 secs,278.390435 MB/sec
Size :183.055000 M,   20 sample slices with witdth=16:
Ʊm�̾���<�vb�  -...- �ѡ���A���Ȋ�  -...- �:���•ϳ��─ɢ  ▲▼▼▼▲ ؃D=�˘Q┬��␌�)��  ▲▼▼▼▲ ▼┼%"�8]%>�⎼�▼�  ▲▼▼▼▲ ��K���[�(��� ▲▼▼▼▲ ���65ű8왗•��█├  ▲▼▼▼▲ �߃���│X┴�����T!  ▲▼▼▼▲ ��<┐�^�@� ��I  ▲▼▼▼▲ ┬ǭ──�⎻��5J#��  ▲▼▼▼▲  ;;Ռ��)�ߣ=�Q�  ▲▼▼▼▲ ޺��J��±6�█^��/  ▲▼▼▼▲ '�%P�•�±��5⎻��'┘  ▲▼▼▼▲ ⎻─T��:��▶Q��° ␉  ▲▼▼▼▲ ┴�┬Y��C%�└^��  ▲▼▼▼▲  �▶��ڛ?���┌�─  ▲▼▼▼▲ ٯJ��▒H@8���#C  ▲Y��▲ �Z─�▒�]����S┐�  ▲▼▼▼▲ P΃
   ��
     �6  ▲▼▼▼▲ R⎽␍�␌͔#�⎺  ▲▼▼▼▲
174▼574219 MB D▒├▒ ┬⎼␋├├␊┼ ├⎺ ⎺▼└⎻4
D▒├▒ ┬⎼␋├├␊┼  ├⎺ F␋┌␊ ⎺▼└⎻4  ␋┼ █▼3696█6 ⎽␊␌⎽◀495▼271592 MB/⎽␊␌

[P⎼⎺±⎼▒└ °␋┼␋⎽#␊␍]

Python 5 times faster than C, just simple testing.

Incredible! Without Numba, Python is 30 times slower than C language, but with Numba and fastmath=True enabled, it's 5 times faster than C language - how is this possible?
t1.c:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
	
clock_t start, finish;
double total_time;

total_time = (double)(finish - start) / CLOCKS_PER_SEC ;
int tt=10000*10000;
printf("Calculate x*x-(x-2)*(x+1) for 100,000,000 times:\n");
    start = clock();
    for (int x=0;x<tt;x++){
    	int k=x*x-(x-2)*(x+1);

    }
    finish = clock();
total_time = (double)(finish - start) / CLOCKS_PER_SEC ;
printf(" In C language: %lf secs,%lf  M/sec\n", total_time,tt/total_time/1000/1000);
system("python test.py");
return 0;
}



test py:

import time
import numba
ts=10000*10000
@numba.jit(nopython=True)
def test():
    for x in range(ts):
	    v=x*x-(x-2)*(x+1)

@numba.jit(nopython=True,fastmath=True)
def test1():
    for x in range(ts):
	    v=x*x-(x-2)*(x+1)
	

    

def test2():
    for x in range(ts):
	    v=x*x-(x-2)*(x+1)
	
    
t0=time.time()
test()
t=time.time()-t0
print("In python with Numba, nopython:%f secs,%f  M/sec\n" %(t,ts/t/1000/1000))


t0=time.time()
test1()
t=time.time()-t0
print("In python with Numba, nopython,fastmath:%f secs,%f  M/sec\n" %(t,ts/t/1000/1000))



t0=time.time()
test2()
t=time.time()-t0
print("In  python without Numba:,%ff secs,%f  M/sec\n" %(t,ts/t/1000/1000))

Solution for insinstallingtalling FastAPI, pydantic, and Jupyterlab in Pydroid3:


Solution for insinstallingtalling FastAPI, pydantic, and Jupyterlab in Pydroid3:

The issue is not with Pydroid3 itself, but with the fact that FastAPI, pydantic, and Jupyterlab have introduced new technologies in their updated versions, which are not currently supported in Pydroid3. To use the latest versions, you will need to use Termux instead.

To install the older versions that are compatible with Pydroid3, simply copy and paste the following text:

fastapi==0.103.0

jupyterlab==3.5.3

pydantic==1.10.12

Dict -like Python Class works on file

This is code from a few months ago.The initial development of this feature was because I found data types like dict to be very convenient to use and could serve as the foundation for many advanced functionalities. If there was a stable and reliable dictionary class work on file, it would easily solve most data access problems and greatly speed up the development process.
I have always believed that programming skills are not essential. Before starting to type code, one should find the correct method. As long as the method is correct, the code can always be written. The specific steps implemented in different languages may vary slightly, but the underlying method is consistent.

The first pure Python version was just for learning and research purposes and has been deprecated. The version using SQLite3 is still being used and so far no issues have been found, so there haven't been any improvements made.


#FileDict.py

import os

import bisect

import numpy as np

import struct

class FileDict:

    def __init__(self, file_path):

        self.data_file = file_path + '.data'

        self.index_file = file_path + '.index'

        self.ram_index = []

        if not os.path.exists(self.data_file):

            open(self.data_file, 'wb').close()

        if not os.path.exists(self.index_file):

            open(self.index_file, 'wb').close()

        self.load_index(self.index_file)

    def load_index(self, index_file):

        if os.path.getsize(index_file) > 0:

            with open(index_file, 'rb') as f:

                self.ram_index = np.fromfile(f, dtype=np.int64).reshape(-1, 2).tolist()

                self.ram_index.sort()

    def __getitem__(self, key):

        h_key = hash(key)

        i = bisect.bisect_left(self.ram_index, [h_key, 0])

        if i != len(self.ram_index) and self.ram_index[i][0] == h_key:

            with open(self.data_file, 'rb') as f:

                f.seek(self.ram_index[i][1])

                flag, stored_key, value = self.read_record(f)

                if flag != b'D' and stored_key == key:

                    return value

        raise KeyError(key)

    def __setitem__(self, key, value):

        h_key = hash(key)

        i = bisect.bisect_left(self.ram_index, [h_key, 0])

        if i != len(self.ram_index) and self.ram_index[i][0] == h_key:

            with open(self.data_file, 'r+b') as f:

                f.seek(self.ram_index[i][1])

                flag, stored_key, value1 = self.read_record(f)

                if flag == b'V' and stored_key == key:

                    f.seek(self.ram_index[i][1])

                    f.write(b'D')

                    f.truncate()

                    pos=self.append_record(f, key, value)

                    self.ram_index[i]=[h_key,pos ]

                    with open(self.index_file, 'ab') as f:

                        f.write(np.array([[h_key, self.ram_index[i][1]]], dtype=np.int64).tobytes())

                elif flag != b'D' and stored_key == key and value == value1:

                    pass 

                else:

                    f.seek(self.ram_index[i][1])

                    f.truncate()

                    bisect.insort_left(self.ram_index, [h_key, self.append_record(f, key, value)])

                    with open(self.index_file, 'ab') as f:

                        f.write(np.array([[h_key, self.ram_index[i][1]]], dtype=np.int64).tobytes())

            

                    

        else:

            with open(self.data_file, 'ab') as f:

                bisect.insort_left(self.ram_index, [h_key, self.append_record(f, key, value)])

            with open(self.index_file, 'ab') as f:

                f.write(np.array([[h_key, self.ram_index[i][1]]], dtype=np.int64).tobytes())

            

    def __delitem__(self, key):

        h_key = hash(key)

        i = bisect.bisect_left(self.ram_index, [h_key, 0])

        if i != len(self.ram_index) and self.ram_index[i][0] == h_key:

            with open(self.data_file, 'r+b') as f:

                f.seek(self.ram_index[i][1])

                f.write(b'D')

        else:

            raise KeyError(key)

    def __iter__(self):

        with open(self.data_file, 'rb') as f:

            while True:

                flag, key, _ = self.read_record(f)

                if not flag:

                    break

                if flag != b'D':

                    yield key

    def items(self):

        with open(self.data_file, 'rb') as f:

            while True:

                flag, key, value = self.read_record(f)

                if not flag:

                    break

                if flag != b'D':

                    yield key, value

    

    def from_dict(self, dict):

        new_data_file = self.data_file + '.rebuild'

        new_index = []

        with open(new_data_file, 'wb') as dest:

            for key, value in dict.items():

                hash_key = hash(key)

                new_index.append([hash_key, self.append_record(dest, key, value)])

        os.replace(new_data_file, self.data_file)

        self.ram_index = new_index

        with open(self.index_file, 'wb') as f:

            np.array(new_index, dtype=np.int64).tofile(f)

        self.load_index(self.index_file)

    def add_items(self, items):

        temp_file = self.data_file + '.temp'

        with open(temp_file, 'wb') as dest:

            with open(self.data_file, 'rb') as src:

                flag = True

                while flag:

                    flag1, key, value = self.read_record(src)

                    if flag!=b"D":

                        if key in items:

                            self.append_record(dest, key, items[key])

                            

                        else:

                            self.append_record(dest, key, value)

            for key, value in items.items():

                self.append_record(dest, key, value)

        os.replace(temp_file, self.data_file)

        with open(self.index_file, 'wb') as f:

            np.array(self.ram_index, dtype=np.int64).tofile(f)

        self.load_index(self.index_file)    

    def read_record(self, f):

        flag = f.read(1)

        if not flag:

            return None, None, None

        key_len = struct.unpack('Q', f.read(8))[0]

        key = f.read(key_len).decode('utf-8')

        value_len = struct.unpack('Q', f.read(8))[0]

        value = f.read(value_len).decode('utf-8')

        return flag, key, value

    def append_record(self, f, key, value):

        position = f.tell()

        k=key.encode('utf-8')

        v=value.encode('utf-8')

        f.write(b'V')

        f.write(struct.pack('Q', len(k)))

        f.write(k)

        f.write(struct.pack('Q', len(v)))

        f.write(v)

        return position

    def rebuild(self):

        new_data_file = self.data_file + '.rebuild'

        new_index = []

        with open(self.data_file, 'rb') as src, open(new_data_file, 'wb') as dst:

            while True:

                flag, key, value = self.read_record(src)

                if not flag:

                    break

                if flag != b'D':

                    new_index.append([hash(key), self.append_record(dst, key, value)])

        os.replace(new_data_file, self.data_file)

        self.ram_index = new_index

        with open(self.index_file, 'wb') as f:

            np.array(new_index, dtype=np.int64).tofile(f)

        self.load_index(self.index_file)


FileDict3.py is specifically used for handling text-based data. It has been optimized for handling large amounts of data while ensuring data security. By changing the table parameter, it is possible to simultaneously access multiple dict classes in a single file, making it suitable for handling complex situations.


#FileDict3.py

import sqlite3

import time

import atexit

class FileDict:

    def __init__(self, file_path, buffer_size=1000, buffer_idle_time=1, table='filedict'):

        self.file_path = file_path

        self.table = table

        self.conn = sqlite3.connect(file_path,check_same_thread=False)

        self.conn.execute('CREATE TABLE IF NOT EXISTS {} (key TEXT PRIMARY KEY, value TEXT)'.format(self.table))

        self.buffer = []

        self.buffer_size = buffer_size

        self.last_commit_time = time.time()

        self.buffer_idle_time = buffer_idle_time

        atexit.register(self.close)

    def get(self, key):

        try:return self.__getitem__(key)

        except KeyError: return None

    

    def __getitem__(self, key):

        self._check_buffer()

        cursor = self.conn.execute('SELECT value FROM {} WHERE key = ?'.format(self.table), (key,))

        result = cursor.fetchone()

        if result is None:

            raise KeyError(key)

        return result[0]

    def Tables(self):

        cursor = self.conn.execute("SELECT name FROM sqlite_master WHERE type='table';")

        tables = cursor.fetchall()

        table_names = [t[0] for t in tables]

        return table_names

    def __setitem__(self, key, value):

        try:

            self.check_key(key)

            self.buffer.append(('set', key, value))

            self._check_buffer()

        except sqlite3.IntegrityError:

            self.buffer.append(('update', key, value))

            self._check_buffer()

    def __delitem__(self, key):

        self.buffer.append(('del', key))

        self._check_buffer()

    def __iter__(self):

        self._check_buffer()

        cursor = self.conn.execute('SELECT key FROM {}'.format(self.table))

        for row in cursor:

            yield row[0]

    def items(self):

        self._check_buffer()

        cursor = self.conn.execute('SELECT key, value FROM {}'.format(self.table))

        return cursor.fetchall()

    def from_dict(self, dict):

        self.check_dict(dict)

        self.conn.execute('DROP TABLE IF EXISTS {}'.format(self.table))

        self.conn.execute('CREATE TABLE {} (key TEXT PRIMARY KEY, value TEXT)'.format(self.table))

        self.conn.executemany('INSERT INTO {} (key, value) VALUES (?, ?)'.format(self.table), dict.items())

        self.conn.commit()

    def add_items(self, items):

        for key, value in items.items():

            try:

                self.check_key(key)

                self.buffer.append(('set', key, value))

                self._check_buffer()

            except sqlite3.IntegrityError:

                self.buffer.append(('update', key, value))

                self._check_buffer()

        self._check_buffer()

    def _check_buffer(self):

        if not self.buffer:

            return

        idle_time = time.time() - self.last_commit_time

        if len(self.buffer) >= self.buffer_size or idle_time >= self.buffer_idle_time:

            self._commit()

    def _commit(self):

        if not self.buffer:

            return 

        cursor = self.conn.cursor()

        for op in self.buffer:

            if op[0] == 'set':

                cursor.execute('INSERT OR REPLACE INTO {} (key, value) VALUES (?, ?)'.format(self.table), (op[1], op[2]))

            elif op[0] == 'update':

                cursor.execute('UPDATE {} SET value = ? WHERE key = ?'.format(self.table), (op[2], op[1]))

            elif op[0] == 'del':

                cursor.execute('DELETE FROM {} WHERE key = ?'.format(self.table), (op[1],))

        self.buffer = []

        self.last_commit_time = time.time()

        self.conn.commit()

    def check_dict(self, dictionary):

        for key in dictionary:

            self.check_key(key)

    def check_key(self, key):

        if not isinstance(key, str):

            raise TypeError('Keys must be strings.')

        if not key:

            raise ValueError('Keys cannot be empty strings.')

    def search_keys(self, pattern, like=True, values=False):

        self._check_buffer()

        operator = 'LIKE' if like else '='

        cursor = self.conn.cursor()

        cursor.execute(f"SELECT key FROM {self.table} WHERE key {operator} ?", (pattern,))

        return [row[0] for row in cursor.fetchall()]

    def close(self):       

        self._commit()

        try:

            self.conn.commit()

        except:

            pass

        self.conn.close()


FileSQL3.py is used for storing binary data. It automatically splits large files into smaller chunks and when reading, it simulates a File-like object for easy positioning and reading. It also has a caching mechanism, so there is no loss in performance during continuous reading. Currently, it is mainly used in conjunction with FastAPI to access a server on my home LAN network and play multimedia files. The speed is comparable to accessing it directly at home. However, it is still not perfect overall and is not suitable for storing large files that require frequent modifications.


#FileSQL3.py

import os,json

import sqlite3

import uuid

from datetime import datetime

import mimetypes

mimetypes.add_type("video/webm" ,'.mkv')

mimetypes.add_type("audio/flac",".flac")

   

DEFAULT_BLOCK_SIZE = 1024*1024*8 

class FileS:

    def __init__(self, meta, conn):

        self.size = meta['length']

        self.create = meta['created']

        self.modified = meta['modified']

        self.mimetype = meta['mimetype']

        self.encoding = meta['encoding']

        self.parts = json.loads(meta['parts'])

        self.conn = conn

        self.position = 0

        self.buffer = [b'', -1, -1]

    def read(self, size=-1):

        if size < 0:

            size = self.size - self.position

        data = b''

        while size > 0:

            if size < DEFAULT_BLOCK_SIZE and self.buffer[1] <= self.position < self.buffer[2]:

                chunk = self.buffer[0]

                start = self.position - self.buffer[1]

                end = min(start + size, self.buffer[2] - self.buffer[1])

                data += chunk[start:end]

                size -= end - start

                self.position += end - start

            else:

                

                part = self._get_next_part()

                if not part:

                    break

                cur = self.conn.cursor()

                cur.execute('SELECT data FROM datas WHERE uuid=?', (part['uuid'],))

                chunk = cur.fetchone()[0]

                if size >= DEFAULT_BLOCK_SIZE:

                    start = self.position % DEFAULT_BLOCK_SIZE

                    end = start + DEFAULT_BLOCK_SIZE

                    data += chunk[start:end]

                    size -= end - start

                    self.position += end - start

                else:

                    

                    chunk_start = self.position // DEFAULT_BLOCK_SIZE * DEFAULT_BLOCK_SIZE

                    chunk_end = min(chunk_start + DEFAULT_BLOCK_SIZE, part['end'])

                    chunk_pos_start = chunk_start - part['start']

                    chunk_pos_end = chunk_end - part['start']

                    self.buffer = [chunk[chunk_pos_start:chunk_pos_end], chunk_start, chunk_end]

                    start = self.position - chunk_start

                    end = min(start + size, chunk_end - chunk_start)

                    data += chunk[chunk_pos_start+start:chunk_pos_start+end]

                    size -= end - start

                    self.position += end - start

        return data

    def _get_next_part(self):

        for part in self.parts:

            if self.position < part['end'] and self.position >= part['start']:

                return part

        return None

    def seek(self, position):

        self.position = position

        self.buffer = [b'', -1, -1]

    def tell(self):

        return self.position

class FileSQL3:

    def __init__(self, db_path):

        self.conn = sqlite3.connect(db_path,check_same_thread=False)

        self.conn.row_factory = sqlite3.Row

        self._init_tables()

    def _init_tables(self):

        cur = self.conn.cursor()

        cur.execute('''CREATE TABLE IF NOT EXISTS files (

                        path TEXT PRIMARY KEY,

                        created TEXT,

                        modified TEXT,

                        length INTEGER,

                        encoding TEXT,

                        mimetype TEXT,

                        description TEXT,

                        parts TEXT)''')

        cur.execute('''CREATE TABLE IF NOT EXISTS datas (

                        uuid TEXT PRIMARY KEY,

                        data BLOB,

                        path TEXT,

                        start INTEGER,

                        end INTEGER)''')

        self.conn.commit()

    def get(self, file_path):

        cur = self.conn.cursor()

        cur.execute('SELECT * FROM files WHERE path=?', (file_path,))

        meta = cur.fetchone()

        if meta:

            return FileS(dict(meta), self.conn)

    def put(self, file_path, p_path=None, description=None, block_size=DEFAULT_BLOCK_SIZE):

        if not p_path:

            p_path = file_path

        

        with open(file_path, "rb") as f:

            file_size = os.path.getsize(file_path)

            file_created = datetime.fromtimestamp(os.path.getctime(file_path)).isoformat()

            file_modified = datetime.fromtimestamp(os.path.getmtime(file_path)).isoformat()

            parts = []

            start = 0

            while start < file_size:

                end = min(start + block_size, file_size)

                data = f.read(block_size)

                data_uuid = str(uuid.uuid4())

                parts.append({'uuid': data_uuid, 'start': start, 'end': end})

                cur = self.conn.cursor()

                cur.execute('INSERT INTO datas (uuid, data, path, start, end) VALUES (?, ?, ?, ?, ?)',

                            (data_uuid, data, p_path, start, end))

                start = end

            parts_json = json.dumps(parts)

            try:

                cur = self.conn.cursor()

                mt, ec = mimetypes.guess_type(file_path)

                

                cur.execute('''INSERT INTO files (path, created, modified, length, encoding, mimetype, description, parts)

                            VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',

                            (p_path, file_created, file_modified, file_size, ec, mt, description, parts_json))

            except sqlite3.IntegrityError:

                cur.execute('DELETE FROM files WHERE path=?', (p_path,))

                cur.execute('''INSERT INTO files (path, created, modified, length, encoding, mimetype, description, parts)

                            VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',

                            (p_path, file_created, file_modified, file_size, ec, mt, description, parts_json))

            self.conn.commit()

    def update_files_table(self, path, **fields):

        cur = self.conn.cursor()

        query = "UPDATE files SET "

        query += ', '.join([f"{k} = ?" for k in fields.keys()])

        query += " WHERE path = ?"

        cur.execute(query, (*fields.values(), path))

        self.conn.commit()

    def search(self, search_string):

        cur = self.conn.cursor()

        cur.execute('SELECT path FROM files WHERE path LIKE ?', (search_string ,))

        return [row['path'] for row in cur.fetchall()]

    def delete(self, file_path):

        cur = self.conn.cursor()

        cur.execute('SELECT parts FROM files WHERE path=?', (file_path,))

        parts = cur.fetchone()

        if parts:

            for part in json.loads(parts['parts']):

                cur.execute('DELETE FROM datas WHERE uuid=?', (part['uuid'],))

            cur.execute('DELETE FROM files WHERE path=?', (file_path,))

            self.conn.commit()


Successfully compiled in Termux, making it easy to integrate into the system.

Successfully compiled in Termux, making it easy to integrate into the system.
It is pointless to operate only in Cxxdroid; it must be successfully compiled in Termux in order to be integrated into the system. The code that I have already written has been continuously improved through repeated use, and when combined, it creates a powerful system. This is my first attempt at compiling my own C language code in Termux. Although I had already written over 2,000 lines of code in Cxxdroid, I did not initially realize that I was using a language that was a mix of C and C++. At first, I tried many different tools, but every attempt to compile directly failed. The usage of each compilation tool was very complicated and had many parameters. Simply browsing through once would take a long time. Eventually, I started with the simplest method and split the code into parts. Once each part was successfully compiled, I combined them again. If I encountered a problem, I would research it, which sometimes took an entire day of effort. Finally, it was successfully compiled. Some parts of the code had to be modified to work properly. Learning to use compilation tools is more difficult than learning the language itself because of the many parameters and complex steps. If everything works without any issues, I would rather not explore it further.
colors.sh and t.sh to compile the code in Termux:

g++  -Wall -Wextra -g  -std=c++2a colors.cpp -o ~/bin/colors -lstdc++  -lz -lncursesw  -ljpeg  -lpng -fopenmp -lpanel -lm 

g++  -Wall -Wextra -g  -std=c++20 t.cpp -o ~/bin/t -lstdc++  -lz -lncursesw  -ljpeg  -lm -lpng
Print matrix with colors directly in C language:

void printMatrixC() {
    for (int y = 0; y < getHeight(); y++) {
        for (int x = 0; x < getWidth(); x++) {
            Point2D point = {(double)x, (double)y};
            unsigned char value = getValue(point);

            // Choose the background color based on the value
            int backgroundColor = (int)value;

            // Set the background color and print a space
            printf("\033[48;5;%dm  ", backgroundColor);
        }
        printf("\n");
    }
}
Corrected the issue of dimming in Termux and also optimized the calculation process.
The transformation involving a lot of sine and cosine calculations, but in reality, it does not require a very high precision. By using the method of precomputing approximate values of sine and cosine for 0-360 degrees, the amount of calculations can be greatly reduced.


const float sinTable[360]={0.000,0.017,0.035,0.052,0.070,0.087,0.105,0.122,0.139,0.156,0.174,0.191,0.208,0.225,0.242,0.259,0.276,0.292,0.309,0.326,0.342,0.358,0.375,0.391,0.407,0.423,0.438,0.454,0.469,0.485,0.500,0.515,0.530,0.545,0.559,0.574,0.588,0.602,0.616,0.629,0.643,0.656,0.669,0.682,0.695,0.707,0.719,0.731,0.743,0.755,0.766,0.777,0.788,0.799,0.809,0.819,0.829,0.839,0.848,0.857,0.866,0.875,0.883,0.891,0.899,0.906,0.914,0.920,0.927,0.934,0.940,0.946,0.951,0.956,0.961,0.966,0.970,0.974,0.978,0.982,0.985,0.988,0.990,0.993,0.995,0.996,0.998,0.999,0.999,1.000,1.000,1.000,0.999,0.999,0.998,0.996,0.995,0.993,0.990,0.988,0.985,0.982,0.978,0.974,0.970,0.966,0.961,0.956,0.951,0.946,0.940,0.934,0.927,0.921,0.914,0.906,0.899,0.891,0.883,0.875,0.866,0.857,0.848,0.839,0.829,0.819,0.809,0.799,0.788,0.777,0.766,0.755,0.743,0.731,0.719,0.707,0.695,0.682,0.669,0.656,0.643,0.629,0.616,0.602,0.588,0.574,0.559,0.545,0.530,0.515,0.500,0.485,0.470,0.454,0.438,0.423,0.407,0.391,0.375,0.358,0.342,0.326,0.309,0.292,0.276,0.259,0.242,0.225,0.208,0.191,0.174,0.156,0.139,0.122,0.105,0.087,0.070,0.052,0.035,0.018,0.000,-0.017,-0.035,-0.052,-0.070,-0.087,-0.104,-0.122,-0.139,-0.156,-0.174,-0.191,-0.208,-0.225,-0.242,-0.259,-0.276,-0.292,-0.309,-0.326,-0.342,-0.358,-0.375,-0.391,-0.407,-0.423,-0.438,-0.454,-0.469,-0.485,-0.500,-0.515,-0.530,-0.545,-0.559,-0.574,-0.588,-0.602,-0.616,-0.629,-0.643,-0.656,-0.669,-0.682,-0.695,-0.707,-0.719,-0.731,-0.743,-0.755,-0.766,-0.777,-0.788,-0.799,-0.809,-0.819,-0.829,-0.839,-0.848,-0.857,-0.866,-0.875,-0.883,-0.891,-0.899,-0.906,-0.914,-0.920,-0.927,-0.934,-0.940,-0.945,-0.951,-0.956,-0.961,-0.966,-0.970,-0.974,-0.978,-0.982,-0.985,-0.988,-0.990,-0.993,-0.995,-0.996,-0.998,-0.999,-0.999,-1.000,-1.000,-1.000,-0.999,-0.999,-0.998,-0.996,-0.995,-0.993,-0.990,-0.988,-0.985,-0.982,-0.978,-0.974,-0.970,-0.966,-0.961,-0.956,-0.951,-0.946,-0.940,-0.934,-0.927,-0.921,-0.914,-0.906,-0.899,-0.891,-0.883,-0.875,-0.866,-0.857,-0.848,-0.839,-0.829,-0.819,-0.809,-0.799,-0.788,-0.777,-0.766,-0.755,-0.743,-0.731,-0.719,-0.707,-0.695,-0.682,-0.669,-0.656,-0.643,-0.629,-0.616,-0.602,-0.588,-0.574,-0.559,-0.545,-0.530,-0.515,-0.500,-0.485,-0.470,-0.454,-0.438,-0.423,-0.407,-0.391,-0.375,-0.358,-0.342,-0.326,-0.309,-0.292,-0.276,-0.259,-0.242,-0.225,-0.208,-0.191,-0.174,-0.157,-0.139,-0.122,-0.105,-0.087,-0.070,-0.052,-0.035,-0.018};

const float cosTable[360]={1.000,1.000,0.999,0.999,0.998,0.996,0.995,0.993,0.990,0.988,0.985,0.982,0.978,0.974,0.970,0.966,0.961,0.956,0.951,0.946,0.940,0.934,0.927,0.921,0.914,0.906,0.899,0.891,0.883,0.875,0.866,0.857,0.848,0.839,0.829,0.819,0.809,0.799,0.788,0.777,0.766,0.755,0.743,0.731,0.719,0.707,0.695,0.682,0.669,0.656,0.643,0.629,0.616,0.602,0.588,0.574,0.559,0.545,0.530,0.515,0.500,0.485,0.469,0.454,0.438,0.423,0.407,0.391,0.375,0.358,0.342,0.326,0.309,0.292,0.276,0.259,0.242,0.225,0.208,0.191,0.174,0.156,0.139,0.122,0.105,0.087,0.070,0.052,0.035,0.017,0.000,-0.017,-0.035,-0.052,-0.070,-0.087,-0.105,-0.122,-0.139,-0.156,-0.174,-0.191,-0.208,-0.225,-0.242,-0.259,-0.276,-0.292,-0.309,-0.326,-0.342,-0.358,-0.375,-0.391,-0.407,-0.423,-0.438,-0.454,-0.469,-0.485,-0.500,-0.515,-0.530,-0.545,-0.559,-0.574,-0.588,-0.602,-0.616,-0.629,-0.643,-0.656,-0.669,-0.682,-0.695,-0.707,-0.719,-0.731,-0.743,-0.755,-0.766,-0.777,-0.788,-0.799,-0.809,-0.819,-0.829,-0.839,-0.848,-0.857,-0.866,-0.875,-0.883,-0.891,-0.899,-0.906,-0.914,-0.920,-0.927,-0.934,-0.940,-0.946,-0.951,-0.956,-0.961,-0.966,-0.970,-0.974,-0.978,-0.982,-0.985,-0.988,-0.990,-0.993,-0.995,-0.996,-0.998,-0.999,-0.999,-1.000,-1.000,-1.000,-0.999,-0.999,-0.998,-0.996,-0.995,-0.993,-0.990,-0.988,-0.985,-0.982,-0.978,-0.974,-0.970,-0.966,-0.961,-0.956,-0.951,-0.946,-0.940,-0.934,-0.927,-0.921,-0.914,-0.906,-0.899,-0.891,-0.883,-0.875,-0.866,-0.857,-0.848,-0.839,-0.829,-0.819,-0.809,-0.799,-0.788,-0.777,-0.766,-0.755,-0.743,-0.731,-0.719,-0.707,-0.695,-0.682,-0.669,-0.656,-0.643,-0.629,-0.616,-0.602,-0.588,-0.574,-0.559,-0.545,-0.530,-0.515,-0.500,-0.485,-0.470,-0.454,-0.438,-0.423,-0.407,-0.391,-0.375,-0.358,-0.342,-0.326,-0.309,-0.292,-0.276,-0.259,-0.242,-0.225,-0.208,-0.191,-0.174,-0.157,-0.139,-0.122,-0.105,-0.087,-0.070,-0.052,-0.035,-0.018,-0.000,0.017,0.035,0.052,0.070,0.087,0.104,0.122,0.139,0.156,0.174,0.191,0.208,0.225,0.242,0.259,0.276,0.292,0.309,0.325,0.342,0.358,0.375,0.391,0.407,0.423,0.438,0.454,0.469,0.485,0.500,0.515,0.530,0.545,0.559,0.574,0.588,0.602,0.616,0.629,0.643,0.656,0.669,0.682,0.695,0.707,0.719,0.731,0.743,0.755,0.766,0.777,0.788,0.799,0.809,0.819,0.829,0.839,0.848,0.857,0.866,0.875,0.883,0.891,0.899,0.906,0.914,0.920,0.927,0.934,0.940,0.945,0.951,0.956,0.961,0.966,0.970,0.974,0.978,0.982,0.985,0.988,0.990,0.993,0.995,0.996,0.998,0.999,0.999,1.000};

angle = angle %360;

if (angle<0) angle+=360;

=

double newX = oldPoint.x * cosTable[angle] + oldPoint.y * sinTable[angle];

				double newY = oldPoint.y * cosTable[angle] - oldPoint.x * sinTable[angle];

All possible methods that can currently be thought of have been used for optimization.
Every time I try to realize a new idea, I work on it through research and implementation. I try to implement the best method I found during my research. The knowledge and skills I acquire during this process may be expendable, but the completed code is something that must be preserved. This code contains the accumulated efforts and creations over a long period of time. When facing similar problems in the future, I can improve upon this foundation and efficiently complete various complex tasks.
When using the C language to implement these ideas, I have optimized the process to achieve high-efficiency function that completes a series of tasks simultaneously. This advanced function can greatly simplify the process of solving real-world problems, accelerating the completion of various complex ideas. Even without the need for advanced languages, developing a high-level function that processes characters and manages processes can efficiently complete all tasks.

struct Color
{
	unsigned char r;
	unsigned char g;
	unsigned char b;
	unsigned char a;
};

Istruct Image
{
	int width;
	int height;
	Color *array;

	int getIndex(int x, int y)
	{
		return y * width + x;
	}

	Image(int w, int h, Color color = {NULL, NULL, NULL, NULL})
	{
		width = w;
		height = h;
		array = (Color *)malloc(width * height * sizeof(Color));
		if (array == NULL)
		{
			fprintf(stderr, "Failed to allocate memory for array\n");
			exit(EXIT_FAILURE);
		}

		for (int i = 0; i < width * height; i++)
		{
			array[i] = color;
		}
	}

	~Image()
	{
		free(array);
	}

	int getWidth()
	{
		return width;
	}

	int getHeight()
	{
		return height;
	}

Color getPoint(Point2D point)
	{
		int x = round(point.x);
		int y = round(point.y);

		if (x < 0 || x >= width || y < 0 || y >= height)
		{
			return {0, 0, 0, 0};
		}

		return array[getIndex(x, y)];
	}

	void setPoint(Point2D point, Color color)
	{
		int x = round(point.x);
		int y = round(point.y);

		if (x < 0 || x >= width || y < 0 || y >= height)
		{
			return;
		}

		array[getIndex(x, y)] = color;
	}
	void set(int x, int y, Color color)
	{
		array[y * width + x] = color;
	}
	Color get(int x, int y)
	{
		return array[y * width + x];
	}

Point2D getCenter()
	{
		return {width / 2.0, height / 2.0};
	}

	void clear(Color color)
	{
		for (int i = 0; i < width * height; i++)
		{
			array[i] = color;
		}
	}

Image rotated(int angle, double resized = 1.42, int cX = NULL, int cY = NULL, int oX = NULL, int oY = NULL, int angleXZ = 0, int angleYZ = 0)
	{ //double k=0.174;
		angle = angle % 360;
		if (angle < 0)
			angle += 360;
		if (angleXZ != 0)
		{
			angleXZ = angleXZ % 360;
			if (angleXZ < 0)
				angleXZ += 360;
		}
		if (angleYZ != NULL)
		{
			angleYZ = angleYZ % 360;
			if (angleYZ < 0)
				angleYZ += 360;
		}
		Image rotatedImage(width, height);
		Point2D center = getCenter();
		if (cX != NULL)
		{
			center.x = cX;
		}
		if (cY != NULL)
		{
			center.x = cY;
		}
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				Point2D oldPoint = {(double)x, (double)y};
				oldPoint.x -= center.x;
				oldPoint.y -= center.y;
				int newX = oldPoint.x * cosTable[angle] + oldPoint.y * sinTable[angle];
				int newY = oldPoint.y * cosTable[angle] - oldPoint.x * sinTable[angle];
				int tempX = newX;
				int tempY = newY;
				if (angleXZ != 0)
				{
					newY = tempY / cosTable[angleXZ];
				}
				if (angleYZ != 0)
				{
					newX = tempX / cosTable[angleYZ];
				}
				if (resized != 1)
				{
					newX = newX * resized;
					newY = newY * resized;
				}
				newX += center.x;
				newY += center.y;
				if (newX < 0 || newX >= width || newY < 0 || newY >= height) continue;

				Color color = get(newX, newY);

				int rX = x;
				int rY = y;
				if (oX != NULL)
				{
					rX += oX;
				}
				if (oY != NULL)
				{
					rY += oY;
				}
				if (rX < 0 || rX >= width || rY < 0 || rY >= height) continue;

				rotatedImage.set(rX, rY, color);
			}
		}

		return rotatedImage;
	}

};
Almost finished running on Cxxdroid and Termux, now I'm planning to start the next project.
Actually, the process of development is a continuous process of improvement through testing. The first code written inevitably hides countless problems. If there are efficient and comprehensive testing methods, all potential problems can be identified in the shortest possible time. It is also possible to try and compare different solutions and implement the best solution in the shortest time, greatly increasing the efficiency of exploring unknown fields.
When the code reaches thousands of lines, it is impossible to find problems by looking at each line of code, and it is beyond the capabilities of AI tools. Tools that present testing data results in a visual way like this can intuitively find abnormal areas and detect and correct problems early.
Starting the next step: Revised a problem once again and added some new functionalities. In this process, I have learned many valuable things. Next, I plan to add some advanced text processing functions based on this foundation. I also intend to incorporate a time element into the workflow control component. By combining these elements together, I will be able to quickly develop new and higher level features. https://fb.watch/mJmKsh3OTX/?mibextid=Nif5oz
The function is very easy to use after completion.

Enhancing and exploring web and string handling capabilities through testing and analysis.
By using Popen+curl, it is easy to load files via the network. The same method can also be used to execute Python, LLama-CPP, or other powerful tools, easily unlocking all possibilities in the C language. It is best to first create all the features first and then improve them in use.
Continuing to add new features, you can transform and manipulate all data according to your ideas. When transforming to 256 colors, grayscale, or monochrome, the closest color to the original color is calculated with advanced contrast calculation algorithms, not by formula conversion. Additionally, you can also find the closest color name from the color code, and all features will be integrated with an AI model in the future to unlock even more possibilities.


#include "mylib.h"

const char *colorNames[256]={ "Black","Maroon","Green","Olive","Navy","Purple","Teal","Silver","Grey","Red","Lime","Yellow","Blue","Fuchsia","Aqua","White","Grey0","NavyBlue","DarkBlue","Blue3","Blue3","Blue1","DarkGreen","DeepSkyBlue4","DeepSkyBlue4","DeepSkyBlue4","DodgerBlue3","DodgerBlue2","Green4","SpringGreen4","Turquoise4","DeepSkyBlue3","DeepSkyBlue3","DodgerBlue1","Green3","SpringGreen3","DarkCyan","LightSeaGreen","DeepSkyBlue2","DeepSkyBlue1","Green3","SpringGreen3","SpringGreen2","Cyan3","DarkTurquoise","Turquoise2","Green1","SpringGreen2","SpringGreen1","MediumSpringGreen","Cyan2","Cyan1","DarkRed","DeepPink4","Purple4","Purple4","Purple3","BlueViolet","Orange4","Grey37","MediumPurple4","SlateBlue3","SlateBlue3","RoyalBlue1","Chartreuse4","DarkSeaGreen4","PaleTurquoise4","SteelBlue","SteelBlue3","CornflowerBlue","Chartreuse3","DarkSeaGreen4","CadetBlue","CadetBlue","SkyBlue3","SteelBlue1","Chartreuse3","PaleGreen3","SeaGreen3","Aquamarine3","MediumTurquoise","SteelBlue1","Chartreuse2","SeaGreen2","SeaGreen1","SeaGreen1","Aquamarine1","DarkSlateGray2","DarkRed","DeepPink4","DarkMagenta","DarkMagenta","DarkViolet","Purple","Orange4","LightPink4","Plum4","MediumPurple3","MediumPurple3","SlateBlue1","Yellow4","Wheat4","Grey53","LightSlateGrey","MediumPurple","LightSlateBlue","Yellow4","DarkOliveGreen3","DarkSeaGreen","LightSkyBlue3","LightSkyBlue3","SkyBlue2","Chartreuse2","DarkOliveGreen3","PaleGreen3","DarkSeaGreen3","DarkSlateGray3","SkyBlue1","Chartreuse1","LightGreen","LightGreen","PaleGreen1","Aquamarine1","DarkSlateGray1","Red3","DeepPink4","MediumVioletRed","Magenta3","DarkViolet","Purple","DarkOrange3","IndianRed","HotPink3","MediumOrchid3","MediumOrchid","MediumPurple2","DarkGoldenrod","LightSalmon3","RosyBrown","Grey63","MediumPurple2","MediumPurple1","Gold3","DarkKhaki","NavajoWhite3","Grey69","LightSteelBlue3","LightSteelBlue","Yellow3","DarkOliveGreen3","DarkSeaGreen3","DarkSeaGreen2","LightCyan3","LightSkyBlue1","GreenYellow","DarkOliveGreen2","PaleGreen1","DarkSeaGreen2","DarkSeaGreen1","PaleTurquoise1","Red3","DeepPink3","DeepPink3","Magenta3","Magenta3","Magenta2","DarkOrange3","IndianRed","HotPink3","HotPink2","Orchid","MediumOrchid1","Orange3","LightSalmon3","LightPink3","Pink3","Plum3","Violet","Gold3","LightGoldenrod3","Tan","MistyRose3","Thistle3","Plum2","Yellow3","Khaki3","LightGoldenrod2","LightYellow3","Grey84","LightSteelBlue1","Yellow2","DarkOliveGreen1","DarkOliveGreen1","DarkSeaGreen1","Honeydew2","LightCyan1","Red1","DeepPink2","DeepPink1","DeepPink1","Magenta2","Magenta1","OrangeRed1","IndianRed1","IndianRed1","HotPink","HotPink","MediumOrchid1","DarkOrange","Salmon1","LightCoral","PaleVioletRed1","Orchid2","Orchid1","Orange1","SandyBrown","LightSalmon1","LightPink1","Pink1","Plum1","Gold1","LightGoldenrod2","LightGoldenrod2","NavajoWhite1","MistyRose1","Thistle1","Yellow1","LightGoldenrod1","Khaki1","Wheat1","Cornsilk1","Grey100","Grey3","Grey7","Grey11","Grey15","Grey19","Grey23","Grey27","Grey30","Grey35","Grey39","Grey42","Grey46","Grey50","Grey54","Grey58","Grey62","Grey66","Grey70","Grey74","Grey78","Grey82","Grey85","Grey89","Grey93"};

const int colorMap[256][3] = { {0,0,0},{128,0,0},{0,128,0},{128,128,0},{0,0,128},{128,0,128},{0,128,128},{192,192,192},{128,128,128},{255,0,0},{0,255,0},{255,255,0},{0,0,255},{255,0,255},{0,255,255},{255,255,255},{0,0,0},{0,0,95},{0,0,135},{0,0,175},{0,0,215},{0,0,255},{0,95,0},{0,95,95},{0,95,135},{0,95,175},{0,95,215},{0,95,255},{0,135,0},{0,135,95},{0,135,135},{0,135,175},{0,135,215},{0,135,255},{0,175,0},{0,175,95},{0,175,135},{0,175,175},{0,175,215},{0,175,255},{0,215,0},{0,215,95},{0,215,135},{0,215,175},{0,215,215},{0,215,255},{0,255,0},{0,255,95},{0,255,135},{0,255,175},{0,255,215},{0,255,255},{95,0,0},{95,0,95},{95,0,135},{95,0,175},{95,0,215},{95,0,255},{95,95,0},{95,95,95},{95,95,135},{95,95,175},{95,95,215},{95,95,255},{95,135,0},{95,135,95},{95,135,135},{95,135,175},{95,135,215},{95,135,255},{95,175,0},{95,175,95},{95,175,135},{95,175,175},{95,175,215},{95,175,255},{95,215,0},{95,215,95},{95,215,135},{95,215,175},{95,215,215},{95,215,255},{95,255,0},{95,255,95},{95,255,135},{95,255,175},{95,255,215},{95,255,255},{135,0,0},{135,0,95},{135,0,135},{135,0,175},{135,0,215},{135,0,255},{135,95,0},{135,95,95},{135,95,135},{135,95,175},{135,95,215},{135,95,255},{135,135,0},{135,135,95},{135,135,135},{135,135,175},{135,135,215},{135,135,255},{135,175,0},{135,175,95},{135,175,135},{135,175,175},{135,175,215},{135,175,255},{135,215,0},{135,215,95},{135,215,135},{135,215,175},{135,215,215},{135,215,255},{135,255,0},{135,255,95},{135,255,135},{135,255,175},{135,255,215},{135,255,255},{175,0,0},{175,0,95},{175,0,135},{175,0,175},{175,0,215},{175,0,255},{175,95,0},{175,95,95},{175,95,135},{175,95,175},{175,95,215},{175,95,255},{175,135,0},{175,135,95},{175,135,135},{175,135,175},{175,135,215},{175,135,255},{175,175,0},{175,175,95},{175,175,135},{175,175,175},{175,175,215},{175,175,255},{175,215,0},{175,215,95},{175,215,135},{175,215,175},{175,215,215},{175,215,255},{175,255,0},{175,255,95},{175,255,135},{175,255,175},{175,255,215},{175,255,255},{215,0,0},{215,0,95},{215,0,135},{215,0,175},{215,0,215},{215,0,255},{215,95,0},{215,95,95},{215,95,135},{215,95,175},{215,95,215},{215,95,255},{215,135,0},{215,135,95},{215,135,135},{215,135,175},{215,135,215},{215,135,255},{215,175,0},{215,175,95},{215,175,135},{215,175,175},{215,175,215},{215,175,255},{215,215,0},{215,215,95},{215,215,135},{215,215,175},{215,215,215},{215,215,255},{215,255,0},{215,255,95},{215,255,135},{215,255,175},{215,255,215},{215,255,255},{255,0,0},{255,0,95},{255,0,135},{255,0,175},{255,0,215},{255,0,255},{255,95,0},{255,95,95},{255,95,135},{255,95,175},{255,95,215},{255,95,255},{255,135,0},{255,135,95},{255,135,135},{255,135,175},{255,135,215},{255,135,255},{255,175,0},{255,175,95},{255,175,135},{255,175,175},{255,175,215},{255,175,255},{255,215,0},{255,215,95},{255,215,135},{255,215,175},{255,215,215},{255,215,255},{255,255,0},{255,255,95},{255,255,135},{255,255,175},{255,255,215},{255,255,255},{8,8,8},{18,18,18},{28,28,28},{38,38,38},{48,48,48},{58,58,58},{68,68,68},{78,78,78},{88,88,88},{98,98,98},{108,108,108},{118,118,118},{128,128,128},{138,138,138},{148,148,148},{158,158,158},{168,168,168},{178,178,178},{188,188,188},{198,198,198},{208,208,208},{218,218,218},{228,228,228},{238,238,238}};

int main()

{	/*

	Point2D p={NAN,NAN};

	printf("%d\n",isnan(p.x));

	char test[]="😁測試or tes測試😆";

	printf("%d,%d\n",startsWith(test,"😁測試or "),endsWith(test,"測試😆"));

//return 0;

	FILE *fRead;

	char buffer[1024];

char url[500]="http://localhost:8000/static/std.js";

char uri[3024]="curl -s ";

strcat(uri,url);

printf("%d\n%s\n",startsWith(url,"http"),uri);

fRead=popen(uri, "r");

if (fRead == NULL) {

	printf("Failed to open pipe\n");

}

else{while (fgets(buffer,1024, fRead)){

printf("%s",buffer);}

}

pclose(fRead);

//return 1;

*/

struct winsize size;

ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);

int x=size.ws_col/2;

printf("\n%d X %d\n",x,x);

Matrix matrix0=FromImage("http://localhost:8000/static/house.jpg").resize(x,x).toMatrix();

//Matrix matrix0=FromImage("https://live.staticflickr.com/848/42925979414_7e1627f1c8_b.jpg").resize(x,x).toMatrix();

matrix0.printMatrixC();

FromImage("http://localhost:8000/static/house.jpg").resize(x,x).toMatrixGray().printMatrixC();

FromImage("http://localhost:8000/static/house.jpg").resize(x,x).toMatrixR().printMatrixC();

FromImage("http://localhost:8000/static/house.jpg").resize(x,x).toMatrixG().printMatrixC();

FromImage("http://localhost:8000/static/house.jpg").resize(x,x).toMatrixB().printMatrixC();

matrix0.printMatrix();

Matrix matrix=FromImage("http://localhost:8000/static/icon.png").resize(x,x).toMatrix();

matrix.printMatrixC();

//return 1;

matrix.rotated(150,1.22,135,145).printMatrix();

Matrix matrix1=FromImage("http://localhost:8000/static/test1.jpg").resize(x,x).toMatrix();

matrix1.printMatrixC();

FromImage("http://localhost:8000/static/test1.jpg").resize(x,x).toMatrixGray().printMatrixC();

FromImage("http://localhost:8000/static/test1.jpg").resize(x,x).toMatrixR().printMatrixC();

FromImage("http://localhost:8000/static/test1.jpg").resize(x,x).toMatrixG().printMatrixC();

FromImage("http://localhost:8000/static/test1.jpg").resize(x,x).toMatrixB().printMatrixC();

matrix1.printMatrix();

Matrix matrix2=FromImage("http://localhost:8000/static/test.jpg").resize(x,x).toMatrix();

matrix2 .printMatrixC();

FromImage("http://localhost:8000/static/test.jpg").resize(x,x).toMatrixGray().printMatrixC();

FromImage("http://localhost:8000/static/test.jpg").resize(x,x).toMatrixR().printMatrixC();

FromImage("http://localhost:8000/static/test.jpg").resize(x,x).toMatrixG().printMatrixC();

FromImage("http://localhost:8000/static/test.jpg").resize(x,x).toMatrixB().printMatrixC();

matrix2.printMatrix();

return 0;

}

I have written an image processing library in the C language.

I have written an image processing library in the C language.
I have added the functionality of simulating graphic display in the terminal, which makes it more convenient to test and verify results when developing new features. The feature that converts normal colors into colors that are close and can be displayed on a 256-color terminal has been rewritten many times, requiring the AI to calculate the closest color that can be displayed on the terminal by converting normal colors. This feature is something I have always wanted to implement. It can be used not only in Terminal, but also as the foundation for many other interesting functionalities. There is still much room for improvement, and behind each feature lies much knowledge that must be learned and improved upon during use.
There are now 1300 lines of code, With the help of AI, it only took a few days to complete the spatial-temporal task, and there is no need to worry about problems arising. Each feature is only related to one or two basic elements. As long as the basic elements are not modified, fixing a feature's problem only requires changing the problematic part, which only involves a few lines of code. The AI is fully capable of handling this. As long as this process is maintained, even if the code increases by thousands of lines, it can be easily handled.Ultimately, it will be combined with an AI model. Once this library is finished, we will start researching loading large language models through C programming language.


const int colorMap[256][3] = {

{0, 0, 0}, {128, 0, 0}, {0, 128, 0}, {128, 128, 0},

    {0, 0, 128}, {128, 0, 128}, {0, 128, 128}, {192, 192, 192},

    {128, 128, 128}, {255, 0, 0}, {0, 255, 0}, {255, 255, 0},

    {0, 0, 255}, {255, 0, 255}, {0, 255, 255}, {255, 255, 255},

    {0, 0, 0}, {0, 0, 95}, {0, 0, 135}, {0, 0, 175},

    {0, 0, 215}, {0, 0, 255}, {0, 95, 0}, {0, 95, 95},

    {0, 95, 135}, {0, 95, 175}, {0, 95, 215}, {0, 95, 255},

    {0, 135, 0}, {0, 135, 95}, {0, 135, 135}, {0, 135, 175},

    {0, 135, 215}, {0, 135, 255}, {0, 175, 0}, {0, 175, 95},

    {0, 175, 135}, {0, 175, 175}, {0, 175, 215}, {0, 175, 255},

    {0, 215, 0}, {0, 215, 95}, {0, 215, 135}, {0, 215, 175},

    {0, 215, 215}, {0, 215, 255}, {0, 255, 0}, {0, 255, 95},

    {0, 255, 135}, {0, 255, 175}, {0, 255, 215}, {0, 255, 255},

    {95, 0, 0}, {95, 0, 95}, {95, 0, 135}, {95, 0, 175},

    {95, 0, 215}, {95, 0, 255}, {95, 95, 0}, {95, 95, 95},

    {95, 95, 135}, {95, 95, 175}, {95, 95, 215}, {95, 95, 255},

    {95, 135, 0}, {95, 135, 95}, {95, 135, 135}, {95, 135, 175},

    {95, 135, 215}, {95, 135, 255}, {95, 175, 0}, {95, 175, 95},

    {95, 175, 135}, {95, 175, 175}, {95, 175, 215}, {95, 175, 255},

    {95, 215, 0}, {95, 215, 95}, {95, 215, 135}, {95, 215, 175},

    {95, 215, 215}, {95, 215, 255}, {95, 255, 0}, {95, 255, 95},

    {95, 255, 135}, {95, 255, 175}, {95, 255, 215}, {95, 255, 255},

    {135, 0, 0}, {135, 0, 95}, {135, 0, 135}, {135, 0, 175},

    {135, 0, 215}, {135, 0, 255}, {135, 95, 0}, {135, 95, 95},

    {135, 95, 135}, {135, 95, 175}, {135, 95, 215}, {135, 95, 255},

    {135, 135, 0}, {135, 135, 95}, {135, 135, 135}, {135, 135, 175},

    {135, 135, 215}, {135, 135, 255}, {135, 175, 0}, {135, 175, 95},

    {135, 175, 135}, {135, 175, 175}, {135, 175, 215}, {135, 175, 255},

    {135, 215, 0}, {135, 215, 95}, {135, 215, 135}, {135, 215, 175},

    {135, 215, 215}, {135, 215, 255}, {135, 255, 0}, {135, 255, 95},

    {135, 255, 135}, {135, 255, 175}, {135, 255, 215}, {135, 255, 255},

    {175, 0, 0}, {175, 0, 95}, {175, 0, 135}, {175, 0, 175},

    {175, 0, 215}, {175, 0, 255}, {175, 95, 0}, {175, 95, 95},

    {175, 95, 135}, {175, 95, 175}, {175, 95, 215}, {175, 95, 255},

    {175, 135, 0}, {175, 135, 95}, {175, 135, 135}, {175, 135, 175},

    {175, 135, 215}, {175, 135, 255}, {175, 175, 0}, {175, 175, 95},

    {175, 175, 135}, {175, 175, 175}, {175, 175, 215}, {175, 175, 255},

    {175, 215, 0}, {175, 215, 95}, {175, 215, 135}, {175, 215, 175},

    {175, 215, 215}, {175, 215, 255}, {175, 255, 0}, {175, 255, 95},

    {175, 255, 135}, {175, 255, 175}, {175, 255, 215}, {175, 255, 255},

    {215, 0, 0}, {215, 0, 95}, {215, 0, 135}, {215, 0, 175},

    {215, 0, 215}, {215, 0, 255}, {215, 95, 0}, {215, 95, 95},

    {215, 95, 135}, {215, 95, 175}, {215, 95, 215}, {215, 95, 255},

    {215, 135, 0}, {215, 135, 95}, {215, 135, 135}, {215, 135, 175},

    {215, 135, 215}, {215, 135, 255}, {215, 175, 0}, {215, 175, 95},

    {215, 175, 135}, {215, 175, 175}, {215, 175, 215}, {215, 175, 255},

    {215, 215, 0}, {215, 215, 95}, {215, 215, 135}, {215, 215, 175},

    {215, 215, 215}, {215, 215, 255}, {215, 255, 0}, {215, 255, 95},

    {215, 255, 135}, {215, 255, 175}, {215, 255, 215}, {215, 255, 255},

    {255, 0, 0}, {255, 0, 95}, {255, 0, 135}, {255, 0, 175},

    {255, 255, 255}

}; 

struct Matrix {

    int width;

    int height;

    unsigned char* array;

    Matrix(int w, int h,unsigned char value=0) {

        width = w;

        height = h;

        array = (unsigned char*)malloc(width * height * sizeof(unsigned char));

        if (array == NULL) {

            fprintf(stderr, "Failed to allocate memory for array\n");

            exit(EXIT_FAILURE);

        }

        for (int i = 0; i < width * height; i++) {

            array[i] = value ;

        }

    }

    ~Matrix() {

        free(array);

    }

    int getWidth() {

        return width;

    }

    int getHeight() {

        return height;

    }

    unsigned char getValue(Point2D point) {

        int x = round(point.x);

        int y = round(point.y);

        if (x < 0 || x >= width || y < 0 || y >= height) {

            return 0;

        }

        return array[y * width + x];

    }

    void setValue(Point2D point, unsigned char value) {

        int x = round(point.x);

        int y = round(point.y);

        if (x < 0 || x >= width || y < 0 || y >= height) {

            return;

        }

        array[y * width + x] = value;

    }

    

    void clear(unsigned char value = 0) {

        for (int i = 0; i < width * height; i++) {

            array[i] = value;

        }

    }

void showMatrix(int col, int row) {

    for (int i = 0; i < 256; i++) {

        init_color(i, colorMap[i][0], colorMap[i][1], colorMap[i][2]);

        init_pair(i, i, i);

    }

    // Draw the matrix on the ncurses screen

    for (int y = 0; y < getHeight(); y++) {

        for (int x = 0; x < getWidth(); x++) {

            Point2D point = { (float)x, (float)y };

            unsigned char value = getValue(point);

            // Choose the color pair based on the value

            int colorPair = (int)value;

            // Set the color pair and print a star

            attron(COLOR_PAIR(colorPair));

            mvprintw(row + y, col + x*2, "  ");

            attroff(COLOR_PAIR(colorPair));

        }

    }

    // Refresh the screen and wait for a key press to exit

    refresh();

    

}

};



#include "myimage.h"

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include  <cassert>

#include <assert.h>

#include <vector>

#include <cmath>

#include <stdint.h>

#include <iostream>

#include <ncurses.h>

#include <time.h>

#include <sys/time.h>

#include <unistd.h>

#include <termios.h>

#include <sys/ioctl.h>

#include "png.h"

#include <jpeglib.h>

#include "uuid4.h"

#include <ncurses.h>

#include <stdlib.h>

#include <time.h>

#include <sys/time.h>

#include <unistd.h>

void main() {

 initscr();

   int maxRow, maxCol; 

    getmaxyx(stdscr, maxRow, maxCol);

  start_color();

 Image img=FromImage("icon.png").resize(maxCol/2,maxCol/2);

 Image img2=FromImage("bot.png").resize(maxCol/2,maxCol/2);

 Image img3=FromImage("image.jpg").resize(maxCol/2,maxCol/2);

 Matrix matrix=img.toMatrix();

 Matrix matrix2=img2.toMatrix();

 Matrix matrix3=img3.toMatrix();

 Matrix matrix4=Matrix(maxCol/2,maxCol/2,64);

 Bezier bezier;

 Line line;

 bezier.controlPoint={(float)maxCol/4,(float)maxCol/4};

 bezier.points=new Point2D[3];

bezier.points[0]={(float)0,(float)maxCol/2};

bezier.points[1]={(float)maxCol/8,(float)maxCol/8};

bezier.points[2]={(float)maxCol/2,(float)maxCol/8};

line.points={{},{},{}};

line.points[0]={(float)0,(float)maxCol/2};

line .points[1]={(float)maxCol/8,(float)maxCol/8};

line.points[2]={(float)maxCol/2,(float)maxCol/8};

 

 struct timeval startTime;   

 struct timeval endTime; 

gettimeofday(&startTime, NULL); 

 struct timespec req = {.tv_sec = 1, .tv_nsec = 0 }; 

struct timespec req1 = {.tv_sec = 0, .tv_nsec = 90000000 }; 

struct timespec req2 = {.tv_sec = 0, .tv_nsec = 30000000 }; 

while (1){ 

mvprintw(0,0,"Matrix (%d X %d) from icon.png. " ,maxCol/2,maxCol/2);

   matrix.showMatrix(0,1);

   nanosleep(&req, NULL);

mvprintw(0,0,"Matrix (%d X %d) from bot.png. " ,maxCol/2,maxCol/2);

   matrix2.showMatrix(0,1);

  nanosleep(&req, NULL);

mvprintw(0,0,"Matrix (%d X %d) from image.jpg. " ,maxCol/2,maxCol/2);

   matrix3.showMatrix(0,1);

  nanosleep(&req, NULL);

  for (int i = 0; i < 5; i++) {

mvprintw(0,0,"Matrix4 (%d X %d) . " ,maxCol/2,maxCol/2);

matrix4.clear(rand()%239+16);

   matrix4.showMatrix(0,1);

  nanosleep(&req1, NULL);

}

matrix4.clear(0);

Rectangle rect;

rect.topLeft={(float )0,(float )0};

rect.bottomRight={(float )maxCol/2,(float )maxCol/2};

Ellipse ellipse;

ellipse.center={(float )maxCol/4,(float)maxCol /4};

ellipse.xRadius=(float)maxCol /4-1;

ellipse.yRadius=(float)maxCol /4-5;

Polygon pologon0=ellipse.toPolygon(100);

Polygon pologon=rect.toPolygon();

 StraightLine *xLines= pologon.scanLineX(0,maxCol/2);

StraightLine *yLines0= pologon.scanLineY(0,maxCol/2);

mvprintw(0,0,"Matrix4 scanLineXY (%d X %d) . " ,maxCol/2,maxCol/2);

 	for (int i = 0; i <maxCol/2; i++)

	{

int v=rand()%239+16;		

for (auto point : xLines[i].toPoints()){

matrix4.setValue(point,v);

   

}

matrix4.showMatrix(0,1);

  nanosleep(&req2, NULL);  

}

	for (int i = 0; i <maxCol/2; i++)

	{

int v=rand()%239+16;		

for (auto point : yLines0[i].toPoints()){

matrix4.setValue(point,v);

   

}

matrix4.showMatrix(0,1);

  nanosleep(&req2, NULL);  

}

struct StraightLine *yLines= pologon.scanLineY(0,maxCol/2);

matrix4.clear(0);

mvprintw(0,0,"Matrix4 ellipse and  bezier (%d X %d) . " ,maxCol/2,maxCol/2);

 	for (int i = 0; i <maxCol/2; i++)

	{

int v=rand()%239+16;		

for (auto point : ellipse.toPoints()){

matrix4.setValue(point,v);  

}

for (auto point : bezier.toPoints()){

matrix4.setValue(point,v);  

}

for (auto point : line.toPoints()){

matrix4.setValue(point,v);  

}

matrix4.showMatrix(0,1);

  nanosleep(&req2, NULL);  

}

} 

}

Still in constant improvement, this is written in C language. The speed of processing pixels is very fast. The slowness observed when dealing with high pixel count is due to the slow process of simulating images with colored characters in the terminal. The rotation function has also been modified multiple times, and in the end, I had to come up with my own solution. Now, in the rotated image, there will absolutely be no empty spaces in the center. The advantage of developing it on my own is that I can customize functionalities as required and efficiently accomplish various tasks. Still in constant improvement, this is written in C language. The speed of processing pixels is very fast. The slowness observed when dealing with high pixel count is due to the slow process of simulating images with colored characters in the terminal. The rotation function has also been modified multiple times, and in the end, I had to come up with my own solution. Now, in the rotated image, there will absolutely be no empty spaces in the center. The advantage of developing it on my own is that I can customize functionalities as required and efficiently accomplish various tasks.
Finally, this idea be implemented in C language.
The rotation function,only requires 50 lines of code and includes rotation, translation, center point adjustment,, position adjustment and the simulation of 3D rotation. The key is that the simplest method was used within a single computational cycle to achieve all of the above functions, thereby minimizing computational power consumption. This also proves that with C langua,ge, it is possible to achieve powerful functionality with very little code.

#include "myimage.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cassert>
#include <assert.h>
#include <vector>
#include <cmath>
#include <stdint.h>
#include <iostream>
#include <ncurses.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "png.h"
#include <jpeglib.h>
#include "uuid4.h"
#include <ncurses.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

void main()
{
	initscr();
	int maxRow, maxCol;
	getmaxyx(stdscr, maxRow, maxCol);
	start_color();
	Image img = FromImage("icon.png").resize(maxCol / 2, maxCol / 2);
	Image img2 = FromImage("bot.png").resize(maxCol / 2, maxCol / 2);
	Image img3 = FromImage("image.jpg").resize(maxCol / 2, maxCol / 2);
	Matrix matrix = img.toMatrix();
	Matrix matrix2 = img2.toMatrix();
	Matrix matrix3 = img3.toMatrix();
	Matrix matrix4 = Matrix(maxCol / 2, maxCol / 2, 64);
	Bezier bezier;
	Line line;
	bezier.controlPoint = {(double)maxCol / 4, (double)maxCol / 4};
	bezier.points = new Point2D[3];
	bezier.points[0] = {(double)0, (double)maxCol / 2};
	bezier.points[1] = {(double)maxCol / 8, (double)maxCol / 8};
	bezier.points[2] = {(double)maxCol / 2, (double)maxCol / 8};
	line.points = {{}, {}, {}};
	line.points[0] = {(double)0, (double)maxCol / 2};
	line.points[1] = {(double)maxCol / 8, (double)maxCol / 8};
	line.points[2] = {(double)maxCol / 2, (double)maxCol / 8};

	struct timeval startTime;
	struct timeval endTime;
	gettimeofday(&startTime, NULL);
	struct timespec req = {.tv_sec = 1, .tv_nsec = 0};
	struct timespec req1 = {.tv_sec = 0, .tv_nsec = 90000000};
	struct timespec req2 = {.tv_sec = 0, .tv_nsec = 1000000};

	while (1)
	{
		matrix4.clear(0);
		Rectangle rect;
		rect.topLeft = {(double)0, (double)0};
		rect.bottomRight = {(double)maxCol / 2, (double)maxCol / 2};
		Ellipse ellipse;
		ellipse.center = {(double)maxCol / 4, (double)maxCol / 4};
		ellipse.xRadius = (double)maxCol / 8 - 1;
		ellipse.yRadius = (double)maxCol / 4 - 1;
		Polygon pologon0 = ellipse.toPolygon(maxCol);
		Polygon pologon1 = ellipse.toPolygon(maxCol);
		pologon1.resize(0.5);

		Polygon pologon = rect.toPolygon();
		StraightLine *xLines = pologon.scanLineX(0, maxCol / 2);
		StraightLine *yLines0 = pologon.scanLineY(0, maxCol / 2);

		struct StraightLine *yLines = pologon0.scanLineY(0, maxCol / 2);

		mvprintw(0, 0, "Matrix (%d X %d) from icon.png.          ", maxCol / 2, maxCol / 2);
		double aX, aY, aZ, r, oX, oY;
		aX = 0;
		r = 1.42;
		oX = (double)(0 - maxCol / 4.0);
		oY = (double)(maxCol / 4.0);

		for (double j = 0; j < 360; j++)
		{
			Matrix matrixT = img.rotated(aX, r, NULL, NULL, oX, oY).toMatrix();
			oX += (double)maxCol / 720.0;
			oY -= (double)maxCol / 720.0;
			aX--;
			r += 0.5 / 360;
			matrixT.showMatrix(0, 1);
			nanosleep(&req2, NULL);
		}

		mvprintw(0, 0, "Matrix (%d X %d) from bot.png.         ", maxCol / 2, maxCol / 2);

		aX = 0;
		oX = (double)(maxCol / 4.0);
		oY = (double)(maxCol / 4.0);

		for (double j = 0; j < 360; j++)
		{
			Matrix matrixT = img2.rotated(aX, r, NULL,NULL,oX, oY).toMatrix();
			oX -= maxCol / 720.0;
			oY -= maxCol / 720.0;
			aX++;
			r -= (0.5 / 360);
			matrixT.showMatrix(0, 1);
			nanosleep(&req2, NULL);
		}

		mvprintw(0, 0, "Matrix (%d X %d) 3D simulation         ", maxCol / 2, maxCol / 2);
		aX = 0;
		aY=90;
		aZ=45;

		for (double j = 0; j < 720; j++)
		{
			Matrix matrixT = img3.rotated(aX, 1, NULL, NULL, NULL, NULL,aY,aZ).toMatrix();
			matrixT.showMatrix(0, 1);
			aX++;
			aY++;
			aZ--;
			nanosleep(&req2, NULL);
		}

	   aX = 0;
		aY=45;
		aZ=90;

		for (double j = 0; j < 720; j++)
		{
			Matrix matrixT = img3.rotated(aX, 1, NULL, NULL, NULL, NULL,aY,aZ).toMatrix();
			matrixT.showMatrix(0, 1);
			aX--;
			aY--;
			aZ++;
			nanosleep(&req2, NULL);
		}


aX = 0;
		r = 1.42;
		oX = (double)(0 - maxCol / 4.0);
		oY = (double)(maxCol / 4.0);
		aX = 0;
		aY=45;
		aZ=90;

		for (double j = 0; j < 720; j++)
		{
			Matrix matrixT = img.rotated(aX, r, NULL, NULL, oX, oY,aY,aZ).toMatrix();
			oX += (double)maxCol / 720.0/2;
			oY -= (double)maxCol / 720.0/2;
			aX--;
			//r += 0.5 / 360;
			aX--;
			aY++;
			aZ--;
			matrixT.showMatrix(0, 1);
			nanosleep(&req2, NULL);
		}

aX = 0;
		r = 1.42;
		oX = (double)(maxCol / 4.0);
		oY = (double)(maxCol / 4.0);
		aX = 0;
		aY=45;
		aZ=90;

		for (double j = 0; j < 720; j++)
		{
			Matrix matrixT = img2.rotated(aX, 1, NULL, NULL, oX, oY,aY,aZ).toMatrix();
			oX -= (double)maxCol / 720.0/2;
			oY -= (double)maxCol / 720.0/2;
			aX--;
			//r += 0.5 / 360;
			aX--;
			aY--;
			aZ++;
			matrixT.showMatrix(0, 1);
			nanosleep(&req2, NULL);
		}


		matrix4.clear(0);
		mvprintw(0, 0, "Matrix4 ellipse and  bezier (%d X %d) . ", maxCol / 2, maxCol / 2);
		int v;
		int vx, vy, k;
		k = maxCol / 8;
		vx = maxCol / 4 - k;
		vy = maxCol / 4 - k;
		pologon0.moveTo(vx, vy);
		for (int i = 0; i < k; i++)
		{
			matrix4.clear(0);
			v = rand() % 239 + 16;

			for (auto point : pologon0.toPoints())
			{
				matrix4.setValue(point, v);
			}
			v = rand() % 239 + 16;
			for (auto point : bezier.toPoints())
			{
				matrix4.setValue(point, v);
			}
			v = rand() % 239 + 16;
			for (auto point : line.toPoints())
			{
				matrix4.setValue(point, v);
			}

			vx++;
			vy++;
			pologon0.moveTo(vx, vy);

			matrix4.showMatrix(0, 1);
			nanosleep(&req1, NULL);
		}
		matrix4.clear(0);
		mvprintw(0, 0, "Matrix4 ellipse  rotate(%d X %d) .       ", maxCol / 2, maxCol / 2);
		for (int j = 0; j < 50; j++)
		{
			v = rand() % 239 + 16;
			pologon1.rotate(0.15);
			matrix4.clear(0);
			for (auto point : pologon1.toPoints())
			{
				matrix4.setValue(point, v);
			}
			matrix4.showMatrix(0, 1);
			nanosleep(&req1, NULL);
		}
		mvprintw(0, 0, "Matrix4 ellipse  resize(%d X %d) .       ", maxCol / 2, maxCol / 2);
		matrix4.clear(0);
		for (int j = 0; j < 50; j++)
		{
			v = rand() % 239 + 16;
			pologon1.resize(1.015);
			matrix4.clear(0);
			for (auto point : pologon1.toPoints())
			{
				matrix4.setValue(point, v);
			}
			matrix4.showMatrix(0, 1);
			nanosleep(&req1, NULL);
		}
		for (int j = 0; j < 50; j++)
		{
			v = rand() % 239 + 16;
			pologon1.resize(1 / 1.015);
			matrix4.clear(0);
			for (auto point : pologon1.toPoints())
			{
				matrix4.setValue(point, v);
			}
			matrix4.showMatrix(0, 1);
			nanosleep(&req1, NULL);
		}

		matrix4.clear(0);
		mvprintw(0, 0, "Matrix4 scanLineXY (%d X %d) .        ", maxCol / 2, maxCol / 2);
		for (int i = 0; i < maxCol / 2; i++)
		{
			v = rand() % 239 + 16;
			for (auto point : xLines[i].toPoints())
			{
				matrix4.setValue(point, v);
			}
			matrix4.showMatrix(0, 1);
			nanosleep(&req2, NULL);
		}
		matrix4.clear(0);
		for (int i = 0; i < maxCol / 2; i++)
		{
			v = rand() % 239 + 16;
			for (auto point : yLines0[i].toPoints())
			{
				matrix4.setValue(point, v);
			}
			matrix4.showMatrix(0, 1);
			nanosleep(&req2, NULL);
		}

		for (int i = 0; i < 5; i++)
		{
			mvprintw(0, 0, "Matrix4 (%d X %d) .               ", maxCol / 2, maxCol / 2);
			matrix4.clear(rand() % 239 + 16);
			matrix4.showMatrix(0, 1);
			nanosleep(&req1, NULL);
		}
	}
}