/* * jbgtopbm - JBIG to Portable Bitmap converter * * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/ * * $Id: jbgtopbm.c,v 1.11 2004-06-11 15:17:49+01 mgk25 Exp $ */ #include #include #include #include #include "jbig.h" double koeff = 1.0; void write_it(unsigned char *data, size_t len, void *file) { int bb; unsigned char cc; FILE *ff = (FILE *)file; for(size_t i = 0;i < len;i++) { bb = int(koeff * (*(data+i))); if(bb > 255) cc = 255; else cc = bb; fwrite(&cc, 1, 1, ff); fwrite(&cc, 1, 1, ff); fwrite(&cc, 1, 1, ff); } } int read_file(unsigned char **buf, size_t *buflen, size_t *len, FILE *f) { if (*buflen == 0) { *buflen = 4000; *len = 0; *buf = (unsigned char *) malloc(*buflen); if (!*buf) { fprintf(stderr, "Sorry, not enough memory available!\n"); return 0; } } do { *len += fread(*buf + *len, 1, *buflen - *len, f); if (*len == *buflen) { *buflen *= 2; *buf = (unsigned char *) realloc(*buf, *buflen); if (!*buf) { fprintf(stderr, "Sorry, not enough memory available!\n"); return 0; } } if (ferror(f)) { perror("Problem while reading input file"); return 0; } } while (!feof(f)); *buflen = *len; *buf = (unsigned char *) realloc(*buf, *buflen); if (!*buf) { fprintf(stderr, "Oops, realloc failed when shrinking buffer!\n"); return 0; } return 1; } int jbig2mem (char *argv[]) { FILE *fin = stdin, *fout = stdout; const char *fnin = NULL, *fnout = NULL; int i, result; struct jbg_dec_state s; unsigned char *buffer, *p; size_t buflen, len, cnt; unsigned long xmax = 4294967295UL, ymax = 4294967295UL, max; int plane = -1, use_graycode = 1, multi = 0; printf("+JBIG %s, %s\n", argv[0], argv[1]); buflen = 8000; buffer = (unsigned char *) malloc(buflen); if (!buffer) { return 1; } fnin = argv[0]; fnout = argv[1]; fin = fopen(fnin, "rb"); if (!fin) { free(buffer); return 1; } fout = fopen(fnout, "wb"); if (!fout) { fclose(fin); free(buffer); return 1; } /* send input file to decoder */ jbg_dec_init(&s); jbg_dec_maxsize(&s, xmax, ymax); /* read BIH first to check VLENGTH */ len = fread(buffer, 1, 20, fin); if(len < 20) { fclose(fin); fclose(fout); remove(fnout); return 1; } if (buffer[19] & JBG_VLENGTH) { /* VLENGTH = 1 => we might encounter a NEWLEN, therefore read entire * input file into memory and run two passes over it */ if(!read_file(&buffer, &buflen, &len, fin)) { fclose(fin); fclose(fout); remove(fnout); return 1; } /* scan for NEWLEN marker segments and update BIE header accordingly */ result = jbg_newlen(buffer, len); /* feed data to decoder */ if (result == JBG_EOK) { p = (unsigned char *) buffer; result = JBG_EAGAIN; while (len > 0 && (result == JBG_EAGAIN || (result == JBG_EOK && multi))) { result = jbg_dec_in(&s, p, len, &cnt); p += cnt; len -= cnt; } } } else { /* VLENGTH = 0 => we can simply pass the input file directly to decoder */ result = JBG_EAGAIN; do { cnt = 0; p = (unsigned char *) buffer; while (len > 0 && (result == JBG_EAGAIN || (result == JBG_EOK && multi))) { result = jbg_dec_in(&s, p, len, &cnt); p += cnt; len -= cnt; } if (!(result == JBG_EAGAIN || (result == JBG_EOK && multi))) break; len = fread(buffer, 1, buflen, fin); } while (len > 0); if (ferror(fin)) { fclose(fin); fclose(fout); remove(fnout); return 1; } } if (result != JBG_EOK && result != JBG_EOK_INTR) { fprintf(stderr, "Problem with input file '%s': %s\n", fnin, jbg_strerror(result, JBG_EN)); fclose(fout); remove(fnout); return 1; } if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) { fprintf(stderr, "Image has only %d planes!\n", jbg_dec_getplanes(&s)); fclose(fout); remove(fnout); return 1; } if (jbg_dec_getplanes(&s) == 1 || plane >= 0) { int w, h, bpp = 24; w = jbg_dec_getwidth(&s); h = jbg_dec_getheight(&s); fwrite(&w, sizeof(int), 1, fout); fwrite(&h, sizeof(int), 1, fout); fwrite(&bpp, sizeof(int), 1, fout); unsigned char *d = jbg_dec_getimage(&s, plane < 0 ? 0 : plane), bt; int G = 0, index; bool brk = false; unsigned char S1; for(int f = 0;f < h;f++) { for(int i = 0, g = 0;;g++) { bt = *(d + G); G++; for(int F = 256;F >= 2;F /= 2) { S1 = (unsigned char)(F / 2); index = (bt&S1) ? 0 : 255; fwrite(&index, 1, 1, fout); fwrite(&index, 1, 1, fout); fwrite(&index, 1, 1, fout); if(++i >= w) { brk = true; break; } } if(brk) { brk = false; break; } } } } else { /* write PGM output file */ if ((size_t) jbg_dec_getplanes(&s) > sizeof(unsigned long) * 8) { fprintf(stderr, "Image has too many planes (%d)!\n", jbg_dec_getplanes(&s)); fclose(fout); jbg_dec_free(&s); return 1; } max = 0; for (i = jbg_dec_getplanes(&s); i > 0; i--) max = (max << 1) | 1; int w, h, bpp = 24; w = jbg_dec_getwidth(&s); h = jbg_dec_getheight(&s); fwrite(&w, sizeof(int), 1, fout); fwrite(&h, sizeof(int), 1, fout); fwrite(&bpp, sizeof(int), 1, fout); koeff = 255.0 / max; jbg_dec_merge_planes(&s, use_graycode, write_it, fout); } /* check for file errors and close fout */ if (ferror(fout) || fclose(fout)) { fprintf(stderr, "Problem while writing output file '%s", fnout); perror("'"); jbg_dec_free(&s); return 1; } jbg_dec_free(&s); return 0; }