c jpeg YUV picture frame is divided into 8*8 blocks, and reversely restores 8*8 to frames

1. Divide the forward direction into several 8*8 blocks

     The following program is a general program that can split any block


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>  //v4l2 头文件
#include <string.h>
#include <sys/mman.h>
#include <linux/fb.h>

int main(void){
	char i[]={1, 2, 3, 4,   5, 6, 7, 8,
	          9,10,11,12,   13,14,15,16,
		      17,18,19,20,  21,22,23,24,
		      25,26,27,28,  29,30,31,32,
		
		      33,34,35,36,  37,38,39,40,
			  41,42,43,44,  45,46,47,48,
		      49,50,51,52,  53,54,55,56,
		      57,58,59,60,  61,62,63,64
	       };
	
	int width=8;              //被分割数据宽度
	int heigth=8;             //被分割数据高度
	                   
	int fwidth=4;             //分割块的宽度     分割成4×2块
	int fheigth=2;            //分割块的高度
	
	
	char o[width*heigth];     //分割后的数据
	int t=0;

		for(int c=0;c<heigth/fheigth;c++){
		 
		  for(int b=c*width*fheigth;b<width+c*fheigth*width;b=b+fwidth){
			
			for(int a=0;a<fheigth;a++){
			    memcpy(&o[t],&i[a*width+b],fwidth);
			    t=t+fwidth;
			
			}
		  }
		}
//--------------------------------------------------------------	
	char (*p1)[2][4]=(char (*)[2][4])o;   //显示4×2 块
	
	for(int a=0;a<8;a++){
		for(int b=0;b<2;b++){
			for(int c=0;c<4;c++){
				printf("%d  ",p1[a][b][c]);
			}
			printf("\n");
		}
		puts("-----------");
		
	}


	return 0;
}

2. Convert 8*8 blocks into frames


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>  //v4l2 头文件
#include <string.h>
#include <sys/mman.h>
#include <linux/fb.h>

int main(void){
/*	char i[]={1, 2, 3, 4,   5, 6, 7, 8,
	          9,10,11,12,   13,14,15,16,
		      17,18,19,20,  21,22,23,24,
		      25,26,27,28,  29,30,31,32,
		
		      33,34,35,36,  37,38,39,40,
			  41,42,43,44,  45,46,47,48,
		      49,50,51,52,  53,54,55,56,
		      57,58,59,60,  61,62,63,64
	};*/
	
    char io[]={
		1,  2,  3,  4,  
		9,  10,  11,  12,  
		17,  18,  19,  20,  
		25,  26,  27,  28,  
		
		5,  6,  7,  8,  
		13,  14,  15,  16,  
		21,  22,  23,  24,  
		29,  30,  31,  32,  
		
		33,  34,  35,  36,  
		41,  42,  43,  44,  
		49,  50,  51,  52,  
		57,  58,  59,  60,  
		
		37,  38,  39,  40,  
		45,  46,  47,  48,  
		53,  54,  55,  56,  
		61,  62,  63,  64
	};
	
	int width=8;              //被分割数据宽度
	int heigth=8;             //被分割数据高度
	                   
	int fwidth=4;             //分割块的宽度     
	int fheigth=4;            //分割块的高度
	
/*	
	char o[width*heigth];     //分割后的数据
	int t=0;

		for(int c=0;c<heigth/fheigth;c++){
		 		
		   for(int b=c*width*fheigth;b<width+c*fheigth*width;b=b+fwidth){
				for(int a=0;a<fheigth;a++){   
			
			    memcpy(&o[t],&i[a*width+b],fwidth);
			    t=t+fwidth;
			
			}
		  }
		}
*/	
	char oo[width*heigth];    
	int ot=0;
	
	for(int c=0;c<heigth/fheigth;c++){
		for(int a=0;a<fheigth;a++){
	    	for(int b=0;b<width/fwidth;b++){
			
				memcpy(&oo[ot],&io[b*fwidth*fheigth+a*fwidth+c*fheigth*fwidth*width/fwidth],fwidth);
				ot=ot+fwidth;
				
			}
		}
	}
//--------------------------------------------------------------	
	char (*p1)[4][4]=(char (*)[4][4])oo;   //显示
	
	for(int a=0;a<4;a++){
		for(int b=0;b<4;b++){
			for(int c=0;c<4;c++){
				printf("%d,  ",p1[a][b][c]);
			}
			printf("\n");
		}
		puts("-----------");
		
	}


	return 0;
}

