Category : C Source Code
Archive   : IMDSRC78.ZIP
Filename : IMAGEIO.C

 
Output of file : IMAGEIO.C contained in archive : IMDSRC78.ZIP
/*** IMDISP module IMAGEIO.C
Image I/O routines for labeled images

Includes routines for opening images, reading and writing
image lines, and converting pixel formats.

Added GIF interface - Ron Baalke - 06/28/91
***/

#define __MSC

/* * * * INCLUDE files * * * */

#include
#include
#include
#include
#include "mshell.h"
#include "imdef.h"
#include "imdisp.h"
#include "imdutil.h"
#include "fileio.h"
#include "labutil.h"
#include "palutil.h"
#include "rescale.h"
#include "gif_lib.h"
#include "dispio.h"
#include "mem.h"
#include "textutil.h"

/* * * * External functions * * * */

/* * * * Function declarations * * * */

int ReadLabel (int, char *, int, char *);
int WriteLabel (int, char *, unsigned int, char *);
int OpenImage (char *, int, char *, int *, int *, int *, char *);
int CloseImage (int, char *);
int ReadLine (int, unsigned char *, int, int, int, char *);
int WriteLine (int, unsigned char *, int, int, int, char *);
int CheckStatus (char *);
int ConvertLine (unsigned char *, unsigned char *, int, int, int, char *);
int ReadXMSLine (unsigned char *, int, int, int);
int OpenGifFile(char *, int *, int *, int *, char *);

/* * * * Global Variables * * * */

/* The image control block structure */
struct ImageBlockType
{
long block; /* block # of start of buffer at */
int blksiz; /* block size in bytes */
int maxbuf; /* max size of buffer in blocks */
int bufsiz; /* # of blocks of buffer in use */
unsigned int lblsiz; /* label size in bytes */
int pixsiz; /* size of pixels in bits */
int reclen; /* record length in bytes */
int nl, ns; /* number of lines and samples */
int linhed; /* line header length in bytes */
char access; /* R for read, W for write */
int gif; /* GIF flag */
} IMCB[MaxNumImages];


unsigned char *ImageBuffer[MaxNumImages]; /* pointers to image buffers */
int ImageLocation; /* where the image reside */
int ImageHandle; /* handle to extended mem */
int ImageMemory;
int ImageGifLine;
char LabelBuf[LabelBufferLen];
char LabelFileName[64];
unsigned char *gif_buffer;

int ReadLabel (int unit, char * LabelBuf, int LabelLength, char * status)

/* ReadLabel reads a buffer full of the beginning of the file and
copies part of it to the label buffer in uppercase.
*/

{
int i, * len, length, next = 0;

IMCB[unit].block = 0L;
ReadBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, &IMCB[unit].bufsiz, status);
memcpy (LabelBuf, ImageBuffer[unit], LabelLength);
if (strncmp(LabelBuf+2,"CCSD",4) == 0 ||
strncmp(LabelBuf+2,"NJPL",4) == 0)
do
{
/* len = (int *)LabelBuf[next]; */
len = (int *) (LabelBuf + next); /* len is a pointer to a 16-bit
integer - the record length */
length = *len; /* and length is the number of
bytes in the label record */
length += length%2; /* word align the label record */
/* LabelBuf[next] = 13; LabelBuf[next+1] = 10; */
*len = 0x0d0a; /* replace length w/ */
if (strncmp(LabelBuf+next+2,"END",3) == 0 && length < 5)
break;
next += length+2; /* bump next to next label record */
} while (next < LabelLength);

for (i = 0; i < LabelLength; i++)
{
LabelBuf[i] = toupper(LabelBuf[i]);
if (LabelBuf[i] == 0) LabelBuf[i] = 32;
}
}




int WriteLabel (int unit, char * LabelBuf, unsigned int labelsize,
char * status)

/* WriteLabel writes the passed label out to the image buffer.
If the label record is larger than the image buffer then
the buffer is written to disk.
*/

