Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7beb171

Browse files
committed
Add NEON Programming
1 parent 432cb26 commit 7beb171

File tree

15 files changed

+1027
-0
lines changed

15 files changed

+1027
-0
lines changed

‎Chapter10/install.sh‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#! /bin/sh
2+
sudo apt-get update
3+
sudo apt-get install qt5-default qtbase5-dev qtdeclarative5-dev qt5-qmake qtcreator libqt5gui5 qtscript5-dev qtmultimedia5-dev libqt5multimedia5-plugins qtquickcontrols2-5-dev libqt5network5 cmake build-essential

‎Chapter13/NeonProgramming/Lena.bmp‎

768 KB
Binary file not shown.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <stdio.h>
2+
#include "bmpHeader.h"
3+
4+
int readBmp(char *filename, unsigned char **data, int *cols, int *rows)
5+
{
6+
BITMAPFILEHEADER bmpHeader;
7+
BITMAPINFOHEADER bmpInfoHeader;
8+
FILE *fp;
9+
10+
/* BMP 파일을 오픈한다. */
11+
fp = fopen(filename,"rb");
12+
if(fp == NULL) {
13+
perror("ERROR\n");
14+
return -1;
15+
}
16+
17+
/* BITMAPFILEHEADER 구조체의 데이터 */
18+
fread(&bmpHeader, sizeof(BITMAPFILEHEADER), 1, fp);
19+
20+
/* BITMAPINFOHEADER 구조체의 데이터 */
21+
fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
22+
23+
/* 트루 컬러를 지원하지 않으면 표시할 수 없다. */
24+
if(bmpInfoHeader.biBitCount != 24) {
25+
perror("This image file doesn't supports 24bit color\n");
26+
fclose(fp);
27+
return -1;
28+
}
29+
30+
/* 이미지에서 해상도의 정보를 가져온다. */
31+
*cols = bmpInfoHeader.biWidth;
32+
*rows = bmpInfoHeader.biHeight;
33+
34+
/* 이미지의 해상도(넓이 ×ばつ 깊이) */
35+
printf("Resolution : %d x %d\n", bmpInfoHeader.biWidth, bmpInfoHeader.biHeight);
36+
printf("Bit Count : %d\n", bmpInfoHeader.biBitCount); /* 픽셀당 비트 수(색상) */
37+
38+
/* 실제 이미지 데이터가 있는 위치를 계산해서 가져온다. */
39+
fseek(fp, bmpHeader.bfOffBits, SEEK_SET);
40+
fread(*data, 1, bmpHeader.bfSize-bmpHeader.bfOffBits, fp);
41+
42+
fclose(fp); /* 사용이 끝난 이미지 파일을 닫는다. */
43+
44+
return 0;
45+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef __BMP_FILE_H__
2+
#define __BMP_FILE_H__
3+
4+
typedef struct __attribute__((__packed__)) {
5+
unsigned short bfType; /* BM 표시: "BM" (2글자) 문자 */
6+
unsigned int bfSize; /* 파일의 크기: 4바이트 정수 */
7+
unsigned short bfReserved1; /* 추후의 확장을 위해 필드(reserved) */
8+
unsigned short bfReserved2; /* 추후의 확장을 위해 필드(reserved) */
9+
unsigned int bfOffBits; /* 실제 이미지까지의 오프셋: 바이트 */
10+
} BITMAPFILEHEADER; /* BMP 파일 데이터를 위한 구조체 */
11+
12+
typedef struct {
13+
unsigned int biSize; /* 현 구조체의 크기: 4바이트 */
14+
unsigned int biWidth; /* 이미지의 폭(픽셀 단위): 4바이트 */
15+
unsigned int biHeight; /* 이미지의 높이(픽셀 단위): 4바이트 */
16+
unsigned short biPlanes; /* 비트 플레인 수(항상1): 2바이트 */
17+
unsigned short biBitCount; /* 픽셀당 비트 수: 2바이트 */
18+
unsigned int biCompression; /* 압축 유형: 4바이트 */
19+
unsigned int SizeImage; /* 이미지의 크기(압축 전 바이트 단위): 4바이트 */
20+
unsigned int biXPelsPerMeter; /* 가로 해상도: 4바이트 */
21+
unsigned int biYPelsPerMeter; /* 세로 해상도: 4바이트 */
22+
unsigned int biClrUsed; /* 실제 사용되는 색상 수: 4바이트 */
23+
unsigned int biClrImportant; /* 중요한 색상 인덱스(0인 경우 전체): 4바이트 */
24+
} BITMAPINFOHEADER; /* BMP 이미지 데이터를 위한 구조체 */
25+
26+
typedef struct {
27+
unsigned char rgbBlue; /* 파란색을 위한 요소 */
28+
unsigned char rgbGreen; /* 초록색을 위한 요소 */
29+
unsigned char rgbRed; /* 빨간색을 위한 요소 */
30+
unsigned char rgbReserved; /* 투명도(알파값) 등을 위한 예약 공간 */
31+
} RGBQUAD; /* 색상 팔레트를 위한 구조체 */
32+
33+
#endif /* __BMP_FILE_H__ */
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <stdio.h>
2+
#include <arm_neon.h> /* ARM NEON 프로그래밍을 위한 헤더 파일 */
3+
4+
void printData(uint8x16_t data)
5+
{
6+
int i;
7+
static uint8_t p[16];
8+
9+
vst1q_u8(p, data); /* 벡터를 배열에 대입한다. */
10+
11+
for (i = 0; i < 16; i++) printf("%02d ", p[i]);
12+
printf ("\n");
13+
}
14+
15+
16+
int main(int argc, char **argv)
17+
{
18+
/* 초기화를 위한 데이터셋 */
19+
const uint8_t source[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
20+
uint8x16_t data, ret; /* 계산된 결과를 위한 벡터(데이터) 변수 */
21+
uint8x16_t fill3 = vmovq_n_u8(3); /* 모두 5로 채워진 16비트 벡터를 생성한다. */
22+
23+
data = vld1q_u8(source); /* 데이터셋을 벡터에 대입한다. */
24+
25+
printf("data : ");
26+
printData(data); /* 벡터에 저장된 값을 출력한다. */
27+
28+
ret = vaddq_u8(data, fill3); /* 두 벡터의 요소들을 각각 더한다. */
29+
printf("Add : "); printData(ret); /* 덧셈의 결과 값을 출력한다. */
30+
31+
ret = vsubq_u8(data, fill3); /* 두 벡터의 요소들을 각각 뺀다. */
32+
printf("Subtract : "); printData(ret); /* 뺄셈의 결과 값을 출력한다. */
33+
34+
ret = vmulq_u8(data, fill3); /* 두 벡터의 요소들을 각각 곱한다. */
35+
printf("Multiply : "); printData(ret); /* 곱셈의 결과 값을 출력한다. */
36+
37+
return 0;
38+
}
39+
40+
41+
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <stdio.h>
2+
#include <stdlib.h> /* malloc() 함수와 free() 함수를 위해서 사용한다. */
3+
#include <string.h> /* memcpy() 함수를 위해서 사용한다. */
4+
#include <fcntl.h> /* O_RDWR 상수를 위해서 사용한다. */
5+
#include <limits.h> /* USHRT_MAX 상수를 위해서 사용한다. */
6+
#include <unistd.h>
7+
#include <sys/mman.h>
8+
#include <sys/ioctl.h>
9+
#include <linux/fb.h>
10+
#include "bmpHeader.h"
11+
12+
#define FBDEVFILE "/dev/fb0"
13+
14+
/* 이미지 데이터의 경계 검사를 위한 매크로 */
15+
#define LIMIT_UBYTE(n) (n>UCHAR_MAX)?UCHAR_MAX:(n<0)?0:n
16+
17+
typedef unsigned char ubyte;
18+
19+
/* BMP 파일의 헤더를 분석해서 원하는 정보를 얻기 위한 함수 */
20+
extern int readBmp(char *filename, ubyte **pData, int *cols, int *rows, int *color);
21+
22+
/* BGR 이미지 데이터를 그레이스케일로 변환하는 함수 */
23+
void cvtBGR2Gray(ubyte *dest, ubyte *src, int n)
24+
{
25+
for(int i = 0; i < n; i++) {
26+
int b = *src++; /* blue */
27+
int g = *src++; /* green */
28+
int r = *src++; /* red */
29+
30+
/* 그레이 스케일 이미지로 변환 */
31+
int y = (r * 77) + (g * 151) + (b * 28);
32+
*dest++ = (y>>8);
33+
*dest++ = (y>>8);
34+
*dest++ = (y>>8);
35+
}
36+
}
37+
38+
int main(int argc, char **argv)
39+
{
40+
int cols, rows, color = 24; /* 프레임 버퍼의 가로 ×ばつ 세로의 크기 */
41+
ubyte r, g, b, a = 255;
42+
ubyte *pData, *pBmpData, *pImageData, *pFbMap;
43+
struct fb_var_screeninfo vinfo;
44+
int fbfd;
45+
46+
if(argc != 2) {
47+
printf("Usage: ./%s xxx.bmp\n", argv[0]);
48+
return 0;
49+
}
50+
51+
/* 프레임 버퍼를 연다. */
52+
fbfd = open(FBDEVFILE, O_RDWR);
53+
if(fbfd < 0) {
54+
perror("open()");
55+
return -1;
56+
}
57+
58+
/* 현재 프레임 버퍼에 대한 화면 정보를 얻어온다. */
59+
if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
60+
perror("ioctl() : FBIOGET_VSCREENINFO");
61+
return -1;
62+
}
63+
64+
/* BMP 출력을 위한 변수의 메모리 할당 */
65+
pBmpData = (ubyte *)malloc(vinfo.xres * vinfo.yres * sizeof(ubyte) * vinfo.bits_per_pixel/8);
66+
pData = (ubyte*)malloc(vinfo.xres * vinfo.yres * sizeof(ubyte) * color/8);
67+
pImageData = (ubyte *)malloc(vinfo.xres * vinfo.yres * sizeof(ubyte) * color/8);
68+
69+
/* 프레임 버퍼에 대한 메모리 맵을 수행한다. */
70+
pFbMap = (ubyte *)mmap(0, vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED, fbfd, 0);
71+
if((unsigned)pFbMap == (unsigned)-1) {
72+
perror("mmap()");
73+
return -1;
74+
}
75+
76+
/* BMP 파일에서 헤더 정보를 가져온다. */
77+
if(readBmp(argv[1], &pImageData, &cols, &rows, &color) < 0) {
78+
perror("readBmp()");
79+
return -1;
80+
}
81+
82+
cvtBGR2Gray(pData, pImageData, vinfo.xres*vinfo.yres);
83+
84+
/* BMP 이미지 데이터를 프레임 버퍼 데이터로 변경 */
85+
for(int y = 0, k, total_y; y < rows; y++) {
86+
k = (rows-y-1)*cols*color/8;
87+
total_y = y*vinfo.xres*vinfo.bits_per_pixel/8;
88+
for(int x = 0; x < cols; x++) {
89+
/* BMP 이미지는 뒤집혀 있기 때문에 BGR 형태로 가져온다. */
90+
b = LIMIT_UBYTE(pData[k+x*color/8+0]);
91+
g = LIMIT_UBYTE(pData[k+x*color/8+1]);
92+
r = LIMIT_UBYTE(pData[k+x*color/8+2]);
93+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 0) = b;
94+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 1) = g;
95+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 2) = r;
96+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 3) = a;
97+
}
98+
}
99+
100+
/* 앞에서 생성한 BMP 데이터를 프레임 버퍼의 메모리 공간으로 복사 */
101+
memcpy(pFbMap, pBmpData, vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8);
102+
103+
/* 프레임 버퍼 파일을 닫고 이미지 데이터를 위해서 사용한 메모리를 해제 */
104+
munmap(pFbMap, vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8);
105+
106+
free(pBmpData);
107+
free(pImageData);
108+
free(pData);
109+
110+
close(fbfd); /* 프레임 버퍼를 위한 디바이스 파일 닫기 */
111+
112+
return 0;
113+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <stdio.h>
2+
#include <stdlib.h> /* malloc() 함수와 free() 함수를 위해서 사용한다. */
3+
#include <string.h> /* memcpy() 함수를 위해서 사용한다. */
4+
#include <fcntl.h> /* O_RDWR 상수를 위해서 사용한다. */
5+
#include <limits.h> /* USHRT_MAX 상수를 위해서 사용한다. */
6+
#include <unistd.h>
7+
#include <sys/mman.h>
8+
#include <sys/ioctl.h>
9+
#include <linux/fb.h>
10+
11+
#include "bmpHeader.h"
12+
13+
#define FBDEVFILE "/dev/fb0"
14+
15+
/* 이미지 데이터의 경계 검사를 위한 매크로 */
16+
#define LIMIT_UBYTE(n) (n>UCHAR_MAX)?UCHAR_MAX:(n<0)?0:n
17+
18+
typedef unsigned char ubyte;
19+
20+
/* BMP 파일의 헤더를 분석해서 원하는 정보를 얻기 위한 함수 */
21+
extern int readBmp(char *filename, ubyte **pData, int *cols, int *rows, int *color);
22+
23+
void cvtBGR2Sepia(ubyte *dest, ubyte *src, int n)
24+
{
25+
for(int i = 0; i < n; i++) {
26+
int b = *src++; /* blue */
27+
int g = *src++; /* green */
28+
int r = *src++; /* red */
29+
30+
/* 세피아 효과 계산 */
31+
ubyte or = (r * 100 + g * 197 + b * 48) >> 8;
32+
ubyte og = (r * 89 + g * 175 + b * 43) >> 8;
33+
ubyte ob = (r * 70 + g * 136 + b * 33) >> 8;
34+
35+
/* 결과값 경계 검사 */
36+
*dest++ = LIMIT_UBYTE(ob);
37+
*dest++ = LIMIT_UBYTE(og);
38+
*dest++ = LIMIT_UBYTE(or);
39+
}
40+
}
41+
42+
int main(int argc, char **argv)
43+
{
44+
int cols, rows, color = 24; /* 프레임 버퍼의 가로 ×ばつ 세로의 크기 */
45+
ubyte r, g, b, a = 255;
46+
ubyte *pData, *pBmpData, *pImageData, *pFbMap;
47+
struct fb_var_screeninfo vinfo;
48+
int fbfd;
49+
50+
if(argc != 2) {
51+
printf("Usage: ./%s xxx.bmp\n", argv[0]);
52+
return 0;
53+
}
54+
55+
/* 프레임 버퍼를 연다. */
56+
fbfd = open(FBDEVFILE, O_RDWR);
57+
if(fbfd < 0) {
58+
perror("open()");
59+
return -1;
60+
}
61+
62+
/* 현재 프레임 버퍼에 대한 화면 정보를 얻어온다. */
63+
if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
64+
perror("ioctl() : FBIOGET_VSCREENINFO");
65+
return -1;
66+
}
67+
68+
/* BMP 출력을 위한 변수의 메모리 할당 */
69+
pBmpData = (ubyte *)malloc(vinfo.xres * vinfo.yres * sizeof(ubyte) * vinfo.bits_per_pixel/8);
70+
pData = (ubyte*)malloc(vinfo.xres * vinfo.yres * sizeof(ubyte) * color/8);
71+
pImageData = (ubyte *)malloc(vinfo.xres * vinfo.yres * sizeof(ubyte) * color/8);
72+
73+
/* 프레임 버퍼에 대한 메모리 맵을 수행한다. */
74+
pFbMap = (ubyte *)mmap(0, vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED, fbfd, 0);
75+
if((unsigned)pFbMap == (unsigned)-1) {
76+
perror("mmap()");
77+
return -1;
78+
}
79+
80+
/* BMP 파일에서 헤더 정보를 가져온다. */
81+
if(readBmp(argv[1], &pImageData, &cols, &rows, &color) < 0) {
82+
perror("readBmp()");
83+
return -1;
84+
}
85+
86+
cvtBGR2Sepia(pData, pImageData, vinfo.xres*vinfo.yres);
87+
88+
/* BMP 이미지 데이터를 프레임 버퍼 데이터로 변경 */
89+
for(int y = 0, k, total_y; y < rows; y++) {
90+
k = (rows-y-1)*cols*color/8;
91+
total_y = y*vinfo.xres*vinfo.bits_per_pixel/8;
92+
for(int x = 0; x < cols; x++) {
93+
/* BMP 이미지는 뒤집혀 있기 때문에 BGR 형태로 가져온다. */
94+
b = LIMIT_UBYTE(pData[k+x*color/8+0]);
95+
g = LIMIT_UBYTE(pData[k+x*color/8+1]);
96+
r = LIMIT_UBYTE(pData[k+x*color/8+2]);
97+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 0) = b;
98+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 1) = g;
99+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 2) = r;
100+
*(pBmpData + x*vinfo.bits_per_pixel/8 + total_y + 3) = a;
101+
}
102+
}
103+
104+
/* 앞에서 생성한 BMP 데이터를 프레임 버퍼의 메모리 공간으로 복사 */
105+
memcpy(pFbMap, pBmpData, vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8);
106+
107+
/* 프레임 버퍼 파일을 닫고 이미지 데이터를 위해서 사용한 메모리를 해제 */
108+
munmap(pFbMap, vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8);
109+
110+
free(pBmpData);
111+
free(pImageData);
112+
free(pData);
113+
114+
close(fbfd); /* 프레임 버퍼를 위한 디바이스 파일 닫기 */
115+
116+
return 0;
117+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /