home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 343_02 / wtiff.c < prev   
C/C++ Source or Header  |  1992-04-29  |  14KB  |  542 lines

  1.  
  2.  
  3.        /************************************************
  4.        *
  5.        *       file d:\lsu\wtiff.c
  6.        *
  7.        *       Functions: This file contains
  8.        *           create_allocate_tiff_file
  9.        *           write_array_into_tiff_image
  10.        *           write_line
  11.        *           insert_short_into_buffer
  12.        *           insert_long_into_buffer
  13.        *           round_off_image_size
  14.        *           does_not_exist
  15.        *
  16.        *       Purpose:
  17.        *          These functions insert a ROWSxCOLS array into
  18.        *          a tiff image already stored on disk.
  19.        *
  20.        *       External Calls:
  21.        *          rtiff.c - seek_to_first_line
  22.        *                    seek_to_end_of_line
  23.        *          tiff.c - read_tiff_header
  24.        *          mrw.c - my_write
  25.        *
  26.        *       Modifications:
  27.        *          29 January 1991 - created
  28.        *
  29.        *************************************************/
  30.  
  31.  
  32.  
  33. #include "d:\cips\cips.h"
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.        /*******************************************************
  43.        *
  44.        *   create_alllocate_tiff_file(...
  45.        *
  46.        *   This function creates a file on disk that will be
  47.        *   large enough to hold a tiff image.  The input
  48.        *   tiff_header_struct describes the desired tiff file.
  49.        *   This function writes the tiff header and then
  50.        *   writes a blank image array out to disk the proper
  51.        *   number of times.  This has the effect of allocating
  52.        *   the correct number of bytes on the disk.
  53.        *
  54.        *******************************************************/
  55.  
  56.  
  57. create_allocate_tiff_file(file_name, image_header, image)
  58.    char   file_name[];
  59.    short  image[ROWS][COLS];
  60.    struct tiff_header_struct *image_header;
  61. {
  62.    char  buffer[12];
  63.  
  64.    int   bytes_written,
  65.          file_desc,
  66.          i,
  67.          j,
  68.          l,
  69.          w;
  70.  
  71.    long  k;
  72.  
  73.  
  74.  
  75.       /***************************************
  76.       *
  77.       *   Create the image file in binary mode
  78.       *   for both reading and writing.
  79.       *
  80.       ****************************************/
  81.  
  82.    file_desc = open(file_name,
  83.           O_CREAT | O_RDWR | O_BINARY,
  84.           S_IREAD | S_IWRITE);
  85.    printf("\n file desc=%d", file_desc);
  86.  
  87.       /***************************************
  88.       *
  89.       *   Write out the first 8 bytes of the
  90.       *   header.  The meaning of the
  91.       *   bytes (HEX) is:
  92.       *      0-1 = 49 49 - LSB first
  93.       *      2-3 = 2A 00 - version #
  94.       *      4-7 = 08 00 00 00 - go to offset
  95.       *           8 for the first
  96.       *           Image File
  97.       *           Directory
  98.       *
  99.       ****************************************/
  100.  
  101.    buffer[0] = 0x49;
  102.    buffer[1] = 0x49;
  103.    buffer[2] = 0x2A;
  104.    buffer[3] = 0x00;
  105.    buffer[4] = 0x08;
  106.    buffer[5] = 0x00;
  107.    buffer[6] = 0x00;
  108.    buffer[7] = 0x00;
  109.  
  110.    bytes_written = my_write(file_desc, buffer, 8);
  111.  
  112.    printf("\n wrote %d bytes", bytes_written);
  113.  
  114.       /***************************************
  115.       *
  116.       *   Write out the first 2 bytes of the
  117.       *   Image File Directory.  These tell
  118.       *   the number of entries in the IFD.
  119.       *
  120.       ****************************************/
  121.  
  122.    buffer[0] = 0x09;
  123.    buffer[1] = 0x00;
  124.    bytes_written = my_write(file_desc, buffer, 2);
  125.  
  126.    printf("\n wrote %d bytes", bytes_written);
  127.  
  128.       /***************************************
  129.       *
  130.       *   Write out the entries into the
  131.       *   Image File Directory.
  132.       *
  133.       ****************************************/
  134.  
  135.       /* Samples per Pixel */
  136.    insert_short_into_buffer(buffer, 0, 277);
  137.    insert_short_into_buffer(buffer, 2, 3);
  138.    insert_short_into_buffer(buffer, 4, 1);
  139.    insert_short_into_buffer(buffer, 8, 1);
  140.  
  141.    bytes_written = my_write(file_desc, buffer, 12);
  142.  
  143.    printf("\n wrote %d bytes", bytes_written);
  144.  
  145.  
  146.       /* Min Sample Value */
  147.    insert_short_into_buffer(buffer, 0, 280);
  148.    insert_short_into_buffer(buffer, 2, 3);
  149.    insert_short_into_buffer(buffer, 4, 1);
  150.    insert_short_into_buffer(buffer, 8, 0);
  151.  
  152.    bytes_written = my_write(file_desc, buffer, 12);
  153.  
  154.    printf("\n wrote %d bytes", bytes_written);
  155.  
  156.  
  157.       /* Max Sample Value */
  158.    insert_short_into_buffer(buffer, 0, 281);
  159.    insert_short_into_buffer(buffer, 2, 3);
  160.    insert_short_into_buffer(buffer, 4, 1);
  161.    if(image_header->bits_per_pixel == 8)
  162.       insert_short_into_buffer(buffer, 8, 255);
  163.    else
  164.       insert_short_into_buffer(buffer, 8, 15);
  165.  
  166.    bytes_written = my_write(file_desc, buffer, 12);
  167.  
  168.    printf("\n wrote %d bytes", bytes_written);
  169.  
  170.  
  171.       /* Photometric Interpretation */
  172.    insert_short_into_buffer(buffer, 0, 262);
  173.    insert_short_into_buffer(buffer, 2, 3);
  174.    insert_short_into_buffer(buffer, 4, 1);
  175.    insert_short_into_buffer(buffer, 8, 1);
  176.  
  177.    bytes_written = my_write(file_desc, buffer, 12);
  178.  
  179.    printf("\n wrote %d bytes", bytes_written);
  180.  
  181.  
  182.       /* Subfile Type */
  183.    buffer[0]  = 0xFF;
  184.    buffer[1]  = 0x00;
  185.    buffer[2]  = 0x03;
  186.    buffer[3]  = 0x00;
  187.    buffer[4]  = 0x01;
  188.    buffer[5]  = 0x00;
  189.    buffer[6]  = 0x00;
  190.    buffer[7]  = 0x00;
  191.    buffer[8]  = 0x01;
  192.    buffer[9]  = 0x00;
  193.    buffer[10] = 0x00;
  194.    buffer[11] = 0x00;
  195.  
  196.    bytes_written = my_write(file_desc, buffer, 12);
  197.  
  198.    printf("\n wrote %d bytes", bytes_written);
  199.  
  200.       /* Image Width */
  201.    insert_short_into_buffer(buffer, 0, 256);
  202.    insert_short_into_buffer(buffer, 2, 3);
  203.    insert_short_into_buffer(buffer, 4, 1);
  204.    insert_short_into_buffer(buffer, 8, image_header->image_width);
  205.  
  206.    bytes_written = my_write(file_desc, buffer, 12);
  207.    printf("\n wrote %d bytes", bytes_written);
  208.  
  209.       /* Image Length */
  210.    insert_short_into_buffer(buffer, 0, 257);
  211.    insert_short_into_buffer(buffer, 2, 3);
  212.    insert_short_into_buffer(buffer, 4, 1);
  213.    insert_short_into_buffer(buffer, 8, image_header->image_length);
  214.  
  215.    bytes_written = my_write(file_desc, buffer, 12);
  216.    printf("\n wrote %d bytes", bytes_written);
  217.  
  218.       /* Bits Per Pixel */
  219.    insert_short_into_buffer(buffer, 0, 258);
  220.    insert_short_into_buffer(buffer, 2, 3);
  221.    insert_short_into_buffer(buffer, 4, 1);
  222.    insert_short_into_buffer(buffer, 8, image_header->bits_per_pixel);
  223.  
  224.    bytes_written = my_write(file_desc, buffer, 12);
  225.    printf("\n wrote %d bytes", bytes_written);
  226.  
  227.       /* Strip Offset */
  228.    insert_short_into_buffer(buffer, 0, 273);
  229.    insert_short_into_buffer(buffer, 2, 3);
  230.    insert_short_into_buffer(buffer, 4, 1);
  231.    insert_short_into_buffer(buffer, 8, 122);
  232.    bytes_written = my_write(file_desc, buffer, 12);
  233.    printf("\n wrote %d bytes", bytes_written);
  234.  
  235.  
  236.       /* Offset to next IFD (0 means no more IFD's) */
  237.    buffer[0]  = 0x00;
  238.    buffer[1]  = 0x00;
  239.    buffer[2]  = 0x00;
  240.    buffer[3]  = 0x00;
  241.  
  242.    bytes_written = my_write(file_desc, buffer, 4);
  243.    printf("\n wrote %d bytes", bytes_written);
  244.    printf("\n length is %ld", image_header->image_length);
  245.    printf("\n width is %ld", image_header->image_width);
  246.  
  247.  
  248.    round_off_image_size(image_header, &l, &w);
  249.    k = l * w;
  250.  
  251.    if(image_header->bits_per_pixel == 8)
  252.       k = k/2;
  253.    else
  254.       k = k/4;
  255.    k++;
  256.  
  257.    for(i=0; i<ROWS; i++)
  258.       for(j=0; j<COLS; j++)
  259.         image[i][j] = 0;
  260.  
  261.    j = sizeof(short) * ROWS * COLS;
  262.  
  263.    for(i=0; i<k; i++){
  264.       bytes_written = my_write(file_desc, image, j);
  265.       printf("\n wrote %d bytes", bytes_written);
  266.    }
  267.  
  268.  
  269.    close(file_desc);
  270.  
  271. }  /* ends create_allocate_tiff_file */
  272.  
  273.  
  274.  
  275.  
  276.  
  277.        /*******************************************************
  278.        *
  279.        *   write_array_into_tiff_file(...
  280.        *
  281.        *   This function takes an array of shorts and writes
  282.        *   them into an existing tiff image file.
  283.        *
  284.        *******************************************************/
  285.  
  286.  
  287.  
  288. write_array_into_tiff_image(image_file_name, array,
  289.                             il, ie, ll, le)
  290.  
  291.         char    image_file_name[];
  292.         int     il, ie, ll, le;
  293.         short   array[ROWS][COLS];
  294. {
  295.  
  296.    char  buffer[COLS];
  297.  
  298.    int   bytes_written,
  299.          closed,
  300.          file_descriptor,
  301.          i,
  302.          written;
  303.  
  304.    float a;
  305.  
  306.    long  line_length,
  307.          offset,
  308.          position;
  309.  
  310.    struct tiff_header_struct image_header;
  311.  
  312.  
  313.  
  314.    read_tiff_header(image_file_name, &image_header);
  315.  
  316.  
  317.       /****************************************************
  318.       *
  319.       *   Procedure:
  320.       *   Seek to the strip offset where the data begins.
  321.       *   Seek to the first line you want.
  322.       *   Loop over the lines you want to write.
  323.       *      Seek to the first element of the line.
  324.       *      Write the line.
  325.       *      Seek to the end of the data in that line.
  326.       *
  327.       ****************************************************/
  328.  
  329.    file_descriptor = my_open(image_file_name);
  330.    position        = lseek(file_descriptor,
  331.                      image_header.strip_offset, 0);
  332.    position        = seek_to_first_line(file_descriptor,
  333.                                         &image_header, il);
  334.  
  335.    for(i=0; i<(ll-il); i++){
  336.       offset        = (ie-1)/(8/image_header.bits_per_pixel);
  337.       position      = lseek(file_descriptor, offset, 1);
  338.       bytes_written = write_line(file_descriptor, array,
  339.                                  i, &image_header, ie, le);
  340.       position      = seek_to_end_of_line(file_descriptor,
  341.                                           le, &image_header);
  342.       position      = lseek(file_descriptor, 1, 1); /*???*/
  343.    }  /* ends loop over i  */
  344.  
  345.    closed = close(file_descriptor);
  346.  
  347. }  /*  ends write_array_into_tiff_image */
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.        /*******************************************************
  357.        *
  358.        *   write_line(...
  359.        *
  360.        *   This function takes an array of shorts, extracts the
  361.        *   numbers and puts them into a buffer, then writes
  362.        *   this buffer into a tiff file on disk.
  363.        *   The process depends on the number of bits per
  364.        *   pixel used in the file (4 or 8).
  365.        *
  366.        *******************************************************/
  367.  
  368. write_line(file_descriptor, array, line_number, image_header, ie, le)
  369.    int    file_descriptor, ie, le, line_number;
  370.    short  array[ROWS][COLS];
  371.    struct tiff_header_struct *image_header;
  372. {
  373.    char     buffer[COLS], first, second;
  374.    float    a, b;
  375.    int      bytes_written, i;
  376.    unsigned int bytes_to_write;
  377.    union    short_char_union scu;
  378.  
  379.    for(i=0; i<COLS; i++)
  380.       buffer[i] = '\0';
  381.  
  382.    bytes_to_write = (le-ie)/(8/image_header->bits_per_pixel);
  383.  
  384.    for(i=0; i<bytes_to_write; i++){
  385.  
  386.         /**********************************************
  387.         *
  388.         *   Use unions defined in cips.h to stuff shorts
  389.         *   into bytess.
  390.         *
  391.         *************************************************/
  392.  
  393.       if(image_header->bits_per_pixel == 8){
  394.        scu.s_num = 0;
  395.        scu.s_num = array[line_number][i];
  396.        buffer[i] = scu.s_alpha[0];
  397.       }  /* ends if bits_per_pixel == 8 */
  398.  
  399.  
  400.       if(image_header->bits_per_pixel == 4){
  401.  
  402.        scu.s_num = 0;
  403.        scu.s_num = array[line_number][i*2];
  404.        first     = scu.s_alpha[0] << 4;
  405.  
  406.        scu.s_num = 0;
  407.        scu.s_num = array[line_number][i*2];
  408.        second    = scu.s_alpha[0] & 0X000F;
  409.  
  410.        buffer[i] = first | second;
  411.       }  /* ends if bits_per_pixel == 4 */
  412.  
  413.    }  /*  ends loop over i  */
  414.  
  415.  
  416.    bytes_written  = write(file_descriptor, buffer, bytes_to_write);
  417.  
  418.    return(bytes_written);
  419.  
  420. }  /* ends write_line  */
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.    /***************************************
  428.    *
  429.    *   insert_short_into_buffer(...
  430.    *
  431.    *   This inserts a two byte short into a
  432.    *   buffer of characters.  It does this
  433.    *   is LSB order.
  434.    *
  435.    ***************************************/
  436.  
  437.  
  438. insert_short_into_buffer(buffer, start, number)
  439.     char  buffer[];
  440.     int   start;
  441.     short number;
  442. {
  443.     union short_char_union lsu;
  444.  
  445.     lsu.s_num       = number;
  446.     buffer[start+0] = lsu.s_alpha[0];
  447.     buffer[start+1] = lsu.s_alpha[1];
  448.  
  449. }  /* ends insert_short_into_buffer */
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.    /***************************************
  463.    *
  464.    *   insert_long_into_buffer(...
  465.    *
  466.    *   This inserts a four byte long into a
  467.    *   buffer of characters.  It does this
  468.    *   is LSB order.
  469.    *
  470.    ***************************************/
  471.  
  472.  
  473.  
  474. insert_long_into_buffer(buffer, start, number)
  475.     char buffer[];
  476.     int  start;
  477.     long number;
  478. {
  479.     union long_char_union lsu;
  480.  
  481.     lsu.l_num       = number;
  482.     buffer[start+0] = lsu.l_alpha[0];
  483.     buffer[start+1] = lsu.l_alpha[1];
  484.     buffer[start+2] = lsu.l_alpha[2];
  485.     buffer[start+3] = lsu.l_alpha[3];
  486.  
  487. }  /* ends insert_short_into_buffer */
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.    /***************************************
  496.    *
  497.    *   round_off_image_size(...
  498.    *
  499.    *   This takes the image header and rounds
  500.    *   it off to a multiple of ROWS and COLS.
  501.    *   e.g. if width=123 it returns 1.
  502.    *
  503.    ***************************************/
  504.  
  505.  
  506. round_off_image_size(image_header, length, width)
  507.     int    *length, *width;
  508.     struct tiff_header_struct *image_header;
  509. {
  510.    *length = (90 + image_header->image_length)/ROWS;
  511.    *width  = (90 + image_header->image_width)/COLS;
  512. } /* ends round_off_image_size */
  513.  
  514.  
  515.  
  516.  
  517.  
  518.    /***********************************************
  519.     *
  520.     *    does_not_exist(...
  521.     *
  522.     *    This function checks the disk to see if
  523.     *    a file exists.  If the file is there this
  524.     *    function returns a 0, if it does not exist
  525.     *    this function returns a 1.
  526.     *
  527.     ***********************************************/
  528.  
  529.  
  530. does_not_exist(file_name)
  531.     char file_name[];
  532. {
  533.    int file_desc, result;
  534.  
  535.    result = 1;
  536.    file_desc = open(file_name, O_BINARY | O_RDONLY);
  537.    if(file_desc > 0)
  538.       result = 0;
  539.    close(file_desc);
  540.    return(result);
  541. }  /* ends does_not_exist */
  542.