c jpeg YUV图片帧分割成 8*8 块 ,与逆向把8*8还原为帧
2023-12-14 00:27:29
1.? 正向分割为若干8*8 块
? ? ?下面的程序为通用程序,可以分割任意块
#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. 8*8 块逆向 转化为帧
#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;
}
实话头都绕晕了,看能不能再想一个好理解的方法。查表法简单,但数据大了就不实用了,如果要程序生成大数据的表,感觉又多了一个环节。而且也不容易
但Z 型排列可以用查表法。
3.用4×4块模拟生成一维的帧
//模拟4×4的块横向拼接成一个16×4的一个大块
下面的拼接思路为:先确定要拼接的输出数组每行总宽度width, 再确定这个总宽度要几个被转换的块,再取出每一个块的第一行组成输出数组的第一行,取每个块的第二行组成输出数组的第二行,直到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;
}
?
?
?
?
文章来源:https://blog.csdn.net/m0_59802969/article/details/134876068
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!