Rasterfile Format questions
andrew yeomans
mcvax!cel!ajy at uunet.uu.net
Thu Jan 5 06:34:29 AEST 1989
mephdbo%prism at gatech.edu (d. majumder):
>1) There are some pub domain rasterfiles with their filename extension
>being ---.im1 or ---.im8. The file command indicates that these are in
>RT_BYTE_ENCODED format. now the screenload command fails to read them most
>of the time. Is there some routine to convert the BYTE_ENCODED rasters to
>STANDARD form or am I doing something wrong.
I've not looked at .im1 or .im8 rasterfiles, so I'm not sure if this is
the same problem. But here goes anyway:-
The sun routine pr_dump does not always encode RT_BYTE_ENCODED rasterfiles
correctly, if copy_flag = 0 (compress in place). It seems to occur when
the encoded image (up to a given point) is longer than the unencoded
image, hence the original image gets corrupted.
This seems to happen more frequently on small images (eg 40*40), when data
values of 0x80 are in the original image. If the image is corrupted, then
pr_load (used by screenload) cannot read the file correctly. Often the
image is recoverable, though a part of a line may be lost, causing the
image to 'slip' partway through.
The following code is my own implementation of the sun pr_load routine,
which might be useful for hacking about. Remove the lines:
if (ch == EOF) /* Check end reached */
return (NULL);
to always return a pixrect even if the file was corrupt (or ignore the
errors returned).
Andrew Yeomans PSTN: 0442 230000 ext 3371
Crosfield Electronics Ltd INTL: +44 442 230000
Three Cherry Trees Lane Fax: 0442 232301
Hemel Hempstead UUCP: ajy at cel.co.uk
Hertfordshire mcvax!ukc!uk.co.cel!ajy
HP2 7RH
England
----- cut here -----
/* pr_load Load a pixrect from Sun raster file */
/* Returns pixrect, or NULL if error */
/* The byte-encoded data format is as follows (not documented by Sun): */
/* 0x80 is used as a flag to introduce run-length encoded data */
/* <0x80> <rept> <value> represents rept+1 occurrences of <value> */
/* <0x80> <0> represents a single occurrence of <0x80> */
/* All other values represent unencoded data */
/* It is only worth encoding repetitions of 3 or more, except if the */
/* value is <0x80> which must always be encoded. */
#include <stdio.h>
#include <malloc.h>
#include <sys/types.h>
#include <pixrect/pixrect.h>
#include <pixrect/memvar.h>
#include <pixrect/pr_io.h>
#include <rasterfile.h>
struct pixrect * pr_load(input, colormap)
register
FILE * input; /* Input file */
colormap_t * colormap; /* Optional colourmap */
{
struct pixrect * output_pr; /* Output pixrect */
struct rasterfile fileheader; /* Rasterfile header */
register
char * p_image; /* Pointer to image data */
register
int length; /* Length of image */
register
int ch; /* Input data character */
register
int ch2; /* Input data character */
/* Read and check file header */
if (fread(&fileheader, sizeof(fileheader), 1, input) != 1)
return (NULL);
if (fileheader.ras_magic != RAS_MAGIC)
return (NULL);
/* Load (or skip) colormap */
if (colormap == NULL)
{
fseek(input, fileheader.ras_maplength, 1); /* skip map */
}
else
{
colormap->type = fileheader.ras_maptype;
if (fileheader.ras_maptype == RMT_EQUAL_RGB)
{
colormap->length = fileheader.ras_maplength / 3;
fread(colormap->map[0], colormap->length, 1, input);
fread(colormap->map[1], colormap->length, 1, input);
fread(colormap->map[2], colormap->length, 1, input);
}
else
{
fseek(input, fileheader.ras_maplength, 1); /* skip map */
}
}
/* Create pixrect and load data */
if ((output_pr = mem_create(fileheader.ras_width, fileheader.ras_height,
fileheader.ras_depth)) == NULL)
return (NULL);
p_image = (char *) mpr_d(output_pr)->md_image;
length = mpr_d(output_pr)->md_linebytes * output_pr->pr_height;
if (fileheader.ras_type == RT_STANDARD)
{
if (fread(p_image, fileheader.ras_length, 1, input) != 1)
return (NULL);
}
else if (fileheader.ras_type == RT_BYTE_ENCODED)
{
while (length--)
{
if ((ch = getc(input)) == 0x80) /* Flag value? */
{
if ((ch2 = getc(input)) != 0) /* Count 0 means a 0x80 */
{
ch = getc(input); /* Else count + 1 of ch */
while (ch2-- && length--)
*p_image++ = ch;
}
}
*p_image++ = ch;
}
if (ch == EOF) /* Check end reached */
return (NULL);
}
return (output_pr);
}
----- cut here -----
More information about the Comp.sys.sun
mailing list