Listing 1 (wtiff.c)

      /************************************************
      *
      *      file d:\lsu\wtiff.c
      *
      *      Functions: This file contains
      *          create_allocate_tiff_file
      *          write_array_into_tiff_image
      *          write_line
      *          insert_short_into_buffer
      *          insert_long_into_buffer
      *          round_off_image_size
      *          does_not_exist
      *
      *      Purpose:
      *         These functions insert a 100x100 array into
      *         a tiff image already stored on disk.
      *
      *      External Calls:
      *         rtiff.c - seek_to_first_line
      *                   seek_to_end_of_line
      *         tiff.c - read_tiff_header
      *         mrw.c - my_write
      *
      *      Modifications:
      *         29 January 1991 - created
      *
      ************************************************/


#include "d:\cips\cips.h"


/*******************************************************
      *
      *   create_alllocate_tiff_file(...
      *
      *   This function creates a file on disk that will be
      *   large enough to hold a tiff image. The input
      *   tiff_header_struct describes the desired tiff file.
      *   This function writes the tiff header and then
      *   writes a blank image array out to disk the proper
      *   number of times. This has the effect of allocating
      *   the correct number of bytes on the disk.
      *

*******************************************************/


create_allocate_tiff_file(file_name, image_header, image)
   char file_name[];
   short image[ROWS][COLS];
   struct tiff_header_struct *image_header;
{
   char buffer[12];

   int bytes_written,
       file_desc,
       i,
       j,
       l,
       w;

   long k;



      /**************************************
      *
      * Create the image file in binary mode
      * for both reading and writing.
      *
      ****************************************/

   file_desc = open(file_name,
         O_CREAT | O_RDWR | O_BINARY,
         S_IREAD | S_IWRITE);
   printf("\n file desc=%d", file_desc);

      /**************************************
      *
      * Write out the first 8 bytes of the
      * header. The meaning of the
      * bytes (HEX) is:
      *    0-1 = 49 49 - LSB first
      *    2-3 = 2A 00 - version #
      *    4-7 = 08 00 00 00 - go to offset
      *         8 for the first
      *         Image File
      *         Directory
      *
      ***************************************/

   buffer[0] = 0x49;
   buffer[1] = 0x49;
   buffer[2] = 0x2A;
   buffer[3] = 0x00;
   buffer[4] = 0x08;
   buffer[5] = 0x00;
   buffer[6] = 0x00;
   buffer[7] = 0x00;

   bytes_written = my_write(file_desc, buffer, 8);

   printf("\n wrote %d bytes", bytes_written);

      /***************************************
      *
      *  Write out the first 2 bytes of the
      *  Image File Directory. These tell
      *  the number of entries in the IFD.
      *
      ***************************************/

   buffer[0] = 0x05;
   buffer[1] = 0x00;
   bytes_written = my_write(file_desc, buffer, 2);

   printf("\n wrote %d bytes", bytes_written);

      /***************************************
      *
      *  Write out the entries into the
      *  Image File Directory.
      *
      ***************************************/

      /* Subfile Type */
   buffer[0] = 0xFF;
   buffer[1] = 0x00;
   buffer[2] = 0x03;
   buffer[3] = 0x00;
   buffer[4] = 0x01;
   buffer[5] = 0x00;
   buffer[6] = 0x00;
   buffer[7]  = 0x00;
   buffer[8]  = 0x01;
   buffer[9]  = 0x00;
   buffer[10] = 0x00;
   buffer[11] = 0x00;

   bytes_written = my_write(file_desc, buffer, 12);

   printf("\n wrote %d bytes", bytes_written);

      /* Image Width */
   insert_short_into_buffer(buffer, 0, 256);
   insert_short_into_buffer(buffer, 2, 3);
   insert_short_into_buffer(buffer, 4, 1);
   insert_short_into_buffer(buffer, 8, image_header->image_width);

   bytes_written = my_write(file_desc, buffer, 12);
   printf("\n wrote %d bytes", bytes_written);

      /* Image Length */
   insert_short_into_buffer(buffer, 0, 257);
   insert_short_into_buffer(buffer, 2, 3);
   insert_short_into_buffer(buffer, 4, 1);
   insert_short_into_buffer(buffer, 8, image_header->image_length);

   bytes_written = my_write(file_desc, buffer, 12);
   printf("\n wrote %d bytes", bytes_written);

      /* Bits Per Pixel */
   insert_short_into_buffer(buffer, 0, 258);
   insert_short_into_buffer(buffer, 2, 3);
   insert_short_into_buffer(buffer, 4, 1);
   insert_short_into_buffer(buffer, 8, image_header->bits_per_pixel);

   bytes_written = my_write(file_desc, buffer, 12);
   printf("\n wrote %d bytes", bytes_written);

      /* Strip Offset */
   insert_short_into_buffer(buffer, 0, 273);
   insert_short_into_buffer(buffer, 2, 3);
   insert_short_into_buffer(buffer, 4, 1);
   insert_short_into_buffer(buffer, 8, 74);

   bytes_written = my_write(file_desc, buffer, 12);
   printf("\n wrote %d bytes", bytes_written);


      /* Offset to next IFD (0 means no more IFD's) */
   buffer[0] = 0x00;
   buffer[1] = 0x00;
   buffer[2] = 0x00;
   buffer[3] = 0x00;

   bytes_written = my_write(file_desc, buffer, 4);
   printf("\n wrote %d bytes", bytes_written);
   printf("\n length is %ld", image_header->image_length);
   printf("\n width is %ld", image_header->image_width);


   round_off_image_size(image_header, &l, &w);
   k = l * w;

   if(image_header->bits_per_pixel == 8)
      k = k/2;
   else
      k = k/4;
   k++;

      for(i=0; i<ROWS; i++)
         for(j=0; j<COLS; j++)
           image[i] [j] = 0;

   j = sizeof(short) * ROWS * COLS;
   for(i=0; i<k; i++){
      bytes_written = my_write(file_desc, image, j);
      printf("\n wrote %d bytes", bytes_written);
   }


   close(file_desc);

} /* ends create_allocate_tiff_file */


      /*************************************************
      *
      * write_array_into_tiff_file(...
      *
      * This function takes an array of shorts and writes
      * them into an existing tiff image file.
      *
      *************************************************/



write_array_into_tiff_image(image_file_name, array,
                        il, ie, ll, le)


      char   image_file_name[];
      int    il, ie, ll, le;
      short  array[ROWS] [COLS];
{

   char buffer[COLS];

   int bytes_written,
       closed,
       file_descriptor,
       i,
       written;

   float a;

   long line_length,
       offset,
       position;

   struct tiff_header_struct image_header;



   read_tiff_header(image_file_name, &image_header);


      /****************************************************
      *
      * Procedure:
      * Seek to the strip offset where the data begins.
      * Seek to the first line you want.
      * Loop over the lines you want to write.
      *    Seek to the first element of the line.
      *    Write the line.
      *    Seek to the end of the data in that line.
      *
      *****************************************************/

   file_descriptor = my_open(image_file_name);
   position        = 1seek(file_descriptor,
                  image_header.strip_offset, 0);
   position        = seek_to_first_line(file_descriptor,
                                  &image_header, il);

   for(i=0; i<(ll-il); i++){
      offset       = (ie-1)/(8/image_header.bits_per_pixel);
      position   = lseek(file_descriptor, offset, 1);
      bytes_written = write_line(file_descriptor, array,
                             i, &image_header, ie, le);
      position   = seek_to_end_of_line(file descriptor,
                                  le, &image_header);
      position   = lseek(file_descriptor, 1, 1); /*???*/
   } /* ends loop over i */

closed = close(file_descriptor);

} /* ends write_array_into_tiff_image */


     /*********************************************************
     *
     *  write_line(...
     *
     *  This function takes an array of shorts, extracts the
     *  numbers and puts them into a buffer, then writes
     *  this buffer into a tiff file on disk.
     *  The process depends on the number of bits per
     *  pixel used in the file (4 or 8).
     *
     *********************************************************/

write_line(file_descriptor, array, line_number, image_header, ie, le)
   int    file_descriptor, ie, le, line_number;
   short  array[ROWS][COLS];
   struct tiff_header_struct *image_header;
{
   char     buffer[100], first, second;
   float    a, b;
   int      bytes_written, i;
   unsigned int bytes_to_write;
   union    short_char_union scu;

   for(i=0; i<100; i++)
      buffer[i] = '\0';

   bytes_to_write = (le-ie)/(8/image_header->bits_per_pixel);

   for(i=0; i<bytes_to_write; i++){

       /**********************************************
       *
       *  Use unions defined in cips.h to stuff shorts
       *  into bytess.
       *
       **********************************************/

      if(image_header->bits_per_pixel == 8){
       scu.s num = 0;
       scu.s num = array[line number][i];
       buffe[i] = scu.s_alpha[0];
      } /* ends if bits_per_pixel == 8 */


      if(image_header->bits_per_pixel == 4){

      scu.s_num = 0;
      scu.s_num = array[line_number] [i*2];
      first     = scu.s_alpha[0] << 4;

      scu.s_num= 0;
      scu.s_num= array[line_number] [i*2];
      second = scu.s_alpha[0] & 0X000F;

       buffer[i] = first | second;
      } /* ends if bits_per_pixel == 4 */

   } /* ends loop over i */
   bytes_written = write(file_descriptor, buffer,
                      bytes_to_write);

   return(bytes_written);

}/* ends write_line */

   /***************************************
   *
   *  insert_short_into_buffer(...
   *
   *  This inserts a two byte short into a
   *  buffer of characters. It does this
   *  is LSB order.
   *
   ***************************************/



insert_short_into_buffer(buffer, start, number)
   char buffer[];
   int start;
   short number;
{
   union short_char_union lsu;

   lsu.s_num = number;
   buffer[start+0] = lsu.s_alpha[0];
   buffer[start+l] = lsu.s_alpha[1];

} /* ends insert_short_into_buffer */

   /***************************************
   *
   *  insert_long_into_buffer(...
   *
   *  This inserts a four byte long into a
   *  buffer of characters. It does this
   *  is LSB order.
   *
   ***************************************/



insert_long_into_buffer(buffer, start, number)
    char buffer[];
    int start;
    long number;
{
    union long_char_union lsu;

    lsu.1_num       = number;
    buffer[start+0] = lsu.l_alpha[0];
    buffer[start+1] = 1su.1_alpha[1];
    buffer[start+2] = lsu.l_alpha[2];
    buffer[start+3] = lsu.l_alpha[3];

}/* ends insert_short_into_buffer */


/***************************************
*
*  round_off_image_size(...
*
*  This takes the image header and rounds
*  it off to a multiple of ROWS and COLS.
*  e.g. if width=123 it returns 1.
*
***************************************/


round_off_image_size(image_header, length, width)
    int  *length, *width;
    struct tiff_header_struct *image_header;
{
    *length = (90 + image_header->image_length)/ROWS;
    *width = (90 + image_header->image_width)/COLS;
} /* ends round_off_image_size */


   /***********************************************
    *
    *  does_not_exist(...
    *
    *  This function checks the disk to see if
    *  a file exists. If the file is there this
    *  function returns a 0, if it does not exist
    *  this function returns a 1.
    *
    ***********************************************/

does_not_exist(file_name)
    char file_name[];
{
    int file_desc, result;

    result = 1;
    file_desc = open(file_name, 0_BINARY | 0_RDONLY);
    if(file_desc > 0)
       result = 0;
    close(file_desc);
    return(result);
} /*  ends does_not_exist */

/*  End of File */