home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
1
/
1391
/
encode.c
next >
Wrap
C/C++ Source or Header
|
1990-12-28
|
12KB
|
357 lines
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% EEEEE N N CCCC OOO DDDD EEEEE %
% E NN N C O O D D E %
% EEE N N N C O O D D EEES %
% E N NN C O O D D E %
% EEEEE N N CCCC OOO DDDD EEEEE %
% %
% %
% Encode or Decode Color Runlength Packets %
% %
% %
% %
% Software Design %
% John Cristy %
% January 1990 %
% %
% %
% Copyright 1990 E. I. Dupont de Nemours & Company %
% %
% Permission to use, copy, modify, distribute, and sell this software and %
% its documentation for any purpose is hereby granted without fee, %
% provided that the above copyright notice appear in all copies and that %
% both that copyright notice and this permission notice appear in %
% supporting documentation, and that the name of E. I. Dupont de Nemours %
% & Company not be used in advertising or publicity pertaining to %
% distribution of the software without specific, written prior %
% permission. E. I. Dupont de Nemours & Company makes no representations %
% about the suitability of this software for any purpose. It is provided %
% "as is" without express or implied warranty. %
% %
% E. I. Dupont de Nemours & Company disclaims all warranties with regard %
% to this software, including all implied warranties of merchantability %
% and fitness, in no event shall E. I. Dupont de Nemours & Company be %
% liable for any special, indirect or consequential damages or any %
% damages whatsoever resulting from loss of use, data or profits, whether %
% in an action of contract, negligence or other tortious action, arising %
% out of or in connection with the use or performance of this software. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
%
*/
#include "display.h"
/*
Define declarations.
*/
#define MaxChannels 8
/*
Typedef declarations.
*/
typedef struct ChannelDescriptor
{
RunlengthPacket
color,
*packet;
unsigned int
color_count,
runlength;
} ChannelDescriptor;
/*
Global variables.
*/
static ChannelDescriptor
channels[MaxChannels];
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I n i t i a l i z e C h a n n e l %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function InitializeChannel allocates a global buffer to help keep track
% of reading or writing runlength packets into image memory. An integer
% value is returned that specifies the channel number to read or write the
% run-length encoded image.
%
% The format of the InitializeChannel routine is:
%
% channel_number=InitializeChannel(image);
%
% A description of each parameter follows.
%
% o channel_number: The InitializeChannel routine returns this integer
% value. Use it as the channel parameter when invoking the ReadPacket
% or WritePacket routines.
%
% o image: The address of a byte (8 bits) array of the run-length
% encoded image.
%
%
*/
unsigned int InitializeChannel(image)
RunlengthPacket
*image;
{
static unsigned char
channel_number = 0;
channel_number++;
channel_number%=MaxChannels;
channels[channel_number].packet=image;
channels[channel_number].color_count=image->length+1;
channels[channel_number].runlength=0;
return(channel_number);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% R e a d P a c k e t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function ReadPacket reads one pixel runlength packet from the image buffer.
% Pixel packets are read until the max_count have been read or a pixel of
% another color is encountered. The integer value returned is the number of
% pixels read.
%
% The format of the ReadPacket routine is:
%
% count=ReadPacket(channel_number,max_count,&red,&green,&blue,&index)
%
% A description of each parameter follows.
%
% o count: The ReadPacket routine returns this integer value. It is
% the actual number of contiguous pixels read from image memory of the
% same red, green, and blue value.
%
% o channel_number: An integer value that specifies the channel to
% read the run-length encoded image. This value is assigned by the
% InitializeChannel routine.
%
% o max_count: An integer value that is the maximum number of pixels
% to read from image memory of this combination of red, green, and
% blue.
%
% o red: The address of a byte value representing the measure of the
% red contribution.
%
% o green: The address of a byte value representing the measure of
% the green contribution.
%
% o blue: The address of a byte value representing the measure of the
% blue contribution.
%
% o index: A byte value representing the colormap index of the
% red, green, and blue contribution.
%
%
*/
unsigned int ReadPacket(channel_number,max_count,red,green,blue,index)
register unsigned char
channel_number;
register unsigned int
max_count;
unsigned char
*red,
*green,
*blue;
unsigned short
*index;
{
register ChannelDescriptor
*c;
static unsigned int
number_pixels;
/*
Read runlength packets until the maximum count or different color.
*/
c=channels+channel_number;
while (c->runlength < max_count)
{
if (c->color_count == 0)
{
/*
Get next runlength packet.
*/
c->packet++;
c->color_count=c->packet->length+1;
}
if (c->runlength == 0)
{
c->color.red=c->packet->red;
c->color.green=c->packet->green;
c->color.blue=c->packet->blue;
c->color.index=c->packet->index;
c->runlength=c->color_count;
c->color_count=0;
}
else
if ((c->color.red == c->packet->red) &&
(c->color.green == c->packet->green) &&
(c->color.blue == c->packet->blue))
{
c->runlength+=c->color_count;
c->color_count=0;
}
else
break;
}
*red=c->color.red;
*green=c->color.green;
*blue=c->color.blue;
*index=c->color.index;
number_pixels=Min(c->runlength,max_count);
c->runlength-=number_pixels;
return(number_pixels);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% W r i t e P a c k e t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function WritePacket encodes RBG values into run-length packets. The
% function writes the packets on the specified channel and returns the
% number of packets encoded.
%
% The format of the WritePacket routine is:
%
% number_packets=WritePacket(channel_number,red,green,blue,index,count)
%
% A description of each parameter follows.
%
% o number_packets: An integer value that indicates the number of
% packets encoded. Note, this value may be zero is if the current
% packet is only partially complete.
%
% o channel_number: An integer value that specifies the channel to
% write the run-length encoded image. This value is assigned by the
% InitializeChannel routine.
%
% o red: A byte value representing the measure of the red
% contribution.
%
% o green: A byte value representing the measure of the green
% contribution.
%
% o blue: A byte value representing the measure of the blue
% contribution.
%
% o index: A byte value representing the colormap index of the
% red, green, and blue contribution.
%
% o count: An integer value that is the number of pixels to write to
% image memory of this combination of red, green, and blue.
%
%
*/
unsigned int WritePacket(channel_number,red,green,blue,index,count)
register unsigned int
channel_number;
register unsigned char
red,
green,
blue;
register unsigned short
index;
register unsigned int
count;
{
register ChannelDescriptor
*c;
register unsigned int
packets;
packets=0;
c=channels+channel_number;
if (c->runlength == 0)
{
/*
Runlength is zero so copy pixels now.
*/
c->runlength=count;
c->packet->red=red;
c->packet->green=green;
c->packet->blue=blue;
c->packet->index=index;
packets++;
}
else
if ((red == c->packet->red) &&
(green == c->packet->green) &&
(blue == c->packet->blue))
c->runlength+=count;
else
{
/*
Transfer new group of pixels.
*/
c->packet->length=(c->runlength-1);
c->packet++;
c->runlength=count;
c->packet->red=red;
c->packet->green=green;
c->packet->blue=blue;
c->packet->index=index;
packets++;
}
if (c->runlength > MaxRgb)
{
/*
Split up pixels if the runlength exceeds MaxRgb.
*/
do
{
c->runlength-=(MaxRgb+1);
c->packet->length=MaxRgb;
c->packet++;
c->packet->red=red;
c->packet->green=green;
c->packet->blue=blue;
c->packet->index=index;
packets++;
}
while (c->runlength > MaxRgb);
if (c->runlength == 0)
packets--;
}
c->packet->length=c->runlength-1;
return(packets);
}