Blame tools/fax2tiff.c

Packit 7838c8
/* $Id: fax2tiff.c,v 1.28 2017-10-29 18:28:45 bfriesen Exp $ */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Copyright (c) 1990-1997 Sam Leffler
Packit 7838c8
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
Packit 7838c8
 *
Packit 7838c8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 7838c8
 * its documentation for any purpose is hereby granted without fee, provided
Packit 7838c8
 * that (i) the above copyright notices and this permission notice appear in
Packit 7838c8
 * all copies of the software and related documentation, and (ii) the names of
Packit 7838c8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 7838c8
 * publicity relating to the software without the specific, prior written
Packit 7838c8
 * permission of Sam Leffler and Silicon Graphics.
Packit 7838c8
 * 
Packit 7838c8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 7838c8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 7838c8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 7838c8
 * 
Packit 7838c8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 7838c8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 7838c8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 7838c8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 7838c8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 7838c8
 * OF THIS SOFTWARE.
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
/* 
Packit 7838c8
 * Convert a CCITT Group 3 or 4 FAX file to TIFF Group 3 or 4 format.
Packit 7838c8
 */
Packit 7838c8
#include "tif_config.h"
Packit 7838c8
Packit 7838c8
#include <stdio.h>
Packit 7838c8
#include <stdlib.h>		/* should have atof & getopt */
Packit 7838c8
Packit 7838c8
#ifdef HAVE_UNISTD_H
Packit 7838c8
# include <unistd.h>
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#ifdef HAVE_FCNTL_H
Packit 7838c8
# include <fcntl.h>
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#ifdef HAVE_IO_H
Packit 7838c8
# include <io.h>
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#ifdef NEED_LIBPORT
Packit 7838c8
# include "libport.h"
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#include "tiffiop.h"
Packit 7838c8
Packit 7838c8
#ifndef EXIT_SUCCESS
Packit 7838c8
# define EXIT_SUCCESS	0
Packit 7838c8
#endif
Packit 7838c8
#ifndef EXIT_FAILURE
Packit 7838c8
# define EXIT_FAILURE	1
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
Packit 7838c8
Packit 7838c8
TIFF	*faxTIFF;
Packit 7838c8
char	*rowbuf;
Packit 7838c8
char	*refbuf;
Packit 7838c8
Packit 7838c8
uint32	xsize = 1728;
Packit 7838c8
int	verbose;
Packit 7838c8
int	stretch;
Packit 7838c8
uint16	badfaxrun;
Packit 7838c8
uint32	badfaxlines;
Packit 7838c8
Packit 7838c8
int	copyFaxFile(TIFF* tifin, TIFF* tifout);
Packit 7838c8
static	void usage(void);
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
  Struct to carry client data.  Note that it does not appear that the client
Packit 7838c8
  data is actually used in this program.
