shithub: jbig2

ref: 0a396e48949d90a8cd1a91c685af09a165a1f5d9
dir: jbig2/jb2.c

View raw version
#include "config.h"
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_image.h"
#include "jbig2_image_rw.h"
#include <draw.h>
#include <memdraw.h>

static void
usage(void)
{
	fprint(2, "usage: %s [-p PAGE]\n", argv0);
	exits("usage");
}

void
main(int argc, char **argv)
{
	/* this header is inserted in case the input stream doesn't have one (when extracted from a PDF) */
	uchar header[] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x01 };
    int n, w, h, x, y, page;
	uchar *rgb, d[8192];
	Jbig2Image *j;
	Jbig2Ctx *ctx;
	Memimage *m;

	page = 0;
	ARGBEGIN{
	case 'p':
		page = atoi(EARGF(usage()));
		break;
	default:
		usage();
	}ARGEND

	if(argc != 0)
		usage();

	memimageinit();

	if((ctx = jbig2_ctx_new(nil, 0, nil, nil, nil)) == nil){
		werrstr("ctx_new");
		goto error;
	}
	for(x = 0;; x += n){
		if((n = read(0, d, sizeof(d))) == 0)
			break;
		if(n < 0)
			goto error;
		if(x == 0 && n >= 8 && memcmp(d, header, 8) != 0)
			jbig2_data_in(ctx, header, sizeof(header));
		if(jbig2_data_in(ctx, d, n) < 0){
			werrstr("data_in");
			goto error;
		}
	}
	if(jbig2_complete_page(ctx) < 0){
		werrstr("unable to complete page");
		goto error;
	}

	n = page;
	while((j = jbig2_page_out(ctx)) != nil){
		if(n > 1){
			n--;
			jbig2_release_page(ctx, j);
			continue;
		}

		w = j->width;
		h = j->height;
		if((rgb = malloc(j->stride*h)) == nil){
			werrstr("memory");
			goto error;
		}
		for(y = 0; y < h; y++){
			memmove(rgb+y*j->stride, j->data+y*j->stride, j->stride);
			for(x = 0; x < j->stride; x++)
				rgb[y*j->stride+x] = ~rgb[y*j->stride+x];
		}
		jbig2_release_page(ctx, j);

		if((m = allocmemimage(Rect(0,0,w,h), GREY1)) == nil){
			werrstr("memory");
			goto error;
		}
		loadmemimage(m, m->r, rgb, w*h);
		free(rgb);
		writememimage(1, m);
		freememimage(m);

		if(n == 1){
			n--;
			break;
		}
	}
	if(n > 0){
		werrstr("no page %d", page);
		goto error;
	}

	exits(nil);
error:
	fprint(2, "%r\n");
	exits("error");
}