cnv/painttorle.c

Summary

Maintainability
Test Coverage
/*
 * This software is copyrighted as noted below.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is 
 * preserved on all copies.
 * 
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the author, who may or may not act on them as he desires.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the 
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 */
/* 
 * paint2rle.c - Convert MacPaint images to RLE.
 * 
 * Author:    John W. Peterson
 *         Computer Science Dept.
 *         University of Utah
 * Date:    Wed Oct 15 1986
 * Copyright (c) 1986, John W. Peterson
 *
 * Usage is:
 *   paint2rle [-c [r] [g] [b] [alpha]] [-r] [-o outfile.rle] [infile.paint] 
 *
 * -r         Inverts the pixels in the macpaint file
 *  r,g,b,a    Allows the value of the resulting RLE file to be specified.
 *
 * The rleflip is needed because MacPaint images have their origin at the
 * top left instead of the bottom.
 */

#include <stdio.h>
#include "rle.h"

/* Default color values */
int redval = 255, grnval = 255, bluval = 255, alfval = 255;
unsigned char in_line[72];
rle_pixel **outrows;
int  xlat[256];
int invert_flag = 0, oflag = 0;

void init(), read_scan(), write_scan();

void
main(argc,argv) 
int argc;
char *argv[];
{ 
    char            *in_fname = NULL,
                   *out_fname = NULL;
    int            cflag = 0;
    FILE           *infile;
    int i;
    rle_hdr        hdr;

    if ( scanargs( argc, argv,
       "% c%-red%dgreen%dblue%dalpha%d r%- o%-outfile!s infile.paint%s\n(\
\tConvert MacPaint file to RLE.\n\
\t-c\tSpecify \"white\" color, optionally include alpha value.\n\
\t-r\tReverse image (foreground colored, background black).)",
           &cflag, &redval, &grnval, &bluval, &alfval, &invert_flag,
           &oflag, &out_fname, &in_fname ) == 0)
    exit(-1);
  
    hdr = *rle_hdr_init( (rle_hdr *)NULL );
    rle_names( &hdr, cmd_name( argv ), in_fname, 0 );
    infile = rle_open_f( hdr.cmd, in_fname, "r" );
    hdr.rle_file = rle_open_f(hdr.cmd, out_fname, "w");

    hdr.xmax = 575;
    hdr.ymax = 719;
    hdr.alpha = 1;
    hdr.ncolors = 3;
    RLE_SET_BIT( hdr, RLE_ALPHA );    /* So it gets generated */

    if (rle_row_alloc( &hdr, &outrows ))
    {
    fprintf(stderr, "%s: No heap space\n", hdr.cmd);
    exit(-2);
    }

    rle_addhist( argv, (rle_hdr *)NULL, &hdr );
    rle_put_setup( &hdr );
    /* initialize bit-twiddling tables */
    init();

    /* read and discard 512 byte MacPaint header */
    for (i=0; i<512; i++)
    getc(infile);

    /* Read and process each of the 720 MacPaint scan lines */
    for (i=0; i < 720; i++)
    {
    read_scan( infile );
    write_scan( &hdr );
    }

    rle_puteof( &hdr );
    exit(0);
}

/* 
 * Read a line from the MacPaint file, uncompressing the data into in_line 
 */
void
read_scan( infile )
FILE *infile;
{
    int in_pos, count, data_byte;

    in_pos = 0;
    while (in_pos < 72)
    {
    count = getc(infile);
    if (count > 127) count -= 256;

    if (count >= 0) {    /* run of raw bytes */
        count++;        /* # of bytes to read */
        while (count--)
        in_line[in_pos++] = getc(infile);
    }
    else {            /* run of repeated byte */
        count = -count+1;    /* repetition factor */
        data_byte = getc(infile); /* byte to repeat */

        while (count--)
        in_line[in_pos++] = data_byte;
    }
    }
}

/*
 * Write out a scanline
 */
void
write_scan( hdr )
rle_hdr *hdr;
{
    register int i, j;
    register int bit;
    int outval, outpos;

    /* Convert the array of bits to an array of pixels */

    for (i = 0; i < 72; i++ )
    {
    for (bit = 7; bit >= 0; bit--)
    {
        outval = xlat[in_line[i] & 0xff] & 0xff;
        outval = (outval >> bit) & 1; /* Convert to boolean */
        if (invert_flag) outval = 1-outval;
        outpos = i*8 + (7-bit);
        if (outval)
        {
        outrows[RLE_ALPHA][outpos] = alfval;
        outrows[RLE_RED][outpos]   = redval;
        outrows[RLE_GREEN][outpos] = grnval;
        outrows[RLE_BLUE][outpos]  = bluval;
        }
        else
        {
        for( j = RLE_ALPHA; j <= RLE_BLUE; j++ )
            outrows[j][outpos] = 0;
        }
     }
    }
    rle_putrow( outrows, 576, hdr );
}

/* Set up some tables for converting bits to bytes */
void
init() 
{
    int bits[8], i, j;

    /* initialize translation table */
    j = 1;
    for( i=0; i<8; i++ )
    {
    bits[i] = j;
    j *= (1 << 1);
    }

    for( i=0; i<256; i++ )
    {
    if( i &      1 )    xlat[i] = bits[0];
    else        xlat[i] = 0;

    if( i &   2 )    xlat[i] += bits[1];
    if( i &   4 )    xlat[i] += bits[2];
    if( i &   8 )   xlat[i] += bits[3];
    if( i &  16 )    xlat[i] += bits[4];
    if( i &  32 )    xlat[i] += bits[5];
    if( i &  64 )    xlat[i] += bits[6];
    if( i & 128 )    xlat[i] += bits[7];
    }
}