This repository has been archived by the owner on Nov 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathimage_util.c
124 lines (100 loc) · 2.96 KB
/
image_util.c
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "zgl.h"
/*
* image conversion
*/
void gl_convertRGB_to_5R6G5B(GLushort* pixmap, GLubyte* rgb, GLint xsize, GLint ysize) {
GLint i, n;
GLubyte* p;
p = rgb;
n = xsize * ysize;
for (i = 0; i < n; i++) {
pixmap[i] = ((p[0] & 0xF8) << 8) | ((p[1] & 0xFC) << 3) | ((p[2] & 0xF8) >> 3);
p += 3;
}
}
/*
This actually converts to ARGB!!!
This is the format of the entire engine!!!
*/
void gl_convertRGB_to_8A8R8G8B(GLuint* pixmap, GLubyte* rgb, GLint xsize, GLint ysize) {
GLint i, n;
GLubyte* p;
p = rgb;
n = xsize * ysize;
for (i = 0; i < n; i++) {
pixmap[i] = (((GLuint)p[0]) << 16) | (((GLuint)p[1]) << 8) | (((GLuint)p[2]));
p += 3;
}
}
/*
* linear GLinterpolation with xf,yf normalized to 2^16
*/
#define INTERP_NORM_BITS 16
#define INTERP_NORM (1 << INTERP_NORM_BITS)
static GLint GLinterpolate_imutil(GLint v00, GLint v01, GLint v10, GLint xf, GLint yf) {
return v00 + (((v01 - v00) * xf + (v10 - v00) * yf) >> INTERP_NORM_BITS);
}
/*
* TODO: more accurate resampling
*/
void gl_resizeImage(GLubyte* dest, GLint xsize_dest, GLint ysize_dest, GLubyte* src, GLint xsize_src, GLint ysize_src) {
GLubyte *pix, *pix_src;
GLfloat x1, y1, x1inc, y1inc;
GLint xi, yi, j, xf, yf, x, y;
pix = dest;
pix_src = src;
x1inc = (GLfloat)(xsize_src - 1) / (GLfloat)(xsize_dest - 1);
y1inc = (GLfloat)(ysize_src - 1) / (GLfloat)(ysize_dest - 1);
y1 = 0;
for (y = 0; y < ysize_dest; y++) {
x1 = 0;
for (x = 0; x < xsize_dest; x++) {
xi = (GLint)x1;
yi = (GLint)y1;
xf = (GLint)((x1 - floor(x1)) * INTERP_NORM);
yf = (GLint)((y1 - floor(y1)) * INTERP_NORM);
if ((xf + yf) <= INTERP_NORM) {
for (j = 0; j < 3; j++) {
pix[j] = GLinterpolate_imutil(pix_src[(yi * xsize_src + xi) * 3 + j], pix_src[(yi * xsize_src + xi + 1) * 3 + j],
pix_src[((yi + 1) * xsize_src + xi) * 3 + j], xf, yf);
}
} else {
xf = INTERP_NORM - xf;
yf = INTERP_NORM - yf;
for (j = 0; j < 3; j++) {
pix[j] = GLinterpolate_imutil(pix_src[((yi + 1) * xsize_src + xi + 1) * 3 + j], pix_src[((yi + 1) * xsize_src + xi) * 3 + j],
pix_src[(yi * xsize_src + xi + 1) * 3 + j], xf, yf);
}
}
pix += 3;
x1 += x1inc;
}
y1 += y1inc;
}
}
#define FRAC_BITS 16
/* resizing with no GLinterlating nor nearest pixel */
void gl_resizeImageNoInterpolate(GLubyte* dest, GLint xsize_dest, GLint ysize_dest, GLubyte* src, GLint xsize_src, GLint ysize_src) {
GLubyte *pix, *pix_src, *pix1;
GLint x1, y1, x1inc, y1inc;
GLint xi, yi, x, y;
pix = dest;
pix_src = src;
x1inc = (GLint)((GLfloat)((xsize_src) << FRAC_BITS) / (GLfloat)(xsize_dest));
y1inc = (GLint)((GLfloat)((ysize_src) << FRAC_BITS) / (GLfloat)(ysize_dest));
y1 = 0;
for (y = 0; y < ysize_dest; y++) {
x1 = 0;
for (x = 0; x < xsize_dest; x++) {
xi = x1 >> FRAC_BITS;
yi = y1 >> FRAC_BITS;
pix1 = pix_src + (yi * xsize_src + xi) * 3;
pix[0] = pix1[0];
pix[1] = pix1[1];
pix[2] = pix1[2];
pix += 3;
x1 += x1inc;
}
y1 += y1inc;
}
}