Packit 7838c8
*/
Packit 7838c8
typedef struct _FAX_Client_Data
Packit 7838c8
{
Packit 7838c8
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
Packit 7838c8
        intptr_t fh; /* Operating system file handle */
Packit 7838c8
#else
Packit 7838c8
        int fd;      /* Integer file descriptor */
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
} FAX_Client_Data;
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
main(int argc, char* argv[])
Packit 7838c8
{
Packit 7838c8
	FILE *in;
Packit 7838c8
	TIFF *out = NULL;
Packit 7838c8
        FAX_Client_Data client_data;
Packit 7838c8
	TIFFErrorHandler whandler = NULL;
Packit 7838c8
	int compression_in = COMPRESSION_CCITTFAX3;
Packit 7838c8
	int compression_out = COMPRESSION_CCITTFAX3;
Packit 7838c8
	int fillorder_in = FILLORDER_LSB2MSB;
Packit 7838c8
	int fillorder_out = FILLORDER_LSB2MSB;
Packit 7838c8
	uint32 group3options_in = 0;	/* 1d-encoded */
Packit 7838c8
	uint32 group3options_out = 0;	/* 1d-encoded */
Packit 7838c8
	uint32 group4options_in = 0;	/* compressed */
Packit 7838c8
	uint32 group4options_out = 0;	/* compressed */
Packit 7838c8
	uint32 defrowsperstrip = (uint32) 0;
Packit 7838c8
	uint32 rowsperstrip;
Packit 7838c8
	int photometric_in = PHOTOMETRIC_MINISWHITE;
Packit 7838c8
	int photometric_out = PHOTOMETRIC_MINISWHITE;
Packit 7838c8
	int mode = FAXMODE_CLASSF;
Packit 7838c8
	int rows;
Packit 7838c8
	int c;
Packit 7838c8
	int pn, npages;
Packit 7838c8
	float resY = 196.0;
Packit 7838c8
Packit 7838c8
#if !HAVE_DECL_OPTARG
Packit 7838c8
	extern int optind;
Packit 7838c8
	extern char* optarg;
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
	while ((c = getopt(argc, argv, "R:X:o:r:1234ABLMPUW5678abcflmprsuvwz?")) != -1)
Packit 7838c8
		switch (c) {
Packit 7838c8
			/* input-related options */
Packit 7838c8
		case '3':		/* input is g3-encoded */
Packit 7838c8
			compression_in = COMPRESSION_CCITTFAX3;
Packit 7838c8
			break;
Packit 7838c8
		case '4':		/* input is g4-encoded */
Packit 7838c8
			compression_in = COMPRESSION_CCITTFAX4;
Packit 7838c8
			break;
Packit 7838c8
		case 'U':		/* input is uncompressed (g3 and g4) */
Packit 7838c8
			group3options_in |= GROUP3OPT_UNCOMPRESSED;
Packit 7838c8
			group4options_in |= GROUP4OPT_UNCOMPRESSED;
Packit 7838c8
			break;
Packit 7838c8
		case '1':		/* input is 1d-encoded (g3 only) */
Packit 7838c8
			group3options_in &= ~GROUP3OPT_2DENCODING;
Packit 7838c8
			break;
Packit 7838c8
		case '2':		/* input is 2d-encoded (g3 only) */
Packit 7838c8
			group3options_in |= GROUP3OPT_2DENCODING;
Packit 7838c8
			break;
Packit 7838c8
		case 'P':	/* input has not-aligned EOL (g3 only) */
Packit 7838c8
			group3options_in &= ~GROUP3OPT_FILLBITS;
Packit 7838c8
			break;
Packit 7838c8
		case 'A':		/* input has aligned EOL (g3 only) */
Packit 7838c8
			group3options_in |= GROUP3OPT_FILLBITS;
Packit 7838c8
			break;
Packit 7838c8
		case 'W':		/* input has 0 mean white */
Packit 7838c8
			photometric_in = PHOTOMETRIC_MINISWHITE;
Packit 7838c8
			break;
Packit 7838c8
		case 'B':		/* input has 0 mean black */
Packit 7838c8
			photometric_in = PHOTOMETRIC_MINISBLACK;
Packit 7838c8
			break;
Packit 7838c8
		case 'L':		/* input has lsb-to-msb fillorder */
Packit 7838c8
			fillorder_in = FILLORDER_LSB2MSB;
Packit 7838c8
			break;
Packit 7838c8
		case 'M':		/* input has msb-to-lsb fillorder */
Packit 7838c8
			fillorder_in = FILLORDER_MSB2LSB;
Packit 7838c8
			break;
Packit 7838c8
		case 'R':		/* input resolution */
Packit 7838c8
			resY = (float) atof(optarg);
Packit 7838c8
			break;
Packit 7838c8
		case 'X':		/* input width */
Packit 7838c8
			xsize = (uint32) atoi(optarg);
Packit 7838c8
			break;
Packit 7838c8
Packit 7838c8
			/* output-related options */
Packit 7838c8
		case '7':		/* generate g3-encoded output */
Packit 7838c8
			compression_out = COMPRESSION_CCITTFAX3;
Packit 7838c8
			break;
Packit 7838c8
		case '8':		/* generate g4-encoded output */
Packit 7838c8
			compression_out = COMPRESSION_CCITTFAX4;
Packit 7838c8
			break;
Packit 7838c8
		case 'u':	/* generate uncompressed output (g3 and g4) */
Packit 7838c8
			group3options_out |= GROUP3OPT_UNCOMPRESSED;
Packit 7838c8
			group4options_out |= GROUP4OPT_UNCOMPRESSED;
Packit 7838c8
			break;
Packit 7838c8
		case '5':	/* generate 1d-encoded output (g3 only) */
Packit 7838c8
			group3options_out &= ~GROUP3OPT_2DENCODING;
Packit 7838c8
			break;
Packit 7838c8
		case '6':	/* generate 2d-encoded output (g3 only) */
Packit 7838c8
			group3options_out |= GROUP3OPT_2DENCODING;
Packit 7838c8
			break;
Packit 7838c8
		case 'c':		/* generate "classic" g3 format */
Packit 7838c8
			mode = FAXMODE_CLASSIC;
Packit 7838c8
			break;
Packit 7838c8
		case 'f':		/* generate Class F format */
Packit 7838c8
			mode = FAXMODE_CLASSF;
Packit 7838c8
			break;
Packit 7838c8
		case 'm':		/* output's fillorder is msb-to-lsb */
Packit 7838c8
			fillorder_out = FILLORDER_MSB2LSB;
Packit 7838c8
			break;
Packit 7838c8
		case 'l':		/* output's fillorder is lsb-to-msb */
Packit 7838c8
			fillorder_out = FILLORDER_LSB2MSB;
Packit 7838c8
			break;
Packit 7838c8
		case 'o':
Packit 7838c8
			out = TIFFOpen(optarg, "w");
Packit 7838c8
			if (out == NULL) {
Packit 7838c8
				fprintf(stderr,
Packit 7838c8
				    "%s: Can not create or open %s\n",
Packit 7838c8
				    argv[0], optarg);
Packit 7838c8
				return EXIT_FAILURE;
Packit 7838c8
			}
Packit 7838c8
			break;
Packit 7838c8
		case 'a':	/* generate EOL-aligned output (g3 only) */
Packit 7838c8
			group3options_out |= GROUP3OPT_FILLBITS;
Packit 7838c8
			break;
Packit 7838c8
		case 'p':	/* generate not EOL-aligned output (g3 only) */
Packit 7838c8
			group3options_out &= ~GROUP3OPT_FILLBITS;
Packit 7838c8
			break;
Packit 7838c8
		case 'r':		/* rows/strip */
Packit 7838c8
			defrowsperstrip = atol(optarg);
Packit 7838c8
			break;
Packit 7838c8
		case 's':		/* stretch image by dup'ng scanlines */
Packit 7838c8
			stretch = 1;
Packit 7838c8
			break;
Packit 7838c8
		case 'w':		/* undocumented -- for testing */
Packit 7838c8
			photometric_out = PHOTOMETRIC_MINISWHITE;
Packit 7838c8
			break;
Packit 7838c8
		case 'b':		/* undocumented -- for testing */
Packit 7838c8
			photometric_out = PHOTOMETRIC_MINISBLACK;
Packit 7838c8
			break;
Packit 7838c8
		case 'z':		/* undocumented -- for testing */
Packit 7838c8
			compression_out = COMPRESSION_LZW;
Packit 7838c8
			break;
Packit 7838c8
		case 'v':		/* -v for info */
Packit 7838c8
			verbose++;
Packit 7838c8
			break;
Packit 7838c8
		case '?':
Packit 7838c8
			usage();
Packit 7838c8
			/*NOTREACHED*/
Packit 7838c8
		}
Packit 7838c8
	npages = argc - optind;
Packit 7838c8
	if (npages < 1)
Packit 7838c8
		usage();
Packit 7838c8
Packit 7838c8
	rowbuf = _TIFFmalloc(TIFFhowmany8(xsize));
Packit 7838c8
	refbuf = _TIFFmalloc(TIFFhowmany8(xsize));
Packit 7838c8
	if (rowbuf == NULL || refbuf == NULL) {
Packit 7838c8
		fprintf(stderr, "%s: Not enough memory\n", argv[0]);
Packit 7838c8
		return (EXIT_FAILURE);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	if (out == NULL) {
Packit 7838c8
		out = TIFFOpen("fax.tif", "w");
Packit 7838c8
		if (out == NULL) {
Packit 7838c8
			fprintf(stderr, "%s: Can not create fax.tif\n",
Packit 7838c8
			    argv[0]);
Packit 7838c8
			return (EXIT_FAILURE);
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
		
Packit 7838c8
	faxTIFF = TIFFClientOpen("(FakeInput)", "w",
Packit 7838c8
	/* TIFFClientOpen() fails if we don't set existing value here */
Packit 7838c8
				 TIFFClientdata(out),
Packit 7838c8
				 TIFFGetReadProc(out), TIFFGetWriteProc(out),
Packit 7838c8
				 TIFFGetSeekProc(out), TIFFGetCloseProc(out),
Packit 7838c8
				 TIFFGetSizeProc(out), TIFFGetMapFileProc(out),
Packit 7838c8
				 TIFFGetUnmapFileProc(out));
Packit 7838c8
	if (faxTIFF == NULL) {
Packit 7838c8
		fprintf(stderr, "%s: Can not create fake input file\n",
Packit 7838c8
		    argv[0]);
Packit 7838c8
		return (EXIT_FAILURE);
Packit 7838c8
	}
Packit 7838c8
	TIFFSetMode(faxTIFF, O_RDONLY);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH,	xsize);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL,	1);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE,	1);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_FILLORDER,	fillorder_in);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG,	PLANARCONFIG_CONTIG);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC,	photometric_in);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION,	resY);
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT,	RESUNIT_INCH);
Packit 7838c8
	
