home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fbm / src / tiff2fbm.c < prev    next >
C/C++ Source or Header  |  1990-06-24  |  9KB  |  322 lines

  1. /*****************************************************************
  2.  * tiff2fbm.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989,1990 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * tiff2fbm.c: 
  11.  *    Convert a TIFF format image to FBM format.  Uses Sam Leffler's
  12.  *    libtiff.a TIFF image library to read TIFF format.  See also,
  13.  *    fbm2tiff for the opposite conversion.
  14.  *
  15.  * USAGE
  16.  *    % tiff2fbm [ -<num> ] foo.tif > foo.fbm
  17.  *
  18.  * EDITLOG
  19.  *    LastEditDate = Mon Jun 25 00:18:45 1990 - Michael Mauldin
  20.  *    LastFileName = /usr2/mlm/src/misc/fbm/tiff2fbm.c
  21.  *
  22.  * HISTORY
  23.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  24.  *    Package for Release 1.0
  25.  *
  26.  * 20-Jun-90  Paul Milazzo (milazzo) at BBN
  27.  *    Patched for STDC.
  28.  *
  29.  * 14-Jun-89  Michael Mauldin (mlm) at Carnegie-Mellon University
  30.  *    Created.  Based on tiff2ps by Sam Leffler.
  31.  *****************************************************************/
  32.  
  33. # include <stdio.h>
  34. # include <ctype.h>
  35. # ifdef BYTE
  36. # undef BYTE
  37. # endif
  38. # include <tiff.h>
  39. # include <tiffio.h>
  40. # include "fbm.h"
  41.  
  42. # ifdef __STDC__
  43. #   define FIELD(tif,f)    TIFFFieldSet(tif, FIELD_ ## f)
  44. # else
  45.     /* The following macro is taken from tiff_print.c */
  46. #   define FIELD(tif,f)    TIFFFieldSet(tif, FIELD_/**/f)
  47. # endif
  48.  
  49. # define USAGE "Usage: tiff2fbm [ -<num> ] foo.tif > foo.fbm"
  50.  
  51. /****************************************************************
  52.  * main
  53.  ****************************************************************/
  54.  
  55. #ifndef lint
  56. static char *fbmid =
  57. "$FBM tiff2fbm.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
  58. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  59. #endif
  60.  
  61. #define    howmany(x, y)    (((x)+((y)-1))/(y))
  62.  
  63. main (argc, argv)
  64. char *argv[];
  65. { FBM image;
  66.   int userdir = 1, fw, fh, rowlen, plnlen, clrlen=0, colors=0;
  67.   double aspect = 0.0;
  68.   char *fname = NULL, *title = NULL, *credits = NULL;
  69.  
  70.   TIFF *tif;
  71.   TIFFDirectory *td;
  72.   u_char *scanbuf, *tail;
  73.   register u_char *pp, *obm, *tmp;
  74.   int bitspersample, scanline, samplesperbyte;
  75.   register unsigned int mask;
  76.   register int shift, nib;
  77.   register int poff, k, planes;
  78.   int i, j, w, h, dirnum = 0;
  79.  
  80.   /* Get the options */
  81.   while (--argc > 0 && (*++argv)[0] == '-')
  82.   { while (*++(*argv))
  83.     { switch (**argv)
  84.       {
  85.     case 'a':    aspect = atof (*argv+1); SKIPARG; break;
  86.     case 't':    title = *argv+1; SKIPARG; break;
  87.     case 'c':    credits = *argv+1; SKIPARG; break;
  88.     default:        if (!isdigit (argv[0][1]))
  89.             { fprintf (stderr, "%s\n", USAGE);
  90.                           exit (1);
  91.             }
  92.             else
  93.             { userdir = atoi (*argv+1);
  94.               SKIPARG;
  95.             }
  96.       }
  97.     }
  98.   }
  99.  
  100.   /* Get name of input file */
  101.   if (argc != 1)
  102.   { fprintf (stderr, "%s\n", USAGE);
  103.     exit (1);
  104.   }
  105.   
  106.   fname = *argv;
  107.  
  108.   /* Clear the memory pointers so alloc_fbm won't be confused */
  109.   image.cm  = image.bm  = (unsigned char *) NULL;
  110.  
  111.   /* Now read in the TIFF format image */
  112.   /*------------------------------*/
  113.  
  114.   if ((tif = TIFFOpen(fname, "r")) == NULL)
  115.   { exit (1); }
  116.  
  117.   do
  118.   { ++dirnum;
  119.  
  120.     if (userdir != dirnum) continue;
  121.  
  122.     td = &tif->tif_dir;
  123.     bitspersample = td->td_bitspersample;
  124.     planes = td->td_samplesperpixel;
  125.  
  126.     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
  127.     { bitspersample *= planes; }
  128.  
  129.     scanline = howmany (bitspersample * td->td_imagewidth, 8);
  130.     scanbuf = (u_char *) malloc (scanline);
  131.     if (scanbuf == NULL)
  132.     { printf ("No space for scanline buffer\n");
  133.       continue;
  134.     }
  135.  
  136.     w = td->td_imagewidth;
  137.     h = td->td_imagelength;
  138.  
  139.     switch (bitspersample)
  140.     { case 1:    samplesperbyte = 8; break;
  141.       case 2:    samplesperbyte = 4; break;
  142.       case 4:    samplesperbyte = 2; break;
  143.       case 8:    samplesperbyte = 1; break;
  144.       case 24:    samplesperbyte = 1; break;
  145.       default:    fprintf (stderr, "I can't handle %d bits per sample\n",
  146.             bitspersample);
  147.         exit (1);
  148.     }
  149.  
  150.     /* Now build FBM image header */
  151.     
  152.     if (bitspersample == 1)
  153.     { rowlen = 16 * ((w+15)/16); }
  154.     else
  155.     { rowlen = 2 * ((w+1)/2); }
  156.  
  157.     plnlen = rowlen * h;
  158.  
  159.     /* Build header */
  160.     image.hdr.title[0] = image.hdr.credits[0] = '\0';
  161.     
  162.     image.hdr.rows = h;
  163.     image.hdr.cols = w;
  164.     image.hdr.planes = planes;
  165.     image.hdr.bits = bitspersample / planes;
  166.     image.hdr.physbits = 8;
  167.     image.hdr.rowlen = rowlen;
  168.     image.hdr.plnlen = plnlen;
  169.     colors = FIELD (tif,COLORMAP) ? (1 << td->td_bitspersample) : 0;
  170.     image.hdr.clrlen = colors * 3;
  171.  
  172.  
  173.     /* Determine aspect from X and Y resolution */
  174.     if (FIELD (tif,RESOLUTION) && td->td_yresolution != 0)
  175.     { image.hdr.aspect = td->td_xresolution / td->td_yresolution; }
  176.     else
  177.     { image.hdr.aspect = 1.0; }
  178.  
  179.     /* Extract Title and Credit information */
  180.     if (FIELD (tif,DOCUMENTNAME))
  181.     { strcpy (image.hdr.title, td->td_documentname); }
  182.     else if (FIELD (tif,IMAGEDESCRIPTION))
  183.     { strcpy (image.hdr.title, td->td_imagedescription); }
  184.     else
  185.     { strcpy (image.hdr.title, fname); }
  186.     
  187.     if (FIELD (tif,ARTIST))
  188.     { strcpy (image.hdr.credits, td->td_artist); }
  189.     else if (FIELD (tif,SOFTWARE))
  190.     { strcpy (image.hdr.credits, td->td_software); }
  191.     else if (FIELD (tif,MAKE))
  192.     { strcpy (image.hdr.credits, td->td_make);
  193.       if (FIELD (tif,MODEL))
  194.       { strcat (image.hdr.credits, ", ");
  195.         strcat (image.hdr.credits, td->td_model);
  196.       }
  197.     }
  198.  
  199.     fprintf (stderr, "Reading \"%s\" [%dx%d], %d bits, directory %d\n",
  200.          image.hdr.title, w, h, bitspersample, userdir);
  201.  
  202.     /*----------------------------------------------------------------*/
  203.  
  204.     alloc_fbm (&image);
  205.  
  206.     /* Read colormap: Note TIFF colors are 16 bit, FBM colors 8 bit */
  207.     if (FIELD (tif,COLORMAP))
  208.     { for (i=0; i<colors; i++)
  209.       { image.cm[i]            = td->td_redcolormap[i] >> 8;
  210.         image.cm[i + colors]        = td->td_greencolormap[i] >> 8;
  211.         image.cm[i + colors + colors]    = td->td_bluecolormap[i] >> 8;
  212.       }
  213.     }
  214.  
  215.  
  216.     /* Check for multiplane images */
  217.     if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
  218.         planes > 1)
  219.     { fprintf (stderr, "Multiplane images (%d) not yet implemented\n",
  220.            planes);
  221.       exit (1);
  222.     }
  223.  
  224.     else
  225.     {
  226.  
  227.       /*
  228.        * Read single plane images (for RGB color, values are stored in 
  229.        * successive bytes)
  230.        */
  231.   
  232.       /* Precompute mask and shift parameters */
  233.       switch (samplesperbyte)
  234.       { case 8:    mask = 0x01; shift = 1; break;
  235.     case 4:    mask = 0x03; shift = 2; break;
  236.     case 2:    mask = 0x0f; shift = 4; break;
  237.     case 1:    mask = 0xff; shift = 8; break;
  238.       }
  239.       nib = 8 - shift;
  240.   
  241.       fprintf (stderr, "Samples per byte %d, mask %02x, shift %d, planes %d, scanline %d\n", 
  242.         samplesperbyte, mask, shift, planes, scanline);
  243.  
  244.       /* Each loop does one scan line */
  245.       for (j=0; j<h; j++)
  246.       { if (TIFFReadScanline (tif, scanbuf, j, 0) < 0)
  247.     { fprintf (stderr, "Error: only read %d lines\n", j); break; }
  248.     
  249.     /* If 0 is WHITE, then flip all bits in the scanline */
  250.     if (td->td_photometric == PHOTOMETRIC_MINISWHITE)
  251.     { for (pp = scanbuf, i=scanline; --i >= 0; pp++)
  252.       { *pp = ~ *pp; }
  253.     }
  254.     
  255.     pp = scanbuf;
  256.     obm = &image.bm[j * rowlen];
  257.     tmp = obm;
  258.     tail = obm + w;
  259.     
  260.     if (samplesperbyte > 1)
  261.     { for (; obm < tail; obm++)
  262.       { for (k=0, poff=0; k<planes; k++, poff += plnlen)
  263.         { obm[poff] = (*pp >> nib) & mask;
  264. # ifdef DEBUG
  265.           if (j< 10 && (obm-tmp)< 18)
  266.           { fprintf (stderr, "<%2d,%2d>  obm[%d] = %d, nib %d, mask %d, pp %08x\n",
  267.             (obm-tmp), j, poff, obm[poff], nib, mask, pp);
  268.           }
  269. # endif
  270.           if ((nib -= shift) < 0) { pp++; nib = 8 - shift; }
  271.         }
  272.       }
  273.     }
  274.     
  275.     else
  276.     { for (; obm < tail; obm++)
  277.       { for (k=0, poff=0; k<planes; k++, poff += plnlen)
  278.         { obm[poff] = *pp++; }
  279.       }
  280.     }
  281.       }
  282.     }
  283.   } while (TIFFReadDirectory (tif));
  284.  
  285.   /*----------------------------------------------------------------*/
  286.  
  287.   if (tif)
  288.   { TIFFClose (tif); }
  289.  
  290.   /* Check whether an image was read */
  291.   if (userdir > dirnum)
  292.   { if (dirnum > 0)
  293.     { fprintf (stderr, "File %s has only %d directories, %d out of range\n",
  294.         fname, dirnum, userdir);
  295.     }
  296.     else
  297.     { fprintf (stderr, "File %s has no directories\n", fname); }
  298.     
  299.     exit (1);
  300.   }
  301.  
  302.   /*------------------------------*/
  303.  
  304.   if (aspect != 0.0)
  305.   { fprintf (stderr,
  306.          "Overiding aspect ratio read (%1.3lf) with (%1.3lf)\n",
  307.          image.hdr.aspect, aspect);
  308.     image.hdr.aspect = aspect;
  309.   }
  310.  
  311.   if (title)
  312.   { strncpy (image.hdr.title, title, FBM_MAX_TITLE); }
  313.  
  314.   if (credits)
  315.   { strncpy (image.hdr.credits, credits, FBM_MAX_TITLE); }
  316.  
  317.   if (write_bitmap (&image, stdout, FMT_FBM))
  318.   { exit (0); }
  319.  
  320.   exit (1);
  321. }
  322.