|
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); }