Packit 7838c8
	/* NB: this must be done after directory info is setup */
Packit 7838c8
	TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, compression_in);
Packit 7838c8
	if (compression_in == COMPRESSION_CCITTFAX3)
Packit 7838c8
		TIFFSetField(faxTIFF, TIFFTAG_GROUP3OPTIONS, group3options_in);
Packit 7838c8
	else if (compression_in == COMPRESSION_CCITTFAX4)
Packit 7838c8
		TIFFSetField(faxTIFF, TIFFTAG_GROUP4OPTIONS, group4options_in);
Packit 7838c8
	for (pn = 0; optind < argc; pn++, optind++) {
Packit 7838c8
		in = fopen(argv[optind], "rb");
Packit 7838c8
		if (in == NULL) {
Packit 7838c8
			fprintf(stderr,
Packit 7838c8
			    "%s: %s: Can not open\n", argv[0], argv[optind]);
Packit 7838c8
			continue;
Packit 7838c8
		}
Packit 7838c8
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
Packit 7838c8
                client_data.fh = _get_osfhandle(fileno(in));
Packit 7838c8
#else
Packit 7838c8
                client_data.fd = fileno(in);
Packit 7838c8
#endif
Packit 7838c8
                TIFFSetClientdata(faxTIFF, (thandle_t) &client_data);
Packit 7838c8
		TIFFSetFileName(faxTIFF, (const char*)argv[optind]);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_IMAGEWIDTH, xsize);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_COMPRESSION, compression_out);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric_out);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
