diff options
Diffstat (limited to 'generic/tkImgPPM.c')
-rw-r--r-- | generic/tkImgPPM.c | 238 |
1 files changed, 121 insertions, 117 deletions
diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c index ac989db..73f4844 100644 --- a/generic/tkImgPPM.c +++ b/generic/tkImgPPM.c @@ -6,22 +6,22 @@ * Copyright (c) 1994 The Australian National University. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Author: Paul Mackerras (paulus@cs.anu.edu.au), * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPPM.c,v 1.14 2004/03/27 00:12:22 dkf Exp $ + * RCS: @(#) $Id: tkImgPPM.c,v 1.15 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" #include "tkPort.h" /* - * The maximum amount of memory to allocate for data read from the - * file. If we need more than this, we do it in pieces. + * The maximum amount of memory to allocate for data read from the file. If we + * need more than this, we do it in pieces. */ #define MAX_MEMORY 10000 /* don't allocate > 10KB */ @@ -37,27 +37,23 @@ * The format record for the PPM file format: */ -static int FileMatchPPM _ANSI_ARGS_((Tcl_Channel chan, +static int FileMatchPPM(Tcl_Channel chan, CONST char *fileName, + Tcl_Obj *format, int *widthPtr, int *heightPtr, + Tcl_Interp *interp); +static int FileReadPPM(Tcl_Interp *interp, Tcl_Channel chan, CONST char *fileName, Tcl_Obj *format, - int *widthPtr, int *heightPtr, - Tcl_Interp *interp)); -static int FileReadPPM _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Channel chan, CONST char *fileName, + Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY); +static int FileWritePPM(Tcl_Interp *interp, CONST char *fileName, + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); +static int StringWritePPM(Tcl_Interp *interp, Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr); +static int StringMatchPPM(Tcl_Obj *dataObj, Tcl_Obj *format, + int *widthPtr, int *heightPtr, Tcl_Interp *interp); +static int StringReadPPM(Tcl_Interp *interp, Tcl_Obj *dataObj, Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height, - int srcX, int srcY)); -static int FileWritePPM _ANSI_ARGS_((Tcl_Interp *interp, - CONST char *fileName, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr)); -static int StringWritePPM _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr)); -static int StringMatchPPM _ANSI_ARGS_((Tcl_Obj *dataObj, - Tcl_Obj *format, int *widthPtr, int *heightPtr, - Tcl_Interp *interp)); -static int StringReadPPM _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *dataObj, Tcl_Obj *format, - Tk_PhotoHandle imageHandle, int destX, int destY, - int width, int height, int srcX, int srcY)); + int srcX, int srcY); Tk_PhotoImageFormat tkImgFmtPPM = { @@ -71,28 +67,26 @@ Tk_PhotoImageFormat tkImgFmtPPM = { }; /* - * Prototypes for local procedures defined in this file: + * Prototypes for local functions defined in this file: */ -static int ReadPPMFileHeader _ANSI_ARGS_((Tcl_Channel chan, - int *widthPtr, int *heightPtr, - int *maxIntensityPtr)); -static int ReadPPMStringHeader _ANSI_ARGS_((Tcl_Obj *dataObj, - int *widthPtr, int *heightPtr, - int *maxIntensityPtr, - unsigned char **dataBufferPtr, int *dataSizePtr)); +static int ReadPPMFileHeader(Tcl_Channel chan, int *widthPtr, + int *heightPtr, int *maxIntensityPtr); +static int ReadPPMStringHeader(Tcl_Obj *dataObj, int *widthPtr, + int *heightPtr, int *maxIntensityPtr, + unsigned char **dataBufferPtr, int *dataSizePtr); /* *---------------------------------------------------------------------- * * FileMatchPPM -- * - * This procedure is invoked by the photo image type to see if - * a file contains image data in PPM format. + * This function is invoked by the photo image type to see if a file + * contains image data in PPM format. * * Results: - * The return value is >0 if the first characters in file "f" look - * like PPM data, and 0 otherwise. + * The return value is >0 if the first characters in file "f" look like + * PPM data, and 0 otherwise. * * Side effects: * The access position in f may change. @@ -105,9 +99,9 @@ FileMatchPPM(chan, fileName, format, widthPtr, heightPtr, interp) Tcl_Channel chan; /* The image file, open for reading. */ CONST char *fileName; /* The name of the image file. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here if the file is a valid - * raw PPM file. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here if the file is a valid raw PPM + * file. */ Tcl_Interp *interp; /* unused */ { int dummy; @@ -120,17 +114,16 @@ FileMatchPPM(chan, fileName, format, widthPtr, heightPtr, interp) * * FileReadPPM -- * - * This procedure is called by the photo image type to read - * PPM format data from a file and write it into a given - * photo image. + * This function is called by the photo image type to read PPM format + * data from a file and write it into a given photo image. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: - * The access position in file f is changed, and new data is - * added to the image given by imageHandle. + * The access position in file f is changed, and new data is added to the + * image given by imageHandle. * *---------------------------------------------------------------------- */ @@ -143,12 +136,12 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY, CONST char *fileName; /* The name of the image file. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle; /* The photo image to write into. */ - int destX, destY; /* Coordinates of top-left pixel in - * photo image to be written to. */ - int width, height; /* Dimensions of block of photo image to - * be written to. */ - int srcX, srcY; /* Coordinates of top-left pixel to be used - * in image being read. */ + int destX, destY; /* Coordinates of top-left pixel in photo + * image to be written to. */ + int width, height; /* Dimensions of block of photo image to be + * written to. */ + int srcX, srcY; /* Coordinates of top-left pixel to be used in + * image being read. */ { int fileWidth, fileHeight, maxIntensity; int nLines, nBytes, h, type, count; @@ -191,8 +184,7 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY, block.offset[0] = 0; block.offset[1] = 0; block.offset[2] = 0; - } - else { + } else { block.pixelSize = 3; block.offset[0] = 0; block.offset[1] = 1; @@ -261,12 +253,12 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY, * * FileWritePPM -- * - * This procedure is invoked to write image data to a file in PPM - * format. + * This function is invoked to write image data to a file in PPM format + * (although we can read PGM files, we never write them). * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * Data is written to the file given by "fileName". @@ -302,10 +294,10 @@ FileWritePPM(interp, fileName, format, blockPtr) Tcl_Close(NULL, chan); return TCL_ERROR; } - + sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height); Tcl_Write(chan, header, -1); - + pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; @@ -320,9 +312,9 @@ FileWritePPM(interp, fileName, format, blockPtr) for (h = blockPtr->height; h > 0; h--) { pixelPtr = pixLinePtr; for (w = blockPtr->width; w > 0; w--) { - if ((Tcl_Write(chan, (char *) &pixelPtr[0], 1) == -1) - || (Tcl_Write(chan, (char *) &pixelPtr[greenOffset], 1) == -1) - || (Tcl_Write(chan, (char *) &pixelPtr[blueOffset], 1) == -1)) { + if ( Tcl_Write(chan,(char *)&pixelPtr[0], 1) == -1 || + Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1)==-1 || + Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) ==-1) { goto writeerror; } pixelPtr += blockPtr->pixelSize; @@ -336,7 +328,7 @@ FileWritePPM(interp, fileName, format, blockPtr) } chan = NULL; - writeerror: + writeerror: Tcl_AppendResult(interp, "error writing \"", fileName, "\": ", Tcl_PosixError(interp), NULL); if (chan != NULL) { @@ -350,12 +342,12 @@ FileWritePPM(interp, fileName, format, blockPtr) * * StringWritePPM -- * - * This procedure is invoked to write image data to a string in PPM + * This function is invoked to write image data to a string in PPM * format. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * None. @@ -375,10 +367,12 @@ StringWritePPM(interp, format, blockPtr) Tcl_Obj *byteArrayObj; sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height); + /* * Construct a byte array of the right size with the header and * get a pointer to the data part of it. */ + size = strlen(header); byteArrayObj = Tcl_NewByteArrayObj((unsigned char *)header, size); byteArray = Tcl_SetByteArrayLength(byteArrayObj, @@ -392,6 +386,7 @@ StringWritePPM(interp, format, blockPtr) /* * Check if we can do the data move in single action. */ + if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3) && (blockPtr->pitch == (blockPtr->width * 3))) { memcpy(byteArray, pixLinePtr, @@ -413,6 +408,7 @@ StringWritePPM(interp, format, blockPtr) /* * Return the object in the interpreter result. */ + Tcl_SetObjResult(interp, byteArrayObj); return TCL_OK; } @@ -422,12 +418,12 @@ StringWritePPM(interp, format, blockPtr) * * StringMatchPPM -- * - * This procedure is invoked by the photo image type to see if - * a string contains image data in PPM format. + * This function is invoked by the photo image type to see if a string + * contains image data in PPM format. * * Results: - * The return value is >0 if the first characters in file "f" look - * like PPM data, and 0 otherwise. + * The return value is >0 if the first characters in file "f" look like + * PPM data, and 0 otherwise. * * Side effects: * The access position in f may change. @@ -439,9 +435,9 @@ static int StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp) Tcl_Obj *dataObj; /* The image data. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here if the file is a valid - * raw PPM file. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here if the file is a valid raw PPM + * file. */ Tcl_Interp *interp; /* unused */ { int dummy; @@ -455,13 +451,12 @@ StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp) * * StringReadPPM -- * - * This procedure is called by the photo image type to read - * PPM format data from a string and write it into a given - * photo image. + * This function is called by the photo image type to read PPM format + * data from a string and write it into a given photo image. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * New data is added to the image given by imageHandle. @@ -476,12 +471,12 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, Tcl_Obj *dataObj; /* The image data. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle; /* The photo image to write into. */ - int destX, destY; /* Coordinates of top-left pixel in - * photo image to be written to. */ - int width, height; /* Dimensions of block of photo image to - * be written to. */ - int srcX, srcY; /* Coordinates of top-left pixel to be used - * in image being read. */ + int destX, destY; /* Coordinates of top-left pixel in photo + * image to be written to. */ + int width, height; /* Dimensions of block of photo image to be + * written to. */ + int srcX, srcY; /* Coordinates of top-left pixel to be used in + * image being read. */ { int fileWidth, fileHeight, maxIntensity; int nLines, nBytes, h, type, count, dataSize; @@ -543,9 +538,9 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, if (maxIntensity == 255) { /* - * We have all the data in memory, so write everything in one - * go. + * We have all the data in memory, so write everything in one go. */ + if (block.pitch*height < dataSize) { Tcl_AppendResult(interp, "truncated PPM data", NULL); return TCL_ERROR; @@ -606,16 +601,15 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, * * ReadPPMFileHeader -- * - * This procedure reads the PPM header from the beginning of a - * PPM file and returns information from the header. + * This function reads the PPM header from the beginning of a PPM file + * and returns information from the header. * * Results: - * The return value is PGM if file "f" appears to start with - * a valid PGM header, PPM if "f" appears to start with a valid - * PPM header, and 0 otherwise. If the header is valid, - * then *widthPtr and *heightPtr are modified to hold the - * dimensions of the image and *maxIntensityPtr is modified to - * hold the value of a "fully on" intensity value. + * The return value is PGM if file "f" appears to start with a valid PGM + * header, PPM if "f" appears to start with a valid PPM header, and 0 + * otherwise. If the header is valid, then *widthPtr and *heightPtr are + * modified to hold the dimensions of the image and *maxIntensityPtr is + * modified to hold the value of a "fully on" intensity value. * * Side effects: * The access position in f advances. @@ -625,11 +619,11 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, static int ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) - Tcl_Channel chan; /* Image file to read the header from */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here. */ - int *maxIntensityPtr; /* The maximum intensity value for - * the image is stored here. */ + Tcl_Channel chan; /* Image file to read the header from. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here. */ + int *maxIntensityPtr; /* The maximum intensity value for the image + * is stored here. */ { #define BUFFER_SIZE 1000 char buffer[BUFFER_SIZE]; @@ -638,8 +632,8 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) char c; /* - * Read 4 space-separated fields from the file, ignoring - * comments (any line that starts with "#"). + * Read 4 space-separated fields from the file, ignoring comments (any + * line that starts with "#"). */ if (Tcl_Read(chan, &c, 1) != 1) { @@ -685,7 +679,8 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) i++; } } - done: + + done: buffer[i] = 0; /* @@ -711,16 +706,16 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) * * ReadPPMStringHeader -- * - * This procedure reads the PPM header from the beginning of a - * PPM-format string and returns information from the header. + * This function reads the PPM header from the beginning of a PPM-format + * string and returns information from the header. * * Results: - * The return value is PGM if the string appears to start with - * a valid PGM header, PPM if the string appears to start with - * a valid PPM header, and 0 otherwise. If the header is valid, - * then *widthPtr and *heightPtr are modified to hold the - * dimensions of the image and *maxIntensityPtr is modified to - * hold the value of a "fully on" intensity value. + * The return value is PGM if the string appears to start with a valid + * PGM header, PPM if the string appears to start with a valid PPM + * header, and 0 otherwise. If the header is valid, then *widthPtr and + * *heightPtr are modified to hold the dimensions of the image and + * *maxIntensityPtr is modified to hold the value of a "fully on" + * intensity value. * * Side effects: * None @@ -732,10 +727,10 @@ static int ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, dataBufferPtr, dataSizePtr) Tcl_Obj *dataPtr; /* Object to read the header from. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here. */ - int *maxIntensityPtr; /* The maximum intensity value for - * the image is stored here. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here. */ + int *maxIntensityPtr; /* The maximum intensity value for the image + * is stored here. */ unsigned char **dataBufferPtr; int *dataSizePtr; { @@ -749,8 +744,8 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize); /* - * Read 4 space-separated fields from the string, ignoring - * comments (any line that starts with "#"). + * Read 4 space-separated fields from the string, ignoring comments (any + * line that starts with "#"). */ if (dataSize-- < 1) { @@ -800,7 +795,8 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, i++; } } - done: + + done: buffer[i] = 0; /* @@ -824,3 +820,11 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, } return type; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |