pam.c
Go to the documentation of this file.
1 /* Copyright (C) 2013-2016, The Regents of The University of Michigan.
2 All rights reserved.
3 
4 This software was developed in the APRIL Robotics Lab under the
5 direction of Edwin Olson, ebolson@umich.edu. This software may be
6 available under alternative licensing terms; contact the address above.
7 
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12 
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <assert.h>
26 
27 #include "pam.h"
28 
29 pam_t *pam_create_from_file(const char *inpath)
30 {
31  FILE *infile = fopen(inpath, "r");
32  if (infile == NULL) {
33  printf("pam.c: couldn't open input file: %s\n", inpath);
34  return NULL;
35  }
36 
37  pam_t *pam = calloc(1, sizeof(pam_t));
38  pam->width = -1;
39  pam->height = -1;
40  pam->depth = -1;
41  pam->maxval = -1;
42  pam->type = -1;
43 
44  int linenumber = 0;
45 
46  while (1) {
47  char line[1024];
48  if (!fgets(line, sizeof(line), infile)) {
49  printf("pam.c: unexpected EOF\n");
50  goto fail;
51  }
52  linenumber++;
53 
54  char *tok0 = line;
55  char *tok1 = NULL;
56 
57  if (line[0] == '#') // comment
58  continue;
59 
60  size_t linelen = strlen(line);
61  for (int idx = 0; idx < linelen; idx++) {
62  if (line[idx] == ' ') {
63  line[idx] = 0;
64  if (tok1) {
65  printf("pam.c: More than two tokens, %s:%d\n", inpath, linenumber);
66  }
67 
68  tok1 = &line[idx+1];
69  }
70  if (line[idx] == '\n')
71  line[idx] = 0;
72  }
73 
74  if (!strcmp(tok0, "P7"))
75  continue;
76 
77  if (!strcmp(tok0, "ENDHDR"))
78  break;
79 
80  if (!strcmp(tok0, "WIDTH") && tok1) {
81  pam->width = atoi(tok1);
82  continue;
83  }
84 
85  if (!strcmp(tok0, "HEIGHT") && tok1) {
86  pam->height = atoi(tok1);
87  continue;
88  }
89 
90  if (!strcmp(tok0, "DEPTH") && tok1) {
91  pam->depth = atoi(tok1);
92  continue;
93  }
94 
95  if (!strcmp(tok0, "MAXVAL") && tok1) {
96  pam->maxval = atoi(tok1);
97  continue;
98  }
99 
100  if (!strcmp(tok0, "TUPLTYPE") && tok1) {
101  if (!strcmp(tok1, "GRAYSCALE_ALPHA")) {
102  pam->type = PAM_GRAYSCALE_ALPHA;
103  continue;
104  }
105 
106  if (!strcmp(tok1, "RGB_ALPHA")) {
107  pam->type = PAM_RGB_ALPHA;
108  continue;
109  }
110 
111  if (!strcmp(tok1, "RGB")) {
112  pam->type = PAM_RGB;
113  continue;
114  }
115 
116  if (!strcmp(tok1, "GRAYSCALE")) {
117  pam->type = PAM_GRAYSCALE;
118  continue;
119  }
120 
121  printf("pam.c: unrecognized tupl type %s\n", tok1);
122  continue;
123  }
124 
125  printf("pam.c: unrecognized attribute %s\n", tok0);
126  }
127 
128  if (pam->width < 0 || pam->height < 0 || pam->depth < 0 ||
129  pam->maxval < 0 || pam->type < 0) {
130  printf("pam.c: missing required metadata field\n");
131  goto fail;
132  }
133 
134  assert(pam->maxval == 255);
135 
136  pam->datalen = pam->width * pam->height * pam->depth;
137  pam->data = malloc(pam->datalen);
138  if (pam->datalen != fread(pam->data, 1, pam->datalen, infile)) {
139  printf("pam.c: couldn't read body\n");
140  goto fail;
141  }
142 
143  fclose(infile);
144  return pam;
145 
146  fail:
147  free(pam);
148  fclose(infile);
149  return NULL;
150 }
151 
152 int pam_write_file(pam_t *pam, const char *outpath)
153 {
154  FILE *f = fopen(outpath, "w+");
155  if (!f)
156  return -1;
157 
158  const char *tupl = NULL;
159  switch (pam->type) {
160  case PAM_GRAYSCALE_ALPHA:
161  tupl = "GRAYSCALE_ALPHA";
162  break;
163  case PAM_RGB_ALPHA:
164  tupl = "RGB_ALPHA";
165  break;
166  case PAM_RGB:
167  tupl = "RGB";
168  break;
169  case PAM_GRAYSCALE:
170  tupl = "GRAYSCALE";
171  break;
172  default:
173  assert(0);
174  }
175 
176  fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
177  pam->width, pam->height, pam->depth, pam->maxval, tupl);
178  int len = pam->width * pam->height * pam->depth;
179  if (len != fwrite(pam->data, 1, len, f)) {
180  fclose(f);
181  return -2;
182  }
183 
184  fclose(f);
185 
186  return 0;
187 }
188 
190 {
191  if (!pam)
192  return;
193 
194  free(pam->data);
195  free(pam);
196 }
197 
199 {
200  pam_t *copy = calloc(1, sizeof(pam_t));
201  copy->width = pam->width;
202  copy->height = pam->height;
203  copy->depth = pam->depth;
204  copy->maxval = pam->maxval;
205  copy->type = pam->type;
206 
207  copy->datalen = pam->datalen;
208  copy->data = malloc(pam->datalen);
209  memcpy(copy->data, pam->data, pam->datalen);
210 
211  return copy;
212 }
213 
214 pam_t *pam_convert(pam_t *in, int type)
215 {
216  if (type == in->type)
217  return pam_copy(in);
218 
219  assert(type == PAM_RGB_ALPHA); // we don't support a lot yet
220  assert(in->maxval == 255);
221 
222  int w = in->width;
223  int h = in->height;
224 
225  pam_t *out = calloc(1, sizeof(pam_t));
226  out->type = type;
227  out->width = w;
228  out->height = h;
229  out->maxval = in->maxval;
230  out->depth = 4;
231  out->datalen = 4 * w * h;
232  out->data = malloc(out->datalen);
233 
234  if (in->type == PAM_RGB) {
235  assert(in->depth == 3);
236  for (int y = 0; y < h; y++) {
237  for (int x = 0; x < w; x++) {
238  out->data[y*4*w + 4*x + 0] = in->data[y*3*w + 3*x + 0];
239  out->data[y*4*w + 4*x + 1] = in->data[y*3*w + 3*x + 1];
240  out->data[y*4*w + 4*x + 2] = in->data[y*3*w + 3*x + 2];
241  out->data[y*4*w + 4*x + 3] = 255;
242  }
243  }
244  } else {
245  printf("pam.c unsupported type %d\n", in->type);
246  assert(0);
247  }
248 
249  return out;
250 }
uint8_t * data
Definition: pam.h:39
int datalen
Definition: pam.h:38
void pam_destroy(pam_t *pam)
Definition: pam.c:189
int height
Definition: pam.h:34
int type
Definition: pam.h:32
int depth
Definition: pam.h:35
pam_t * pam_create_from_file(const char *inpath)
Definition: pam.c:29
Definition: pam.h:30
int maxval
Definition: pam.h:36
pam_t * pam_convert(pam_t *in, int type)
Definition: pam.c:214
pam_t * pam_copy(pam_t *pam)
Definition: pam.c:198
Definition: pam.h:27
int width
Definition: pam.h:34
int pam_write_file(pam_t *pam, const char *outpath)
Definition: pam.c:152
static TTYPENAME *TFN() copy(TTYPENAME *hash)
Definition: thash_impl.h:322


apriltags2
Author(s): Danylo Malyuta
autogenerated on Fri Oct 19 2018 04:02:32