Packit 7838c8
		switch (compression_out) {
Packit 7838c8
			/* g3 */
Packit 7838c8
			case COMPRESSION_CCITTFAX3:
Packit 7838c8
			TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
Packit 7838c8
				     group3options_out);
Packit 7838c8
			TIFFSetField(out, TIFFTAG_FAXMODE, mode);
Packit 7838c8
			rowsperstrip =
Packit 7838c8
				(defrowsperstrip)?defrowsperstrip:(uint32)-1L;
Packit 7838c8
			break;
Packit 7838c8
Packit 7838c8
			/* g4 */
Packit 7838c8
			case COMPRESSION_CCITTFAX4:
Packit 7838c8
			TIFFSetField(out, TIFFTAG_GROUP4OPTIONS,
Packit 7838c8
				     group4options_out);
Packit 7838c8
			TIFFSetField(out, TIFFTAG_FAXMODE, mode);
Packit 7838c8
			rowsperstrip =
Packit 7838c8
				(defrowsperstrip)?defrowsperstrip:(uint32)-1L;
Packit 7838c8
			break;
Packit 7838c8
Packit 7838c8
			default:
Packit 7838c8
			rowsperstrip = (defrowsperstrip) ?
Packit 7838c8
				defrowsperstrip : TIFFDefaultStripSize(out, 0);
Packit 7838c8
		}
Packit 7838c8
		TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_FILLORDER, fillorder_out);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_SOFTWARE, "fax2tiff");
Packit 7838c8
		TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0);
Packit 7838c8
		if (!stretch) {
Packit 7838c8
			TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY);
Packit 7838c8
			TIFFSetField(out, TIFFTAG_YRESOLUTION, resY);
Packit 7838c8
		} else
Packit 7838c8
			TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
Packit 7838c8
		TIFFSetField(out, TIFFTAG_PAGENUMBER, pn, npages);
