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