Plan 9 from Bell Labs’s /usr/web/sources/contrib/quanstro/src/tiff/tiffexpand.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <bio.h>
#include <tiff.h>

static int
lg2(ulong i)
{
	int j;

	for(j = 0; (i >>= 1) != 0; j++)
		;
	return j;
}

static ulong
genmsk(ulong n)
{
	ulong i;

	for(i = 0; n; n--)
		i = i<<1 | 1;
	return i;
}

static int
expand(Tiff *t, ulong i, ulong o)
{
	uchar *p, *e, *s, *op;
	ulong scale, mask, bits, nbits, shift, r, rb;
	long l;
	int c;

	shift = lg2(o/i);
	l = tiffimglen(t)<<shift;
	s = malloc(l+4);
	if(!s)
		return -1;

	p = t->rawimg;
	e = t->rawimge;
	bits = 0;
	nbits = 0;
	r = 0;
	rb = 0;
	mask = genmsk(i);
	scale = genmsk(o)/mask;

	for(op = s; op < s+l; ){
		while(nbits < i){
			if(p >= e)
				sysfatal("p>e %uld %uld", (ulong)p, (ulong)e); //goto bad;
			c = *p++;
			bits = bits<<8|c;
			nbits += 8;
		}
		if(nbits<i)
			break;
		while(nbits >= i){
			nbits -= i;
			r = r<<o | ((bits>>nbits)&mask)*scale;
			rb += o;
			while(rb >= 8){
				rb -= 8;
				*op++ = (r>>rb)&0xff;
				r >>= 8;
			}
		}
		bits &= mask;	// delete used bits.
	}
	if(nbits != 0)
		goto bad;
	if(rb)
		*op = r&0xff;
	free(t->rawimg);
	t->rawimg = s;
	t->rawimge = s+l;
	return l;
bad:
	free(s);
	return -1;
}

static int
chanokay(int n)
{
	if(n==0 || (n>8 && n%8) || (n<8 && 8%n))
		return 0;
	return n;
}

static int
cdepthequal(Tiff *t){
	IFD *cdepth;
	int n, i;

	cdepth = lookifdptr(t, Tbitspersample);
	if(!cdepth)
		return 0;
	n = cdepth->sp[0];
	for(i = 1; i < cdepth->n; i++)
		if(cdepth->sp[i] != n)
			return 0;
	return n;
}

static int
setbitsps(Tiff *t, int o)
{
	IFD *i;
	int j;

	i = lookifdptr(t, Tbitspersample);
	if(!i)
		return -1;
	for(j = 0; j < i->n; j++)
		i->sp[j] = o;
	t->bpp = o*i->n;	
	return 0;
}

int
tiffexpand(Tiff *t)
{
	int n, m, i;

	if(chanokay(t->bpp))
		return 0;
	if((n = cdepthequal(t)) == 0)
		return -1;

	// number theory.
	for(i = 1; i < 5; i++)
		if(chanokay(3*(n+i)))
			break;
	if(i>5)
		return -1;
	m = n+i;
	if(expand(t, n, m) == -1)
		return -1;
	if(setbitsps(t, m))
		return -1;
	return 0;
}	


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].