shithub: imgtools

ref: d758f7428946545dd5760ece0da7cbbabbea1811
dir: imgtools/iconv.c

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>

static struct {
	char *name[2];
	ulong chan;
}chans[] = {
	{{"grey1", "k1"}, GREY1},
	{{"grey2", "k2"}, GREY2},
	{{"grey4", "k4"}, GREY4},
	{{"grey8", "k8"}, GREY8},
	{{"cmap8", "m8"}, CMAP8},
	{{"rgb15", "x1r5g5b5"}, RGB15},
	{{"rgb16", "r5g6b5"}, RGB16},
	{{"rgb24", "r8g8b8"}, RGB24},
	{{"rgba32", "r8g8b8a8"}, RGBA32},
	{{"argb32", "a8r8g8b8"}, ARGB32},
	{{"xrgb32", "x8r8g8b8"}, XRGB32},
	{{"bgr24", "b8g8r8"}, BGR24},
	{{"abgr32", "a8b8g8r8"}, ABGR32},
	{{"xbgr32", "x8b8g8r8"}, XBGR32},
};

static void
usage(void)
{
	fprint(2, "usage: %s [-c CHAN] [-r] [-u] [FILE]\n", argv0);
	exits("usage");
}

void
main(int argc, char **argv)
{
	int ci, raw, uncomp, fd;
	Memimage *a, *b;
	char *s;

	ci = -1;
	raw = 0;
	uncomp = 0;
	ARGBEGIN{
	case 'c':
		s = EARGF(usage());
		for(ci = 0;
		    ci < nelem(chans) &&
		    cistrcmp(chans[ci].name[0], s) != 0 &&
		    cistrcmp(chans[ci].name[1], s) != 0;
		    ci++)
		;
		if(ci >= nelem(chans)){
			fprint(2, "invalid chan %s\n", s);
			sysfatal("chan");
		}
		break;
	case 'r':
		raw = 1;
		break;
	case 'u':
		uncomp = 1;
		break;
	default:
		usage();
	}ARGEND

	fd = 0;
	if(argc == 1){
		if((fd = open(*argv, OREAD)) < 0)
			sysfatal("%r");
	}else if(argc != 0)
		usage();

	memimageinit();
	if((a = readmemimage(fd)) == nil)
		sysfatal("memory");
	if(ci >= 0 && a->chan != chans[ci].chan){
		if((b = allocmemimage(a->r, chans[ci].chan)) == nil)
			sysfatal("memory");
		memimagedraw(b, a->r, a, ZP, nil, ZP, S);
		freememimage(a);
		a = b;
	}
	if(raw || uncomp){
		char chan[32];
		int bpl, y, n;
		uchar *b;

		if(!raw){
			if(chantostr(chan, a->chan) == nil)
				sysfatal("chantostr: %r");
			fprint(1, "%11s %11d %11d %11d %11d ", chan, a->r.min.x, a->r.min.y, a->r.max.x, a->r.max.y);
		}

		bpl = bytesperline(a->r, a->depth);
		b = malloc(bpl);
		if(b == nil)
			sysfatal("memory");
		for(y = a->r.min.y; y < a->r.max.y; y++){
			n = unloadmemimage(a, Rect(a->r.min.x, y, a->r.max.x, y+1), b, bpl);
			if(n != bpl)
				sysfatal("unload: %r");
			if(write(1, b, bpl) != bpl)
				sysfatal("%r");
		}
	}else{
		writememimage(1, a);
	}

	exits(nil);
}