Packit 7838c8
Packit 7838c8
		if (!verbose)
Packit 7838c8
		    whandler = TIFFSetWarningHandler(NULL);
Packit 7838c8
		rows = copyFaxFile(faxTIFF, out);
Packit 7838c8
		fclose(in);
Packit 7838c8
		if (!verbose)
Packit 7838c8
		    (void) TIFFSetWarningHandler(whandler);
Packit 7838c8
Packit 7838c8
		TIFFSetField(out, TIFFTAG_IMAGELENGTH, rows);
Packit 7838c8
Packit 7838c8
		if (verbose) {
Packit 7838c8
			fprintf(stderr, "%s:\n", argv[optind]);
Packit 7838c8
			fprintf(stderr, "%d rows in input\n", rows);
Packit 7838c8
			fprintf(stderr, "%ld total bad rows\n",
Packit 7838c8
			    (long) badfaxlines);
Packit 7838c8
			fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun);
Packit 7838c8
		}
Packit 7838c8
		if (compression_out == COMPRESSION_CCITTFAX3 &&
Packit 7838c8
		    mode == FAXMODE_CLASSF) {
Packit 7838c8
			TIFFSetField(out, TIFFTAG_BADFAXLINES, badfaxlines);
Packit 7838c8
			TIFFSetField(out, TIFFTAG_CLEANFAXDATA, badfaxlines ?
Packit 7838c8
			    CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN);
Packit 7838c8
			TIFFSetField(out, TIFFTAG_CONSECUTIVEBADFAXLINES, badfaxrun);
Packit 7838c8
		}
Packit 7838c8
		TIFFWriteDirectory(out);
Packit 7838c8
	}
Packit 7838c8
	TIFFClose(out);
Packit 7838c8
	_TIFFfree(rowbuf);
Packit 7838c8
	_TIFFfree(refbuf);
Packit 7838c8
	return (EXIT_SUCCESS);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
