bitmap.c revision 20253
120253Sjoerg/*-
220253Sjoerg * Copyright (c) 1996 by David L. Nugent <davidn@blaze.net.au>.
320253Sjoerg * All rights reserved.
420253Sjoerg *
520253Sjoerg * Redistribution and use in source and binary forms, with or without
620253Sjoerg * modification, are permitted provided that the following conditions
720253Sjoerg * are met:
820253Sjoerg * 1. Redistributions of source code must retain the above copyright
920253Sjoerg *    notice, this list of conditions and the following disclaimer as
1020253Sjoerg *    the first lines of this file unmodified.
1120253Sjoerg * 2. Redistributions in binary form must reproduce the above copyright
1220253Sjoerg *    notice, this list of conditions and the following disclaimer in the
1320253Sjoerg *    documentation and/or other materials provided with the distribution.
1420253Sjoerg * 3. All advertising materials mentioning features or use of this software
1520253Sjoerg *    must display the following acknowledgement:
1620253Sjoerg *	This product includes software developed by David L. Nugent.
1720253Sjoerg * 4. The name of the author may not be used to endorse or promote products
1820253Sjoerg *    derived from this software without specific prior written permission.
1920253Sjoerg *
2020253Sjoerg * THIS SOFTWARE IS PROVIDED BY THE DAVID L. NUGENT ``AS IS'' AND
2120253Sjoerg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2220253Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2320253Sjoerg * ARE DISCLAIMED.  IN NO EVENT SHALL DAVID L. NUGENT BE LIABLE
2420253Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2520253Sjoerg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2620253Sjoerg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2720253Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2820253Sjoerg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2920253Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3020253Sjoerg * SUCH DAMAGE.
3120253Sjoerg *
3220253Sjoerg *	$Id$
3320253Sjoerg */
3420253Sjoerg
3520253Sjoerg#include <stdlib.h>
3620253Sjoerg#include <string.h>
3720253Sjoerg
3820253Sjoerg#include "bitmap.h"
3920253Sjoerg
4020253Sjoergstruct bitmap
4120253Sjoergbm_alloc(int size)
4220253Sjoerg{
4320253Sjoerg	struct bitmap   bm;
4420253Sjoerg	int             szmap = (size / 8) + !!(size % 8);
4520253Sjoerg
4620253Sjoerg	bm.size = size;
4720253Sjoerg	bm.map = malloc(szmap);
4820253Sjoerg	if (bm.map)
4920253Sjoerg		memset(bm.map, 0, szmap);
5020253Sjoerg	return bm;
5120253Sjoerg}
5220253Sjoerg
5320253Sjoergvoid
5420253Sjoergbm_dealloc(struct bitmap * bm)
5520253Sjoerg{
5620253Sjoerg	if (bm->map)
5720253Sjoerg		free(bm->map);
5820253Sjoerg}
5920253Sjoerg
6020253Sjoergstatic void
6120253Sjoergbm_getmask(int *pos, unsigned char *bmask)
6220253Sjoerg{
6320253Sjoerg	*bmask = (unsigned char) (1 << (*pos % 8));
6420253Sjoerg	*pos /= 8;
6520253Sjoerg}
6620253Sjoerg
6720253Sjoergvoid
6820253Sjoergbm_setbit(struct bitmap * bm, int pos)
6920253Sjoerg{
7020253Sjoerg	unsigned char   bmask;
7120253Sjoerg
7220253Sjoerg	bm_getmask(&pos, &bmask);
7320253Sjoerg	bm->map[pos] |= bmask;
7420253Sjoerg}
7520253Sjoerg
7620253Sjoergvoid
7720253Sjoergbm_clrbit(struct bitmap * bm, int pos)
7820253Sjoerg{
7920253Sjoerg	unsigned char   bmask;
8020253Sjoerg
8120253Sjoerg	bm_getmask(&pos, &bmask);
8220253Sjoerg	bm->map[pos] &= ~bmask;
8320253Sjoerg}
8420253Sjoerg
8520253Sjoergint
8620253Sjoergbm_isset(struct bitmap * bm, int pos)
8720253Sjoerg{
8820253Sjoerg	unsigned char   bmask;
8920253Sjoerg
9020253Sjoerg	bm_getmask(&pos, &bmask);
9120253Sjoerg	return !!(bm->map[pos] & bmask);
9220253Sjoerg}
9320253Sjoerg
9420253Sjoergint
9520253Sjoergbm_firstunset(struct bitmap * bm)
9620253Sjoerg{
9720253Sjoerg	int             szmap = (bm->size / 8) + !!(bm->size % 8);
9820253Sjoerg	int             at = 0;
9920253Sjoerg	int             pos = 0;
10020253Sjoerg
10120253Sjoerg	while (pos < szmap) {
10220253Sjoerg		unsigned char   bmv = bm->map[pos++];
10320253Sjoerg		unsigned char   bmask = 1;
10420253Sjoerg
10520253Sjoerg		while (bmask & 0xff) {
10620253Sjoerg			if ((bmv & bmask) == 0)
10720253Sjoerg				return at;
10820253Sjoerg			bmask <<= 1;
10920253Sjoerg			++at;
11020253Sjoerg		}
11120253Sjoerg	}
11220253Sjoerg	return at;
11320253Sjoerg}
11420253Sjoerg
11520253Sjoergint
11620253Sjoergbm_lastset(struct bitmap * bm)
11720253Sjoerg{
11820253Sjoerg	int             szmap = (bm->size / 8) + !!(bm->size % 8);
11920253Sjoerg	int             at = 0;
12020253Sjoerg	int             pos = 0;
12120253Sjoerg	int             ofs = 0;
12220253Sjoerg
12320253Sjoerg	while (pos < szmap) {
12420253Sjoerg		unsigned char   bmv = bm->map[pos++];
12520253Sjoerg		unsigned char   bmask = 1;
12620253Sjoerg
12720253Sjoerg		while (bmask & 0xff) {
12820253Sjoerg			if ((bmv & bmask) != 0)
12920253Sjoerg				ofs = at;
13020253Sjoerg			bmask <<= 1;
13120253Sjoerg			++at;
13220253Sjoerg		}
13320253Sjoerg	}
13420253Sjoerg	return ofs;
13520253Sjoerg}
136