This is tiffdither.c in view mode; [Download] [Up]
#ifndef lint static char rcsid[] = "/mode/users/src/master/tiff/tools/tiffdither.c,v 1.1.1.1 1994/04/01 17:15:37 fedor Exp"; #endif /* * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler * Copyright (c) 1991, 1992 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include <stdio.h> #include "tiffio.h" typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned long u_long; #if defined(SYSV) || defined(THINK_C) || defined(applec) || defined(VMS) #define bzero(dst,len) memset(dst, 0, len) #endif #define CopyField(tag, v) \ if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) u_long imagewidth; u_long imagelength; int threshold = 128; usage() { fprintf(stderr, "usage: tiffdither [-f24op] [-t threshold] in.tif out.tif.\n"); exit(-1); } /* * Floyd-Steinberg error propragation with threshold. * This code is stolen from tiffmedian. */ static fsdither(in, out) TIFF *in, *out; { u_char *outline, *inputline, *inptr; short *thisline, *nextline, *tmpptr; register u_char *outptr; register short *thisptr, *nextptr; register long i, j; u_long imax, jmax; int lastline, lastpixel; int bit, outlinesize; imax = imagelength - 1; jmax = imagewidth - 1; inputline = (u_char *)malloc(TIFFScanlineSize(in)); thisline = (short *)malloc(imagewidth * sizeof (short)); nextline = (short *)malloc(imagewidth * sizeof (short)); outlinesize = TIFFScanlineSize(out); outline = (u_char *) malloc(outlinesize); /* * Get first line */ if (TIFFReadScanline(in, inputline, 0, 0) <= 0) return; inptr = inputline; nextptr = nextline; for (j = 0; j < imagewidth; ++j) *nextptr++ = *inptr++; for (i = 1; i < imagelength; ++i) { tmpptr = thisline; thisline = nextline; nextline = tmpptr; lastline = (i == imax); if (TIFFReadScanline(in, inputline, i, 0) <= 0) break; inptr = inputline; nextptr = nextline; for (j = 0; j < imagewidth; ++j) *nextptr++ = *inptr++; thisptr = thisline; nextptr = nextline; bzero(outptr = outline, outlinesize); bit = 0x80; for (j = 0; j < imagewidth; ++j) { register int v; lastpixel = (j == jmax); v = *thisptr++; if (v < 0) v = 0; else if (v > 255) v = 255; if (v > threshold) { *outptr |= bit; v -= 255; } bit >>= 1; if (bit == 0) { outptr++; bit = 0x80; } if (!lastpixel) thisptr[0] += v * 7 / 16; if (!lastline) { if (j != 0) nextptr[-1] += v * 3 / 16; *nextptr++ += v * 5 / 16; if (!lastpixel) nextptr[0] += v / 16; } } if (TIFFWriteScanline(out, outline, i-1, 0) < 0) break; } free(inputline); free(thisline); free(nextline); free(outline); } main(argc, argv) int argc; char *argv[]; { TIFF *in, *out; u_short samplesperpixel, bitspersample = 1, shortv, config; float floatv; char thing[1024]; long rowsperstrip; int c, compression = COMPRESSION_LZW; int onestrip = 0; int fillorder = FILLORDER_LSB2MSB; long group3options = GROUP3OPT_FILLBITS; extern int optind; extern char *optarg; while ((c = getopt(argc, argv, "t:f24ops")) != -1) switch (c) { case 't': threshold = atoi(optarg); if (threshold < 0) threshold = 0; else if (threshold > 255) threshold = 255; break; case 'f': /* CCITT Group 3 */ compression = COMPRESSION_CCITTFAX3; onestrip = 1; break; case '4': /* CCITT Group 4 */ compression = COMPRESSION_CCITTFAX4; onestrip = 1; break; case 'o': /* reverse bit ordering in output */ fillorder = FILLORDER_LSB2MSB; break; case '2': /* 2d-encoding */ group3options |= GROUP3OPT_2DENCODING; break; case 'p': /* zero pad scanlines before EOL */ group3options &= ~GROUP3OPT_FILLBITS; break; case '?': usage(); /*NOTREACHED*/ } if (argc - optind < 2) usage(); in = TIFFOpen(argv[optind], "r"); if (in == NULL) exit(-1); TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); if (samplesperpixel != 1) { fprintf(stderr, "%s: Not a b&w image.\n", argv[0]); exit(-1); } TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); if (bitspersample != 8) { fprintf(stderr, " %s: Sorry, only handle 8-bit samples.\n", argv[0]); exit(-1); } out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) exit(-1); CopyField(TIFFTAG_IMAGEWIDTH, imagewidth); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength); TIFFSetField(out, TIFFTAG_IMAGELENGTH, imagelength-1); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(out, TIFFTAG_COMPRESSION, compression); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); sprintf(thing, "Dithered B&W version of %s", argv[optind]); TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); CopyField(TIFFTAG_ORIENTATION, shortv); CopyField(TIFFTAG_XRESOLUTION, floatv); CopyField(TIFFTAG_YRESOLUTION, floatv); CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); if (onestrip) rowsperstrip = imagelength-1; else rowsperstrip = (8*1024)/TIFFScanlineSize(out); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip == 0 ? 1 : rowsperstrip); if (compression == COMPRESSION_CCITTFAX3 && group3options) TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options); fsdither(in, out); TIFFClose(in); TIFFClose(out); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.