copyFaxFile(TIFF* tifin, TIFF* tifout)
Packit 7838c8
{
Packit 7838c8
	uint32 row;
Packit 7838c8
	uint32 linesize = TIFFhowmany8(xsize);
Packit 7838c8
	uint16 badrun;
Packit 7838c8
	int ok;
Packit 7838c8
Packit 7838c8
	tifin->tif_rawdatasize = (tmsize_t)TIFFGetFileSize(tifin);
Packit 7838c8
	if (tifin->tif_rawdatasize == 0) {
Packit 7838c8
		TIFFError(tifin->tif_name, "Empty input file");
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	tifin->tif_rawdata = _TIFFmalloc(tifin->tif_rawdatasize);
Packit 7838c8
	if (tifin->tif_rawdata == NULL) {
Packit 7838c8
		TIFFError(tifin->tif_name, "Not enough memory");
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	if (!ReadOK(tifin, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
Packit 7838c8
		TIFFError(tifin->tif_name, "Read error at scanline 0");
Packit 7838c8
		return (0);
Packit 7838c8
	}
Packit 7838c8
	tifin->tif_rawcp = tifin->tif_rawdata;
Packit 7838c8
	tifin->tif_rawcc = tifin->tif_rawdatasize;
Packit 7838c8
Packit 7838c8
	(*tifin->tif_setupdecode)(tifin);
Packit 7838c8
	(*tifin->tif_predecode)(tifin, (tsample_t) 0);
Packit 7838c8
	tifin->tif_row = 0;
Packit 7838c8
	badfaxlines = 0;
Packit 7838c8
	badfaxrun = 0;
Packit 7838c8
Packit 7838c8
	_TIFFmemset(refbuf, 0, linesize);
Packit 7838c8
	row = 0;
Packit 7838c8
	badrun = 0;		/* current run of bad lines */
Packit 7838c8
	while (tifin->tif_rawcc > 0) {
Packit 7838c8
		ok = (*tifin->tif_decoderow)(tifin, (tdata_t) rowbuf, 
Packit 7838c8
					     linesize, 0);
Packit 7838c8
		if (!ok) {
Packit 7838c8
			badfaxlines++;
Packit 7838c8
			badrun++;
Packit 7838c8
			/* regenerate line from previous good line */
Packit 7838c8
			_TIFFmemcpy(rowbuf, refbuf, linesize);
Packit 7838c8
		} else {
Packit 7838c8
			if (badrun > badfaxrun)
Packit 7838c8
				badfaxrun = badrun;
Packit 7838c8
			badrun = 0;
Packit 7838c8
			_TIFFmemcpy(refbuf, rowbuf, linesize);
Packit 7838c8
		}
Packit 7838c8
		tifin->tif_row++;
Packit 7838c8
Packit 7838c8
		if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
Packit 7838c8
			fprintf(stderr, "%s: Write error at row %ld.\n",
Packit 7838c8
			    tifout->tif_name, (long) row);
Packit 7838c8
			break;
Packit 7838c8
		}
Packit 7838c8
		row++;
Packit 7838c8
		if (stretch) {
Packit 7838c8
			if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
Packit 7838c8
				fprintf(stderr, "%s: Write error at row %ld.\n",
Packit 7838c8
				    tifout->tif_name, (long) row);
Packit 7838c8
				break;
Packit 7838c8
			}
Packit 7838c8
			row++;
Packit 7838c8
		}
Packit 7838c8
	}
Packit 7838c8
	if (badrun > badfaxrun)
Packit 7838c8
		badfaxrun = badrun;
Packit 7838c8
	_TIFFfree(tifin->tif_rawdata);
Packit 7838c8
	return (row);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
char* stuff[] = {
Packit 7838c8
"usage: fax2tiff [options] input.raw...",
Packit 7838c8
"where options are:",
Packit 7838c8
" -3		input data is G3-encoded		[default]",
Packit 7838c8
" -4		input data is G4-encoded",
Packit 7838c8
" -U		input data is uncompressed (G3 or G4)",
Packit 7838c8
" -1		input data is 1D-encoded (G3 only)	[default]",
Packit 7838c8
" -2		input data is 2D-encoded (G3 only)",
Packit 7838c8
" -P		input is not EOL-aligned (G3 only)	[default]",
Packit 7838c8
" -A		input is EOL-aligned (G3 only)",
Packit 7838c8
" -M		input data has MSB2LSB bit order",
Packit 7838c8
" -L		input data has LSB2MSB bit order	[default]",
Packit 7838c8
" -B		input data has min 0 means black",
Packit 7838c8
" -W		input data has min 0 means white	[default]",
Packit 7838c8
" -R #		input data has # resolution (lines/inch) [default is 196]",
Packit 7838c8
" -X #		input data has # width			[default is 1728]",
Packit 7838c8
"",
Packit 7838c8
" -o out.tif	write output to out.tif",
Packit 7838c8
" -7		generate G3-encoded output		[default]",
Packit 7838c8
" -8		generate G4-encoded output",
Packit 7838c8
" -u		generate uncompressed output (G3 or G4)",
Packit 7838c8
" -5		generate 1D-encoded output (G3 only)",
Packit 7838c8
" -6		generate 2D-encoded output (G3 only)	[default]",
Packit 7838c8
" -p		generate not EOL-aligned output (G3 only)",
Packit 7838c8
" -a		generate EOL-aligned output (G3 only)	[default]",
Packit 7838c8
" -c		generate \"classic\" TIFF format",
Packit 7838c8
" -f		generate TIFF Class F (TIFF/F) format	[default]",
Packit 7838c8
" -m		output fill order is MSB2LSB",
Packit 7838c8
" -l		output fill order is LSB2MSB		[default]",
Packit 7838c8
" -r #		make each strip have no more than # rows",
Packit 7838c8
" -s		stretch image by duplicating scanlines",
Packit 7838c8
" -v		print information about conversion work",
Packit 7838c8
" -z		generate LZW compressed output",
Packit 7838c8
NULL
Packit 7838c8
};
Packit 7838c8
Packit 7838c8
static void
Packit 7838c8
usage(void)
Packit 7838c8
{
Packit 7838c8
	char buf[BUFSIZ];
Packit 7838c8
	int i;
Packit 7838c8
Packit 7838c8
	setbuf(stderr, buf);
Packit 7838c8
        fprintf(stderr, "%s\n\n", TIFFGetVersion());
Packit 7838c8
	for (i = 0; stuff[i] != NULL; i++)
Packit 7838c8
		fprintf(stderr, "%s\n", stuff[i]);
Packit 7838c8
	exit(EXIT_FAILURE);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 8
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */