|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 17448 (0x4428)
Types: TextFile
Names: »pixelExt.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/Toolkit/Xr/src/Xrlib/Editor/pixelExt.c«
/*
* $Source: /u1/Xr/src/Xrlib/Editor/RCS/pixelExt.c,v $
* $Header: pixelExt.c,v 1.1 86/12/17 09:06:57 swick Exp $
*/
#ifndef lint
static char *rcsid_pixelExt_c = "$Header: pixelExt.c,v 1.1 86/12/17 09:06:57 swick Exp $";
#endif lint
#include <Xr/xr-copyright.h>
/* $Header: pixelExt.c,v 1.1 86/12/17 09:06:57 swick Exp $ */
/* Copyright 1986, Hewlett-Packard Company */
/* Copyright 1986, Massachussetts Institute of Technology */
static char rcsid[] = "$Header: pixelExt.c,v 1.1 86/12/17 09:06:57 swick Exp $";
/*************************************<+>*************************************
*****************************************************************************
**
** File: pixelExt.c
**
** Project: X-ray Toolbox
**
** Description:
** This module contains the pixel extraction intrinsic
** routine. It is capable of extracting pixel information
** from a raster image with a depth of 1 bit, or 1, 2, 3 or
** 4 bytes.
**
**
** ------------------------ MODIFICATION RECORD ------------------------
*
* $Log: pixelExt.c,v $
* Revision 1.1 86/12/17 09:06:57 swick
* Initial revision
*
* Revision 7.0 86/11/13 08:30:38 08:30:38 fred ()
* Final QA Release
*
* Revision 6.0 86/11/10 15:39:11 15:39:11 fred ()
* QA #2 release
*
* Revision 5.1 86/11/07 14:27:04 14:27:04 fred ()
* Added new copyright message.
*
* Revision 5.0 86/10/28 08:40:52 08:40:52 fred ()
* QA #1.1 release
*
* Revision 4.1 86/10/23 09:12:18 09:12:18 fred ()
* Removed unused variables.
*
* Revision 4.0 86/10/20 12:16:44 12:16:44 fred ()
* QA #1 release
*
* Revision 3.1 86/10/16 09:24:32 09:24:32 fred ()
* Performance enhanced: added use of register variables.
*
* Revision 3.0 86/10/02 16:06:46 16:06:46 fred ()
* Alpha release set to 3.0
*
* Revision 2.1 86/09/22 12:33:08 12:33:08 fred ()
* Changed xrPixMap structure to xrPixmap structure.
*
* Revision 2.0 86/09/16 08:16:52 08:16:52 fred ()
* No change; upgraded to revision 2.0 to match other source.
*
* Revision 1.4 86/09/15 06:48:37 06:48:37 fred ()
* Filled in file headers, and broke up larger routines.▶1b◀
*
* Revision 1.3 86/09/08 15:26:31 15:26:31 fred ()
* Modified the bit per pixel extraction/setting routine so that
* it processed the raster data as 16 bit quanities, instead of
* 8 bit. Also changed it so that the bits were ordered 15 ... 0
* instead of 0 ... 15, within a word.
*
* Revision 1.2 86/09/08 06:52:02 06:52:02 fred ()
* Expanded to allow not only the extraction of pixel data, but
* also to allow the setting of a pixel within a raster image.
*
* Revision 1.1 86/09/03 14:00:20 14:00:20 fred ()
* Initial revision
*
*
*****************************************************************************
*************************************<+>*************************************/
#include <X/Xlib.h>
#include <Xr/defs.h>
#include <Xr/types.h>
#include <Xr/in_types.h>
extern xrPixelData * MsgNewHandler();
extern xrPixelData * MsgLocationHandler();
extern xrPixelData * MsgValueHandler();
\f
/*************************************<->*************************************
*
* _XrPixelExtract (instance, message, data)
*
* xrPixelData * instance;
* INT32 message;
* INT8 * data;
*
* Description:
* -----------
* This intrinsic extracts a single pixel of information from a
* specified raster image, or sets a single pixel of information
* within a raster image; the image can have a depth of 1 bit,
* or 1, 2, 3 or 4 bytes. When the instance is first created, using
* the MSG_NEW message, the extraction location is set to (0,0), and
* an instance pointer is returned to the application; this instance
* pointer must be used for all subsequent requests made in regard to
* that particular raster image. Using the MSG_LOCATION message,
* an application can change this extraction location to by any point
* within the bounds of the raster image. The extraction location is
* automatically incremented after each MSG_GETVALUE or MSG_SETVALUE
* request, and will wrap back to (0,0), when the end of the raster
* image is reached. When an extraction instance is no longer needed,
* it should be freed up, using the MSG_FREE message.
*
*
* Inputs:
* ------
* instance = For all messages except MSG_NEW, this must specify
* the instance which is to be affected by the message.
* For MSG_NEW, this should be set to NULL.
*
* message = This specifies the action to be performed by this
* intrinsic.
*
* data = This points to a message specific data structure.
*
* Outputs:
* -------
* All messages return the instance pointer upon successful
* completion; NULL is returned upon failure, and the global
* xrErrno will be set.
*
* Procedures Called
* -----------------
* MsgNewHandler()
* MsgLocationHandler()
* MsgValueHandler()
*
*************************************<->***********************************/
xrPixelData *
_XrPixelExtract (instance, message, data)
register xrPixelData * instance;
INT32 message;
INT8 * data;
{
switch (message)
{
case MSG_NEW:
{
/*
* Create a new extraction instance, and initialize its
* instance structure; return a pointer to this structure
* back to the application program.
*
* The 'data' parameter is interpreted as a pointer to an
* instance of the 'xrPixmap' structure, with the 'depth',
* 'height', 'width' and 'raster' fields filled out to describe
* the pixmap which is to have its data extracted.
*/
return ((xrPixelData *) MsgNewHandler (data));
}
case MSG_FREE:
{
/*
* Destroy an active extraction instance; this involves
* simply freeing up the memory occupied by its instance
* structure. The only parameter of interest is the
* the instance pointer; 'data' is ignored.
*/
if (instance == NULL)
{
xrErrno = XrINVALIDID;
return ((xrPixelData *) NULL);
}
(*xrFree) (instance);
return (instance);
}
case MSG_LOCATION:
{
/*
* Set up a new extraction location within the raster
* image. If the point is outside the range of the
* image's dimensions, then the request will fail. The
* 'data' parameter is interpreted as a pointer to a POINT
* structure, containing the new x and y extraction point.
*/
return ((xrPixelData *) MsgLocationHandler (instance, data));
}
case MSG_SETVALUE:
case MSG_GETVALUE:
{
/*
* MSG_GETVALUE:
* Extract the next pixel value from the raster image,
* and return it in the 32 bit integer value pointed
* to by the 'data' parameter.
*
* MSG_SETVALUE:
* Set the pixel specified as the current extraction
* location, to the value specified by the 'data' parameter.
*
* The extraction location will then be incremented by 1.
* If the last column in a row is reached, then the extraction
* location will be set to the start of the next row; if, however,
* this moves us past the last row, then the extraction point
* will wrap back to (0,0).
*/
return ((xrPixelData *) MsgValueHandler (instance, message, data));
}
} /* end of switch */
xrErrno = XrINVALIDMSG;
return ((xrPixelData *) NULL);
} /* end of _XrPixelExtract() */
\f
/*************************************<->*************************************
*
* xrPixelData *
* MsgNewHandler (pixmapInfo)
*
* xrPixmap * pixmapInfo;
*
* Description:
* -----------
* This routine is responsible for creating a new pixel extraction
* instance. It will allocate a structure to hold all of the
* extraction information, initialize it, and then return a pointer
* to this structure back to the calling application; this pointer
* will serve as a unique handle for that particular extraction
* instance. A MSG_NEW request will fail if the instance data is
* not supplied, or an invalid raster depth is supplied, or the
* system is out of memory.
*
*
* Inputs:
* ------
* pixmapInfo = This is a pointer to an X-ray pixmap structure,
* containing the description of the raster image
* which is to have an extraction instance created.
* This includes the raster data, the height and
* width of the data, and the depth of the raster data.
*
* Outputs:
* -------
* Upon successful completion, the instance pointer for the new
* extraction instance will be returned. If the request
* fails, then 'NULL' is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
*
*************************************<->***********************************/
static
xrPixelData *
MsgNewHandler (pixmapInfo)
register xrPixmap * pixmapInfo;
{
register xrPixelData * instance;
INT8 depth;
if (pixmapInfo == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrPixelData *) NULL);
}
/* Check for an invalid raster depth specification */
depth = pixmapInfo->depth;
if ((depth != XrBIT1) && (depth != XrBYTE1) && (depth != XrBYTE2) &&
(depth != XrBYTE3) && (depth != XrBYTE4))
{
xrErrno = XrINVALIDDEPTH;
return ((xrPixelData *) NULL);
}
/* Allocate an instance structure, and initialize it */
if ((instance = (xrPixelData *) (*xrMalloc) (sizeof (xrPixelData)))
== NULL)
{
xrErrno = XrOUTOFMEM;
return ((xrPixelData *) NULL);
}
instance->height = pixmapInfo->height;
instance->width = pixmapInfo->width;
instance->depth = depth;
instance->data = (UINT8 *) pixmapInfo->raster;
instance->extractionLoc.x = 0;
instance->extractionLoc.y = 0;
return (instance);
}
\f
/*************************************<->*************************************
*
* xrPixelData *
* MsgLocationHandler (instance, location)
*
* xrPixelData * instance;
* POINT * location;
*
* Description:
* -----------
* This routine modifies the point at which a pixel value is extracted,
* for a MSG_GETVALUE request, or set, for a MSG_SETVALUE request. The
* value is in the form (x,y), where 'x' is the column number, and 'y'
* is the row number. This request will fail if the location is outside
* the range of the raster image.
*
*
* Inputs:
* ------
* instance = This handle indicates which extraction instance is to
* have its extraction location modified. This is a
* pointer to the extraction data structure, allocated
* during the MSG_NEW request.
*
* location = This is a pointer to a POINT structure, containing the
* new extraction location, specified as an (x,y) pair.
*
* Outputs:
* -------
* Upon successful completion, the instance pointer will be returned;
* otherwise, a value of 'NULL' is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* XrCopyPt() [calc.c]
*
*************************************<->***********************************/
static
xrPixelData *
MsgLocationHandler (instance, location)
register xrPixelData * instance;
register POINT * location;
{
if (instance == NULL)
{
xrErrno = XrINVALIDID;
return ((xrPixelData *) NULL);
}
else if (location == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrPixelData *) NULL);
}
/*
* Verify the new extraction point falls within the
* bounds of the raster image.
*/
if ((location->x >= instance->width) ||
(location->y >= instance->height) ||
(location->x < 0) || (location->y < 0))
{
xrErrno = XrPARMOUTOFRANGE;
return ((xrPixelData *) NULL);
}
XrCopyPt (location, &instance->extractionLoc);
return (instance);
}
\f
/*************************************<->*************************************
*
* xrPixelData *
* MsgValueHandler (instance, message, value)
*
* xrPixelData * instance;
* INT32 message;
* UINT32 * value;
*
* Description:
* -----------
* This routine allows an application to either extract the next
* pixel value, or set a pixel value within the raster image. In
* either case, the current extraction location is used to determine
* where to grab/set the pixel value, and this location will be
* automatically incremented afterwards; if the end of the image is
* reached, then the extraction location will wrap back to (0,0).
*
*
* Inputs:
* ------
* instance = This is a handle, describing which pixel extraction
* instance is to be used. It is a pointer to the
* extraction data created by the MSG_NEW request.
*
* message = This must be either MSG_GETVALUE or MSG_SETVALUE.
*
* value = If the message is MSG_GETVALUE, then this is a pointer
* to an unsigned 32 bit integer value, into which the
* next pixel value will be placed. If the message is
* MSG_SETVALUE, then this is an unsigned 32 bit value
* which will be stored into the raster image, at the
* current extraction location.
*
* Outputs:
* -------
* Upon successful completion, the instance pointer will be returned;
* in addition, if this was a MSG_GETVALUE request, then the
* next pixel value will be returned by means of the unsigned
* 32 bit integer value pointed to by the 'value' parameter. If
* this request fails, then 'NULL' is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* XrCopyPt() [calc.c]
*
*************************************<->***********************************/
static
xrPixelData *
MsgValueHandler (instance, message, value)
register xrPixelData * instance;
INT32 message;
UINT32 * value;
{
INT8 depth;
if (instance == NULL)
{
xrErrno = XrINVALIDID;
return ((xrPixelData *) NULL);
}
else if ((message == MSG_GETVALUE) && (value == NULL))
{
xrErrno = XrINVALIDPTR;
return ((xrPixelData *) NULL);
}
depth = instance->depth;
if (depth == XrBIT1)
{
/*
* Bit extraction requires a different algorithm than that used
* to extract bytes of data. Using the extraction location, we
* must first determine which word of data the desired bit resides
* in, and then we must construct a mask, used to extract out that
* single bit from the word, or to set/clear that bit.
*/
UINT16 * wordPtr; /* Ptr to word of interest */
UINT16 extractionMask; /* Mask to extract bit of interest */
wordPtr = (UINT16 *)instance->data +
(instance->extractionLoc.x >> 4) +
(instance->extractionLoc.y * ((instance->width + 15) >> 4));
extractionMask = 1 << (instance->extractionLoc.x & 15);
if (message == MSG_GETVALUE)
*value = (*wordPtr & extractionMask) ? 1 : 0;
else
{
if (value)
*wordPtr |= extractionMask;
else
*wordPtr &= ~extractionMask;
}
}
else
{
/*
* Byte extraction is easy, since we only need to determine the
* number of bytes to extract (based upon the depth of the raster
* image), and then we can extract the data.
*/
register INT32 valueLen; /* Number of bytes to extract */
register UINT8 * valuePtr; /* Ptr to bytes of interest */
register UINT32 pixelValue; /* Value being extracted */
INT32 setValue;
INT32 i;
valueLen = depth >> 3;
valuePtr = instance->data +
(instance->extractionLoc.x * valueLen) +
(instance->extractionLoc.y * (valueLen * instance->width));
if (message == MSG_GETVALUE)
{
for (i = 0, pixelValue = 0; i < valueLen; i++)
pixelValue = (pixelValue << 8) + *valuePtr++;
*value = pixelValue;
}
else
{
for (i = 0, setValue = (INT32) value; i < valueLen; i++)
{
*(valuePtr + valueLen - 1 - i) = setValue & 0xFF;
setValue = setValue >> 4;
}
}
}
/* Update the extraction location; wrap, if necessary */
instance->extractionLoc.x++;
if (instance->extractionLoc.x >= instance->width)
{
if (instance->extractionLoc.y >= (instance->height - 1))
XrCopyPt (&xrZeroPt, &instance->extractionLoc);
else
{
instance->extractionLoc.x = 0;
instance->extractionLoc.y++;
}
}
return (instance);
}