13 static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax)
30 #define FIXMUL(a, b) (((a) * (b)) >> 8)
31 #define FIXDIV(a, b) (((a) << 8) / (b))
33 #define LERP(a, b, t) ((a) + FIXMUL((b) - (a), (t)))
35 int clip_line(int *x0, int *y0, int *x1, int *y1, int xmin, int ymin, int xmax, int ymax)
39 int oc0 = outcode(*x0, *y0, xmin, ymin, xmax, ymax);
40 int oc1 = outcode(*x1, *y1, xmin, ymin, xmax, ymax);
42 long fx0, fy0, fx1, fy1, fxmin, fymin, fxmax, fymax;
44 if(!(oc0 | oc1)) return 1; /* both points are inside */
58 if(oc0 & oc1) return 0; /* both have points with the same outbit, not visible */
59 if(!(oc0 | oc1)) break; /* both points are inside */
61 oc_out = oc0 ? oc0 : oc1;
64 t = FIXDIV(fymin - fy0, fy1 - fy0);
65 x = LERP(fx0, fx1, t);
67 } else if(oc_out & BOTTOM) {
68 t = FIXDIV(fymax - fy0, fy1 - fy0);
69 x = LERP(fx0, fx1, t);
71 } else if(oc_out & LEFT) {
72 t = FIXDIV(fxmin - fx0, fx1 - fx0);
74 y = LERP(fy0, fy1, t);
75 } else if(oc_out & RIGHT) {
76 t = FIXDIV(fxmax - fx0, fx1 - fx0);
78 y = LERP(fy0, fy1, t);
84 oc0 = outcode(fx0 >> 8, fy0 >> 8, xmin, ymin, xmax, ymax);
88 oc1 = outcode(fx1 >> 8, fy1 >> 8, xmin, ymin, xmax, ymax);
99 void draw_line(int x0, int y0, int x1, int y1, unsigned short color)
101 int i, dx, dy, x_inc, y_inc, error;
102 unsigned short *fb = fb_pixels;
104 fb += y0 * FB_WIDTH + x0;
124 for(i=0; i<=dx; i++) {
135 for(i=0; i<=dy; i++) {
148 #define BLUR(w, h, pstep, sstep) \
149 for(i=0; i<h; i++) { \
151 int rsum = UNPACK_R16(sptr[0]) * (rad + 1); \
152 int gsum = UNPACK_G16(sptr[0]) * (rad + 1); \
153 int bsum = UNPACK_B16(sptr[0]) * (rad + 1); \
154 int count = (rad * 2 + 1) << 8; \
155 int midsize = w - rad * 2; \
156 int rfirstpix = UNPACK_R16(sptr[0]); \
157 int rlastpix = UNPACK_R16(sptr[pstep * (w - 1)]); \
158 int gfirstpix = UNPACK_G16(sptr[0]); \
159 int glastpix = UNPACK_G16(sptr[pstep * (w - 1)]); \
160 int bfirstpix = UNPACK_B16(sptr[0]); \
161 int blastpix = UNPACK_B16(sptr[pstep * (w - 1)]); \
162 /* add up the contributions for the -1 pixel */ \
163 for(j=0; j<rad; j++) { \
164 rsum += UNPACK_R16(sptr[pstep * j]); \
165 gsum += UNPACK_G16(sptr[pstep * j]); \
166 bsum += UNPACK_B16(sptr[pstep * j]); \
168 /* first part adding sptr[rad] and subtracting sptr[0] */ \
169 for(j=0; j<=rad; j++) { \
170 rsum += UNPACK_R16((int)sptr[pstep * rad]) - rfirstpix; \
171 gsum += UNPACK_G16((int)sptr[pstep * rad]) - gfirstpix; \
172 bsum += UNPACK_B16((int)sptr[pstep * rad]) - bfirstpix; \
174 r = scale * rsum / count; \
175 g = scale * gsum / count; \
176 b = scale * bsum / count; \
177 *dptr = PACK_RGB16(r, g, b); \
180 /* middle part adding sptr[rad] and subtracting sptr[-(rad+1)] */ \
181 for(j=1; j<midsize; j++) { \
182 rsum += UNPACK_R16((int)sptr[pstep * rad]) - UNPACK_R16((int)sptr[-(rad + 1) * pstep]); \
183 gsum += UNPACK_G16((int)sptr[pstep * rad]) - UNPACK_G16((int)sptr[-(rad + 1) * pstep]); \
184 bsum += UNPACK_B16((int)sptr[pstep * rad]) - UNPACK_B16((int)sptr[-(rad + 1) * pstep]); \
186 r = scale * rsum / count; \
187 g = scale * gsum / count; \
188 b = scale * bsum / count; \
189 *dptr = PACK_RGB16(r, g, b); \
192 /* last part adding lastpix and subtracting sptr[-(rad+1)] */ \
193 for(j=0; j<rad; j++) { \
194 rsum += rlastpix - UNPACK_R16((int)sptr[-(rad + 1) * pstep]); \
195 gsum += glastpix - UNPACK_G16((int)sptr[-(rad + 1) * pstep]); \
196 bsum += blastpix - UNPACK_B16((int)sptr[-(rad + 1) * pstep]); \
198 r = scale * rsum / count; \
199 g = scale * gsum / count; \
200 b = scale * bsum / count; \
201 *dptr = PACK_RGB16(r, g, b); \
208 /* TODO bound blur rad to image size to avoid inner loop conditionals */
209 /* TODO make version with pow2 (rad*2+1) to avoid div with count everywhere */
210 void blur_horiz(uint16_t *dest, uint16_t *src, int xsz, int ysz, int rad, int scale)
213 uint16_t *dptr = dest;
214 uint16_t *sptr = src;
216 BLUR(xsz, ysz, 1, 0);
220 void blur_vert(uint16_t *dest, uint16_t *src, int xsz, int ysz, int rad, int scale)
223 uint16_t *dptr = dest;
224 uint16_t *sptr = src;
225 int pixel_step = xsz;
226 int scanline_step = 1 - ysz * pixel_step;
228 BLUR(ysz, xsz, pixel_step, scanline_step);
231 void convimg_rgb24_rgb16(uint16_t *dest, unsigned char *src, int xsz, int ysz)
234 int npixels = xsz * ysz;
236 for(i=0; i<npixels; i++) {
240 *dest++ = PACK_RGB16(r, g, b);
244 void blitfb(uint16_t *dest, uint16_t *src, int width, int height, int pitch_pix)
247 for(i=0; i<height; i++) {
248 memcpy(dest, src, width << 1);
254 void blit(uint16_t *dest, int destwidth, uint16_t *src, int width, int height, int pitch_pix)
256 int i, spansz = width << 1;
257 for(i=0; i<height; i++) {
258 memcpy(dest, src, spansz);
264 void blit_key(uint16_t *dest, int destwidth, uint16_t *src, int width, int height, int pitch_pix, uint16_t key)
267 int dadv = destwidth - width;
268 int sadv = pitch_pix - width;
270 for(i=0; i<height; i++) {
271 for(j=0; j<width; j++) {
272 uint16_t scol = *src++;
273 if(scol != key) *dest = scol;