Category : Files from Magazines
Archive   : CUJ0894.ZIP
Filename : SCALE.C

 
Output of file : SCALE.C contained in archive : CUJ0894.ZIP
/***************************************************************
* file: SCALE.C
* purpose: demonstration framework for minimalist scaler, see usage()
* copyright: 1994 by David Weber. All rights reserved.
* history:
* 04-4-94 - initial code cobbled together from various sources
**************************************************************/

#include
#include
#include
#include
#include
#include
#include
#include
#include "args.h"
#include "pcx.h"
#include "faxscale.h"

/* Borland 4.0 exception plug */
#ifdef __BORLANDC__
void _ExceptInit(void) {}
#endif

/* definitions */
#define EXIT_OK 0 /* exit values for scale */
#define EXIT_USAGE 1
#define EXIT_OPEN_FAIL 2
#define EXIT_NO_MEMORY 3
#define EXIT_BAD_PCX 4
#define EXIT_WRITE_ERROR 5
#define EXIT_READ_ERROR 6
#define EXIT_BAD_SCALE 7
#ifndef FILENAME_MAX /* maximum length for a filename, ANSI C */
#define FILENAME_MAX 128
#endif
#define SRC_BUFFER_SIZE 8192 /* input and output buffer sizes */
#define DEST_BUFFER_SIZE 8192
#define SCALE_BUFFER_SIZE 32768 /* split scaling buffer */
#define FAX_WIDTH 216 /* byte width of a fax line */
#define MAX_FAX_LENGTH 2800 /* arbitrary maximum page length 14" @ 200 dpi */

/* global functions */
void usage(void); /* global so args.c can grab it */

/* local functions */
static void cleanup(void); /* cleans up resources */

/* local data */
static int x_scale,y_scale; /* x & y scale factors in percent */
static int src_handle,dest_handle; /* file handles for input and output files */
static unsigned char *src_file_buffer; /* file buffer pointers */
static unsigned char *dest_file_buffer;
static unsigned char *src_scale_buffer; /* scaling buffers */
static unsigned char *dest_scale_buffer;
static unsigned int src_bytes_per_line; /* bytes in a source scan line */
static unsigned int dest_bytes_per_line; /* bytes in a destination scan line */
static char formatlist[] = {INTARG,INTARG}; /* stuff for argument parser in args.c */
static void *valuelist[] = {&x_scale,&y_scale};
static char src_file[FILENAME_MAX+1];
static char dest_file[FILENAME_MAX+1];
static char *namelist[] = {src_file,dest_file,NULL};
static ARGS arglist = /* command line arguments */
{
"xy",
formatlist,
valuelist,
FILENAME_MAX,
namelist
} ;


