00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <malloc.h>
00027 #include "bitmask.h"
00028
00029 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00030
00031 bitmask *bitmask_create(int w, int h)
00032 {
00033 bitmask *temp = malloc(sizeof(bitmask));
00034 if (! temp) return 0;
00035 temp->w = w;
00036 temp->h = h;
00037 temp->bits = calloc(h*((w - 1)/BITW_LEN + 1),sizeof(BITW));
00038 if (! temp->bits)
00039 {
00040 free(temp);
00041 return 0;
00042 }
00043 else
00044 return temp;
00045 }
00046
00047 void bitmask_free(bitmask *m)
00048 {
00049 free(m->bits);
00050 free(m);
00051 }
00052
00053 int bitmask_overlap(const bitmask *a,const bitmask *b,int xoffset, int yoffset)
00054 {
00055 BITW *a_entry,*a_end;
00056 BITW *b_entry;
00057 BITW *ap,*bp;
00058 int shift,rshift,i,astripes,bstripes;
00059
00060 if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h))
00061 return 0;
00062
00063 if (xoffset >= 0)
00064 {
00065 if (yoffset >= 0)
00066 {
00067 a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset;
00068 a_end = a_entry + MIN(b->h,a->h - yoffset);
00069 b_entry = b->bits;
00070 }
00071 else
00072 {
00073 a_entry = a->bits + a->h*(xoffset/BITW_LEN);
00074 a_end = a_entry + MIN(b->h + yoffset,a->h);
00075 b_entry = b->bits - yoffset;
00076 }
00077 shift = xoffset & BITW_MASK;
00078 if (shift)
00079 {
00080 rshift = BITW_LEN - shift;
00081 astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN;
00082 bstripes = (b->w - 1)/BITW_LEN + 1;
00083 if (bstripes > astripes)
00084 {
00085 for (i=0;i<astripes;i++)
00086 {
00087 for (ap = a_entry,bp = b_entry;ap < a_end;)
00088 if ((*ap++ >> shift) & *bp++) return 1;
00089 a_entry += a->h;
00090 a_end += a->h;
00091 for (ap = a_entry,bp = b_entry;ap < a_end;)
00092 if ((*ap++ << rshift) & *bp++) return 1;
00093 b_entry += b->h;
00094 }
00095 for (ap = a_entry,bp = b_entry;ap < a_end;)
00096 if ((*ap++ >> shift) & *bp++) return 1;
00097 return 0;
00098 }
00099 else
00100 {
00101 for (i=0;i<bstripes;i++)
00102 {
00103 for (ap = a_entry,bp = b_entry;ap < a_end;)
00104 if ((*ap++ >> shift) & *bp++) return 1;
00105 a_entry += a->h;
00106 a_end += a->h;
00107 for (ap = a_entry,bp = b_entry;ap < a_end;)
00108 if ((*ap++ << rshift) & *bp++) return 1;
00109 b_entry += b->h;
00110 }
00111 return 0;
00112 }
00113 }
00114 else
00115 {
00116 astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1;
00117 for (i=0;i<astripes;i++)
00118 {
00119 for (ap = a_entry,bp = b_entry;ap < a_end;)
00120 if (*ap++ & *bp++) return 1;
00121 a_entry += a->h;
00122 a_end += a->h;
00123 b_entry += b->h;
00124 }
00125 return 0;
00126 }
00127 }
00128 else
00129 return bitmask_overlap(b,a,-xoffset,-yoffset);
00130 }
00131
00132
00133 static INLINE int firstsetbit(BITW w)
00134 {
00135 int i = 0;
00136 while ((w & 1) == 0)
00137 {
00138 i++;
00139 w/=2;
00140 }
00141 return i;
00142 }
00143
00144
00145 int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffset, int *x, int *y)
00146 {
00147 BITW *a_entry,*a_end;
00148 BITW *b_entry;
00149 BITW *ap,*bp;
00150 int shift,rshift,i,astripes,bstripes;
00151
00152 if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h))
00153 return 0;
00154
00155 if (xoffset >= 0)
00156 {
00157 if (yoffset >= 0)
00158 {
00159 a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset;
00160 a_end = a_entry + MIN(b->h,a->h - yoffset);
00161 b_entry = b->bits;
00162 }
00163 else
00164 {
00165 a_entry = a->bits + a->h*(xoffset/BITW_LEN);
00166 a_end = a_entry + MIN(b->h + yoffset,a->h);
00167 b_entry = b->bits - yoffset;
00168 }
00169 shift = xoffset & BITW_MASK;
00170 if (shift)
00171 {
00172 rshift = BITW_LEN - shift;
00173 astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN;
00174 bstripes = (b->w - 1)/BITW_LEN + 1;
00175 if (bstripes > astripes)
00176 {
00177 for (i=0;i<astripes;i++)
00178 {
00179 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00180 if (*ap & (*bp << shift))
00181 {
00182 *y = (ap - a->bits) % a->h;
00183 *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp << shift));
00184 return 1;
00185 }
00186 a_entry += a->h;
00187 a_end += a->h;
00188 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00189 if (*ap & (*bp >> rshift))
00190 {
00191 *y = (ap - a->bits) % a->h;
00192 *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift));
00193 return 1;
00194 }
00195 b_entry += b->h;
00196 }
00197 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00198 if (*ap & (*bp << shift))
00199 {
00200 *y = (ap - a->bits) % a->h;
00201 *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp << shift));
00202 return 1;
00203 }
00204 return 0;
00205 }
00206 else
00207 {
00208 for (i=0;i<bstripes;i++)
00209 {
00210 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00211 if (*ap & (*bp << shift))
00212 {
00213 *y = (ap - a->bits) % a->h;
00214 *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp << shift));
00215 return 1;
00216 }
00217 a_entry += a->h;
00218 a_end += a->h;
00219 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00220 if (*ap & (*bp >> rshift))
00221 {
00222 *y = (ap - a->bits) % a->h;
00223 *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift));
00224 return 1;
00225 }
00226 b_entry += b->h;
00227 }
00228 return 0;
00229 }
00230 }
00231 else
00232 {
00233 astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1;
00234 for (i=0;i<astripes;i++)
00235 {
00236 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00237 {
00238 if (*ap & *bp)
00239 {
00240 *y = (ap - a->bits) % a->h;
00241 *x = ((ap - a->bits) / a->h)*BITW_LEN + firstsetbit(*ap & *bp);
00242 return 1;
00243 }
00244 }
00245 a_entry += a->h;
00246 a_end += a->h;
00247 b_entry += b->h;
00248 }
00249 return 0;
00250 }
00251 }
00252 else
00253 {
00254 if (bitmask_overlap_pos(b,a,-xoffset,-yoffset,x,y))
00255 {
00256 *x += xoffset;
00257 *y += yoffset;
00258 return 1;
00259 }
00260 else
00261 return 0;
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270 static INLINE int bitcount(unsigned long n)
00271 {
00272 register unsigned long tmp;
00273 return (tmp = (n) - (((n) >> 1) & 033333333333) - (((n) >> 2) & 011111111111),\
00274 tmp = ((tmp + (tmp >> 3)) & 030707070707), \
00275 tmp = (tmp + (tmp >> 6)), \
00276 tmp = (tmp + (tmp >> 12) + (tmp >> 24)) & 077);
00277 }
00278
00279
00280
00281 int bitmask_overlap_area(const bitmask *a,const bitmask *b,int xoffset, int yoffset)
00282 {
00283 BITW *a_entry,*a_end;
00284 BITW *b_entry;
00285 BITW *ap,*bp;
00286 int shift,rshift,i,astripes,bstripes;
00287 int count = 0;
00288
00289 if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h))
00290 return 0;
00291
00292 if (xoffset >= 0)
00293 {
00294 if (yoffset >= 0)
00295 {
00296 a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset;
00297 a_end = a_entry + MIN(b->h,a->h - yoffset);
00298 b_entry = b->bits;
00299 }
00300 else
00301 {
00302 a_entry = a->bits + a->h*(xoffset/BITW_LEN);
00303 a_end = a_entry + MIN(b->h + yoffset,a->h);
00304 b_entry = b->bits - yoffset;
00305 }
00306 shift = xoffset & BITW_MASK;
00307 if (shift)
00308 {
00309 rshift = BITW_LEN - shift;
00310 astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN;
00311 bstripes = (b->w - 1)/BITW_LEN + 1;
00312 if (bstripes > astripes)
00313 {
00314 for (i=0;i<astripes;i++)
00315 {
00316 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00317 count += bitcount(((*ap >> shift) | (*(ap + a->h) << rshift)) & *bp);
00318 a_entry += a->h;
00319 a_end += a->h;
00320 b_entry += b->h;
00321 }
00322 for (ap = a_entry,bp = b_entry;ap < a_end;)
00323 count += bitcount((*ap++ >> shift) & *bp++);
00324 return count;
00325 }
00326 else
00327 {
00328 for (i=0;i<bstripes;i++)
00329 {
00330 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00331 count += bitcount(((*ap >> shift) | (*(ap + a->h) << rshift)) & *bp);
00332 a_entry += a->h;
00333 a_end += a->h;
00334 b_entry += b->h;
00335 }
00336 return count;
00337 }
00338 }
00339 else
00340 {
00341 astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1;
00342 for (i=0;i<astripes;i++)
00343 {
00344 for (ap = a_entry,bp = b_entry;ap < a_end;)
00345 count += bitcount(*ap++ & *bp++);
00346
00347 a_entry += a->h;
00348 a_end += a->h;
00349 b_entry += b->h;
00350 }
00351 return count;
00352 }
00353 }
00354 else
00355 return bitmask_overlap_area(b,a,-xoffset,-yoffset);
00356 }
00357
00358
00359
00360 void bitmask_draw(bitmask *a,bitmask *b,int xoffset, int yoffset)
00361 {
00362 BITW *a_entry,*a_end;
00363 BITW *b_entry;
00364 BITW *ap,*bp;
00365 bitmask *swap;
00366 int shift,rshift,i,astripes,bstripes;
00367
00368 if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h))
00369 return;
00370
00371 if (xoffset >= 0)
00372 {
00373 if (yoffset >= 0)
00374 {
00375 a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset;
00376 a_end = a_entry + MIN(b->h,a->h - yoffset);
00377 b_entry = b->bits;
00378 }
00379 else
00380 {
00381 a_entry = a->bits + a->h*(xoffset/BITW_LEN);
00382 a_end = a_entry + MIN(b->h + yoffset,a->h);
00383 b_entry = b->bits - yoffset;
00384 }
00385 shift = xoffset & BITW_MASK;
00386 if (shift)
00387 {
00388 rshift = BITW_LEN - shift;
00389 astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN;
00390 bstripes = (b->w - 1)/BITW_LEN + 1;
00391 if (bstripes > astripes)
00392 {
00393 for (i=0;i<astripes;i++)
00394 {
00395 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00396 *ap |= (*bp << shift);
00397 a_entry += a->h;
00398 a_end += a->h;
00399 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00400 *ap |= (*bp >> rshift);
00401 b_entry += b->h;
00402 }
00403 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00404 *ap |= (*bp << shift);
00405 return;
00406 }
00407 else
00408 {
00409 for (i=0;i<bstripes;i++)
00410 {
00411 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00412 *ap |= (*bp << shift);
00413 a_entry += a->h;
00414 a_end += a->h;
00415 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00416 *ap |= (*bp >> rshift);
00417 b_entry += b->h;
00418 }
00419 return;
00420 }
00421 }
00422 else
00423 {
00424 astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1;
00425 for (i=0;i<astripes;i++)
00426 {
00427 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00428 {
00429 *ap |= *bp;
00430 }
00431 a_entry += a->h;
00432 a_end += a->h;
00433 b_entry += b->h;
00434 }
00435 return;
00436 }
00437 }
00438 else
00439 {
00440
00441 swap = a;
00442 a = b;
00443 b = swap;
00444 xoffset *= -1;
00445 yoffset *= -1;
00446
00447 if (yoffset >= 0)
00448 {
00449 a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset;
00450 a_end = a_entry + MIN(b->h,a->h - yoffset);
00451 b_entry = b->bits;
00452 }
00453 else
00454 {
00455 a_entry = a->bits + a->h*(xoffset/BITW_LEN);
00456 a_end = a_entry + MIN(b->h + yoffset,a->h);
00457 b_entry = b->bits - yoffset;
00458 }
00459 shift = xoffset & BITW_MASK;
00460 if (shift)
00461 {
00462 rshift = BITW_LEN - shift;
00463 astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN;
00464 bstripes = (b->w - 1)/BITW_LEN + 1;
00465 if (bstripes > astripes)
00466 {
00467 for (i=0;i<astripes;i++)
00468 {
00469 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00470 *bp |= (*ap >> shift);
00471 a_entry += a->h;
00472 a_end += a->h;
00473 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00474 *bp |= (*ap <<rshift);
00475 b_entry += b->h;
00476 }
00477 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00478 *bp |= (*ap >> shift);
00479 return;
00480 }
00481 else
00482 {
00483 for (i=0;i<bstripes;i++)
00484 {
00485 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00486 *bp |= (*ap >> shift);
00487 a_entry += a->h;
00488 a_end += a->h;
00489 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00490 *bp |= (*ap << rshift);
00491 b_entry += b->h;
00492 }
00493 return;
00494 }
00495 }
00496 else
00497 {
00498 astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1;
00499 for (i=0;i<astripes;i++)
00500 {
00501 for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++)
00502 {
00503 *bp |= *ap;
00504 }
00505 a_entry += a->h;
00506 a_end += a->h;
00507 b_entry += b->h;
00508 }
00509 return;
00510 }
00511 }
00512 }