home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 5
/
FreshFish_July-August1994.bin
/
bbs
/
gnu
/
gs-2.6.1.4-src.lha
/
src
/
amiga
/
gs-2.6.1.4
/
gdevtiff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-27
|
27KB
|
770 lines
/* $Header: /usr/people/sam/fax/gs/RCS/gdevtiff.c,v 1.3 93/03/20 11:44:02 sam Exp $ */
/*
* Copyright (c) 1992, 1993 Sam Leffler
* Copyright (c) 1992, 1993 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.
*/
/*
* 5/19/93 modified by L. Peter Deutsch, Aladdin Enterprises,
* for compatibility with Ghostscript 2.6.1.
*/
/* gdevtiff.c */
#include "gdevprn.h"
#include "gdevdfg3.h"
#include "gdevtiff.h"
#ifdef __PROTOTYPES__
# define PROTO_ARGS(X) X
#else
# define PROTO_ARGS(X) ()
#endif
/*
* TIFF fax output driver.
*/
typedef struct {
FILE* fp;
long prevdir; /* file offset of previous directory offset */
long diroff; /* file offset of next write */
int bigendian; /* 1 if machine is big-endian, 0 otherwise */
unsigned long iwidth; /* width of image data in pixels */
int fax_byte;
int fax_weight;
} TIFFOUT;
private void faxout_open_fp PROTO_ARGS((FILE *, TIFFOUT*));
private int faxout_begin_page PROTO_ARGS((TIFFOUT*, gx_device_printer*));
private int faxout_eolcode PROTO_ARGS((TIFFOUT *));
private int faxout_end_page PROTO_ARGS((TIFFOUT *));
private void tofax PROTO_ARGS((TIFFOUT*, unsigned char*));
private void putwhitespan();
private void putblackspan();
private void putcode();
private void puteol();
private void putbit();
private void flushbits();
/*
* Redefine the device descriptor.
*/
struct gx_device_tiff_s {
gx_device_common;
gx_prn_device_common;
TIFFOUT fax;
};
typedef struct gx_device_tiff_s gx_device_tiff;
/* The device descriptor */
#define X_DPI 204
#define Y_DPI 196
#define LINE_SIZE ((X_DPI * 101 / 10 + 7) / 8) /* bytes per line */
private dev_proc_open_device(tiff_prn_open);
private dev_proc_print_page(tiff_print_page);
private dev_proc_close_device(tiff_prn_close);
gx_device_procs tiff_std_procs =
prn_procs(tiff_prn_open, gdev_prn_output_page, tiff_prn_close);
gx_device_tiff far_data gs_tiffg3_device =
{ prn_device_std_body(
gx_device_tiff,
tiff_std_procs,
"tiffg3",
85, /* width_10ths, 8.5" */
110, /* height_10ths, 11" */
X_DPI, Y_DPI,
0,0,0,0, /* margins */
1,
tiff_print_page
)
};
static struct pageinfo {
short w, h; /* page width and height in 10ths */
unsigned long iw; /* image width */
} pageinfo[] = {
#define PAPER_SIZE_LETTER 0
{ 85, 110, 1728 },
#define PAPER_SIZE_A4 1
{ 85, 117, 1728 },
#define PAPER_SIZE_B4 2
{ 101, 143, 2048 }
};
#define NPAGEINFO (sizeof (pageinfo) / sizeof (pageinfo[0]))
/* Get the paper size code, based on width and height. */
static int
papersize(gx_device *dev)
{
return
(dev->height / dev->y_pixels_per_inch >= 11.8 ? PAPER_SIZE_B4 :
dev->height / dev->y_pixels_per_inch >= 11.1 ? PAPER_SIZE_A4 :
PAPER_SIZE_LETTER);
}
/*
* Driver entry points.
*/
/*
* Setup device according to output page.
*/
private int
tiff_prn_open(gx_device *pdev)
{
struct pageinfo* pi = &pageinfo[papersize(pdev)];
int rc;
pdev->width = (int)((pi->w * pdev->x_pixels_per_inch) / 10);
pdev->height = (int)((pi->h * pdev->y_pixels_per_inch) / 10);
rc = gdev_prn_open(pdev);
if (rc == 0) {
gx_device_tiff* ddev = (gx_device_tiff*) pdev;
faxout_open_fp(ddev->file, &ddev->fax);
ddev->fax.iwidth = pi->iw;
}
return (rc);
}
private int
tiff_print_page(gx_device_printer *pdev, FILE *prn_stream)
{
gx_device_tiff* ddev = (gx_device_tiff*) pdev;
unsigned char data[LINE_SIZE + 4];
int lnum, line_size;
TIFFOUT* fax = &ddev->fax;
/* For some odd reason, the file isn't open until now */
fax->fp = prn_stream;
faxout_begin_page(fax, pdev);
line_size = gdev_mem_bytes_per_scan_line((gx_device*)pdev);
for (lnum = 0; lnum < pdev->height; lnum++) {
gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size);
tofax(fax, data);
}
faxout_end_page(fax);
return (0);
}
private int
tiff_prn_close(gx_device *pdev)
{
gx_device_tiff* ddev = (gx_device_tiff*) pdev;
TIFFOUT* fax = &ddev->fax;
if (fax->fp)
fflush(fax->fp);
return (gdev_prn_close(pdev));
}
/*
* Internal routines.
*/
private void
faxout_open_fp(FILE *fp, register TIFFOUT* faxp)
{
faxp->fp = fp;
faxp->diroff = 0L;
faxp->prevdir = 0L;
faxp->bigendian = arch_is_big_endian;
faxp->fax_byte = 0;
faxp->fax_weight = 0x80;
}
/* NB: this array is sorted by tag number (assumed below) */
typedef struct {
TIFFDirEntry subfiletype;
TIFFDirEntry imagewidth;
TIFFDirEntry imagelength;
TIFFDirEntry bitspersample;
TIFFDirEntry compression;
TIFFDirEntry photometric;
TIFFDirEntry fillorder;
#ifdef notdef
TIFFDirEntry documentname;
#endif
TIFFDirEntry stripoffsets;
TIFFDirEntry orientation;
TIFFDirEntry samplesperpixel;
TIFFDirEntry rowsperstrip;
TIFFDirEntry stripbytecounts;
TIFFDirEntry xresolution;
TIFFDirEntry yresolution;
TIFFDirEntry planarconfig;
TIFFDirEntry group3options;
TIFFDirEntry resolutionunit;
#ifdef notdef
TIFFDirEntry software;
#endif
TIFFDirEntry cleanfaxdata;
unsigned long diroff; /* offset to next directory */
unsigned long xresValue[2]; /* xresolution indirect value */
unsigned long yresValue[2]; /* yresolution indirect value */
} TIFFDirectory;
private TIFFDirectory dirTemplate = {
{ TIFFTAG_SUBFILETYPE, TIFF_LONG, 1, FILETYPE_PAGE },
{ TIFFTAG_IMAGEWIDTH, TIFF_LONG, 1 },
{ TIFFTAG_IMAGELENGTH, TIFF_LONG, 1 },
{ TIFFTAG_BITSPERSAMPLE, TIFF_SHORT, 1, 1 },
{ TIFFTAG_COMPRESSION, TIFF_SHORT, 1, COMPRESSION_CCITTFAX3 },
{ TIFFTAG_PHOTOMETRIC, TIFF_SHORT, 1, PHOTOMETRIC_MINISWHITE },
{ TIFFTAG_FILLORDER, TIFF_SHORT, 1, FILLORDER_MSB2LSB },
#ifdef notdef
{ TIFFTAG_DOCUMENTNAME, TIFF_ASCII, 1 },
#endif
{ TIFFTAG_STRIPOFFSETS, TIFF_LONG, 1 },
{ TIFFTAG_ORIENTATION, TIFF_SHORT, 1, ORIENTATION_TOPLEFT },
{ TIFFTAG_SAMPLESPERPIXEL, TIFF_SHORT, 1, 1 },
{ TIFFTAG_ROWSPERSTRIP, TIFF_LONG, 1, -1L },
{ TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG, 1, 1 },
{ TIFFTAG_XRESOLUTION, TIFF_RATIONAL, 1 },
{ TIFFTAG_YRESOLUTION, TIFF_RATIONAL, 1 },
{ TIFFTAG_PLANARCONFIG, TIFF_SHORT, 1, PLANARCONFIG_CONTIG },
{ TIFFTAG_GROUP3OPTIONS, TIFF_LONG, 1 },
{ TIFFTAG_RESOLUTIONUNIT, TIFF_SHORT, 1, RESUNIT_INCH },
#ifdef notdef
{ TIFFTAG_SOFTWARE, TIFF_ASCII, 1 },
#endif
{ TIFFTAG_CLEANFAXDATA, TIFF_SHORT, 1, CLEANFAXDATA_CLEAN },
0, { 0, 1 }, { 0, 1 },
};
#define OFFSET(x) ((unsigned)&(((TIFFDirectory*)0)->x))
#define NTAGS (OFFSET(diroff) / sizeof (TIFFDirEntry))
/* correct tag values on bigendian machines */
private void
faxout_fixuptags(TIFFDirEntry* dp, int n)
{
while (n-- > 0) {
if (dp->tdir_type == TIFF_SHORT || dp->tdir_type == TIFF_SSHORT)
dp->tdir_offset <<= 16;
else if (dp->tdir_type == TIFF_BYTE || dp->tdir_type == TIFF_SBYTE)
dp->tdir_offset <<= 24;
dp++;
}
}
private int
faxout_begin_page(TIFFOUT *faxp, gx_device_printer* pdev)
{
gx_device_tiff* ddev = (gx_device_tiff*) pdev;
short dircount;
TIFFDirectory dir;
/*
* Writing the header is delayed t