/[dtapublic]/projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkimgppm.c
ViewVC logotype

Diff of /projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkimgppm.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 70 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkImgPPM.c --   * tkImgPPM.c --
5   *   *
6   *      A photo image file handler for PPM (Portable PixMap) files.   *      A photo image file handler for PPM (Portable PixMap) files.
7   *   *
8   * Copyright (c) 1994 The Australian National University.   * Copyright (c) 1994 The Australian National University.
9   * Copyright (c) 1994-1997 Sun Microsystems, Inc.   * Copyright (c) 1994-1997 Sun Microsystems, Inc.
10   *   *
11   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
12   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13   *   *
14   * Author: Paul Mackerras (paulus@cs.anu.edu.au),   * Author: Paul Mackerras (paulus@cs.anu.edu.au),
15   *         Department of Computer Science,   *         Department of Computer Science,
16   *         Australian National University.   *         Australian National University.
17   *   *
18   * RCS: @(#) $Id: tkimgppm.c,v 1.1.1.1 2001/06/13 05:03:30 dtashley Exp $   * RCS: @(#) $Id: tkimgppm.c,v 1.1.1.1 2001/06/13 05:03:30 dtashley Exp $
19   */   */
20    
21  #define USE_OLD_IMAGE  #define USE_OLD_IMAGE
22    
23  #include "tkInt.h"  #include "tkInt.h"
24  #include "tkPort.h"  #include "tkPort.h"
25    
26  /*  /*
27   * The maximum amount of memory to allocate for data read from the   * The maximum amount of memory to allocate for data read from the
28   * file.  If we need more than this, we do it in pieces.   * file.  If we need more than this, we do it in pieces.
29   */   */
30    
31  #define MAX_MEMORY      10000           /* don't allocate > 10KB */  #define MAX_MEMORY      10000           /* don't allocate > 10KB */
32    
33  /*  /*
34   * Define PGM and PPM, i.e. gray images and color images.   * Define PGM and PPM, i.e. gray images and color images.
35   */   */
36    
37  #define PGM 1  #define PGM 1
38  #define PPM 2  #define PPM 2
39    
40  /*  /*
41   * The format record for the PPM file format:   * The format record for the PPM file format:
42   */   */
43    
44  static int              FileMatchPPM _ANSI_ARGS_((Tcl_Channel chan,  static int              FileMatchPPM _ANSI_ARGS_((Tcl_Channel chan,
45                              char *fileName, char *formatString,                              char *fileName, char *formatString,
46                              int *widthPtr, int *heightPtr));                              int *widthPtr, int *heightPtr));
47  static int              FileReadPPM  _ANSI_ARGS_((Tcl_Interp *interp,  static int              FileReadPPM  _ANSI_ARGS_((Tcl_Interp *interp,
48                              Tcl_Channel chan, char *fileName,                              Tcl_Channel chan, char *fileName,
49                              char *formatString, Tk_PhotoHandle imageHandle,                              char *formatString, Tk_PhotoHandle imageHandle,
50                              int destX, int destY, int width, int height,                              int destX, int destY, int width, int height,
51                              int srcX, int srcY));                              int srcX, int srcY));
52  static int              FileWritePPM _ANSI_ARGS_((Tcl_Interp *interp,  static int              FileWritePPM _ANSI_ARGS_((Tcl_Interp *interp,
53                              char *fileName, char *formatString,                              char *fileName, char *formatString,
54                              Tk_PhotoImageBlock *blockPtr));                              Tk_PhotoImageBlock *blockPtr));
55    
56  Tk_PhotoImageFormat tkImgFmtPPM = {  Tk_PhotoImageFormat tkImgFmtPPM = {
57      "PPM",                      /* name */      "PPM",                      /* name */
58      FileMatchPPM,               /* fileMatchProc */      FileMatchPPM,               /* fileMatchProc */
59      NULL,                       /* stringMatchProc */      NULL,                       /* stringMatchProc */
60      FileReadPPM,                /* fileReadProc */      FileReadPPM,                /* fileReadProc */
61      NULL,                       /* stringReadProc */      NULL,                       /* stringReadProc */
62      FileWritePPM,               /* fileWriteProc */      FileWritePPM,               /* fileWriteProc */
63      NULL,                       /* stringWriteProc */      NULL,                       /* stringWriteProc */
64  };  };
65    
66  /*  /*
67   * Prototypes for local procedures defined in this file:   * Prototypes for local procedures defined in this file:
68   */   */
69    
70  static int              ReadPPMFileHeader _ANSI_ARGS_((Tcl_Channel chan,  static int              ReadPPMFileHeader _ANSI_ARGS_((Tcl_Channel chan,
71                              int *widthPtr, int *heightPtr,                              int *widthPtr, int *heightPtr,
72                              int *maxIntensityPtr));                              int *maxIntensityPtr));
73    
74  /*  /*
75   *----------------------------------------------------------------------   *----------------------------------------------------------------------
76   *   *
77   * FileMatchPPM --   * FileMatchPPM --
78   *   *
79   *      This procedure is invoked by the photo image type to see if   *      This procedure is invoked by the photo image type to see if
80   *      a file contains image data in PPM format.   *      a file contains image data in PPM format.
81   *   *
82   * Results:   * Results:
83   *      The return value is >0 if the first characters in file "f" look   *      The return value is >0 if the first characters in file "f" look
84   *      like PPM data, and 0 otherwise.   *      like PPM data, and 0 otherwise.
85   *   *
86   * Side effects:   * Side effects:
87   *      The access position in f may change.   *      The access position in f may change.
88   *   *
89   *----------------------------------------------------------------------   *----------------------------------------------------------------------
90   */   */
91    
92  static int  static int
93  FileMatchPPM(chan, fileName, formatString, widthPtr, heightPtr)  FileMatchPPM(chan, fileName, formatString, widthPtr, heightPtr)
94      Tcl_Channel chan;           /* The image file, open for reading. */      Tcl_Channel chan;           /* The image file, open for reading. */
95      char *fileName;             /* The name of the image file. */      char *fileName;             /* The name of the image file. */
96      char *formatString;         /* User-specified format string, or NULL. */      char *formatString;         /* User-specified format string, or NULL. */
97      int *widthPtr, *heightPtr;  /* The dimensions of the image are      int *widthPtr, *heightPtr;  /* The dimensions of the image are
98                                   * returned here if the file is a valid                                   * returned here if the file is a valid
99                                   * raw PPM file. */                                   * raw PPM file. */
100  {  {
101      int dummy;      int dummy;
102    
103      return ReadPPMFileHeader(chan, widthPtr, heightPtr, &dummy);      return ReadPPMFileHeader(chan, widthPtr, heightPtr, &dummy);
104  }  }
105    
106  /*  /*
107   *----------------------------------------------------------------------   *----------------------------------------------------------------------
108   *   *
109   * FileReadPPM --   * FileReadPPM --
110   *   *
111   *      This procedure is called by the photo image type to read   *      This procedure is called by the photo image type to read
112   *      PPM format data from a file and write it into a given   *      PPM format data from a file and write it into a given
113   *      photo image.   *      photo image.
114   *   *
115   * Results:   * Results:
116   *      A standard TCL completion code.  If TCL_ERROR is returned   *      A standard TCL completion code.  If TCL_ERROR is returned
117   *      then an error message is left in the interp's result.   *      then an error message is left in the interp's result.
118   *   *
119   * Side effects:   * Side effects:
120   *      The access position in file f is changed, and new data is   *      The access position in file f is changed, and new data is
121   *      added to the image given by imageHandle.   *      added to the image given by imageHandle.
122   *   *
123   *----------------------------------------------------------------------   *----------------------------------------------------------------------
124   */   */
125    
126  static int  static int
127  FileReadPPM(interp, chan, fileName, formatString, imageHandle, destX, destY,  FileReadPPM(interp, chan, fileName, formatString, imageHandle, destX, destY,
128          width, height, srcX, srcY)          width, height, srcX, srcY)
129      Tcl_Interp *interp;         /* Interpreter to use for reporting errors. */      Tcl_Interp *interp;         /* Interpreter to use for reporting errors. */
130      Tcl_Channel chan;           /* The image file, open for reading. */      Tcl_Channel chan;           /* The image file, open for reading. */
131      char *fileName;             /* The name of the image file. */      char *fileName;             /* The name of the image file. */
132      char *formatString;         /* User-specified format string, or NULL. */      char *formatString;         /* User-specified format string, or NULL. */
133      Tk_PhotoHandle imageHandle; /* The photo image to write into. */      Tk_PhotoHandle imageHandle; /* The photo image to write into. */
134      int destX, destY;           /* Coordinates of top-left pixel in      int destX, destY;           /* Coordinates of top-left pixel in
135                                   * photo image to be written to. */                                   * photo image to be written to. */
136      int width, height;          /* Dimensions of block of photo image to      int width, height;          /* Dimensions of block of photo image to
137                                   * be written to. */                                   * be written to. */
138      int srcX, srcY;             /* Coordinates of top-left pixel to be used      int srcX, srcY;             /* Coordinates of top-left pixel to be used
139                                   * in image being read. */                                   * in image being read. */
140  {  {
141      int fileWidth, fileHeight, maxIntensity;      int fileWidth, fileHeight, maxIntensity;
142      int nLines, nBytes, h, type, count;      int nLines, nBytes, h, type, count;
143      unsigned char *pixelPtr;      unsigned char *pixelPtr;
144      Tk_PhotoImageBlock block;      Tk_PhotoImageBlock block;
145    
146      type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);      type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);
147      if (type == 0) {      if (type == 0) {
148          Tcl_AppendResult(interp, "couldn't read raw PPM header from file \"",          Tcl_AppendResult(interp, "couldn't read raw PPM header from file \"",
149                  fileName, "\"", NULL);                  fileName, "\"", NULL);
150          return TCL_ERROR;          return TCL_ERROR;
151      }      }
152      if ((fileWidth <= 0) || (fileHeight <= 0)) {      if ((fileWidth <= 0) || (fileHeight <= 0)) {
153          Tcl_AppendResult(interp, "PPM image file \"", fileName,          Tcl_AppendResult(interp, "PPM image file \"", fileName,
154                  "\" has dimension(s) <= 0", (char *) NULL);                  "\" has dimension(s) <= 0", (char *) NULL);
155          return TCL_ERROR;          return TCL_ERROR;
156      }      }
157      if ((maxIntensity <= 0) || (maxIntensity >= 256)) {      if ((maxIntensity <= 0) || (maxIntensity >= 256)) {
158          char buffer[TCL_INTEGER_SPACE];          char buffer[TCL_INTEGER_SPACE];
159    
160          sprintf(buffer, "%d", maxIntensity);          sprintf(buffer, "%d", maxIntensity);
161          Tcl_AppendResult(interp, "PPM image file \"", fileName,          Tcl_AppendResult(interp, "PPM image file \"", fileName,
162                  "\" has bad maximum intensity value ", buffer,                  "\" has bad maximum intensity value ", buffer,
163                  (char *) NULL);                  (char *) NULL);
164          return TCL_ERROR;          return TCL_ERROR;
165      }      }
166    
167      if ((srcX + width) > fileWidth) {      if ((srcX + width) > fileWidth) {
168          width = fileWidth - srcX;          width = fileWidth - srcX;
169      }      }
170      if ((srcY + height) > fileHeight) {      if ((srcY + height) > fileHeight) {
171          height = fileHeight - srcY;          height = fileHeight - srcY;
172      }      }
173      if ((width <= 0) || (height <= 0)      if ((width <= 0) || (height <= 0)
174          || (srcX >= fileWidth) || (srcY >= fileHeight)) {          || (srcX >= fileWidth) || (srcY >= fileHeight)) {
175          return TCL_OK;          return TCL_OK;
176      }      }
177    
178      if (type == PGM) {      if (type == PGM) {
179          block.pixelSize = 1;          block.pixelSize = 1;
180          block.offset[0] = 0;          block.offset[0] = 0;
181          block.offset[1] = 0;          block.offset[1] = 0;
182          block.offset[2] = 0;          block.offset[2] = 0;
183      }      }
184      else {      else {
185          block.pixelSize = 3;          block.pixelSize = 3;
186          block.offset[0] = 0;          block.offset[0] = 0;
187          block.offset[1] = 1;          block.offset[1] = 1;
188          block.offset[2] = 2;          block.offset[2] = 2;
189      }      }
190      block.offset[3] = 0;      block.offset[3] = 0;
191      block.width = width;      block.width = width;
192      block.pitch = block.pixelSize * fileWidth;      block.pitch = block.pixelSize * fileWidth;
193    
194      Tk_PhotoExpand(imageHandle, destX + width, destY + height);      Tk_PhotoExpand(imageHandle, destX + width, destY + height);
195    
196      if (srcY > 0) {      if (srcY > 0) {
197          Tcl_Seek(chan, (srcY * block.pitch), SEEK_CUR);          Tcl_Seek(chan, (srcY * block.pitch), SEEK_CUR);
198      }      }
199    
200      nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch;      nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch;
201      if (nLines > height) {      if (nLines > height) {
202          nLines = height;          nLines = height;
203      }      }
204      if (nLines <= 0) {      if (nLines <= 0) {
205          nLines = 1;          nLines = 1;
206      }      }
207      nBytes = nLines * block.pitch;      nBytes = nLines * block.pitch;
208      pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);      pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
209      block.pixelPtr = pixelPtr + srcX * block.pixelSize;      block.pixelPtr = pixelPtr + srcX * block.pixelSize;
210    
211      for (h = height; h > 0; h -= nLines) {      for (h = height; h > 0; h -= nLines) {
212          if (nLines > h) {          if (nLines > h) {
213              nLines = h;              nLines = h;
214              nBytes = nLines * block.pitch;              nBytes = nLines * block.pitch;
215          }          }
216          count = Tcl_Read(chan, (char *) pixelPtr, nBytes);          count = Tcl_Read(chan, (char *) pixelPtr, nBytes);
217          if (count != nBytes) {          if (count != nBytes) {
218              Tcl_AppendResult(interp, "error reading PPM image file \"",              Tcl_AppendResult(interp, "error reading PPM image file \"",
219                      fileName, "\": ",                      fileName, "\": ",
220                      Tcl_Eof(chan) ? "not enough data" : Tcl_PosixError(interp),                      Tcl_Eof(chan) ? "not enough data" : Tcl_PosixError(interp),
221                      (char *) NULL);                      (char *) NULL);
222              ckfree((char *) pixelPtr);              ckfree((char *) pixelPtr);
223              return TCL_ERROR;              return TCL_ERROR;
224          }          }
225          if (maxIntensity != 255) {          if (maxIntensity != 255) {
226              unsigned char *p;              unsigned char *p;
227    
228              for (p = pixelPtr; count > 0; count--, p++) {              for (p = pixelPtr; count > 0; count--, p++) {
229                  *p = (((int) *p) * 255)/maxIntensity;                  *p = (((int) *p) * 255)/maxIntensity;
230              }              }
231          }          }
232          block.height = nLines;          block.height = nLines;
233          Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, nLines);          Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, nLines);
234          destY += nLines;          destY += nLines;
235      }      }
236    
237      ckfree((char *) pixelPtr);      ckfree((char *) pixelPtr);
238      return TCL_OK;      return TCL_OK;
239  }  }
240    
241  /*  /*
242   *----------------------------------------------------------------------   *----------------------------------------------------------------------
243   *   *
244   * FileWritePPM --   * FileWritePPM --
245   *   *
246   *      This procedure is invoked to write image data to a file in PPM   *      This procedure is invoked to write image data to a file in PPM
247   *      format.   *      format.
248   *   *
249   * Results:   * Results:
250   *      A standard TCL completion code.  If TCL_ERROR is returned   *      A standard TCL completion code.  If TCL_ERROR is returned
251   *      then an error message is left in the interp's result.   *      then an error message is left in the interp's result.
252   *   *
253   * Side effects:   * Side effects:
254   *      Data is written to the file given by "fileName".   *      Data is written to the file given by "fileName".
255   *   *
256   *----------------------------------------------------------------------   *----------------------------------------------------------------------
257   */   */
258    
259  static int  static int
260  FileWritePPM(interp, fileName, formatString, blockPtr)  FileWritePPM(interp, fileName, formatString, blockPtr)
261      Tcl_Interp *interp;      Tcl_Interp *interp;
262      char *fileName;      char *fileName;
263      char *formatString;      char *formatString;
264      Tk_PhotoImageBlock *blockPtr;      Tk_PhotoImageBlock *blockPtr;
265  {  {
266      Tcl_Channel chan;      Tcl_Channel chan;
267      int w, h;      int w, h;
268      int greenOffset, blueOffset, nBytes;      int greenOffset, blueOffset, nBytes;
269      unsigned char *pixelPtr, *pixLinePtr;      unsigned char *pixelPtr, *pixLinePtr;
270      char header[16 + TCL_INTEGER_SPACE * 2];      char header[16 + TCL_INTEGER_SPACE * 2];
271    
272      chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);      chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
273      if (chan == NULL) {      if (chan == NULL) {
274          return TCL_ERROR;          return TCL_ERROR;
275      }      }
276    
277      if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")      if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
278              != TCL_OK) {              != TCL_OK) {
279          return TCL_ERROR;          return TCL_ERROR;
280      }      }
281      if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")      if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
282              != TCL_OK) {              != TCL_OK) {
283          return TCL_ERROR;          return TCL_ERROR;
284      }      }
285            
286      sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);      sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
287      Tcl_Write(chan, header, -1);      Tcl_Write(chan, header, -1);
288                    
289      pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];      pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
290      greenOffset = blockPtr->offset[1] - blockPtr->offset[0];      greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
291      blueOffset = blockPtr->offset[2] - blockPtr->offset[0];      blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
292    
293      if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)      if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
294              && (blockPtr->pitch == (blockPtr->width * 3))) {              && (blockPtr->pitch == (blockPtr->width * 3))) {
295          nBytes = blockPtr->height * blockPtr->pitch;          nBytes = blockPtr->height * blockPtr->pitch;
296          if (Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {          if (Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
297              goto writeerror;              goto writeerror;
298          }          }
299      } else {      } else {
300          for (h = blockPtr->height; h > 0; h--) {          for (h = blockPtr->height; h > 0; h--) {
301              pixelPtr = pixLinePtr;              pixelPtr = pixLinePtr;
302              for (w = blockPtr->width; w > 0; w--) {              for (w = blockPtr->width; w > 0; w--) {
303                  if ((Tcl_Write(chan, (char *) &pixelPtr[0], 1) == -1)                  if ((Tcl_Write(chan, (char *) &pixelPtr[0], 1) == -1)
304                          || (Tcl_Write(chan, (char *) &pixelPtr[greenOffset], 1) == -1)                          || (Tcl_Write(chan, (char *) &pixelPtr[greenOffset], 1) == -1)
305                          || (Tcl_Write(chan, (char *) &pixelPtr[blueOffset], 1) == -1)) {                          || (Tcl_Write(chan, (char *) &pixelPtr[blueOffset], 1) == -1)) {
306                      goto writeerror;                      goto writeerror;
307                  }                  }
308                  pixelPtr += blockPtr->pixelSize;                  pixelPtr += blockPtr->pixelSize;
309              }              }
310              pixLinePtr += blockPtr->pitch;              pixLinePtr += blockPtr->pitch;
311          }          }
312      }      }
313    
314      if (Tcl_Close(NULL, chan) == 0) {      if (Tcl_Close(NULL, chan) == 0) {
315          return TCL_OK;          return TCL_OK;
316      }      }
317      chan = NULL;      chan = NULL;
318    
319   writeerror:   writeerror:
320      Tcl_AppendResult(interp, "error writing \"", fileName, "\": ",      Tcl_AppendResult(interp, "error writing \"", fileName, "\": ",
321              Tcl_PosixError(interp), (char *) NULL);              Tcl_PosixError(interp), (char *) NULL);
322      if (chan != NULL) {      if (chan != NULL) {
323          Tcl_Close(NULL, chan);          Tcl_Close(NULL, chan);
324      }      }
325      return TCL_ERROR;      return TCL_ERROR;
326  }  }
327    
328  /*  /*
329   *----------------------------------------------------------------------   *----------------------------------------------------------------------
330   *   *
331   * ReadPPMFileHeader --   * ReadPPMFileHeader --
332   *   *
333   *      This procedure reads the PPM header from the beginning of a   *      This procedure reads the PPM header from the beginning of a
334   *      PPM file and returns information from the header.   *      PPM file and returns information from the header.
335   *   *
336   * Results:   * Results:
337   *      The return value is PGM if file "f" appears to start with   *      The return value is PGM if file "f" appears to start with
338   *      a valid PGM header, PPM if "f" appears to start with a valid   *      a valid PGM header, PPM if "f" appears to start with a valid
339   *      PPM header, and 0 otherwise.  If the header is valid,   *      PPM header, and 0 otherwise.  If the header is valid,
340   *      then *widthPtr and *heightPtr are modified to hold the   *      then *widthPtr and *heightPtr are modified to hold the
341   *      dimensions of the image and *maxIntensityPtr is modified to   *      dimensions of the image and *maxIntensityPtr is modified to
342   *      hold the value of a "fully on" intensity value.   *      hold the value of a "fully on" intensity value.
343   *   *
344   * Side effects:   * Side effects:
345   *      The access position in f advances.   *      The access position in f advances.
346   *   *
347   *----------------------------------------------------------------------   *----------------------------------------------------------------------
348   */   */
349    
350  static int  static int
351  ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr)  ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr)
352      Tcl_Channel chan;           /* Image file to read the header from */      Tcl_Channel chan;           /* Image file to read the header from */
353      int *widthPtr, *heightPtr;  /* The dimensions of the image are      int *widthPtr, *heightPtr;  /* The dimensions of the image are
354                                   * returned here. */                                   * returned here. */
355      int *maxIntensityPtr;       /* The maximum intensity value for      int *maxIntensityPtr;       /* The maximum intensity value for
356                                   * the image is stored here. */                                   * the image is stored here. */
357  {  {
358  #define BUFFER_SIZE 1000  #define BUFFER_SIZE 1000
359      char buffer[BUFFER_SIZE];      char buffer[BUFFER_SIZE];
360      int i, numFields;      int i, numFields;
361      int type = 0;      int type = 0;
362      char c;      char c;
363    
364      /*      /*
365       * Read 4 space-separated fields from the file, ignoring       * Read 4 space-separated fields from the file, ignoring
366       * comments (any line that starts with "#").       * comments (any line that starts with "#").
367       */       */
368    
369      if (Tcl_Read(chan, &c, 1) != 1) {      if (Tcl_Read(chan, &c, 1) != 1) {
370          return 0;          return 0;
371      }      }
372      i = 0;      i = 0;
373      for (numFields = 0; numFields < 4; numFields++) {      for (numFields = 0; numFields < 4; numFields++) {
374          /*          /*
375           * Skip comments and white space.           * Skip comments and white space.
376           */           */
377    
378          while (1) {          while (1) {
379              while (isspace(UCHAR(c))) {              while (isspace(UCHAR(c))) {
380                  if (Tcl_Read(chan, &c, 1) != 1) {                  if (Tcl_Read(chan, &c, 1) != 1) {
381                      return 0;                      return 0;
382                  }                  }
383              }              }
384              if (c != '#') {              if (c != '#') {
385                  break;                  break;
386              }              }
387              do {              do {
388                  if (Tcl_Read(chan, &c, 1) != 1) {                  if (Tcl_Read(chan, &c, 1) != 1) {
389                      return 0;                      return 0;
390                  }                  }
391              } while (c != '\n');              } while (c != '\n');
392          }          }
393    
394          /*          /*
395           * Read a field (everything up to the next white space).           * Read a field (everything up to the next white space).
396           */           */
397    
398          while (!isspace(UCHAR(c))) {          while (!isspace(UCHAR(c))) {
399              if (i < (BUFFER_SIZE-2)) {              if (i < (BUFFER_SIZE-2)) {
400                  buffer[i] = c;                  buffer[i] = c;
401                  i++;                  i++;
402              }              }
403              if (Tcl_Read(chan, &c, 1) != 1) {              if (Tcl_Read(chan, &c, 1) != 1) {
404                  goto done;                  goto done;
405              }              }
406          }          }
407          if (i < (BUFFER_SIZE-1)) {          if (i < (BUFFER_SIZE-1)) {
408              buffer[i] = ' ';              buffer[i] = ' ';
409              i++;              i++;
410          }          }
411      }      }
412      done:      done:
413      buffer[i] = 0;      buffer[i] = 0;
414    
415      /*      /*
416       * Parse the fields, which are: id, width, height, maxIntensity.       * Parse the fields, which are: id, width, height, maxIntensity.
417       */       */
418    
419      if (strncmp(buffer, "P6 ", 3) == 0) {      if (strncmp(buffer, "P6 ", 3) == 0) {
420          type = PPM;          type = PPM;
421      } else if (strncmp(buffer, "P5 ", 3) == 0) {      } else if (strncmp(buffer, "P5 ", 3) == 0) {
422          type = PGM;          type = PGM;
423      } else {      } else {
424          return 0;          return 0;
425      }      }
426      if (sscanf(buffer+3, "%d %d %d", widthPtr, heightPtr, maxIntensityPtr)      if (sscanf(buffer+3, "%d %d %d", widthPtr, heightPtr, maxIntensityPtr)
427              != 3) {              != 3) {
428          return 0;          return 0;
429      }      }
430      return type;      return type;
431  }  }
432    
433  /* End of tkimgppm.c */  /* End of tkimgppm.c */

Legend:
Removed from v.70  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25