{
int movebytes, bytesleft, inptr;

strcpy (status, "");
memset (ImageBuffer[unit], 0, LabelBufferLen);

IMCB[unit].block = 0L;
if (labelsize < LabelBufferLen)
movebytes = labelsize;
else
movebytes = LabelBufferLen;
memcpy (ImageBuffer[unit], LabelBuf, movebytes);
IMCB[unit].bufsiz = ((movebytes-1) / IMCB[unit].blksiz) + 1;
bytesleft = labelsize - movebytes;
inptr = movebytes;

while (bytesleft > 0)
{
WriteBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, status);
if (strlen(status) > 0) return(0);
IMCB[unit].block = IMCB[unit].block + IMCB[unit].maxbuf;
if (bytesleft < LabelBufferLen)
movebytes = bytesleft;
else
movebytes = LabelBufferLen;
memset (&ImageBuffer[unit][movebytes], 0, ImBufMax-movebytes);
memcpy (ImageBuffer[unit], &LabelBuf[inptr], movebytes);
IMCB[unit].bufsiz = ( (movebytes-1) / IMCB[unit].blksiz ) + 1;
bytesleft = bytesleft - movebytes;
inptr = inptr + movebytes;
}
}

int OpenImage (char * filename, int unit, char * IOmode, int * p_nline,
int * p_nsamp, int * p_bitsperpix, char * status)

/*** OpenImage opens an image file either for reading or writing. The
size of the image and pixel format are returned if the file is
opened for reading. If the file is opened for writing then the
passed number of lines and samples and pixel format are used for
the new image. The unit number is used to refer to the file in
subsequent operations. If the file is opened for input then the
label processing routines will parse Vicar2 and PDS labels and
will prompt for user info if the image is unlabeled. PDS detached
labels and palettes are handled transparently in this routine. If
the file is for writing then a PDS label will be output. An error
is returned if there is insufficient room to dynamically allocate
the image buffer, or if there is a file error. For images with
pixel sizes less than a byte, each line is assumed to start with a
new byte.

Parameter Type In/out Description

filename char ptr in Name of image file to open
unit int in Unit number of image (0,1,2...)
IOmode char ptr in Access mode of file
("r..." for reading, "w..." for writing)
p_nline int ptr in/out The number of lines in the image
p_nsamp int ptr in/out The number of samples in the image
p_bitsperpix int ptr in/out The number of bits in a pixel (pixel format)
(16 for integer, 8 for byte,
4 for nibble, 1 for binary)
status char ptr out Return string with error message
(0 length string if no error)

***/

{
int reclen, lineheadbytes, p;
/* unsigned int labelsize; */
unsigned int size;
char accessmode[2], format, tmpstr[64];
char DetachedFileName[64];
char DetachedPaletteName[64];

unsigned char *buffer;
int i,j,k;
char stat[128];
long offset;
int type;
unsigned long lsize;
int error;
int InterlacedOffset[4]; /* The way Interlaced image should */
int InterlacedJumps[4]; /* be read - offsets and jumps... */

strcpy(stat,"");

InterlacedOffset[0] = 0;
InterlacedOffset[1] = 4;
InterlacedOffset[2] = 2;
InterlacedOffset[3] = 1;

InterlacedJumps[0] = 8;
InterlacedJumps[1] = 8;
InterlacedJumps[2] = 4;
InterlacedJumps[3] = 2;


if ( (unit < 0) || (unit > MaxNumImages-1) )
{
strcpy (status, "Illegal unit number");
return(1);
}
accessmode[1] = 0;
accessmode[0] = toupper(IOmode[0]);
if (accessmode[0] != 'W')
accessmode[0] = 'R';

if (strstr( filename, ".GIF") != NULL) /* check for GIF file */
IMCB[unit].gif = TRUE;
else
IMCB[unit].gif = FALSE;
if (ImageFormat == GIF_FORMAT) IMCB[unit].gif = TRUE;

if (IMCB[unit].gif) /* Open GIF file processing */
{
_GifError = 0;
if (accessmode[0] == 'R')
{
/* Open GIF for read */
error = OpenGifFile(filename,p_nline, p_nsamp, p_bitsperpix, status);
if (error != 0)
return(1);
labelsize = 0;
reclen = 0;
lineheadbytes = 0;

}
else /* else open GIF file for writing */
{
remove(filename);
EGifSetGifVersion("87a");
GifFileOut = EGifOpenFileName( filename, TRUE);
if (GifFileOut == NULL)
{
sprintf(status,"Error %d in opening GIF file",_GifError);
return(1);
}
ReadPalette(CT);
GifPalette = (GifColorType *) CT;
EGifPutScreenDesc( GifFileOut, *p_nsamp, *p_nline, numDN, 0,
*p_bitsperpix, GifPalette);
EGifPutImageDesc( GifFileOut, 0, 0, *p_nsamp, *p_nline, 0,
*p_bitsperpix, NULL);
}
}
else /* else file is not GIF */
{
OpenFile (filename, unit, accessmode, &IMCB[unit].blksiz, status);
if (strlen(status) > 0) return(0);

/* Allocate image buffer on heap */
/* Only allocate 2048 bytes for output buffer */
size = (accessmode[0]=='W') ? LabelBufferLen : ImBufMax;

if ( (ImageBuffer[unit] = malloc (size)) == NULL )
{
FatalError( "Not enough memory for ImageBuffer.\n");
}


IMCB[unit].maxbuf = size / IMCB[unit].blksiz; /* MDM 2/3/88*/

if (accessmode[0] == 'R')
{
ReadLabel (unit, LabelBuf, LabelBufferLen, status);
if (strlen(status) > 0) goto CloseUp;

/* patch for microsoft driver */
/* this checks for dates found in certain positions in the extended
attr record. These could be found elsewhere, but probably not */
if (LabelBuf[10] == '1' && LabelBuf[11] == '9' &&
LabelBuf[26] == '1' && LabelBuf[27] == '9')
{
Microsoft = 1; /*read the label again*/
ReadLabel (unit, LabelBuf, LabelBufferLen, status);
if (strlen(status) > 0) goto CloseUp;
}
else Microsoft = 0;

/* end of patch */

InterpretLabel (LabelBuf, LabelBufferLen,
&labelsize, p_nline, p_nsamp, p_bitsperpix,
&reclen, &lineheadbytes, DetachedFileName,
DetachedPaletteName, unit);
if (reclen == 0) return(0);
LabelFileName[0]=0;
if (strlen(DetachedFileName) > 0)
{
strcpy(LabelFileName,filename);
CloseFile (unit, status);
if ( (strchr(DetachedFileName, '\\') == NULL) &&
(strchr(DetachedFileName, ':') == NULL) &&
(strnicmp(filename,"CD:",3) != 0) )
{
p = strlen(filename) - 1;
while ((p > -1) && (filename[p] != '\\')
&& (filename[p] != ':')) p--;
strcpy (tmpstr, filename);
tmpstr[p+1] = 0;
strcat (tmpstr, DetachedFileName);
strcpy (DetachedFileName, tmpstr);
}

OpenFile (DetachedFileName, unit, accessmode,
&IMCB[unit].blksiz, status);
if (strlen(status) > 0) goto FreeUp;
IMCB[unit].maxbuf = ImBufMax / IMCB[unit].blksiz;
IMCB[unit].block = 0L;
ReadBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, &IMCB[unit].bufsiz, status);
if (strlen(status) > 0) goto CloseUp;

/* patch for microsoft driver */
if (ImageBuffer[unit][10] == '1' && ImageBuffer[unit][11] == '9' &&
ImageBuffer[unit][26] == '1' && ImageBuffer[unit][27] == '9')
{
Microsoft = 1; /*read the label again*/
ReadBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, &IMCB[unit].bufsiz, status);
if (strlen(status) > 0) goto CloseUp;
}
else Microsoft = 0;

}

if ( (strlen(DetachedPaletteName) > 0) || (Palette > 0L) )
/* Ron Baalke - Added detached */
{ /* palette processing - 07/27/90*/
LoadPalette(DetachedPaletteName);
}

}

else
{
reclen = ( (long)*p_nsamp* (long)*p_bitsperpix - 1 )/8 + 1;
if (ImageFormat != RAW_FORMAT)
{
MakeLabel (LabelBuf, &labelsize, *p_nline, *p_nsamp,
*p_bitsperpix, reclen);
WriteLabel (unit, LabelBuf, labelsize, status);
if (strlen(status) > 0) goto CloseUp;
}
else
labelsize = 0;

lineheadbytes = 0;
}
}
IMCB[unit].lblsiz = labelsize;
IMCB[unit].reclen = reclen;
IMCB[unit].nl = *p_nline;
IMCB[unit].ns = *p_nsamp;
IMCB[unit].pixsiz = *p_bitsperpix;
IMCB[unit].linhed = lineheadbytes;
IMCB[unit].access = accessmode[0];

if (unit == 0)
ImageLocation = VIRTUAL_FILE; /* Extended memory interface added*/
/* 05/18/91 - Ron Baalke */
if ((unit == 0) && (*p_bitsperpix == 8) &&
(accessmode[0] == 'R') && ImageMemory)
{
lsize = (long)(*p_nsamp) * (long)(*p_nline);
if (Memory_Alloc(lsize,&ImageHandle,&type) == 0)
{
size = *p_nsamp;
if ((buffer = malloc(size)) == NULL)
Memory_Free(ImageHandle, type);
else
{
if (PromptFlag)
{
if (IMCB[unit].gif)
StatusLine(2, "Loading GIF into memory, please wait...");
else
StatusLine(2, "Loading image into memory, please wait....");
}

strcpy(stat,"");

/* special handle interlaced GIF's */

if (IMCB[unit].gif && GifFileIn->IInterlace)
{
size = *p_nsamp;
for (i=0; i<4; i++)
for (j=InterlacedOffset[i]; j<*p_nline;
j += InterlacedJumps[i])
{
if (DGifGetLine(GifFileIn, buffer, size) == GIF_ERROR)
{
sprintf(status,"Error %d in reading interlaced GIF",_GifError);
Memory_Free(ImageHandle, type);
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
free(buffer);
return(1);
}
offset = (long)(j) * size;
Memory_PutLine(ImageHandle, type, buffer, offset, size);
k++;
}
}
else /* else read in image line by line */
{
for (i=1; (i<=*p_nline) && (strlen(stat) == 0); i++)
{
ReadLine(0,buffer,i,1,size,stat);
offset = (long)(i-1) * size;
Memory_PutLine(ImageHandle, type, buffer, offset, size);
}
}
if (strlen(stat) == 0)
ImageLocation = type;
else
{
sprintf(status,"Error %d in reading line %d",i-1,_GifError);
DGifCloseFile( GifFileIn );
Memory_Free(ImageHandle, type);
if (gif_buffer != NULL) free(gif_buffer);
free(buffer);
return(1);
}

free(buffer);
}
}
}

/* Interlaced GIF's have to be in memory */

if ((IMCB[unit].gif) && (GifFileIn->IInterlace) &&
(ImageLocation == VIRTUAL_FILE) && (accessmode[0] == 'R'))
{
strcpy(status,"Not enough memory for interlaced GIF");
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
return(1);
}

return(0);

CloseUp:
CloseFile (unit, LabelBuf);
FreeUp:
free(ImageBuffer[unit]);
}


int ReadLine (int unit, unsigned char * buffer, int line, int sss, int nss,
char * status)

/*** ReadLine reads a line of pixels from the image into the user's
buffer. The reading is completely random access, the lines may be
read in any order; it is more efficient, however, to read lines
sequentially. Partial image lines may be read. The output data
is in the same format as the file (the convert routine may be used
to convert pixel formats).

Parameter Type In/out Description

unit int in Unit number of image (same as in open)
buffer char ptr out Buffer to receive pixels
line int in The number of the image line to read (1 is first)
sss int in The starting sample in the line
nss int in The number of samples to read into buffer
status char ptr out Return string with error message
(0 length string if no error)

***/
{

long filebyte, blknum;
int offset, bufsizebytes, numbytes;
int movebytes, bytesleft, outptr;
unsigned char hold, hold1;
int i,j;
int dummy1, dummy2, dummy3;

strcpy (status, "");

if (IMCB[unit].gif) /* Process GIF files */
{
j = ImageGifLine;
if (line <= ImageGifLine) /* If past line, reset to beginning of file*/
{
if (DGifCloseFile(GifFileIn) == GIF_ERROR)
{
strcpy(status,"Error in closing GIF file");
return(1);
}
if (gif_buffer != NULL) free(gif_buffer);
OpenGifFile(ImageFileName,&dummy1, &dummy2, &dummy3, status);
if (strlen(status) > 0)
return(1);
j = 0;
}
for (i=j; i {
if (DGifGetLine(GifFileIn, gif_buffer, IMCB[0].ns) == GIF_ERROR)
{
sprintf(status,"Error %d in reading GIF line %d",_GifError,line);
return(1);
}
}
ImageGifLine = line;
/* memmove(buffer, gif_buffer+sss-1, nss); */
memcpy(buffer, gif_buffer+sss-1, nss);
return(0);
}
else /* else process non-GIF file */
{
if (line > IMCB[unit].nl)
strcpy (status, "Line off image");
/* Calculate the block in the image to start at,
and read it in if necessary */
filebyte = IMCB[unit].lblsiz
+ (long)(line-1) * (long)IMCB[unit].reclen
+ ( (long)(sss-1) * (long)IMCB[unit].pixsiz) / 8
+ (long)IMCB[unit].linhed;
if (GiantLabel > 0)
filebyte = GiantLabel
+ (long)(line-1) * (long)IMCB[unit].reclen
+ ( (long)(sss-1) * (long)IMCB[unit].pixsiz) / 8
+ (long)IMCB[unit].linhed;

blknum = filebyte/IMCB[unit].blksiz;

if ( (blknum < IMCB[unit].block) ||
(blknum > IMCB[unit].block + IMCB[unit].bufsiz-1) )
{
IMCB[unit].block = blknum;
ReadBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, &IMCB[unit].bufsiz, status);
if (strlen(status) > 0) return(0);
}


offset = filebyte - IMCB[unit].blksiz*IMCB[unit].block;
numbytes = ( (long)nss*IMCB[unit].pixsiz - 1 ) /8 + 1;

/* Transfer the part of the line thats in the image buffer */
bufsizebytes = IMCB[unit].blksiz*IMCB[unit].bufsiz;
movebytes = bufsizebytes - offset;
if (movebytes > numbytes) movebytes = numbytes;
if (IMCB[unit].pixsiz == 16 && ByteSwap == TRUE)
swab(&ImageBuffer[unit][offset], buffer, movebytes);
else
memcpy (buffer, &ImageBuffer[unit][offset], movebytes);
bytesleft = numbytes - movebytes;
outptr = movebytes;

/* Read in more buffer fulls and transfer until done */
while (bytesleft > 0)
{
IMCB[unit].block = IMCB[unit].block + IMCB[unit].bufsiz;
ReadBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, &IMCB[unit].bufsiz, status);
if (strlen(status) > 0) return(0);
bufsizebytes = IMCB[unit].blksiz*IMCB[unit].bufsiz;
if (bufsizebytes > bytesleft) movebytes = bytesleft;
else movebytes = bufsizebytes;
if (IMCB[unit].pixsiz == 16 && ByteSwap == TRUE)
swab(ImageBuffer[unit], &buffer[outptr], movebytes);
else
memcpy(&buffer[outptr], ImageBuffer[unit], movebytes);
bytesleft = bytesleft - movebytes;
outptr = outptr + movebytes;
}
/* swap bytes if FITS or other non swapped format */
/*
if (IMCB[unit].pixsiz == 16 && ByteSwap == TRUE)
{
for (i=0;i<2*nss;i += 2)
{
hold = buffer[i+1];
buffer[i+1] = buffer[i];
buffer[i] = hold;
}
}
*/

/* swap bytes for the 32 bits values. added by AEE, 4-4-89 */

if ((IMCB[unit].pixsiz == 32) && ByteSwap == TRUE)
{
for (i=0; i <4*nss; i +=4)
{
hold= buffer[i+3];
hold1= buffer[i+2];
buffer[i+2]= buffer[i+1];
buffer[i+3]= buffer[i];
buffer[i]= hold;
buffer[i+1]= hold1;
}
}


}
}





int WriteLine (int unit, unsigned char * buffer, int line, int sss, int nss,
char * status)

/*** WriteLine writes a line of pixels from the user buffer to the
image. Although the writing is buffered, completely random access
will not work; the image lines should be written sequentially.
Partial image lines may be written. The input data must be in the
same format as the file (no conversion is performed).

Parameter Type In/out Description

unit int in Unit number of image (same as in open)
buffer char ptr in Buffer of image pixels
line int in The number of the image line to write
sss int in The starting sample in the line
nss int in The number of samples to write from buffer
status char ptr out Return string with error message
(0 length string if no error)

***/

{
long filebyte, blknum;
int offset, bufsizebytes, numbytes;
int movebytes, bytesleft, inptr;

if (IMCB[unit].gif) /* Write out GIF line */
EGifPutLine( GifFileOut, buffer, nss);
else /* else process non-GIF file */
{
if (line > IMCB[unit].nl)
strcpy (status, "Line off image");
else
{
strcpy (status, "");
/* Calculate the block in the image to start at */
filebyte = IMCB[unit].lblsiz
+ (line-1) * (long)IMCB[unit].reclen
+ ((sss-1) * (long)IMCB[unit].pixsiz) / 8
+ IMCB[unit].linhed;
blknum = filebyte/IMCB[unit].blksiz;
if ( (blknum < IMCB[unit].block) ||
(blknum > IMCB[unit].block + IMCB[unit].bufsiz-1) )
{
WriteBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, status);
if (strlen(status) > 0) return(0);
IMCB[unit].block = blknum;
memset (ImageBuffer[unit], 0, LabelBufferLen);
}


offset = filebyte - IMCB[unit].blksiz*IMCB[unit].block;
numbytes = ( (long)nss*IMCB[unit].pixsiz - 1 ) /8 + 1;


/* Transfer the part of the line that fits in the image buffer */
bufsizebytes = LabelBufferLen;
movebytes = bufsizebytes - offset;
if (movebytes > numbytes) movebytes = numbytes;
memcpy (&ImageBuffer[unit][offset], buffer, movebytes);
IMCB[unit].bufsiz = ((offset+movebytes-1) /IMCB[unit].blksiz) + 1;
bytesleft = numbytes - movebytes;
inptr = movebytes;


/* Write out more buffer fulls and transfer until done */
while (bytesleft > 0)
{
WriteBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].maxbuf, status);
if (strlen(status) > 0) return(0);
IMCB[unit].block = IMCB[unit].block + IMCB[unit].maxbuf;
if (bufsizebytes > bytesleft) movebytes = bytesleft;
else movebytes = bufsizebytes;
memset (&ImageBuffer[unit][movebytes], 0, bufsizebytes-movebytes);
memcpy (ImageBuffer[unit], &buffer[inptr], movebytes);
IMCB[unit].bufsiz = ( (movebytes-1) /IMCB[unit].blksiz ) + 1;
bytesleft = bytesleft - movebytes;
inptr = inptr + movebytes;
}

}
}
}



int CloseImage (int unit, char * status)

/*** CloseImage closes the image file. If the image is opened for
writing then the image buffer is first flushed.

Parameter Type In/out Description

unit int in Unit number of image (same as in open)
status char ptr out Return string with error message
(0 length string if no error)
***/

{
if (IMCB[unit].gif)
{
if (IMCB[unit].access == 'W')
EGifCloseFile( GifFileOut );
else
{
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
}
}
else
{

if (IMCB[unit].access == 'W')
{
WriteBlocks (unit, ImageBuffer[unit], IMCB[unit].block,
IMCB[unit].bufsiz, status);
if (strlen(status) > 0) return(0);
}
free (ImageBuffer[unit]);
CloseFile (unit, status);
}

if ((unit == 0) && (ImageLocation != VIRTUAL_FILE))
Memory_Free(ImageHandle, ImageLocation);
}




int CheckStatus (char * status)

/*** CheckStatus checks the status string passed in. If there is no
error the routine returns, otherwise the error message is printed
to the terminal and the program is aborted.

***/