/* wherein life commences
* opens files, sets up buffers, loops on scaler, closes down
* note: there are four buffers, the flow goes as this
* fill src_file_buffer from file as needed
* decode pcx from src_file buffer to src_scale_buffer
* scale from src_scale_buffer to dest_scale_buffer
* encode pcx from dest_scale_buffer to dest_file_buffer
* write dest_file_buffer out to disk as needed
* just begs for threads doesn't it?
*/
int main(int argc,char *argv[])
{
int repeat;
unsigned int lines_per_buffer,src_max_size,src_actual_size;
unsigned int src_lines,dest_lines,total_lines;
unsigned char *src_ptr,*dest_ptr;

parseargs(argc,argv,&arglist); /* get command line arguments */
if (src_file[0] == 0 || dest_file[0] == 0 || x_scale == 0 || y_scale == 0)
usage(); /* all arguments must be used */
src_handle = dest_handle = -1; /* preset buffer/handles as unused */
src_file_buffer = dest_file_buffer = src_scale_buffer = NULL;
if (stricmp(src_file,dest_file) == 0)
{ /* verify files different */
printf("The source file and the destination file cannot be the same.\n");
exit(EXIT_OPEN_FAIL);
}
if ((src_handle = open(src_file,O_RDONLY|O_BINARY)) == -1)
{ /* get source */
printf("Cannot open source file - %s.\n",src_file);
exit(EXIT_OPEN_FAIL);
}
if ((dest_handle = open(dest_file,O_WRONLY|O_BINARY|O_TRUNC|O_CREAT,S_IREAD|S_IWRITE)) == NULL)
{ /* get destination */
printf("Cannot open destination file - %s.\n",dest_file);
cleanup();
exit(EXIT_OPEN_FAIL);
}
src_file_buffer = (unsigned char *) malloc(SRC_BUFFER_SIZE);
dest_file_buffer = (unsigned char *) malloc(DEST_BUFFER_SIZE);
src_scale_buffer = (unsigned char *) malloc(SCALE_BUFFER_SIZE);
if (src_file_buffer == NULL || dest_file_buffer == NULL || src_scale_buffer == NULL)
{ /* allocate memory */
printf("Insufficient memory.\n");
cleanup();
exit(EXIT_NO_MEMORY);
}
if (!open_pcx_read(src_handle,src_file_buffer,SRC_BUFFER_SIZE,&src_bytes_per_line))
{ /* read source PCX header */
printf("Improper PCX format, must be a monochrome PCX/DCX file.\n");
cleanup();
exit(EXIT_BAD_PCX);
}
dest_bytes_per_line = FAX_WIDTH; /* partition split buffer and set up sizes */
lines_per_buffer = (unsigned int) (((long) y_scale * (long) dest_bytes_per_line)/100L + 1) + src_bytes_per_line;
lines_per_buffer = (SCALE_BUFFER_SIZE / lines_per_buffer) - 1;
assert(lines_per_buffer > 0);
src_max_size = lines_per_buffer * src_bytes_per_line;
dest_scale_buffer = src_scale_buffer + lines_per_buffer * src_bytes_per_line;
if (!open_pcx_write(dest_handle,dest_file_buffer,DEST_BUFFER_SIZE,dest_bytes_per_line))
{ /* set up destination PCX header */
printf("Cannot write to destination file - %s.\n",dest_file);
cleanup();
exit(EXIT_WRITE_ERROR);
}
if (!init_fax_scale(x_scale,y_scale,src_bytes_per_line))
{ /* initialize scaler */
printf("Scale values out of range (3%% to 3200%%).\n");
cleanup();
exit(EXIT_BAD_SCALE);
}
total_lines = 0;
do /* main read/scale/write loop */
{ /* note: we have split the buffer so read_pcx and write_pcx stay in lock step */
if ((src_actual_size = read_pcx(src_scale_buffer,src_max_size)) == IO_ERROR)
{ /* read a buffer */
printf("Error reading source file - %s.\n",src_file);
cleanup();
exit(EXIT_READ_ERROR);
}
dest_lines = 0; /* set up line counters and pointers */
src_ptr = src_scale_buffer;
dest_ptr = dest_scale_buffer;
for (src_lines = src_actual_size/src_bytes_per_line ; src_lines > 0 ; src_lines--)
{ /* scale each source line */
repeat = scale_fax_line(dest_ptr,src_ptr);
dest_lines += repeat;
while (repeat--) /* repeat it if necessary */
{
if (repeat)
memcpy(dest_ptr+dest_bytes_per_line,dest_ptr,dest_bytes_per_line);
dest_ptr += dest_bytes_per_line;
}
src_ptr += src_bytes_per_line; /* move pointers */
}
assert(dest_ptr <= src_scale_buffer + SCALE_BUFFER_SIZE);
assert(src_ptr <= dest_scale_buffer);
if (write_pcx(dest_scale_buffer,dest_lines*dest_bytes_per_line) == IO_ERROR)
{ /* write out destination buffer */
printf("Cannot write to destination file - %s.\n",dest_file);
cleanup();
exit(EXIT_WRITE_ERROR);
}
total_lines += dest_lines;
} while (src_actual_size==src_max_size && total_lines if (!close_pcx_read()) /* close PCX source */
{
printf("Error reading source file - %s.\n",src_file);
cleanup();
exit(EXIT_READ_ERROR);
}
if (!close_pcx_write()) /* close PCX destination */
{
printf("Cannot write to destination file - %s.\n",dest_file);
cleanup();
exit(EXIT_WRITE_ERROR);
}
cleanup(); /* deallocate resources */
return EXIT_OK; /* and head home */
}


/************************************************
* function: void usage(void)
* print usage and bomb out
* parameters: none
* returns: exits
************************************************/
void usage(void)
{
printf("Usage: scale -x%% -y%% infile outfile\n");
printf(" Scales a PCX file using a minimalist scaler.\n");
printf(" -h -? print help listing\n");
printf(" -x%% horizontal scale factor in percent, eg. -x50 scales by 50%%\n");
printf(" -y%% vertical scale factor in percent\n");
printf(" infile filename of PCX source\n");
printf(" outfile filename of PCX destination, not the same as the source\n");
printf("\nVersion 1.0 Copyright 1994 - David Weber\n");
exit(EXIT_USAGE);
}


/************************************************
* function: static void cleanup(void)
* cleans up allocated resources
* parameters: none
* returns: nothing
************************************************/
static void cleanup(void)
{
if (src_scale_buffer != NULL) /* buffers */
free(src_scale_buffer);
if (dest_file_buffer != NULL)
free(dest_file_buffer);
if (src_file_buffer != NULL)
free(src_file_buffer);
if (dest_handle != NULL) /* files */
close(dest_handle);
if (src_handle != NULL)
close(src_handle);
}


  3 Responses to “Category : Files from Magazines
Archive   : CUJ0894.ZIP
Filename : SCALE.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/