Blame urt/rle_getrow.c

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 38c941
        overflow_add(comlen, 1);
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