glVertex  5.5.2
glvertex_pnmformat.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 
5 #ifndef GLVERTEX_PNMFORMAT_H
6 #define GLVERTEX_PNMFORMAT_H
7 
8 #include "string.h"
9 #include "glvertex_io.h"
10 
11 // read a PNM image
12 inline unsigned char *lglReadPnmImage(const char *filename,
13  int *width, int *height,
14  int *components)
15 {
16  const int maxstr = 100;
17 
18  char str[maxstr];
19 
20  unsigned char *data, *ptr1, *ptr2;
21  size_t bytes;
22 
23  int pnmtype, maxval;
24  unsigned char *image;
25 
26  data = lglReadFile(filename, &bytes);
27 
28  if (data == NULL) return(NULL);
29  if (bytes < 4) return(NULL);
30 
31  memcpy(str, data, 3);
32  str[3] = '\0';
33 
34  if (sscanf(str, "P%1d\n", &pnmtype) != 1) return(NULL);
35 
36  ptr1 = data+3;
37  while (*ptr1=='\n' || *ptr1=='#')
38  {
39  while (*ptr1 == '\n')
40  if (++ptr1 >= data+bytes) {free(data); return(NULL);}
41  while (*ptr1 == '#')
42  if (++ptr1 >= data+bytes) {free(data); return(NULL);}
43  else
44  while (*ptr1 != '\n')
45  if (++ptr1 >= data+bytes) {free(data); return(NULL);}
46  }
47 
48  ptr2 = ptr1;
49  while (*ptr2!='\n' && *ptr2!=' ')
50  if (++ptr2 >= data+bytes) {free(data); return(NULL);}
51  if (++ptr2 >= data+bytes) {free(data); return(NULL);}
52  while (*ptr2!='\n' && *ptr2!=' ')
53  if (++ptr2 >= data+bytes) {free(data); return(NULL);}
54  if (++ptr2 >= data+bytes) {free(data); return(NULL);}
55  while (*ptr2!='\n' && *ptr2!=' ')
56  if (++ptr2 >= data+bytes) {free(data); return(NULL);}
57  if (++ptr2 >= data+bytes) {free(data); return(NULL);}
58 
59  if (ptr2-ptr1 >= maxstr) {free(data); return(NULL);}
60  memcpy(str, ptr1, ptr2-ptr1);
61  str[ptr2-ptr1] = '\0';
62 
63  if (sscanf(str, "%d %d\n%d\n", width, height, &maxval) != 3) {free(data); return(NULL);}
64 
65  if (*width<1 || *height<1) {free(data); return(NULL);}
66 
67  if (pnmtype==5 && maxval==255) *components = 1;
68  else if (pnmtype==5 && maxval==65535) *components = 2;
69  else if (pnmtype==6 && maxval==255) *components = 3;
70  else {free(data); return(NULL);}
71 
72  if (data+bytes != ptr2+(*width)*(*height)*(*components)) {free(data); return(NULL);}
73  if ((image=(unsigned char *)malloc((*width)*(*height)*(*components))) == NULL) {free(data); return(NULL);}
74 
75  memcpy(image, ptr2, (*width)*(*height)*(*components));
76  free(data);
77 
78  return(image);
79 }
80 
81 inline unsigned char *lglReadPnmImage(std::string filename,
82  int *width, int *height,
83  int *components)
84 {
85  return(lglReadPnmImage(filename.c_str(),
86  width, height,
87  components));
88 }
89 
90 // write a PNM image
91 inline bool lglWritePnmImage(const char *filename,
92  unsigned char *image,
93  int width, int height,
94  int components)
95 {
96  FILE *file;
97 
98  if (width<1 || height<1) return(false);
99  if (components<1 || components>4) return(false);
100 
101  if ((file=fopen(filename, "wb")) == NULL) return(false);
102 
103  if (components==1 || components==2) fprintf(file, "P5");
104  else if (components==3) fprintf(file, "P6");
105  else if (components==4) fprintf(file, "P8");
106 
107  fprintf(file, "\n%d %d\n", width, height);
108 
109  if (components==1 || components==3 || components==4) fprintf(file, "255\n");
110  else fprintf(file, "65535\n");
111 
112  if (fwrite(image, width*height*components, 1, file) != 1) {fclose(file); return(false);}
113  fclose(file);
114 
115  return(true);
116 }
117 
118 inline bool lglWritePnmImage(std::string filename,
119  unsigned char *image,
120  int width, int height,
121  int components)
122 {
123  return(lglWritePnmImage(filename.c_str(),
124  image,
125  width, height,
126  components));
127 }
128 
129 #endif
glvertex_io.h