Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ncar!tank!nic.MR.NET!hal!ncoast!allbery From: rainbow@sbcs.sunysb.edu Newsgroups: comp.sources.misc Subject: v04i127: SUN raster file color to mono converter. Message-ID: <8810151959.AA25566@sbgrad1> Date: 22 Oct 88 01:16:40 GMT Sender: allbery@ncoast.UUCP Reply-To: rainbow@sbcs.sunysb.edu Lines: 939 Approved: allbery@ncoast.UUCP Posting-number: Volume 4, Issue 127 Submitted-by: "A. Nonymous" Archive-name: 8to1 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh Makefile <<'END_OF_Makefile' XBASE_DIR = $(PWD) XCFLAGS = -O XLIBS = -lpixrect X X X Xscload: 8to1 X $(CC) $(CFLAGS) -o scload scload.c $(LIBS) X X8to1: X $(CC) $(CFLAGS) -o 8to1 8to1.c $(LIBS) X X END_OF_Makefile if test 162 -ne `wc -c README <<'END_OF_README' X The program 8to1 converts a 8-bit depth sun raster file (both color, X i.e. rgb are different, and grey, i.e. rgb are the same, and both X standard format and byte-encoded format) to a 1-bit depth mono sun X raster file. If your color image has no colormap, this program would X provide a default grey scale color map. It implements several halftone X algorithms from Digital Halftones by Dot Diffusion in acm Transactions X on Graphics, such as error diffusion, ordered dither and dot diffusion X with and without edge enhancement. Just type 8to1, it will give you X the usage. X X The program "scload" is like Sun's "screenload" program, but more X entertaining, and actually better than screenload. It's written X by Raymond Kreisel, the author of Touchup. X X X The program 8to1 was written by : X X Hong Min X Computer Science Department X SUNY at Stony Brook X e-mail address : X UUCP: {allegra, philabs, pyramid, research}!sbcs!rainbow X ARPA-Internet: rainbow@sbcs.sunysb.edu X CSnet: rainbow@suny-sb X X Everyone is welcome to write to me if you like the program or not. X And welcome to optimize the code, as I haven't fooled with it to X make it efficient yet. X X Enjoy! X END_OF_README if test 1209 -ne `wc -c 8to1.c <<'END_OF_8to1.c' X/************************************************************************** X Copyright (c) 1988 by Hong Min X X compile : cc -O -o 8to1 8to1.c -lpixrect X X The program 8to1 converts a 8-bit depth sun raster file (both color, X i.e. rgb are different, and grey, i.e. rgb are the same, and both X standard format and byte-encoded format) to a 1-bit depth mono sun X raster file. If your color image has no colormap, this program would X provide a default grey scale color map. It implements several halftone X algorithms from Digital Halftones by Dot Diffusion in acm Transactions X on Graphics, such as error diffusion, ordered dither and dot diffusion X with and without edge enhancement. Just type 8to1, it will give you X the usage. X X This program was written by : X X Hong Min X Computer Science Department X SUNY at Stony Brook X e-mail address : X UUCP: {allegra, philabs, pyramid, research}!sbcs!rainbow X ARPA-Internet: rainbow@sbcs.sunysb.edu X CSnet: rainbow@suny-sb X X Everyone is welcome to write to me if you like the program or not. X And welcome to optimize the code, as I haven't fooled with it to X make it efficient yet. X X Enjoy! X X****************************************************************************/ X X X X#include X#include X#include X#include X#include X#include X#include X X#define ORDER 16 /* dither matrix order */ X#define WHITE 0 /* background color */ X#define BLACK ~0 /* foreground color */ X#define FALSE 0 X#define TRUE 1 X#define ALPHA 7 X#define BETA 3 X#define GAMMA 5 X#define DELTA 1 X Xshort **A, **B; Xint ordered_dither[8][8] = { 0, 32, 8, 40, 2, 34, 10, 42, X 48, 16, 56, 24, 50, 18, 58, 26, X 12, 44, 4, 36, 14, 46, 6, 38, X 60, 28, 52, 20, 62, 30, 54, 22, X 3, 35, 11, 43, 1, 33, 9, 41, X 51, 19, 59, 27, 49, 17, 57, 25, X 15, 47, 7, 39, 13, 45, 5, 37, X 63, 31, 55, 23, 61, 29, 53, 21 }; Xint dot_diffusion[8][8] = { 34, 48, 40, 32, 29, 15, 23, 31, X 42, 58, 56, 53, 21, 5, 7, 10, X 50, 62, 61, 45, 13, 1, 2, 18, X 38, 46, 54, 37, 25, 17, 9, 26, X 28, 14, 22, 30, 35, 49, 41, 33, X 20, 4, 6, 11, 43, 59, 57, 52, X 12, 0, 3, 19, 51, 63, 60, 44, X 24, 16, 8, 27, 39, 47, 55, 36 }; Xint reverse_matrix[64] = { 49, 21, 22, 50, 41, 13, 42, 14, X 58, 30, 15, 43, 48, 20, 33, 5, X 57, 29, 23, 51, 40, 12, 34, 6, X 56, 28, 31, 59, 32, 4, 35, 7, X 3, 39, 0, 36, 63, 27, 24, 60, X 2, 38, 8, 44, 55, 19, 25, 61, X 1, 37, 16, 52, 47, 11, 26, 62, X 10, 46, 9, 45, 54, 18, 17, 53 }; X X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ Xregister colormap_t colormap; Xregister unsigned char *map; Xregister struct rasterfile rh; Xregister Pixrect *pr = 0; Xregister int i, default_map = FALSE; Xint option; X X if ((argc > 4) || (argc < 2)) { X fprintf(stderr, "Usage: %s option [infile [outfile]]\n", argv[0]); X fprintf(stderr, "option : 0 -- error diffusion for grey scale\n"); X fprintf(stderr, " 1 -- ordered dither for grey scale\n"); X fprintf(stderr, " 2 -- dot diffusion for grey scale\n"); X fprintf(stderr, " 3 -- error diffusion for grey scale with edge enhancement\n"); X fprintf(stderr, " 4 -- ordered dither for grey scale with edge enhancement\n"); X fprintf(stderr, " 5 -- dot diffusion for grey scale with edge enhancement\n"); X fprintf(stderr, " 6 -- error diffusion for color\n"); X fprintf(stderr, " 7 -- ordered dither for color\n"); X fprintf(stderr, " 8 -- dot diffusion for color\n"); X fprintf(stderr, " 9 -- error diffusion for color with edge enhancement\n"); X fprintf(stderr, " 10 -- ordered dither for color with edge enhancement\n"); X fprintf(stderr, " 11 -- dot diffusion for color with edge enhancement\n"); X exit(1); X } X X sscanf(argv[1], "%d", &option); X X /* open the input file if specified */ X if ((argc > 2) && (freopen(argv[2], "r", stdin) == NULL)) { X fprintf(stderr, "can't open infile %s for read!\n", argv[2]); X exit(1); X } X X /* open the output file if specified */ X if ((argc > 3) && (freopen(argv[3], "w", stdout) == NULL)) { X fprintf(stderr, "can't open outfile %s for write!\n", argv[3]); X exit(1); X } X X /* Load the input rasterfile header */ X if (pr_load_header(stdin, &rh)) { X fprintf(stderr, "read rasterfile header error\n"); X exit(1); X } X X if (rh.ras_depth != 8) { X fprintf(stderr, "input file is not a 8 bits deep\n"); X exit(1); X } X X /* Load the colormap */ X colormap.type = RMT_NONE; X if (pr_load_colormap(stdin, &rh, &colormap)) { X fprintf(stderr, "read rasterfile header error\n"); X exit(1); X } X X if (colormap.type != RMT_NONE && X (colormap.type != RMT_EQUAL_RGB || colormap.length < 256)) { X fprintf(stderr,"input has unsupported colormap type or length\n"); X exit(1); X } X X if ((colormap.type == RMT_NONE) && (colormap.length == 0)) { X default_map = TRUE; X map = (unsigned char *) malloc(256); X for (i=0; i<256; i++) X map[i] = i; X } X X if (rh.ras_type != RT_OLD && rh.ras_type != RT_STANDARD && X !(pr = pr_load_image(stdin, &rh, &colormap))) { X fprintf(stderr, "error reading rasterfile\n"); X exit(1); X } X X /* Write new header */ X rh.ras_type = RT_STANDARD; X rh.ras_depth = 1; X rh.ras_length = mpr_linebytes(rh.ras_width, 1) * rh.ras_height; X rh.ras_maptype = RMT_NONE; X rh.ras_maplength = 0; X X if (pr_dump_header(stdout, &rh, (colormap_t *) 0) == PIX_ERR) { X fprintf(stderr, "error saving raster file header!\n"); X exit(1); X } X X if (rh.ras_width <= 0 || rh.ras_height <= 0) X exit(1); X else { X A = (short **) malloc((rh.ras_width+3)*sizeof(short *)); X B = (short **) malloc((rh.ras_width+3)*sizeof(short *)); X for(i=0; imd_image, stdout, X 0, mpr_d(pr)->md_linebytes - rh.ras_width); X break; X case 7 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 1 : ordered_dither_image(rh.ras_width, rh.ras_height, X map, (u_char *) mpr_d(pr)->md_image, stdout, X 0, mpr_d(pr)->md_linebytes - rh.ras_width); X break; X case 8 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 2 : dot_diffusion_image(rh.ras_width, rh.ras_height, X map, (u_char *) mpr_d(pr)->md_image, stdout, X 0, mpr_d(pr)->md_linebytes - rh.ras_width); X break; X case 9 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 3 : error_diffusion_image(rh.ras_width, rh.ras_height, X map, (u_char *) mpr_d(pr)->md_image, stdout, X 1, mpr_d(pr)->md_linebytes - rh.ras_width); X break; X case 10 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 4 : ordered_dither_image(rh.ras_width, rh.ras_height, X map, (u_char *) mpr_d(pr)->md_image, stdout, X 1, mpr_d(pr)->md_linebytes - rh.ras_width); X break; X case 11 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 5 : dot_diffusion_image(rh.ras_width, rh.ras_height, X map, (u_char *) mpr_d(pr)->md_image, stdout, X 1, mpr_d(pr)->md_linebytes - rh.ras_width); X break; X } X else X switch (option) { X case 6 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 0 : error_diffusion_file(rh.ras_width, rh.ras_height, X map, stdin, stdout, 0, X mpr_linebytes(rh.ras_width, 8) - rh.ras_width); X break; X case 7 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 1 : ordered_dither_file(rh.ras_width, rh.ras_height, X map, stdin, stdout, 0, X mpr_linebytes(rh.ras_width, 8) - rh.ras_width); X break; X case 8 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 2 : dot_diffusion_file(rh.ras_width, rh.ras_height, X map, stdin, stdout, 0, X mpr_linebytes(rh.ras_width, 8) - rh.ras_width); X break; X case 9 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 3 : error_diffusion_file(rh.ras_width, rh.ras_height, X map, stdin, stdout, 1, X mpr_linebytes(rh.ras_width, 8) - rh.ras_width); X break; X case 10 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 4 : ordered_dither_file(rh.ras_width, rh.ras_height, X map, stdin, stdout, 1, X mpr_linebytes(rh.ras_width, 8) - rh.ras_width); X break; X case 11 : map = (unsigned char *) malloc(256); X color_map_3_to_1(colormap, map); X case 5 : dot_diffusion_file(rh.ras_width, rh.ras_height, X map, stdin, stdout, 1, X mpr_linebytes(rh.ras_width, 8) - rh.ras_width); X break; X } X} X Xcolor_map_3_to_1(colormap, map) Xregister colormap_t colormap; Xregister unsigned char *map; X{ Xregister unsigned long tmp, i; X X for (i=0; i<256; i++) { X tmp = colormap.map[0][i]*77 + colormap.map[1][i]*151 + colormap.map[2][i]*28; X map[i] = tmp >> 8; X } X} X X Xedge_enhancement(width, height, off) Xregister int width, height, off; X{ Xregister int i, j, x, y; X X B[off][off] = A[off][off]*6 - A[off][off+1] - A[off+1][off] - A[off+1][off+1]; X B[off][off+height-1] = A[off][off+height-1]*6 - A[off][off+height-2] - A[off+1][off+height-1] - A[off+1][off+height-2]; X B[off+width-1][off] = A[off+width-1][off]*6 - A[off+width-1][off+1] - A[off+width-2][off] - A[off+width-2][off+1]; X B[off+width-1][off+height-1] = A[off+width-1][off+height-1]*6 - A[off+width-1][off+height-2] - A[off+width-2][off+height-1] - A[off+width-2][off+height-2]; X X for (i=1; i 128) X err = A[i][j] - 256; X else { X err = A[i][j]; X dtmp |= 1; X } X A[i+1][j] += (err*ALPHA) >> 4; X A[i-1][j+1] += (err*BETA) >> 4; X A[i][j+1] += (err*GAMMA) >> 4; X A[i+1][j+1] += (err*DELTA) >> 4; X if (((i-1) % 16) == 15) { X putc(dtmp >> 8, out); X putc(dtmp, out); X } X } X for(i=width+1; i<=width+mono_pad; i++) { X dtmp <<= 1; X if (((i-1) % 16) == 15) { X putc(dtmp >> 8, out); X putc(dtmp, out); X } X } X } X} X X/* Compute pixel values using error diffusion */ Xerror_diffusion_image(width, height, map, in, out, edge_enhance, pad) Xregister int width, height; Xregister unsigned char *map; Xregister u_char *in; Xregister FILE *out; Xregister int edge_enhance, pad; X{ Xregister int i, j; X X for(j=1; j= ordered_dither[i%8][j%8]) X dtmp |= 1; X if ((i % 16) == 15) { X putc(dtmp >> 8, out); X putc(dtmp, out); X } X } X for(i=width; i> 8, out); X putc(dtmp, out); X } X } X } X} X Xordered_dither_image(width, height, map, in, out, edge_enhance, pad) Xregister int width, height; Xregister unsigned char *map; Xregister u_char *in; Xregister FILE *out; Xregister int edge_enhance, pad; X{ Xregister int i, j; X X for(j=0; j 128) X B[i][j] = 0; X else X B[i][j] = 1; X err = A[i][j] - (1 - B[i][j])*256; X w = 0; X for(u=i-1; u<=i+1; u++) X for(v=j-1; v<=j+1; v++) X if ((u>=0) && (v>=0) && (dot_diffusion[u%8][v%8] > k)) X w += weight(u-i, v-j); X if (w > 0) { X for(u=i-1; u<=i+1; u++) X for(v=j-1; v<=j+1; v++) X if ((u>=0)&&(v>=0)&&(dot_diffusion[u%8][v%8]>k)) X A[u][v] += err * weight(u-i, v-j) / w; X } X } X } X X for(j=0; j> 8, out); X putc(dtmp, out); X } X } X for(i=width; i> 8, out); X putc(dtmp, out); X } X } X } X} X X Xdot_diffusion_image(width, height, map, in, out, edge_enhance, pad) Xregister int width, height; Xregister unsigned char *map; Xregister u_char *in; Xregister FILE *out; Xregister int edge_enhance, pad; X{ Xregister int i, j; X X for(j=0; jscload.c <<'END_OF_scload.c' X/* Compile: cc -g -o scload scload.c -lpixrect */ X X/************************************************************************** X The program "scload" is like Sun's "screenload" program, but more X entertaining, and actually better than screenload. X X Copyright (c) 1988 by Raymond Kreisel X 7/1/88 @ Suny Stony Brook X X This program may be redistributed without fee as long as this copyright X notice is intact. X X==> PLEASE send comments and bug reports to one of the following addresses: X X Ray Kreisel X CS Dept., SUNY at Stony Brook, Stony Brook NY 11794 X X UUCP: {allegra, philabs, pyramid, research}!sbcs!rayk X ARPA-Internet: rayk@sbcs.sunysb.edu X CSnet: rayk@suny-sb X (If nobody is home at any of the above addresses try: X S72QKRE@TOWSONVX.BITNET ) X X "If I get home before daylight, I just might get some sleep tonight...." X X**************************************************************************/ X#include X#include X#include X#include X#include X X Xint time_rand() X{ X struct tm *localtime(), *nowtime; X long inttime; X X inttime = time(); X nowtime = localtime(&inttime); X return((int)((nowtime->tm_sec))); X} X X Xmain(argc,argv) int argc; char *argv[]; X{ Xint i, my_fb = 0; Xchar *fb, *strcpy(); X X if (argc == 1) { X fprintf(stderr,"Usage: scload [-f frame_buffer] filename\n"); X exit(1); X } X X if ((argv[1][0] == '-') && (argv[1][1] == 'f')) { X if (argc < 4) { X fprintf(stderr,"Usage: scload [-f frame_buffer] filename\n"); X exit(1); X } X fb = strcpy((char *)malloc(strlen(argv[2])+1), argv[2]); X my_fb = 1; X } X else fb = strcpy((char *)malloc(8), "/dev/fb"); X if (argc) X { X for(i=1+my_fb*2;ipr_depth > 1) X { X sleep_time = 0; X if (pr_load_header(fp,&rh)) { X perror("scload: pr_load_header"); X exit(-1); X }; X if (pr_load_colormap(fp,&rh,&colormap)) { X perror("scload: pr_load_colormap"); X exit(-1); X }; X if (!(screen_temp=pr_load_image(fp,&rh,&colormap))) { X perror("scload: pr_load_image"); X exit(-1); X }; X if (colormap.length) X pr_putcolormap(screen,0,rh.ras_maplength/3,colormap.map[0], X colormap.map[1],colormap.map[2]); X X } X else X { X screen_temp = pr_load(fp,NULL); X if (!screen_temp) X { X fprintf(stderr,"Error reading rasterfile header.\n"); X exit(0); X } X } X width = screen_temp->pr_size.x; X height = screen_temp->pr_size.y; X if (screen->pr_size.x > screen_temp->pr_size.x) X off_x = (screen->pr_size.x - screen_temp->pr_size.x)/2; X if (screen->pr_size.y > screen_temp->pr_size.y) X off_y = (screen->pr_size.y - screen_temp->pr_size.y)/2; X X switch(rand()%8) { X case 0: X for (j=height-16; j > 0; j-=16) X { X pr_rop(screen,off_x,j+off_y,width,height-j,PIX_SRC,screen_temp,0,0); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X X break; X case 1: X X for (j=0; j < height; j+=32) X for (i=0; i < width; i+=32) X pr_rop(screen,i+off_x,j+off_y,16,16,PIX_SRC,screen_temp,i,j); X for (j=16; j < height; j+=32) X for (i=16; i < width; i+=32) X pr_rop(screen,i+off_x,j+off_y,16,16,PIX_SRC,screen_temp,i,j); X for (j=16; j < height; j+=32) X for (i=0; i < width; i+=32) X pr_rop(screen,i+off_x,j+off_y,16,16,PIX_SRC,screen_temp,i,j); X for (j=0; j < height; j+=32) X for (i=16; i < width; i+=32) X pr_rop(screen,i+off_x,j+off_y,16,16,PIX_SRC,screen_temp,i,j); X break; X X case 2: X for (j=height-16; j > 0; j-=16) X { X X pr_rop(screen,off_x,off_y,width,height-j,PIX_SRC,screen_temp,0,j); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X break; X X case 3: X for (j=height-16; j > 0; j-=16) X { X X pr_rop(screen,off_x,j+off_y,width/2,height-j,PIX_SRC,screen_temp,0,0); X pr_rop(screen,off_x+width/2,off_y,width/2,height-j,PIX_SRC,screen_temp,width/2,j); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X break; X case 4: X for (j=height-16; j > 0; j-=16) X { X X pr_rop(screen,off_x+width/2,j+off_y,width/2,height-j,PIX_SRC,screen_temp,width/2,0); X pr_rop(screen,off_x,off_y,width/2,height-j,PIX_SRC,screen_temp,0,j); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X break; X X case 5: X for (j=height-16; j > 0; j-=16) X { X X pr_rop(screen,off_x,off_y,width/4,height-j,PIX_SRC,screen_temp,0,j); X pr_rop(screen,off_x+width/4,j+off_y,width/4+2,height-j,PIX_SRC,screen_temp,width/4,0); X pr_rop(screen,off_x+width/4*3,j+off_y,width/4,height-j,PIX_SRC,screen_temp,width/4*3,0); X pr_rop(screen,off_x+width/2,off_y,width/4,height-j,PIX_SRC,screen_temp,width/2,j); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X break; X case 6: X for (j=height-16; j > 0; j-=16) X { X X pr_rop(screen,off_x,off_y,width/4,height-j,PIX_SRC,screen_temp,0,j); X pr_rop(screen,off_x+width/4,j+off_y,width/4,height-j,PIX_SRC,screen_temp,width/4,0); X pr_rop(screen,off_x+width/2,j+off_y,width/4,height-j,PIX_SRC,screen_temp,width/2,0); X pr_rop(screen,off_x+width/4*3,off_y,width/4,height-j,PIX_SRC,screen_temp,width/4*3,j); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X break; X X case 7: X for (j=16; j < width/2; j+=16) X { X X pr_rop(screen,off_x+width/2-j,off_y,j,height,PIX_SRC,screen_temp,0,0); X pr_rop(screen,off_x+width/2,off_y,j,height,PIX_SRC,screen_temp,width-j,0); X usleep(sleep_time); X } X pr_rop(screen,off_x,off_y,width,height,PIX_SRC,screen_temp,0,0); X break; X } X X pr_destroy(screen_temp); X pr_close(screen); X fclose(fp); X} X END_OF_scload.c if test 6462 -ne `wc -c