|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* This software is copyrighted as noted below. It may be freely copied,
|
|
Packit |
78deda |
* modified, and redistributed, provided that the copyright notice is
|
|
Packit |
78deda |
* preserved on all copies.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* There is no warranty or other guarantee of fitness for this software,
|
|
Packit |
78deda |
* it is provided solely "as is". Bug reports or fixes may be sent
|
|
Packit |
78deda |
* to the author, who may or may not act on them as he desires.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* You may not include this software in a program or other software product
|
|
Packit |
78deda |
* without supplying the source, or without informing the end-user that the
|
|
Packit |
78deda |
* source is available for no extra charge.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* If you modify this software, you should include a notice giving the
|
|
Packit |
78deda |
* name of the person performing the modification, the date of modification,
|
|
Packit |
78deda |
* and the reason for such modification.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
|
|
Packit |
78deda |
* to have all "void" functions so declared.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* rle_getrow.c - Read an RLE file in.
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* Author: Spencer W. Thomas
|
|
Packit |
78deda |
* Computer Science Dept.
|
|
Packit |
78deda |
* University of Utah
|
|
Packit |
78deda |
* Date: Wed Apr 10 1985
|
|
Packit |
78deda |
* Copyright (c) 1985 Spencer W. Thomas
|
|
Packit |
78deda |
*
|
|
Packit |
78deda |
* $Id: rle_getrow.c,v 3.0.1.5 1992/03/04 19:33:08 spencer Exp spencer $
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include <string.h>
|
|
Packit |
78deda |
#include <stdio.h>
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "netpbm/pm.h"
|
|
Packit |
78deda |
#include "netpbm/mallocvar.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "rle.h"
|
|
Packit |
78deda |
#include "rle_code.h"
|
|
Packit |
78deda |
#include "vaxshort.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */
|
|
Packit |
78deda |
#define VAXSHORT( var, fp )\
|
|
Packit |
78deda |
{ var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; }
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Instruction format -- first byte is opcode, second is datum. */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#define OPCODE(inst) (inst[0] & ~LONG)
|
|
Packit |
78deda |
#define LONGP(inst) (inst[0] & LONG)
|
|
Packit |
78deda |
#define DATUM(inst) (inst[1] & 0xff) /* Make sure it's unsigned. */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static int debug_f; /* If non-zero, print debug info. */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int
|
|
Packit |
78deda |
rle_get_setup(rle_hdr * const the_hdr) {
|
|
Packit |
78deda |
/*-----------------------------------------------------------------------------
|
|
Packit |
78deda |
Read the initialization information from an RLE file.
|
|
Packit |
78deda |
Inputs:
|
|
Packit |
78deda |
the_hdr: Contains pointer to the input file.
|
|
Packit |
78deda |
Outputs:
|
|
Packit |
78deda |
the_hdr: Initialized with information from the input file.
|
|
Packit |
78deda |
Returns
|
|
Packit |
78deda |
0 on success,
|
|
Packit |
78deda |
-1 if the file is not an RLE file,
|
|
Packit |
78deda |
-2 if malloc of the color map failed,
|
|
Packit |
78deda |
-3 if an immediate EOF is hit (empty input file)
|
|
Packit |
78deda |
-4 if an EOF is encountered reading the setup information.
|
|
Packit |
78deda |
Assumptions:
|
|
Packit |
78deda |
infile points to the "magic" number in an RLE file (usually byte 0
|
|
Packit |
78deda |
in the file).
|
|
Packit |
78deda |
Algorithm:
|
|
Packit |
78deda |
Read in the setup info and fill in the_hdr.
|
|
Packit |
78deda |
---------------------------------------------------------------------------- */
|
|
Packit |
78deda |
struct XtndRsetup setup;
|
|
Packit |
78deda |
short magic;
|
|
Packit |
78deda |
FILE * infile = the_hdr->rle_file;
|
|
Packit |
78deda |
int i;
|
|
Packit |
78deda |
char * comment_buf;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Clear old stuff out of the header. */
|
|
Packit |
78deda |
rle_hdr_clear(the_hdr);
|
|
Packit |
78deda |
if (the_hdr->is_init != RLE_INIT_MAGIC)
|
|
Packit |
78deda |
rle_names(the_hdr, "Urt", "some file", 0);
|
|
Packit |
78deda |
++the_hdr->img_num; /* Count images. */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
VAXSHORT(magic, infile);
|
|
Packit |
78deda |
if (feof(infile))
|
|
Packit |
78deda |
return RLE_EMPTY;
|
|
Packit |
78deda |
if (magic != RLE_MAGIC)
|
|
Packit |
78deda |
return RLE_NOT_RLE;
|
|
Packit |
78deda |
fread(&setup, 1, SETUPSIZE, infile); /* assume VAX packing */
|
|
Packit |
78deda |
if (feof( infile))
|
|
Packit |
78deda |
return RLE_EOF;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Extract information from setup */
|
|
Packit |
78deda |
the_hdr->ncolors = setup.h_ncolors;
|
|
Packit |
78deda |
for (i = 0; i < the_hdr->ncolors; ++i)
|
|
Packit |
78deda |
RLE_SET_BIT(*the_hdr, i);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (!(setup.h_flags & H_NO_BACKGROUND) && setup.h_ncolors > 0) {
|
|
Packit |
78deda |
rle_pixel * bg_color;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
MALLOCARRAY(the_hdr->bg_color, setup.h_ncolors);
|
|
Packit |
78deda |
MALLOCARRAY(bg_color, 1 + (setup.h_ncolors / 2) * 2);
|
|
Packit |
78deda |
RLE_CHECK_ALLOC(the_hdr->cmd, the_hdr->bg_color && bg_color,
|
|
Packit |
78deda |
"background color" );
|
|
Packit |
78deda |
fread((char *)bg_color, 1, 1 + (setup.h_ncolors / 2) * 2, infile);
|
|
Packit |
78deda |
for (i = 0; i < setup.h_ncolors; ++i)
|
|
Packit |
78deda |
the_hdr->bg_color[i] = bg_color[i];
|
|
Packit |
78deda |
free(bg_color);
|
|
Packit |
78deda |
} else {
|
|
Packit |
78deda |
getc(infile); /* skip filler byte */
|
|
Packit |
78deda |
the_hdr->bg_color = NULL;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (setup.h_flags & H_NO_BACKGROUND)
|
|
Packit |
78deda |
the_hdr->background = 0;
|
|
Packit |
78deda |
else if (setup.h_flags & H_CLEARFIRST)
|
|
Packit |
78deda |
the_hdr->background = 2;
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
the_hdr->background = 1;
|
|
Packit |
78deda |
if (setup.h_flags & H_ALPHA) {
|
|
Packit |
78deda |
the_hdr->alpha = 1;
|
|
Packit |
78deda |
RLE_SET_BIT( *the_hdr, RLE_ALPHA );
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
the_hdr->alpha = 0;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
the_hdr->xmin = vax_gshort(setup.hc_xpos);
|
|
Packit |
78deda |
the_hdr->ymin = vax_gshort(setup.hc_ypos);
|
|
Packit |
78deda |
the_hdr->xmax = the_hdr->xmin + vax_gshort(setup.hc_xlen) - 1;
|
|
Packit |
78deda |
the_hdr->ymax = the_hdr->ymin + vax_gshort(setup.hc_ylen) - 1;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
the_hdr->ncmap = setup.h_ncmap;
|
|
Packit |
78deda |
the_hdr->cmaplen = setup.h_cmaplen;
|
|
Packit |
78deda |
if (the_hdr->ncmap > 0) {
|
|
Packit |
78deda |
int const maplen = the_hdr->ncmap * (1 << the_hdr->cmaplen);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int i;
|
|
Packit |
78deda |
char *maptemp;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
MALLOCARRAY(the_hdr->cmap, maplen);
|
|
Packit |
78deda |
MALLOCARRAY(maptemp, 2 * maplen);
|
|
Packit |
78deda |
if (the_hdr->cmap == NULL || maptemp == NULL) {
|
|
Packit |
78deda |
pm_error("Malloc failed for color map of size %d*%d "
|
|
Packit |
78deda |
"in rle_get_setup, reading '%s'",
|
|
Packit |
78deda |
the_hdr->ncmap, (1 << the_hdr->cmaplen),
|
|
Packit |
78deda |
the_hdr->file_name );
|
|
Packit |
78deda |
return RLE_NO_SPACE;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
fread(maptemp, 2, maplen, infile);
|
|
Packit |
78deda |
for (i = 0; i < maplen; ++i)
|
|
Packit |
78deda |
the_hdr->cmap[i] = vax_gshort(&maptemp[i * 2]);
|
|
Packit |
78deda |
free(maptemp);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Check for comments */
|
|
Packit |
78deda |
if (setup.h_flags & H_COMMENT) {
|
|
Packit |
78deda |
short comlen, evenlen;
|
|
Packit |
78deda |
char * cp;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
VAXSHORT(comlen, infile); /* get comment length */
|
|
Packit |
78deda |
evenlen = (comlen + 1) & ~1; /* make it even */
|
|
Packit |
78deda |
if (evenlen) {
|
|
Packit |
78deda |
MALLOCARRAY(comment_buf, evenlen);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (comment_buf == NULL) {
|
|
Packit |
78deda |
pm_error("Malloc failed for comment buffer of size %d "
|
|
Packit |
78deda |
"in rle_get_setup, reading '%s'",
|
|
Packit |
78deda |
comlen, the_hdr->file_name );
|
|
Packit |
78deda |
return RLE_NO_SPACE;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
fread(comment_buf, 1, evenlen, infile);
|
|
Packit |
78deda |
/* Count the comments */
|
|
Packit |
78deda |
for (i = 0, cp = comment_buf; cp < comment_buf + comlen; ++cp)
|
|
Packit |
78deda |
if (*cp == '\0')
|
|
Packit |
78deda |
++i;
|
|
Packit |
78deda |
++i; /* extra for NULL pointer at end */
|
|
Packit |
78deda |
/* Get space to put pointers to comments */
|
|
Packit |
78deda |
MALLOCARRAY(the_hdr->comments, i);
|
|
Packit |
78deda |
if (the_hdr->comments == NULL) {
|
|
Packit |
78deda |
pm_error("Malloc failed for %d comment pointers "
|
|
Packit |
78deda |
"in rle_get_setup, reading '%s'",
|
|
Packit |
78deda |
i, the_hdr->file_name );
|
|
Packit |
78deda |
return RLE_NO_SPACE;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
/* Get pointers to the comments */
|
|
Packit |
78deda |
*the_hdr->comments = comment_buf;
|
|
Packit |
78deda |
for (i = 1, cp = comment_buf + 1;
|
|
Packit |
78deda |
cp < comment_buf + comlen;
|
|
Packit |
78deda |
++cp)
|
|
Packit |
78deda |
if (*(cp - 1) == '\0')
|
|
Packit |
78deda |
the_hdr->comments[i++] = cp;
|
|
Packit |
78deda |
the_hdr->comments[i] = NULL;
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
the_hdr->comments = NULL;
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
the_hdr->comments = NULL;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Initialize state for rle_getrow */
|
|
Packit |
78deda |
the_hdr->priv.get.scan_y = the_hdr->ymin;
|
|
Packit |
78deda |
the_hdr->priv.get.vert_skip = 0;
|
|
Packit |
78deda |
the_hdr->priv.get.is_eof = 0;
|
|
Packit |
78deda |
the_hdr->priv.get.is_seek = ftell(infile) > 0;
|
|
Packit |
78deda |
debug_f = 0;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (!feof(infile))
|
|
Packit |
78deda |
return RLE_SUCCESS; /* success! */
|
|
Packit |
78deda |
else {
|
|
Packit |
78deda |
the_hdr->priv.get.is_eof = 1;
|
|
Packit |
78deda |
return RLE_EOF;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
void
|
|
Packit |
78deda |
rle_get_setup_ok(rle_hdr * const the_hdr,
|
|
Packit |
78deda |
const char * const prog_name,
|
|
Packit |
78deda |
const char * const file_name) {
|
|
Packit |
78deda |
/*-----------------------------------------------------------------------------
|
|
Packit |
78deda |
Read the initialization information from an RLE file.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Inputs:
|
|
Packit |
78deda |
the_hdr: Contains pointer to the input file.
|
|
Packit |
78deda |
prog_name: Program name to be printed in the error message.
|
|
Packit |
78deda |
file_name: File name to be printed in the error message.
|
|
Packit |
78deda |
If NULL, the string "stdin" is generated.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Outputs:
|
|
Packit |
78deda |
the_hdr: Initialized with information from the input file.
|
|
Packit |
78deda |
If reading the header fails, it prints an error message
|
|
Packit |
78deda |
and exits with the appropriate status code.
|
|
Packit |
78deda |
Algorithm:
|
|
Packit |
78deda |
rle_get_setup does all the work.
|
|
Packit |
78deda |
---------------------------------------------------------------------------- */
|
|
Packit |
78deda |
int code;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Backwards compatibility: if is_init is not properly set,
|
|
Packit |
78deda |
* initialize the header.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
if (the_hdr->is_init != RLE_INIT_MAGIC) {
|
|
Packit |
78deda |
FILE * const f = the_hdr->rle_file;
|
|
Packit |
78deda |
rle_hdr_init( the_hdr );
|
|
Packit |
78deda |
the_hdr->rle_file = f;
|
|
Packit |
78deda |
rle_names(the_hdr, prog_name, file_name, 0);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
code = rle_get_error(rle_get_setup(the_hdr),
|
|
Packit |
78deda |
the_hdr->cmd, the_hdr->file_name);
|
|
Packit |
78deda |
if (code)
|
|
Packit |
78deda |
exit(code);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
void
|
|
Packit |
78deda |
rle_debug( on_off )
|
|
Packit |
78deda |
int on_off;
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
/*-----------------------------------------------------------------------------
|
|
Packit |
78deda |
Turn RLE debugging on or off.
|
|
Packit |
78deda |
Inputs:
|
|
Packit |
78deda |
on_off: if 0, stop debugging, else start.
|
|
Packit |
78deda |
Outputs:
|
|
Packit |
78deda |
Sets internal debug flag.
|
|
Packit |
78deda |
Assumptions:
|
|
Packit |
78deda |
[None]
|
|
Packit |
78deda |
Algorithm:
|
|
Packit |
78deda |
[None]
|
|
Packit |
78deda |
---------------------------------------------------------------------------- */
|
|
Packit |
78deda |
debug_f = on_off;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Set line buffering on stderr. Character buffering is the default, and
|
|
Packit |
78deda |
* it is SLOOWWW for large amounts of output.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
setvbuf(stderr, NULL, _IOLBF, 0);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int
|
|
Packit |
78deda |
rle_getrow(rle_hdr * const the_hdr,
|
|
Packit |
78deda |
rle_pixel ** const scanline) {
|
|
Packit |
78deda |
/*-----------------------------------------------------------------------------
|
|
Packit |
78deda |
Get a scanline from the input file.
|
|
Packit |
78deda |
Inputs:
|
|
Packit |
78deda |
the_hdr: Header structure containing information about
|
|
Packit |
78deda |
the input file.
|
|
Packit |
78deda |
Outputs:
|
|
Packit |
78deda |
scanline: an array of pointers to the individual color
|
|
Packit |
78deda |
scanlines. Scanline is assumed to have
|
|
Packit |
78deda |
the_hdr->ncolors pointers to arrays of rle_pixel,
|
|
Packit |
78deda |
each of which is at least the_hdr->xmax+1 long.
|
|
Packit |
78deda |
Returns the current scanline number.
|
|
Packit |
78deda |
Assumptions:
|
|
Packit |
78deda |
rle_get_setup has already been called.
|
|
Packit |
78deda |
Algorithm:
|
|
Packit |
78deda |
If a vertical skip is being executed, and clear-to-background is
|
|
Packit |
78deda |
specified (the_hdr->background is true), just set the
|
|
Packit |
78deda |
scanlines to the background color. If clear-to-background is
|
|
Packit |
78deda |
not set, just increment the scanline number and return.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Otherwise, read input until a vertical skip is encountered,
|
|
Packit |
78deda |
decoding the instructions into scanline data.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
If ymax is reached (or, somehow, passed), continue reading and
|
|
Packit |
78deda |
discarding input until end of image.
|
|
Packit |
78deda |
---------------------------------------------------------------------------- */
|
|
Packit |
78deda |
FILE * const infile = the_hdr->rle_file;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
rle_pixel * scanc;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int scan_x; /* current X position */
|
|
Packit |
78deda |
int max_x; /* End of the scanline */
|
|
Packit |
78deda |
int channel; /* current color channel */
|
|
Packit |
78deda |
int ns; /* Number to skip */
|
|
Packit |
78deda |
int nc;
|
|
Packit |
78deda |
short word, long_data;
|
|
Packit |
78deda |
char inst[2];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
scan_x = the_hdr->xmin; /* initial value */
|
|
Packit |
78deda |
max_x = the_hdr->xmax; /* initial value */
|
|
Packit |
78deda |
channel = 0; /* initial value */
|
|
Packit |
78deda |
/* Clear to background if specified */
|
|
Packit |
78deda |
if (the_hdr->background != 1) {
|
|
Packit |
78deda |
if (the_hdr->alpha && RLE_BIT( *the_hdr, -1))
|
|
Packit |
78deda |
memset((char *)scanline[-1] + the_hdr->xmin, 0,
|
|
Packit |
78deda |
the_hdr->xmax - the_hdr->xmin + 1);
|
|
Packit |
78deda |
for (nc = 0; nc < the_hdr->ncolors; ++nc) {
|
|
Packit |
78deda |
if (RLE_BIT( *the_hdr, nc)) {
|
|
Packit |
78deda |
/* Unless bg color given explicitly, use 0. */
|
|
Packit |
78deda |
if (the_hdr->background != 2 || the_hdr->bg_color[nc] == 0)
|
|
Packit |
78deda |
memset((char *)scanline[nc] + the_hdr->xmin, 0,
|
|
Packit |
78deda |
the_hdr->xmax - the_hdr->xmin + 1);
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
memset((char *)scanline[nc] + the_hdr->xmin,
|
|
Packit |
78deda |
the_hdr->bg_color[nc],
|
|
Packit |
78deda |
the_hdr->xmax - the_hdr->xmin + 1);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* If skipping, then just return */
|
|
Packit |
78deda |
if (the_hdr->priv.get.vert_skip > 0) {
|
|
Packit |
78deda |
--the_hdr->priv.get.vert_skip;
|
|
Packit |
78deda |
++the_hdr->priv.get.scan_y;
|
|
Packit |
78deda |
if (the_hdr->priv.get.vert_skip > 0) {
|
|
Packit |
78deda |
if (the_hdr->priv.get.scan_y >= the_hdr->ymax) {
|
|
Packit |
78deda |
int const y = the_hdr->priv.get.scan_y;
|
|
Packit |
78deda |
while (rle_getskip(the_hdr) != 32768)
|
|
Packit |
78deda |
;
|
|
Packit |
78deda |
return y;
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
return the_hdr->priv.get.scan_y;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* If EOF has been encountered, return also */
|
|
Packit |
78deda |
if (the_hdr->priv.get.is_eof)
|
|
Packit |
78deda |
return ++the_hdr->priv.get.scan_y;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Otherwise, read and interpret instructions until a skipLines
|
|
Packit |
78deda |
instruction is encountered.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
if (RLE_BIT(*the_hdr, channel))
|
|
Packit |
78deda |
scanc = scanline[channel] + scan_x;
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
scanc = NULL;
|
|
Packit |
78deda |
for (;;) {
|
|
Packit |
78deda |
inst[0] = getc(infile);
|
|
Packit |
78deda |
inst[1] = getc(infile);
|
|
Packit |
78deda |
if (feof(infile)) {
|
|
Packit |
78deda |
the_hdr->priv.get.is_eof = 1;
|
|
Packit |
78deda |
break; /* <--- one of the exits */
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
switch(OPCODE(inst)) {
|
|
Packit |
78deda |
case RSkipLinesOp:
|
|
Packit |
78deda |
if (LONGP(inst)) {
|
|
Packit |
78deda |
VAXSHORT(the_hdr->priv.get.vert_skip, infile);
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
the_hdr->priv.get.vert_skip = DATUM(inst);
|
|
Packit |
78deda |
if (debug_f)
|
|
Packit |
78deda |
pm_message("Skip %d Lines (to %d)",
|
|
Packit |
78deda |
the_hdr->priv.get.vert_skip,
|
|
Packit |
78deda |
the_hdr->priv.get.scan_y +
|
|
Packit |
78deda |
the_hdr->priv.get.vert_skip);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
break; /* need to break for() here, too */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
case RSetColorOp:
|
|
Packit |
78deda |
channel = DATUM(inst); /* select color channel */
|
|
Packit |
78deda |
if (channel == 255)
|
|
Packit |
78deda |
channel = -1;
|
|
Packit |
78deda |
scan_x = the_hdr->xmin;
|
|
Packit |
78deda |
if (RLE_BIT(*the_hdr, channel))
|
|
Packit |
78deda |
scanc = scanline[channel]+scan_x;
|
|
Packit |
78deda |
if (debug_f)
|
|
Packit |
78deda |
pm_message("Set color to %d (reset x to %d)",
|
|
Packit |
78deda |
channel, scan_x );
|
|
Packit |
78deda |
break;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
case RSkipPixelsOp:
|
|
Packit |
78deda |
if (LONGP(inst)) {
|
|
Packit |
78deda |
VAXSHORT(long_data, infile);
|
|
Packit |
78deda |
scan_x += long_data;
|
|
Packit |
78deda |
scanc += long_data;
|
|
Packit |
78deda |
if (debug_f)
|
|
Packit |
78deda |
pm_message("Skip %d pixels (to %d)", long_data, scan_x);
|
|
Packit |
78deda |
} else {
|
|
Packit |
78deda |
scan_x += DATUM(inst);
|
|
Packit |
78deda |
scanc += DATUM(inst);
|
|
Packit |
78deda |
if (debug_f)
|
|
Packit |
78deda |
pm_message("Skip %d pixels (to %d)", DATUM(inst), scan_x);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
break;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
case RByteDataOp:
|
|
Packit |
78deda |
if (LONGP(inst)) {
|
|
Packit |
78deda |
VAXSHORT(nc, infile);
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
nc = DATUM(inst);
|
|
Packit |
78deda |
++nc;
|
|
Packit |
78deda |
if (debug_f) {
|
|
Packit |
78deda |
if (RLE_BIT(*the_hdr, channel))
|
|
Packit |
78deda |
pm_message("Pixel data %d (to %d):", nc, scan_x + nc);
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
pm_message("Pixel data %d (to %d)", nc, scan_x + nc);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
if (RLE_BIT(*the_hdr, channel)) {
|
|
Packit |
78deda |
/* Don't fill past end of scanline! */
|
|
Packit |
78deda |
if (scan_x + nc > max_x) {
|
|
Packit |
78deda |
ns = scan_x + nc - max_x - 1;
|
|
Packit |
78deda |
nc -= ns;
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
ns = 0;
|
|
Packit |
78deda |
fread((char *)scanc, 1, nc, infile);
|
|
Packit |
78deda |
while (ns-- > 0)
|
|
Packit |
78deda |
getc(infile);
|
|
Packit |
78deda |
if (nc & 0x1)
|
|
Packit |
78deda |
getc(infile); /* throw away odd byte */
|
|
Packit |
78deda |
} else {
|
|
Packit |
78deda |
if (the_hdr->priv.get.is_seek)
|
|
Packit |
78deda |
fseek(infile, ((nc + 1) / 2) * 2, 1);
|
|
Packit |
78deda |
else {
|
|
Packit |
78deda |
int ii;
|
|
Packit |
78deda |
for (ii = ((nc + 1) / 2) * 2; ii > 0; --ii)
|
|
Packit |
78deda |
getc(infile); /* discard it */
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
scanc += nc;
|
|
Packit |
78deda |
scan_x += nc;
|
|
Packit |
78deda |
if (debug_f && RLE_BIT(*the_hdr, channel)) {
|
|
Packit |
78deda |
rle_pixel * cp;
|
|
Packit |
78deda |
for (cp = scanc - nc; nc > 0; --nc)
|
|
Packit |
78deda |
fprintf(stderr, "%02x", *cp++);
|
|
Packit |
78deda |
putc('\n', stderr);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
break;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
case RRunDataOp:
|
|
Packit |
78deda |
if (LONGP(inst)) {
|
|
Packit |
78deda |
VAXSHORT(nc, infile);
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
nc = DATUM(inst);
|
|
Packit |
78deda |
++nc;
|
|
Packit |
78deda |
scan_x += nc;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
VAXSHORT(word, infile);
|
|
Packit |
78deda |
if (debug_f)
|
|
Packit |
78deda |
pm_message("Run length %d (to %d), data %02x",
|
|
Packit |
78deda |
nc, scan_x, word);
|
|
Packit |
78deda |
if (RLE_BIT(*the_hdr, channel)) {
|
|
Packit |
78deda |
if (scan_x > max_x) {
|
|
Packit |
78deda |
ns = scan_x - max_x - 1;
|
|
Packit |
78deda |
nc -= ns;
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
ns = 0;
|
|
Packit |
78deda |
if (nc >= 10) { /* break point for 785, anyway */
|
|
Packit |
78deda |
memset((char *)scanc, word, nc);
|
|
Packit |
78deda |
scanc += nc;
|
|
Packit |
78deda |
} else {
|
|
Packit |
78deda |
for (nc--; nc >= 0; --nc, ++scanc)
|
|
Packit |
78deda |
*scanc = word;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
break;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
case REOFOp:
|
|
Packit |
78deda |
the_hdr->priv.get.is_eof = 1;
|
|
Packit |
78deda |
if (debug_f)
|
|
Packit |
78deda |
pm_message("End of Image");
|
|
Packit |
78deda |
break;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
default:
|
|
Packit |
78deda |
pm_error("rle_getrow: Unrecognized opcode: %d, reading %s",
|
|
Packit |
78deda |
inst[0], the_hdr->file_name);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
if (OPCODE(inst) == RSkipLinesOp || OPCODE(inst) == REOFOp)
|
|
Packit |
78deda |
break; /* <--- the other loop exit */
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* If at end, skip the rest of a malformed image. */
|
|
Packit |
78deda |
if (the_hdr->priv.get.scan_y >= the_hdr->ymax) {
|
|
Packit |
78deda |
int const y = the_hdr->priv.get.scan_y;
|
|
Packit |
78deda |
while (rle_getskip(the_hdr) != 32768 )
|
|
Packit |
78deda |
;
|
|
Packit |
78deda |
return y;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return the_hdr->priv.get.scan_y;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|