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 >
C/C++ Source or Header  |  1994-01-27  |  27KB  |  770 lines

  1. /* $Header: /usr/people/sam/fax/gs/RCS/gdevtiff.c,v 1.3 93/03/20 11:44:02 sam Exp $ */
  2.  
  3. /*
  4.  * Copyright (c) 1992, 1993 Sam Leffler
  5.  * Copyright (c) 1992, 1993 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. /*
  27.  * 5/19/93 modified by L. Peter Deutsch, Aladdin Enterprises,
  28.  *   for compatibility with Ghostscript 2.6.1.
  29.  */
  30. /* gdevtiff.c */
  31.  
  32. #include "gdevprn.h"
  33. #include "gdevdfg3.h"
  34. #include "gdevtiff.h"
  35.  
  36. #ifdef __PROTOTYPES__
  37. #    define PROTO_ARGS(X)    X
  38. #else
  39. #    define PROTO_ARGS(X)    ()
  40. #endif
  41.  
  42. /*
  43.  * TIFF fax output driver.
  44.  */
  45. typedef struct {
  46.     FILE*    fp;
  47.     long    prevdir;    /* file offset of previous directory offset */
  48.     long    diroff;        /* file offset of next write */
  49.     int        bigendian;    /* 1 if machine is big-endian, 0 otherwise */
  50.     unsigned long iwidth;    /* width of image data in pixels */
  51.     int        fax_byte;
  52.     int        fax_weight;
  53. } TIFFOUT;
  54.  
  55. private void    faxout_open_fp PROTO_ARGS((FILE *, TIFFOUT*));
  56. private int    faxout_begin_page PROTO_ARGS((TIFFOUT*, gx_device_printer*));
  57. private int    faxout_eolcode PROTO_ARGS((TIFFOUT *));
  58. private int    faxout_end_page PROTO_ARGS((TIFFOUT *));
  59. private void    tofax PROTO_ARGS((TIFFOUT*, unsigned char*));
  60.  
  61. private void putwhitespan();
  62. private void putblackspan();
  63. private void putcode();
  64. private void puteol();
  65. private void putbit();
  66. private void flushbits();
  67.  
  68. /*
  69.  * Redefine the device descriptor.
  70.  */
  71. struct gx_device_tiff_s {
  72.     gx_device_common;
  73.     gx_prn_device_common;
  74.     TIFFOUT    fax;
  75. };
  76. typedef struct gx_device_tiff_s gx_device_tiff;
  77.  
  78. /* The device descriptor */
  79. #define X_DPI 204
  80. #define Y_DPI 196
  81. #define LINE_SIZE ((X_DPI * 101 / 10 + 7) / 8)    /* bytes per line */
  82.  
  83. private dev_proc_open_device(tiff_prn_open);
  84. private dev_proc_print_page(tiff_print_page);
  85. private dev_proc_close_device(tiff_prn_close);
  86.  
  87. gx_device_procs tiff_std_procs =
  88.     prn_procs(tiff_prn_open, gdev_prn_output_page, tiff_prn_close);
  89.  
  90. gx_device_tiff far_data gs_tiffg3_device =
  91. {   prn_device_std_body(
  92.     gx_device_tiff,
  93.     tiff_std_procs,
  94.     "tiffg3",
  95.     85,            /* width_10ths, 8.5" */
  96.     110,            /* height_10ths, 11" */
  97.     X_DPI, Y_DPI,
  98.     0,0,0,0,        /* margins */
  99.     1,
  100.     tiff_print_page
  101.     )
  102. };
  103.  
  104.  
  105. static struct pageinfo {
  106.     short w, h;            /* page width and height in 10ths */
  107.     unsigned long iw;        /* image width */
  108. } pageinfo[] = {
  109. #define    PAPER_SIZE_LETTER    0
  110.     { 85,  110, 1728 },
  111. #define    PAPER_SIZE_A4        1
  112.     { 85,  117, 1728 },
  113. #define    PAPER_SIZE_B4        2
  114.     { 101, 143, 2048 }
  115. };
  116. #define    NPAGEINFO (sizeof (pageinfo) / sizeof (pageinfo[0]))
  117.  
  118. /* Get the paper size code, based on width and height. */
  119. static int
  120. papersize(gx_device *dev)
  121. {
  122.     return
  123.       (dev->height / dev->y_pixels_per_inch >= 11.8 ? PAPER_SIZE_B4 :
  124.        dev->height / dev->y_pixels_per_inch >= 11.1 ? PAPER_SIZE_A4 :
  125.        PAPER_SIZE_LETTER);
  126. }
  127.  
  128. /*
  129.  * Driver entry points.
  130.  */
  131.  
  132. /*
  133.  * Setup device according to output page.
  134.  */
  135. private int
  136. tiff_prn_open(gx_device *pdev)
  137. {
  138.     struct pageinfo* pi = &pageinfo[papersize(pdev)];
  139.     int    rc;
  140.  
  141.     pdev->width = (int)((pi->w * pdev->x_pixels_per_inch) / 10);
  142.     pdev->height = (int)((pi->h * pdev->y_pixels_per_inch) / 10);
  143.     rc = gdev_prn_open(pdev);
  144.     if (rc == 0) {
  145.     gx_device_tiff* ddev = (gx_device_tiff*) pdev;
  146.     faxout_open_fp(ddev->file, &ddev->fax);
  147.     ddev->fax.iwidth = pi->iw;
  148.     }
  149.     return (rc);
  150. }
  151.  
  152. private int
  153. tiff_print_page(gx_device_printer *pdev, FILE *prn_stream)
  154. {
  155.     gx_device_tiff* ddev = (gx_device_tiff*) pdev;
  156.     unsigned char data[LINE_SIZE + 4];
  157.     int    lnum, line_size;
  158.     TIFFOUT* fax = &ddev->fax;
  159.  
  160.     /* For some odd reason, the file isn't open until now */
  161.     fax->fp = prn_stream;    
  162.     faxout_begin_page(fax, pdev);
  163.     line_size = gdev_mem_bytes_per_scan_line((gx_device*)pdev);
  164.     for (lnum = 0; lnum < pdev->height; lnum++) {
  165.     gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size);
  166.     tofax(fax, data);
  167.     }
  168.     faxout_end_page(fax);
  169.     return (0);
  170. }
  171.  
  172. private int
  173. tiff_prn_close(gx_device *pdev)
  174. {
  175.     gx_device_tiff* ddev = (gx_device_tiff*) pdev;
  176.     TIFFOUT* fax = &ddev->fax;
  177.  
  178.     if (fax->fp)
  179.     fflush(fax->fp);
  180.     return (gdev_prn_close(pdev));
  181. }
  182.  
  183. /*
  184.  * Internal routines.
  185.  */
  186. private void
  187. faxout_open_fp(FILE *fp, register TIFFOUT* faxp)
  188. {
  189.     faxp->fp = fp;
  190.     faxp->diroff = 0L;
  191.     faxp->prevdir = 0L;
  192.     faxp->bigendian = arch_is_big_endian;
  193.     faxp->fax_byte = 0;
  194.     faxp->fax_weight = 0x80;
  195. }
  196.  
  197. /* NB: this array is sorted by tag number (assumed below) */
  198. typedef struct {
  199.     TIFFDirEntry    subfiletype;
  200.     TIFFDirEntry    imagewidth;
  201.     TIFFDirEntry    imagelength;
  202.     TIFFDirEntry    bitspersample;
  203.     TIFFDirEntry    compression;
  204.     TIFFDirEntry    photometric;
  205.     TIFFDirEntry    fillorder;
  206. #ifdef notdef
  207.     TIFFDirEntry    documentname;
  208. #endif
  209.     TIFFDirEntry    stripoffsets;
  210.     TIFFDirEntry    orientation;
  211.     TIFFDirEntry    samplesperpixel;
  212.     TIFFDirEntry    rowsperstrip;
  213.     TIFFDirEntry    stripbytecounts;
  214.     TIFFDirEntry    xresolution;
  215.     TIFFDirEntry    yresolution;
  216.     TIFFDirEntry    planarconfig;
  217.     TIFFDirEntry    group3options;
  218.     TIFFDirEntry    resolutionunit;
  219. #ifdef notdef
  220.     TIFFDirEntry    software;
  221. #endif
  222.     TIFFDirEntry    cleanfaxdata;
  223.     unsigned long    diroff;            /* offset to next directory */
  224.     unsigned long    xresValue[2];        /* xresolution indirect value */
  225.     unsigned long    yresValue[2];        /* yresolution indirect value */
  226. } TIFFDirectory;
  227. private TIFFDirectory dirTemplate = {
  228.     { TIFFTAG_SUBFILETYPE,    TIFF_LONG,  1, FILETYPE_PAGE },
  229.     { TIFFTAG_IMAGEWIDTH,    TIFF_LONG,  1 },
  230.     { TIFFTAG_IMAGELENGTH,    TIFF_LONG,  1 },
  231.     { TIFFTAG_BITSPERSAMPLE,    TIFF_SHORT, 1, 1 },
  232.     { TIFFTAG_COMPRESSION,    TIFF_SHORT, 1, COMPRESSION_CCITTFAX3 },
  233.     { TIFFTAG_PHOTOMETRIC,    TIFF_SHORT, 1, PHOTOMETRIC_MINISWHITE },
  234.     { TIFFTAG_FILLORDER,    TIFF_SHORT, 1, FILLORDER_MSB2LSB },
  235. #ifdef notdef
  236.     { TIFFTAG_DOCUMENTNAME,    TIFF_ASCII, 1 },
  237. #endif
  238.     { TIFFTAG_STRIPOFFSETS,    TIFF_LONG,  1 },
  239.     { TIFFTAG_ORIENTATION,    TIFF_SHORT, 1, ORIENTATION_TOPLEFT },
  240.     { TIFFTAG_SAMPLESPERPIXEL,    TIFF_SHORT, 1, 1 },
  241.     { TIFFTAG_ROWSPERSTRIP,    TIFF_LONG,  1, -1L },
  242.     { TIFFTAG_STRIPBYTECOUNTS,    TIFF_LONG,  1, 1 },
  243.     { TIFFTAG_XRESOLUTION,    TIFF_RATIONAL, 1 },
  244.     { TIFFTAG_YRESOLUTION,    TIFF_RATIONAL, 1 },
  245.     { TIFFTAG_PLANARCONFIG,    TIFF_SHORT, 1, PLANARCONFIG_CONTIG },
  246.     { TIFFTAG_GROUP3OPTIONS,    TIFF_LONG,  1 },
  247.     { TIFFTAG_RESOLUTIONUNIT,    TIFF_SHORT, 1, RESUNIT_INCH },
  248. #ifdef notdef
  249.     { TIFFTAG_SOFTWARE,        TIFF_ASCII, 1 },
  250. #endif
  251.     { TIFFTAG_CLEANFAXDATA,    TIFF_SHORT, 1, CLEANFAXDATA_CLEAN },
  252.     0, { 0, 1 }, { 0, 1 },
  253. };
  254. #define    OFFSET(x)    ((unsigned)&(((TIFFDirectory*)0)->x))
  255. #define    NTAGS        (OFFSET(diroff) / sizeof (TIFFDirEntry))
  256.  
  257. /* correct tag values on bigendian machines */
  258. private void
  259. faxout_fixuptags(TIFFDirEntry* dp, int n)
  260. {
  261.     while (n-- > 0) {
  262.     if (dp->tdir_type == TIFF_SHORT || dp->tdir_type == TIFF_SSHORT)
  263.         dp->tdir_offset <<= 16;
  264.     else if (dp->tdir_type == TIFF_BYTE || dp->tdir_type == TIFF_SBYTE)
  265.         dp->tdir_offset <<= 24;
  266.     dp++;
  267.     }
  268. }
  269.  
  270. private int
  271. faxout_begin_page(TIFFOUT *faxp, gx_device_printer* pdev)
  272. {
  273.     gx_device_tiff* ddev = (gx_device_tiff*) pdev;
  274.     short dircount;
  275.     TIFFDirectory dir;
  276.  
  277.     /*
  278.      * Writing the header is delayed t