home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
1st Canadian Shareware Disc
/
1st_Canadian_Shareware_Disc_1991.ISO
/
graphics
/
giftif
/
giftif.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-21
|
13KB
|
456 lines
/*----------------------------------------------------------------------*/
/* Copyright (c) 1988-1989 */
/* by CompuServe Inc., Tucson, AZ. All Rights Reserved */
/* GIFTIF.C can be copied and distributed freely for any */
/* non-commercial purposes. GIFTIF.C can only be incorporated */
/* into commercial software with the permission of CompuServe Inc. */
/*----------------------------------------------------------------------*/
/* GIFTIF.C */
/*
* ABSTRACT:
* This file contains main program to convert GIF files into
* one-dimensional group-3 FAX compressed files.
*
* AUTHOR: Doug Chinnock
*
* REVISION HISTORY:
*
*/
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include "GIFbase.h"
#include "cnvhuf.h"
#include "rletif.h"
#include "writetif.h"
#include "readgif.h"
#include "gifreade.h"
#include "expander.h"
extern int scan_lines;
/* Define all the prototypes */
#include "writetif.h"
short int write_TIF_pixel( unsigned char TIF_pixel );
void add_TIF_tag( short int TT_tag_code,
short int TT_value_type,
long int TT_value_count,
short int TT_value1,
short int TT_value2
);
/* Top scope variables and constants: */
static rle_line
TIF_cur_line;
static IFD_header
* IFD_body;
static struct
{
short int
entry_idx; /* Entry with offset values */
short int
entry_offset; /* Values loc in ifd_offset_params */
/* Or -1 if not yet determined */
} ifd_offset_entries[5];
static unsigned char
ifd_offset_params[250]; /* Place to accum oversize parameters */
static short int
ifd_offsets_count, /* Number of ifd_offset_entries */
ifd_offset_free, /* 1st free byte in ifd_offset_params */
ifd_offsets_begin, /* 1st byte in file for offset values */
ifd_offsets_end, /* Last byte in file for offset values */
OBJ_screen_width, /* Length of lines to use to make TIF */
tot_lines; /* Count of lines compressed */
static unsigned
scaling;
short int write_TIF_pixel( unsigned char TIF_pixel )
{
colors
BW_pixel;
unsigned
scale_count;
if ( TIF_pixel == 0 )
BW_pixel = WHITE;
else
BW_pixel = BLACK;
for (scale_count = scaling; scale_count > 0; scale_count --)
{
TIF_cur_line.current_column ++;
if ( TIF_cur_line.rle_pointer < LONGEST_RLE )
{ /* Buffer not full yet */
if ( BW_pixel == TIF_cur_line.rle_color )
{ /* More of same color */
TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] ++;
}
else
{ /* Color change */
TIF_cur_line.rle_color = BW_pixel;
TIF_cur_line.rle_pointer ++;
TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 1;
};
}
else
{ /* Buffer overflowed */
return -1;
}
}
if ( TIF_cur_line.current_column >= OBJ_screen_width )
{ /* Line full now */
while (TIF_cur_line.current_column < FAX_line_width )
{
if ( TIF_cur_line.rle_color != WHITE )
{
TIF_cur_line.rle_color = WHITE;
TIF_cur_line.rle_pointer ++;
TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 1;
}
else
{
TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] ++;
}
TIF_cur_line.current_column ++;
} /* while (TIF_cur_line.current_column < FAX_line_screen_width ) */
TIF_cur_line.rle_pointer ++; /* Count the run */
TIF_cur_line.line_length = TIF_cur_line.current_column;
TIF_cur_line.rle_count = TIF_cur_line.rle_pointer;
for (scale_count = scaling; scale_count > 0; scale_count --)
compress_huffman_line( &TIF_cur_line );
/* Start new line */
TIF_cur_line.current_column = 0;
TIF_cur_line.rle_color = 0;
TIF_cur_line.rle_pointer = 0;
TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 0;
};
return 0;
} /* write_TIF_pixel */
void add_TIF_tag( short int TT_tag_code,
short int TT_value_type,
long int TT_value_count,
short int TT_value1,
short int TT_value2
)
{
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
IFD_tag = TT_tag_code,
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
IFD_type = TT_value_type;
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
IFD_length = TT_value_count;
switch ( TT_value_type )
{
case 3 : /* 16 bit unsigned integer(s) */
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
params.short_pair[0] = TT_value1;
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
params.short_pair[1] = TT_value2;
break;
case 4 : /* 32 bit unsigned integer(s) */
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
params.long_one = (long)TT_value1;
break;
case 5 : /* fraction(2) of 2 32 bit integers */
ifd_offset_entries[ifd_offsets_count].entry_idx =
(*IFD_body).IFD_ele_cnt;
ifd_offset_entries[ifd_offsets_count ++].entry_offset =
ifd_offset_free;
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
(long)(TT_value1) & 0xFF );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
( (long)(TT_value1) >> 8 ) & 0xFF );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
( (long)(TT_value1) >> 16 ) & 0xFF );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
(long)(TT_value1) >> 24 );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
(long)(TT_value2) & 0xFF );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
( (long)(TT_value2) >> 8 ) & 0xFF );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
( (long)(TT_value2) >> 16 ) & 0xFF );
ifd_offset_params[ifd_offset_free ++] = (unsigned char)(
(long)(TT_value2) >> 24 );
break;
case 1 : /* 8 bit unsigned integer(s) */
case 2 : /* ASCIZ string */
default :
printf( "\nTIF type not supported yet\n" );
break;
}; /* switch ( IFD_type ) */
(*IFD_body).IFD_ele_cnt ++;
} /* add_TIF_tag */
void main (void)
{
char
LetterAnswer[2],
input_name[25],
output_name[25];
unsigned
done;
short
GIF_screen_width,
GIF_screen_height,
GIF_color_res,
GIF_fill_color,
GIF_default_color_cnt,
GIF_left_edge,
GIF_top_edge,
GIF_width,
GIF_height,
GIF_interlaced,
GIF_img_color_cnt,
i,
status;
static struct ColorEntry
GIF_default_map[MaxColors],
GIF_img_map[MaxColors];
static union
{ /* Buffer to hold whole TIF header */
TIF_header TIF_member;
char TIF_buffer[sizeof(TIF_header)+sizeof(IFD_header)];
} TIF_work_bfr;
static char
TIF_sign_contents[4] = TIF_sign_par;
/* Access and prepare the GIF file */
do
{
printf( "\nGIF source file: " );
scanf( "%25s", input_name );
}
while ( init_GIF_input(input_name) != 0 );
status = ReadScreenDesc(
next_GIF_byte,
& GIF_screen_width,
& GIF_screen_height,
& GIF_color_res,
& GIF_fill_color,
& GIF_default_color_cnt,
GIF_default_map,
MaxColors
);
if ( status == 0 )
{ /* GIF data set not acceptable */
printf( "\nGIF file not acceptable for conversion\n" );
return;
};
printf( "GIF file has %d lines %d pixels long\n Is scaling wanted? ",
GIF_screen_height,
GIF_screen_width );
scanf( "%1s", LetterAnswer );
if ( LetterAnswer[0] == 'Y' || LetterAnswer[0] == 'y' )
{
scaling = 0;
while ( scaling == 0
|| GIF_screen_width*scaling > FAX_line_width )
{
printf( " Desired enlargement multiplier: ");
scanf( "%u", &scaling );
}
}
else
{
scaling = 1;
}
OBJ_screen_width = GIF_screen_width * scaling;
/* Activate the TIF file builder */
printf( "TIF product file: " );
scanf( "%25s", output_name );
init_TIF_output(output_name);
tot_lines = 0;
done = 0;
while (! done)
{
switch ( next_GIF_byte() ) /* Get character after header */
{
case ',' : /* Start of image */
if (! ReadImageDesc( next_GIF_byte,
& GIF_left_edge,
& GIF_top_edge,
& GIF_width,
& GIF_height,
& GIF_interlaced,
& GIF_img_color_cnt,
GIF_img_map,
MaxColors ) )
{
printf( "\nGIF file not acceptable for conversion\n" );
return;
};
/* Test compatibility */
if ( GIF_interlaced )
{
printf( "\nCannot handle interlaced GIF\n" );
return;
};
/* Create TIF header */
for (i = 0; i < 4; i ++ )
TIF_work_bfr.TIF_member.TIF_sign[i] = TIF_sign_contents[i];
TIF_work_bfr.TIF_member.IFD_offset = sizeof(TIF_header);
IFD_body = (IFD_header *)(&TIF_work_bfr);
FP_OFF(IFD_body) += sizeof(TIF_header);
(*IFD_body).IFD_ele_cnt = 0;
ifd_offsets_count = 0;
ifd_offset_free = 0;
/* Following must be in ascending order by IFD_tag field */
add_TIF_tag( TT_width, TT_width_type, TT_width_cnt, 1728, 0 );
add_TIF_tag( TT_length, TT_length_type, TT_length_cnt,
GIF_height, 0 );
add_TIF_tag( TT_PixBits, TT_PixBits_type, TT_PixBits_cnt,
TT_PixBits_par, 0 );
add_TIF_tag( TT_Cmprs, TT_Cmprs_type, TT_Cmprs_cnt,
TT_Cmprs_par, 0 );
add_TIF_tag( TT_Revrs, TT_Revrs_type, TT_Revrs_cnt,
TT_Revrs_par, 0 );
add_TIF_tag( TT_MSBend, TT_MSBend_type, TT_MSBend_cnt,
TT_MSBend_par, 0 );
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
IFD_tag = TT_Image;
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
IFD_type = TT_Image_type;
(*IFD_body).IFD_tag_element[(*IFD_body).IFD_ele_cnt].
IFD_length = 1;
ifd_offset_entries[ifd_offsets_count].entry_idx =
(*IFD_body).IFD_ele_cnt;
ifd_offset_entries[ifd_offsets_count ++].entry_offset = -1;
(*IFD_body).IFD_ele_cnt ++;
add_TIF_tag( TT_Orient, TT_Orient_type, TT_Orient_cnt,
TT_Orient_par, 0 );
add_TIF_tag( TT_Samps, TT_Samps_type, TT_Samps_cnt,
TT_Samps_par, 0 );
add_TIF_tag( TT_X_dense, TT_X_dense_type, TT_X_dense_cnt,
TT_X_dense_par1, TT_X_dense_par2 );
add_TIF_tag( TT_Y_dense, TT_Y_dense_type, TT_Y_dense_cnt,
TT_Y_dense_par1, TT_Y_dense_par2 );
add_TIF_tag( TT_Grp3Opt, TT_Grp3Opt_type, TT_Grp3Opt_cnt,
TT_Grp3Opt_par, 0 );
add_TIF_tag( TT_Resol, TT_Resol_type, TT_Resol_cnt,
TT_Resol_par, 0 );
add_TIF_tag( TT_PagNum, TT_PagNum_type, TT_PagNum_cnt,
TT_PagNum_par1, TT_PagNum_par2 );
ifd_offsets_begin = sizeof(TIF_header) + sizeof(short int)
+ sizeof(IFD_tag_body) * (*IFD_body).IFD_ele_cnt + 4;
ifd_offsets_end = ifd_offsets_begin + ifd_offset_free;
/* Insert offset pointers into header just build */
for ( i = 0; i < ifd_offsets_count; i ++ )
{
if ( ifd_offset_entries[i].entry_offset >= 0 )
(*IFD_body)
.IFD_tag_element[ ifd_offset_entries[i].entry_idx ]
.params.offset = ifd_offsets_begin
+ ifd_offset_entries[i].entry_offset;
else
(*IFD_body)
.IFD_tag_element[ ifd_offset_entries[i].entry_idx ]
.params.offset = ifd_offsets_end;
};
/* Write out the header */
for ( i = 0; i < ifd_offsets_begin - 4; i ++ )
put_TIF_byte( TIF_work_bfr.TIF_buffer[ i ] );
/* Write out the link to the next IFD */
for ( i = 0; i < 4; i ++ )
put_TIF_byte( 0 ); /* NULL */
/* Write out the indirect parameters */
for ( i = 0; i < ifd_offset_free; i ++ )
put_TIF_byte( ifd_offset_params[ i ] );
/* Setup for conversion of GIF to TIF images */
TIF_cur_line.current_column = 0;
TIF_cur_line.rle_pointer = 0;
TIF_cur_line.rle_list[TIF_cur_line.rle_pointer] = 0;
/* Perform the conversion */
status = Expand_Data( next_GIF_byte,
write_TIF_pixel );
if ( status != 0 )
{
printf( "\nGIF file not acceptable for conversion\n" );
return;
};
for ( i = 0; i < 6; i ++ )
TIF_write_bits( 12, 0x1); /* Write end of page code */
break;
case ';' : /* End of dataset */
done = 1;
break;
case '!' : /* undefined extension */
printf( "\nGIF file not acceptable for conversion\n" );
return;
default : /* Unknown delimiter */
printf( "\nGIF file not acceptable for conversion\n" );
return;
} /* switch */
} /* while (! done) */
close_stream( );
finish_output( );
}