Tachyon (current)  Current Main Branch
ppm.c
Go to the documentation of this file.
1 /*
2  * ppm.c - This file deals with PPM format image files (reading/writing)
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: ppm.c,v 1.26 2022/02/18 17:55:28 johns Exp $
8  *
9  */
10 
11 /* For our puposes, we're interested only in the 3 byte per pixel 24 bit
12  truecolor sort of file.. Probably won't implement any decent checking
13  at this point, probably choke on things like the # comments.. */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <math.h>
18 
19 #define TACHYON_INTERNAL 1
20 #include "tachyon.h"
21 #include "util.h"
22 #include "imageio.h" /* error codes etc */
23 #include "ppm.h"
24 
25 static int getint(FILE * dfile) {
26  char ch[256];
27  int i;
28  int num;
29 
30  num=0;
31  while (num==0) {
32  if (fscanf(dfile, "%255s", ch) == 1) {
33  while (ch[0]=='#') {
34  fgets(ch, sizeof(ch), dfile);
35  }
36  }
37  num=sscanf(ch, "%d", &i);
38  }
39  return i;
40 }
41 
42 int readppm(const char * name, int * xres, int * yres, unsigned char **imgdata) {
43  char data[256];
44  FILE * ifp;
45  int i, bytesread, cnt;
46  int datasize;
47 
48  ifp=fopen(name, "r");
49  if (ifp==NULL) {
50  return IMAGEBADFILE; /* couldn't open the file */
51  }
52 
53  cnt = fscanf(ifp, "%255s", data);
54 
55  if (cnt != 1 || strcmp(data, "P6")) {
56  fclose(ifp);
57  return IMAGEUNSUP; /* not a format we support */
58  }
59 
60  *xres=getint(ifp);
61  *yres=getint(ifp);
62  i=getint(ifp); /* eat the maxval number */
63 
64  /* eat the newline */
65  if (fread(&i, 1, 1, ifp) != 1) {
66  fclose(ifp);
67  return IMAGEUNSUP; /* not a format we support */
68  }
69 
70  datasize = 3 * (*xres) * (*yres);
71 
72  *imgdata=malloc(datasize);
73 
74  bytesread=fread(*imgdata, 1, datasize, ifp);
75 
76  fclose(ifp);
77 
78  if (bytesread != datasize)
79  return IMAGEREADERR;
80 
81  return IMAGENOERR;
82 }
83 
84 
85 int writeppm(const char *name, int xres, int yres, unsigned char *imgdata) {
86  FILE * ofp;
87  int y, xbytes;
88 
89  xbytes = 3*xres;
90 
91  ofp=fopen(name, "wb");
92  if (ofp==NULL)
93  return IMAGEBADFILE;
94 
95  fprintf(ofp, "P6\n");
96  fprintf(ofp, "%d %d\n", xres, yres);
97  fprintf(ofp, "255\n"); /* maxval */
98 
99  for (y=0; y<yres; y++) {
100  if (fwrite(&imgdata[(yres - y - 1)*xbytes], 1, xbytes, ofp) != xbytes) {
101  fclose(ofp);
102  return IMAGEWRITEERR;
103  }
104  }
105 
106  fclose(ofp);
107  return IMAGENOERR;
108 }
109 
110 
111 int writeppm48(const char *name, int xres, int yres, unsigned char *imgdata) {
112  FILE * ofp;
113  int y, xbytes;
114 
115  xbytes = 6*xres;
116 
117  ofp=fopen(name, "wb");
118  if (ofp==NULL)
119  return IMAGEBADFILE;
120 
121  fprintf(ofp, "P6\n");
122  fprintf(ofp, "%d %d\n", xres, yres);
123  fprintf(ofp, "65535\n"); /* maxval */
124 
125  for (y=0; y<yres; y++) {
126  if (fwrite(&imgdata[(yres - y - 1)*xbytes], 1, xbytes, ofp) != xbytes) {
127  fclose(ofp);
128  return IMAGEWRITEERR;
129  }
130  }
131 
132  fclose(ofp);
133  return IMAGENOERR;
134 }
135 
136 
#define IMAGEUNSUP
the image file is an unsupported format
Definition: imageio.h:18
int writeppm(const char *name, int xres, int yres, unsigned char *imgdata)
Definition: ppm.c:85
Tachyon cross-platform timers, special math function wrappers, and RNGs.
int writeppm48(const char *name, int xres, int yres, unsigned char *imgdata)
Definition: ppm.c:111
static int getint(FILE *dfile)
Definition: ppm.c:25
#define IMAGENOERR
no error
Definition: imageio.h:16
#define IMAGEREADERR
failed read, short reads etc
Definition: imageio.h:20
#define IMAGEWRITEERR
failed write, short writes etc
Definition: imageio.h:21
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
#define IMAGEBADFILE
can&#39;t find or can&#39;t open the file
Definition: imageio.h:17
int readppm(const char *name, int *xres, int *yres, unsigned char **imgdata)
Definition: ppm.c:42