home *** CD-ROM | disk | FTP | other *** search
/ 1st Canadian Shareware Disc / 1st_Canadian_Shareware_Disc_1991.ISO / graphics / giftif / giftif.c < prev    next >
C/C++ Source or Header  |  1989-11-21  |  13KB  |  456 lines

  1. /*----------------------------------------------------------------------*/
  2. /* Copyright (c) 1988-1989                        */
  3. /* by CompuServe Inc., Tucson, AZ.  All Rights Reserved            */
  4. /* GIFTIF.C can be copied and distributed freely for any        */
  5. /* non-commercial purposes. GIFTIF.C can only be incorporated        */
  6. /* into commercial software with the permission of CompuServe Inc.    */
  7. /*----------------------------------------------------------------------*/
  8.  
  9. /* GIFTIF.C */
  10.  
  11. /*
  12.  * ABSTRACT:
  13.  *    This file contains main program to convert GIF files into
  14.  *    one-dimensional group-3 FAX compressed files.
  15.  *
  16.  * AUTHOR: Doug Chinnock
  17.  *
  18.  * REVISION HISTORY:
  19.  *
  20.  */
  21.  
  22. #include        <stdio.h>
  23. #include    <string.h>
  24. #include    <dos.h>
  25.  
  26. #include    "GIFbase.h"
  27. #include    "cnvhuf.h"
  28. #include    "rletif.h"
  29. #include    "writetif.h"
  30. #include    "readgif.h"
  31. #include    "gifreade.h"
  32. #include    "expander.h"
  33.  
  34. extern    int    scan_lines; 
  35.  
  36. /* Define all the prototypes */
  37.  
  38. #include    "writetif.h"
  39.  
  40. short int    write_TIF_pixel( unsigned char    TIF_pixel );
  41.  
  42. void    add_TIF_tag(    short int    TT_tag_code,
  43.             short int    TT_value_type,
  44.             long int    TT_value_count,
  45.             short int    TT_value1,
  46.             short int    TT_value2
  47.            );
  48.  
  49. /* Top scope variables and constants: */
  50.  
  51. static rle_line
  52.     TIF_cur_line;
  53.  
  54. static IFD_header
  55.     * IFD_body;
  56.  
  57. static struct
  58.     {
  59.     short int
  60.     entry_idx;            /* Entry with offset values */
  61.     short int
  62.     entry_offset;            /* Values loc in ifd_offset_params */
  63.                     /* Or -1 if not yet determined */
  64.     } ifd_offset_entries[5];
  65.  
  66. static unsigned char
  67.     ifd_offset_params[250];        /* Place to accum oversize parameters */
  68.  
  69. static short int
  70.     ifd_offsets_count,            /* Number of ifd_offset_entries */
  71.     ifd_offset_free,            /* 1st free byte in ifd_offset_params */
  72.     ifd_offsets_begin,            /* 1st byte in file for offset values */
  73.     ifd_offsets_end,            /* Last byte in file for offset values */
  74.     OBJ_screen_width,            /* Length of lines to use to make TIF */
  75.     tot_lines;                /* Count of lines compressed */
  76.  
  77. static unsigned
  78.     scaling;
  79.  
  80. short int    write_TIF_pixel( unsigned char    TIF_pixel )
  81. {
  82. colors
  83.     BW_pixel;
  84.  
  85. unsigned
  86.     scale_count;
  87.  
  88. if ( TIF_pixel == 0 )
  89.     BW_pixel = WHITE;
  90. else
  91.     BW_pixel = BLACK;
  92.  
  93. for (scale_count = scaling; scale_count > 0; scale_count --)
  94.     {
  95.     TIF_cur_line.current_column ++;
  96.  
  97.     if ( TIF_cur_line.rle_pointer < LONGEST_RLE )
  98.     {                /* Buffer not full yet */
  99.     if ( BW_pixel == TIF_cur_line.rle_color )
  100.         {                /* More of same color */
  101.         TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] ++;
  102.         }
  103.     else
  104.         {                /* Color change */
  105.         TIF_cur_line.rle_color = BW_pixel;
  106.         TIF_cur_line.rle_pointer ++;
  107.         TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 1;
  108.         };
  109.     }
  110.     else
  111.     {                /* Buffer overflowed */
  112.     return -1;
  113.     }
  114.     }
  115.  
  116. if ( TIF_cur_line.current_column >= OBJ_screen_width )
  117.     {                /* Line full now */
  118.     while (TIF_cur_line.current_column < FAX_line_width )
  119.     {
  120.     if ( TIF_cur_line.rle_color != WHITE )
  121.         {
  122.         TIF_cur_line.rle_color = WHITE;
  123.         TIF_cur_line.rle_pointer ++;
  124.         TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 1;
  125.         }
  126.     else
  127.         {
  128.         TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] ++;
  129.         }
  130.  
  131.     TIF_cur_line.current_column ++;
  132.     } /* while (TIF_cur_line.current_column < FAX_line_screen_width ) */
  133.  
  134.     TIF_cur_line.rle_pointer ++;    /* Count the run */
  135.     TIF_cur_line.line_length = TIF_cur_line.current_column;
  136.     TIF_cur_line.rle_count = TIF_cur_line.rle_pointer;
  137.  
  138. for (scale_count = scaling; scale_count > 0; scale_count --)
  139.     compress_huffman_line( &TIF_cur_line );
  140.  
  141.     /* Start new line */
  142.  
  143.     TIF_cur_line.current_column = 0;
  144.     TIF_cur_line.rle_color = 0;
  145.     TIF_cur_line.rle_pointer = 0;
  146.     TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 0;
  147.     };
  148.  
  149. return 0;
  150. } /* write_TIF_pixel */
  151.  
  152. void    add_TIF_tag(    short int    TT_tag_code,
  153.             short int    TT_value_type,
  154.             long int    TT_value_count,
  155.             short int    TT_value1,
  156.             short int    TT_value2
  157.            )
  158. {
  159.     (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  160.                 IFD_tag = TT_tag_code,
  161.         (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  162.                 IFD_type = TT_value_type;
  163.         (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  164.                 IFD_length = TT_value_count;
  165.         switch ( TT_value_type )
  166.             {
  167.             case 3 :        /* 16 bit unsigned integer(s) */
  168.             (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  169.                     params.short_pair[0] = TT_value1;
  170.             (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  171.                     params.short_pair[1] = TT_value2;
  172.             break;
  173.             case 4 :        /* 32 bit unsigned integer(s) */
  174.             (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  175.                     params.long_one = (long)TT_value1;
  176.             break;
  177.             case 5 :        /* fraction(2) of 2 32 bit integers */
  178.             ifd_offset_entries[ifd_offsets_count].entry_idx =
  179.                             (*IFD_body).IFD_ele_cnt;
  180.             ifd_offset_entries[ifd_offsets_count ++].entry_offset =
  181.                             ifd_offset_free;
  182.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  183.                     (long)(TT_value1) & 0xFF );
  184.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  185.                     ( (long)(TT_value1) >> 8 ) & 0xFF );
  186.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  187.                     ( (long)(TT_value1) >> 16 ) & 0xFF );
  188.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  189.                     (long)(TT_value1) >> 24 );
  190.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  191.                     (long)(TT_value2) & 0xFF );
  192.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  193.                     ( (long)(TT_value2) >> 8 ) & 0xFF );
  194.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  195.                     ( (long)(TT_value2) >> 16 ) & 0xFF );
  196.             ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
  197.                     (long)(TT_value2) >> 24 );
  198.             break;
  199.             case 1 :        /* 8 bit unsigned integer(s) */
  200.             case 2 :        /* ASCIZ string */
  201.             default :
  202.             printf( "\nTIF type not supported yet\n" );
  203.             break;
  204.             }; /* switch ( IFD_type ) */
  205.  
  206.         (*IFD_body).IFD_ele_cnt ++;
  207.  
  208. } /* add_TIF_tag */
  209.  
  210. void main (void)
  211. {
  212.    char
  213.     LetterAnswer[2],
  214.     input_name[25],
  215.     output_name[25];
  216.    unsigned
  217.     done;
  218.    short
  219.     GIF_screen_width,
  220.     GIF_screen_height,
  221.     GIF_color_res,
  222.     GIF_fill_color,
  223.     GIF_default_color_cnt,
  224.     GIF_left_edge,
  225.     GIF_top_edge,
  226.     GIF_width,
  227.     GIF_height,
  228.     GIF_interlaced,
  229.     GIF_img_color_cnt,
  230.     i,
  231.     status;
  232.  
  233.     static struct ColorEntry
  234.     GIF_default_map[MaxColors],
  235.     GIF_img_map[MaxColors];
  236.  
  237.     static union
  238.     {            /* Buffer to hold whole TIF header */
  239.     TIF_header    TIF_member;
  240.     char        TIF_buffer[sizeof(TIF_header)+sizeof(IFD_header)];
  241.     }    TIF_work_bfr;
  242.  
  243.     static char
  244.     TIF_sign_contents[4] = TIF_sign_par;
  245.  
  246.     /* Access and prepare the GIF file */
  247.  
  248.     do
  249.     {
  250.     printf( "\nGIF source file: " );
  251.     scanf( "%25s", input_name );
  252.     }
  253.     while ( init_GIF_input(input_name) != 0 );
  254.  
  255.     status = ReadScreenDesc(
  256.                    next_GIF_byte,
  257.              & GIF_screen_width,
  258.              & GIF_screen_height,
  259.              & GIF_color_res,
  260.              & GIF_fill_color,
  261.              & GIF_default_color_cnt,
  262.                GIF_default_map,
  263.                MaxColors
  264.             );
  265.     if ( status == 0 )
  266.     {            /* GIF data set not acceptable */
  267.     printf( "\nGIF file not acceptable for conversion\n" );
  268.     return;
  269.     };
  270.  
  271.     printf( "GIF file has %d lines %d pixels long\n Is scaling wanted? ",
  272.         GIF_screen_height,
  273.         GIF_screen_width );
  274.     scanf( "%1s", LetterAnswer );
  275.  
  276.     if ( LetterAnswer[0] == 'Y' || LetterAnswer[0] == 'y' )
  277.     {
  278.     scaling = 0;
  279.     while ( scaling == 0
  280.         ||  GIF_screen_width*scaling > FAX_line_width )
  281.         {
  282.         printf( "   Desired enlargement multiplier: ");
  283.         scanf( "%u", &scaling );
  284.         }
  285.     }
  286.     else
  287.     {
  288.     scaling = 1;
  289.     }
  290.  
  291.     OBJ_screen_width = GIF_screen_width * scaling;
  292.  
  293.     /* Activate the TIF file builder */
  294.  
  295.     printf( "TIF product file: " );
  296.     scanf( "%25s", output_name );
  297.     init_TIF_output(output_name);
  298.  
  299.     tot_lines = 0;
  300.     done = 0;
  301.  
  302.     while (! done)
  303.     {
  304.     switch ( next_GIF_byte() )    /* Get character after header */
  305.         {
  306.         case ',' :            /* Start of image */
  307.         if (! ReadImageDesc( next_GIF_byte,
  308.                      & GIF_left_edge,
  309.                      & GIF_top_edge,
  310.                      & GIF_width,
  311.                      & GIF_height,
  312.                      & GIF_interlaced,
  313.                      & GIF_img_color_cnt,
  314.                        GIF_img_map,
  315.                        MaxColors ) )
  316.             {
  317.             printf( "\nGIF file not acceptable for conversion\n" );
  318.             return;
  319.             };
  320.  
  321.         /* Test compatibility */
  322.  
  323.         if ( GIF_interlaced )
  324.             {
  325.             printf( "\nCannot handle interlaced GIF\n" );
  326.             return;
  327.             };
  328.  
  329.         /* Create TIF header */
  330.  
  331.         for (i = 0; i < 4; i ++ )
  332.             TIF_work_bfr.TIF_member.TIF_sign[i] = TIF_sign_contents[i];
  333.         TIF_work_bfr.TIF_member.IFD_offset = sizeof(TIF_header);
  334.  
  335.         IFD_body = (IFD_header *)(&TIF_work_bfr);
  336.         FP_OFF(IFD_body) += sizeof(TIF_header);
  337.         (*IFD_body).IFD_ele_cnt = 0;
  338.  
  339.         ifd_offsets_count = 0;
  340.         ifd_offset_free = 0;
  341.  
  342.         /* Following must be in ascending order by IFD_tag field */
  343.  
  344.         add_TIF_tag( TT_width, TT_width_type, TT_width_cnt, 1728, 0 );
  345.         add_TIF_tag( TT_length, TT_length_type, TT_length_cnt,
  346.                  GIF_height, 0 );
  347.         add_TIF_tag( TT_PixBits, TT_PixBits_type, TT_PixBits_cnt,
  348.                  TT_PixBits_par, 0 );
  349.         add_TIF_tag( TT_Cmprs, TT_Cmprs_type, TT_Cmprs_cnt,
  350.                  TT_Cmprs_par, 0 );
  351.         add_TIF_tag( TT_Revrs, TT_Revrs_type, TT_Revrs_cnt,
  352.                  TT_Revrs_par, 0 );
  353.         add_TIF_tag( TT_MSBend, TT_MSBend_type, TT_MSBend_cnt,
  354.                  TT_MSBend_par, 0 );
  355.  
  356.         (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  357.                 IFD_tag = TT_Image;
  358.         (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  359.                 IFD_type = TT_Image_type;
  360.         (*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
  361.                 IFD_length = 1;
  362.         ifd_offset_entries[ifd_offsets_count].entry_idx =
  363.                             (*IFD_body).IFD_ele_cnt;
  364.         ifd_offset_entries[ifd_offsets_count ++].entry_offset = -1;
  365.         (*IFD_body).IFD_ele_cnt ++;
  366.  
  367.         add_TIF_tag( TT_Orient, TT_Orient_type, TT_Orient_cnt,
  368.                  TT_Orient_par, 0 );
  369.         add_TIF_tag( TT_Samps, TT_Samps_type, TT_Samps_cnt,
  370.                  TT_Samps_par, 0 );
  371.         add_TIF_tag( TT_X_dense, TT_X_dense_type, TT_X_dense_cnt,
  372.                  TT_X_dense_par1, TT_X_dense_par2 );
  373.         add_TIF_tag( TT_Y_dense, TT_Y_dense_type, TT_Y_dense_cnt,
  374.                  TT_Y_dense_par1, TT_Y_dense_par2 );
  375.         add_TIF_tag( TT_Grp3Opt, TT_Grp3Opt_type, TT_Grp3Opt_cnt,
  376.                   TT_Grp3Opt_par, 0 );
  377.         add_TIF_tag( TT_Resol, TT_Resol_type, TT_Resol_cnt,
  378.                  TT_Resol_par, 0 );
  379.         add_TIF_tag( TT_PagNum, TT_PagNum_type, TT_PagNum_cnt,
  380.                  TT_PagNum_par1, TT_PagNum_par2 );
  381.  
  382.         ifd_offsets_begin = sizeof(TIF_header) + sizeof(short int)
  383.              + sizeof(IFD_tag_body) * (*IFD_body).IFD_ele_cnt + 4;
  384.         ifd_offsets_end = ifd_offsets_begin + ifd_offset_free;
  385.  
  386.         /* Insert offset pointers into header just build */
  387.  
  388.         for ( i = 0; i < ifd_offsets_count; i ++ )
  389.             {
  390.             if ( ifd_offset_entries[i].entry_offset >= 0 )
  391.             (*IFD_body)
  392.             .IFD_tag_element[ ifd_offset_entries[i].entry_idx ]
  393.             .params.offset = ifd_offsets_begin
  394.                            + ifd_offset_entries[i].entry_offset;
  395.             else
  396.             (*IFD_body)
  397.             .IFD_tag_element[ ifd_offset_entries[i].entry_idx ]
  398.             .params.offset = ifd_offsets_end;
  399.             };
  400.  
  401.         /* Write out the header */
  402.  
  403.         for ( i = 0; i < ifd_offsets_begin - 4; i ++ )
  404.             put_TIF_byte( TIF_work_bfr.TIF_buffer[ i ] );
  405.  
  406.         /* Write out the link to the next IFD */
  407.  
  408.         for ( i = 0; i < 4; i ++ )
  409.             put_TIF_byte( 0 );        /* NULL */
  410.  
  411.         /* Write out the indirect parameters */
  412.  
  413.         for ( i = 0; i < ifd_offset_free; i ++ )
  414.             put_TIF_byte( ifd_offset_params[ i ] );
  415.  
  416.         /* Setup for conversion of GIF to TIF images */
  417.  
  418.         TIF_cur_line.current_column = 0;
  419.         TIF_cur_line.rle_pointer = 0;
  420.         TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 0;
  421.  
  422.         /* Perform the conversion */
  423.  
  424.         status = Expand_Data( next_GIF_byte,
  425.                       write_TIF_pixel );
  426.  
  427.         if ( status != 0 )
  428.             {
  429.             printf( "\nGIF file not acceptable for conversion\n" );
  430.             return;
  431.             };
  432.  
  433.         for ( i = 0; i < 6; i ++ )
  434.             TIF_write_bits( 12, 0x1);    /* Write end of page code */
  435.  
  436.         break;
  437.  
  438.         case ';' :            /* End of dataset */
  439.         done = 1;
  440.         break;
  441.  
  442.         case '!' :            /* undefined extension */
  443.         printf( "\nGIF file not acceptable for conversion\n" );
  444.         return;
  445.  
  446.         default :            /* Unknown delimiter */
  447.         printf( "\nGIF file not acceptable for conversion\n" );
  448.         return;
  449.  
  450.         } /* switch */
  451.     } /* while (! done) */
  452.  
  453.    close_stream( );
  454.    finish_output( );
  455. }
  456.