To be honest, my head is spinning. Let me see if I can think of a better way to understand it. The table lookup method is simple, but it is impractical when the data is large. If you want to program a big data table, it feels like there is one more step. And it's not easy either

But the Z-shaped arrangement can use the look-up table method.

3. Use 4×4 block simulation to generate a one-dimensional frame

//Simulate the horizontal splicing of 4×4 blocks into a 16×4 large block

The following splicing idea is: first determine the total width of each row of the output array to be spliced, then determine how many converted blocks this total width requires, and then take the first row of each block to form the first row of the output array. The second row of each block forms the second row of the output array until the end of fheigth.


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>  //v4l2 头文件
#include <string.h>
#include <sys/mman.h>
#include <linux/fb.h>

int main(void){
/*	char i[]={1, 2,3, 4,    5, 6, 7, 8,
	          9,10,11,12,   13,14,15,16,
		      17,18,19,20,  21,22,23,24,
		      25,26,27,28,  29,30,31,32,
		
		      33,34,35,36,  37,38,39,40,
			  41,42,43,44,  45,46,47,48,
		      49,50,51,52,  53,54,55,56,
		      57,58,59,60,  61,62,63,64
	};
*/
	char i1[]={              //模拟4×4的块横向拼接成一个16×4的一个大块
		1, 2,3, 4,    
		9,10,11,12,   
		17,18,19,20, 
		25,26,27,28,
	};
	
	char (*p1)[4]=(char (*)[4])i1;
	
	char i2[]={
		 5, 6, 7, 8,
         13,14,15,16,
	     21,22,23,24,
		 29,30,31,32,
	};
	char (*p2)[4]=(char (*)[4])i2;
	char i3[]={
		33,34,35,36,  
		41,42,43,44,  
		49,50,51,52,  
		57,58,59,60,  
	};
	char (*p3)[4]=(char (*)[4])i3;
	char i4[]={
		 37,38,39,40,
		45,46,47,48,
		53,54,55,56,
		61,62,63,64
	};
	char (*p4)[4]=(char (*)[4])i4;
	
	char i[64];             //4个块合成在一起,相当于逆向余弦后的8×8数据合成一数组
	memcpy(i,i1,16);
	memcpy(&i[16],i2,16);
	memcpy(&i[32],i3,16);
	memcpy(&i[48],i4,16);
	

    int n=4;
	char o[64];             //正常的帧排列
	int fwidth=4;
	int fheigth=4;
	int width=n*fwidth;
	int heigth=4;
	
	char (*po)[width]=(char (*)[width])o;
	char (*ii)[fheigth][fwidth]=(char (*)[fheigth][fwidth])i;	//把要转换的数据转成n个fwidth*fheigth的块,用n的id来代表这些块
//--------------------------------------------------	
	for(int a=0;a<heigth;a++){
		for(int b=0;b<width;b++){            
			
			int k=b/fwidth;                  //这两句非常重要,k=块id
		    po[a][b]=ii[k][a][b-fwidth*k];   //b-fwidth*k 等于每一个块的fwidth
			
		}
		
	}
//-------------------------------------------------	
	for(int t=0;t<64;t++){                  //显示
		printf("%d  ,",o[t]);
	}
	

	return 0;
}

 

 

 

 

Guess you like

Origin blog.csdn.net/m0_59802969/article/details/134876068