Plan 9 from Bell Labs’s /usr/web/sources/contrib/maht/ppm2eps/ppm.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 <ctype.h>

#include "ppm.h"

int ppm_fd, red_fd, green_fd, blue_fd;
int magic, width, height, maxval;
float scalar;

enum
{
	/* Channel descriptors */
	CRGB	= 0,	/* three channels, no map */
	CYCbCr	= 1,	/* three channels, no map, level-shifted 601 color space */
	CY	= 2,	/* one channel, luminance */
	CRGB1	= 3,	/* one channel, map present */
	CRGBV	= 4,	/* one channel, map is RGBV, understood */
	CRGB24	= 5,	/* one channel in correct data order for loadimage(RGB24) */
	CRGBA32	= 6,	/* one channel in correct data order for loadimage(RGBA32) */
	CYA16	= 7,	/* one channel in correct data order for loadimage(Grey8+Alpha8) */
	CRGBVA16= 8,	/* one channel in correct data order for loadimage(CMAP8+Alpha8) */

	/* GIF flags */
	TRANSP	= 1,
	INPUT	= 2,
	DISPMASK = 7<<2
};

static int bitc, nbit;
/*
 * fetch a non-comment character.
 */
static
int
Bgetch(Biobufhdr *b)
{
	int c;

	for(;;) {
		c = Bgetc(b);
		if(c == '#') {
			while((c = Bgetc(b)) != Beof && c != '\n')
				;
		}
		return c;
	}		
}

/*
 * fetch a nonnegative decimal integer.
 */
static
int
Bgetint(Biobufhdr *b)
{
	int c;
	int i;

	while((c = Bgetch(b)) != Beof && !isdigit(c))
		;
	if(c == Beof)
		return -1;

	i = 0;
	do { 
		i = i*10 + (c-'0');
	} while((c = Bgetch(b)) != Beof && isdigit(c));

	return i;
}


static
int
Bgetdecimalbit(Biobufhdr *b)
{
	int c;
	while((c = Bgetch(b)) != Beof && c != '0' && c != '1')
		;
	if(c == Beof)
		return -1;
	return c == '1';
}

static
int
Bgetbit(Biobufhdr *b)
{
	if(nbit == 0) {
		nbit = 8;
		bitc = Bgetc(b);
		if(bitc == -1)
			return -1;
	}
	nbit--;
	return (bitc >> (nbit-1)) & 0x1;
}

static
void
Bflushbit(Biobufhdr*)
{
	nbit = 0;
}

typedef struct Pix	Pix;
struct Pix {
	char magic;
	int	maxcol;
	int	(*fetch)(Biobufhdr*);
	int	nchan;
	int	chandesc;
	int	invert;
	void	(*flush)(Biobufhdr*);
};
static Pix pix[] = {
	{ '1', 1, Bgetdecimalbit, 1, CY, 1, nil },	/* portable bitmap */
	{ '4', 1, Bgetbit, 1, CY, 1, Bflushbit },	/* raw portable bitmap */
	{ '2', 0, Bgetint, 1, CY, 0, nil },	/* portable greymap */
	{ '5', 0, Bgetc, 1, CY, 0, nil },	/* raw portable greymap */
	{ '3', 0, Bgetint, 3, CRGB, 0, nil },	/* portable pixmap */
	{ '6', 0, Bgetc, 3, CRGB, 0, nil },	/* raw portable pixmap */
	{ 0 },
};

RGBint *
free_rgb(RGBint *rgb) {
	if(rgb) {
		free(rgb->r);
		free(rgb->g);
		free(rgb->b);
	}
	return nil;
}

void
eightbit(RGBint *img) {
	int x,y, k;
	float f;

	if(img->maxcol == 255) return;

	float s = 255.0 / img->maxcol;

	k = 0;
	for(x = 0; x < img->width; x++)
	for(y = 0; y < img->height; y++) {
		f = s * (float) img->r[k];
		img->r[k] = (int) f;
		f = s * (float) img->g[k];
		img->g[k] = (int) f;
		f = s * (float) img->b[k];
		img->b[k] = (int) f;
		k++;
	}
}

RGBint * 
readppm(Biobuf *b)
{
	RGBint *rgb;
	int i, c;
	int (*fetch)(Biobufhdr*);
	Pix *p;
	int pixels;

	if(Bgetc(b) != 'P') {
		fprint(2, "Doubt it's a ppm");
		return nil;
	}

	c = Bgetc(b);

	for(p=pix; p->magic; p++)
		if(p->magic == c)
			break;
	if(p->magic == 0) {
		fprint(2, "Bad magic");
		return nil;
	}
		
	if(c != '3' && c != '6') {
		fprint(2, "sorry, RGB only");
		return nil;
	}

	rgb = (RGBint*)malloc(sizeof(RGBint));

	rgb->width = Bgetint(b);
	rgb->height = Bgetint(b);
	if(rgb->width <= 0 || rgb->height <= 0){
		fprint(2, "width or height < 0");
		free_rgb(rgb);
		return nil;
	}
	rgb->maxcol = p->maxcol;
	if(rgb->maxcol == 0) {
		rgb->maxcol = Bgetint(b);
		if(rgb->maxcol <= 0) {
			fprint(2, "rgb->maxcol <= 0");
			free_rgb(rgb);
			return nil;
		}
	}
	pixels = rgb->width * rgb->height;
	rgb->r = (int*)malloc(sizeof(int)*pixels);
	rgb->g = (int*)malloc(sizeof(int)*pixels);
	rgb->b = (int*)malloc(sizeof(int)*pixels);
	fetch = p->fetch;

	for(i=0; rgb && i < pixels; i++)
		if(((rgb->r[i] = (*fetch)(b)) < 0) || ((rgb->g[i] = (*fetch)(b)) < 0) || ((rgb->b[i] = (*fetch)(b)) < 0))
			rgb = free_rgb(rgb);

	return rgb;
}

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.