{
if (strlen(status) > 0)
{
printf ("%s\n", status);
abort();
}
}







int ConvertLine (unsigned char * inbuffer, unsigned char * outbuffer,
int inbits, int outbits, int ns, char * status)

/*** ConvertLine converts a line of pixels into a different format.

Parameter Type In/out Description

inbuffer char ptr in The input buffer of pixels
outbuffer char ptr out The output buffer of pixels
inbits int in The pixel format of the input buffer
outbits int in The pixel format of the output buffer
ns int in The number of samples to convert
status char ptr out Return string with error message


Conversions supported : outbits
1 4 8 16 32
inbits 1 . - . . - . means supported
4 - . . . - - means not supported
8 . . . . .
16 . . . . .
32 - - . . .
***/

{

register i, j;
int bit;

union {
unsigned char *b;
int *i;
long *l;
} inbuf, outbuf;
inbuf.b = inbuffer;
outbuf.b = outbuffer;



strcpy (status, "");
i = 0; j = 0;

if (inbits == outbits)
memcpy (outbuffer, inbuffer, ( (long)ns*inbits - 1 )/8 + 1 );

else if ( (inbits==8) && (outbits==16) )
b2w( inbuf.b, outbuf.i, ns);
/*
for (i = 0; i < ns; i++)
outbuf.i[i] = inbuf.b[i];
*/

else if ( (inbits==16) && (outbits==8) )
w2b( inbuf.i, outbuf.b, ns);
/*
for (i = 0; i < ns; i++)
outbuf.b[i] = inbuf.i[i];
*/

else if ( (inbits==16) && (outbits==32) )
for (i = 0; i < ns; i++)
outbuf.l[i] = inbuf.i[i];

else if ( (inbits==32) && (outbits==16) )
for (i = 0; i < ns; i++)
outbuf.i[i] = inbuf.l[i];

else if ( (inbits==8) && (outbits==32) )
for (i = 0; i < ns; i++)
outbuf.l[i] = inbuf.b[i];

else if ( (inbits==32) && (outbits==8) )
for (i = 0; i < ns; i++)
outbuf.b[i] = inbuf.l[i];

else if ( (inbits==4) && (outbits==8) )
for (i = 0; i <= (ns-1)/2; i++)
{ outbuf.b[j++] = inbuf.b[i] >> 4;
outbuf.b[j++] = inbuf.b[i] & 15;
}

else if ( (inbits==8) && (outbits==4) )
for (j = 0; j <= (ns-1)/2; j++)
outbuf.b[j] = (inbuf.b[i++] << 4) | (inbuf.b[i++] & 15);

else if ( (inbits==1) && (outbits==8) )
for (i = 0; i <= (ns-1)/8; i++)
for (bit = 7; bit >= 0; bit--)
outbuf.b[j++] = (inbuf.b[i] >> bit) & 1;

else if ( (inbits==8) && (outbits==1) )
for (j = 0; j <= (ns-1)/8; j++)
{ outbuf.b[j] = 0;
for (bit = 7; bit >= 0; bit--)
outbuf.b[j] |= ((inbuf.b[i++] & 1) << bit);
}


else if ( (inbits==4) && (outbits==16) )
for (i = 0; i <= (ns-1)/2; i++)
{ outbuf.i[j++] = inbuf.b[i] >> 4;
outbuf.i[j++] = inbuf.b[i] & 15;
}

else if ( (inbits==16) && (outbits==4) )
for (j = 0; j <= (ns-1)/2; j++)
outbuf.b[j] = (inbuf.i[i++] << 4) | (inbuf.i[i++] & 15);

else if ( (inbits==1) && (outbits==16) )
for (i = 0; i <= (ns-1)/8; i++)
for (bit = 7; bit >= 0; bit--)
outbuf.i[j++] = (inbuf.b[i] >> bit) & 1;

else if ( (inbits==16) && (outbits==1) )
for (j = 0; j <= (ns-1)/8; j++)
{ outbuf.b[j] = 0;
for (bit = 7; bit >= 0; bit--)
outbuf.b[j] |= ((inbuf.i[i++] & 1) << bit);
}

else
strcpy (status, "That pixel conversion is not supported");
}

