Plan 9 from Bell Labs’s /usr/web/sources/extra/mothra/floyd.c

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


#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <panel.h>
#include "mothra.h"
#define	NBIT	8		/* bits per uchar, a source of non-portability */
/*
 * Copy an 8 bit image into a newly allocated bitmap, using Floyd-Steinberg
 * if depth<8
 */
Image *floyd(Rectangle r, int depth, uchar *pixels){
	int wid=r.max.x-r.min.x;
	int hgt=r.max.y-r.min.y;
	int w=depth;
	int nval=1<<w;
	uchar lummap[1<<NBIT];
	uchar *data, *dp, *p;
	int *error, *ep, *eerror, cerror, y, value, shift, pv, i;
	Image *b;
	if(depth>8) depth=8;
	b=allocimage(display, r, w<8? CHAN1(CGrey, w) : CHAN1(CMap, 8), 0, DNofill);
	if(b==0) return 0;
	if(depth==8){
		loadimage(b, r, pixels, bytesperline(r, w)*Dy(r));
		return b;
	}
	data=malloc((wid*w+NBIT-1)/NBIT);
	error=malloc((wid+2)*sizeof(int));
	if(error==0 || data==0){
		if(error) free(error);
		if(data) free(data);
		freeimage(b);
		return 0;
	}
	eerror=error+wid+1;
	for(i=0,p=cmap;i!=1<<NBIT;i++,p+=3)
		lummap[i]=(p[0]*299+p[1]*587+p[2]*114)/1000;
	for(ep=error;ep<=eerror;ep++) *ep=0;
	p=pixels;
	for(y=0;y!=hgt;y++){
		cerror=0;
		dp=data-1;
		shift=0;
		for(ep=error+1;ep!=eerror;ep++){
			shift-=w;
			if(shift<0){
				shift+=NBIT;
				*++dp=0;
			}
			value=lummap[p[0]&255];
			value+=ep[0]/16;
			pv=value<=0?0:value<255?value*nval/256:nval-1;
			p++;
			*dp|=(nval-1-pv)<<shift;
			value-=pv*255/(nval-1);
			ep[1]+=value*7;
			ep[-1]+=value*3;
			ep[0]=cerror+value*5;
			cerror=value;
		}
		loadimage(b, Rect(r.min.x, y, r.max.x, y+1), data, wid);
	}
	free(error);
	free(data);
	return b;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.