int ReadXMSLine(unsigned char * buffer, int line, int ss, int ns)
/*** ReadsXMSLine reads a line of pixels of the image from extended memory
Parameter type description
buffer char ptr The receiving array of pixel values
line integer The line coordinate of the first pixel
ss integer The sample coordinate of the first pixel
ns integer The number of pixels to read
***/
{
int n_bytes;
long offset;

offset = (long)(line-1) * IMCB[0].ns + ss - 1;

Memory_GetLine(ImageHandle, ImageLocation, buffer, offset, ns);
n_bytes = ns;

return( n_bytes );
}

/*************************************************************************/
/* OpenGifFile */
/* */
/* Written by Ron Baalke - 11/91 */
/* */
/* This routine will open the GIF file, load in the color palette, and */
/* skip all the records until it is pointing the first line of data. */
/* */
/* It is written as a separate routine do avoid duplicate code, since */
/* the OpenImage() and ReadLine() routine needs to do the exact thing */
/* when it opens a GIF image. */
/*************************************************************************/

int OpenGifFile(char * filename, int * p_nline, int * p_nsamp,
int * p_bitsperpix, char * status)
{
int i;
int done;
GifRecordType RecordType;
GifByteType *Extension;
int ExtCode;
GifColorType *pcolor;
int factor;
int bitsperpix, nline, nsamp;

strcpy(status,"");
ImageGifLine = 0;

GifFileIn = DGifOpenFileName( filename); /* Open GIF for read */
if (GifFileIn == NULL)
{
sprintf(status,"Error %d in opening GIF file",_GifError);
return(1);
}

done = FALSE;
do { /* Get GIF record type */
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
{
sprintf(status,"Error %d in reading GIF record type",_GifError);
return(1);
}
switch (RecordType) {

case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
{
sprintf(status,"Error %d in reading GIF image description",_GifError);
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
return(1);
}
nline = GifFileIn->IHeight;
nsamp = GifFileIn->IWidth;

if ((gif_buffer = malloc (nsamp)) == NULL )
{
strcpy(status,"Not enough memory for GIF buffer");
DGifCloseFile( GifFileIn );
return(1);
}

if (GifFileIn->SColorMap != NULL)
{
bitsperpix = GifFileIn->SBitsPerPixel;
pcolor = (GifColorType *)GifFileIn->SColorMap;
}
else if (GifFileIn->IColorMap != NULL)
{
bitsperpix = GifFileIn->IBitsPerPixel;
pcolor = (GifColorType *)GifFileIn->IColorMap;
}
else
{
strcpy(status,"Error in reading GIF color map");
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
return(1);
}

if (bitsperpix > 8) bitsperpix = 8;

/* Read in GIF color palette */
for (i=0; i<256; i++)
{
CT[i].r = i;
CT[i].g = i;
CT[i].b = i;
}
factor = (1 << bitsperpix);
for (i=0; i {
CT[i].r = pcolor[i].Red;
CT[i].g = pcolor[i].Green;
CT[i].b = pcolor[i].Blue;
}

*p_bitsperpix = 8;
*p_nline = nline;
*p_nsamp = nsamp;

/* if (numDN == 256)
{
CT[255].r = 255;
CT[255].g = 255;
CT[255].b = 255;
}
*/
WritePalette(CT);
done = TRUE;
break;

case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension)
== GIF_ERROR)
{
sprintf(status,"Error %d in reading GIF extension block",_GifError);
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
return(1);
}
while (Extension != NULL)
{
if (DGifGetExtensionNext(GifFileIn, &Extension)
== GIF_ERROR)
{
sprintf(status,"Error %d in reading GIF extension block",_GifError);
DGifCloseFile( GifFileIn );
if (gif_buffer != NULL) free(gif_buffer);
return(1);
}
}
break;

default:
done = TRUE;
break;
}
}
while (!done);

return(0);
}


  3 Responses to “Category : C Source Code
Archive   : IMDSRC78.ZIP
Filename : IMAGEIO.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/