Squashed 'third_party/apriltag/' content from commit 3e8e974d0
git-subtree-dir: third_party/apriltag
git-subtree-split: 3e8e974d0d8d6ab318abf56d87506d15d7f2cc35
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Change-Id: I04ba3cb2106b6813a1013d57aa8074c26f856598
diff --git a/common/pnm.c b/common/pnm.c
new file mode 100644
index 0000000..fe77dde
--- /dev/null
+++ b/common/pnm.c
@@ -0,0 +1,154 @@
+/* Copyright (C) 2013-2016, The Regents of The University of Michigan.
+All rights reserved.
+This software was developed in the APRIL Robotics Lab under the
+direction of Edwin Olson, ebolson@umich.edu. This software may be
+available under alternative licensing terms; contact the address above.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the Regents of The University of Michigan.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pnm.h"
+
+pnm_t *pnm_create_from_file(const char *path)
+{
+ FILE *f = fopen(path, "rb");
+ if (f == NULL)
+ return NULL;
+
+ pnm_t *pnm = calloc(1, sizeof(pnm_t));
+ pnm->format = -1;
+
+ char tmp[1024];
+ int nparams = 0; // will be 3 when we're all done.
+ int params[3];
+
+ while (nparams < 3 && !(pnm->format == PNM_FORMAT_BINARY && nparams == 2)) {
+ if (fgets(tmp, sizeof(tmp), f) == NULL)
+ goto error;
+
+ // skip comments
+ if (tmp[0]=='#')
+ continue;
+
+ char *p = tmp;
+
+ if (pnm->format == -1 && tmp[0]=='P') {
+ pnm->format = tmp[1]-'0';
+ assert(pnm->format == PNM_FORMAT_GRAY || pnm->format == PNM_FORMAT_RGB || pnm->format == PNM_FORMAT_BINARY);
+ p = &tmp[2];
+ }
+
+ // pull integers out of this line until there are no more.
+ while (nparams < 3 && *p!=0) {
+ while (*p==' ')
+ p++;
+
+ // encounter rubbish? (End of line?)
+ if (*p < '0' || *p > '9')
+ break;
+
+ int acc = 0;
+ while (*p >= '0' && *p <= '9') {
+ acc = acc*10 + *p - '0';
+ p++;
+ }
+
+ params[nparams++] = acc;
+ p++;
+ }
+ }
+
+ pnm->width = params[0];
+ pnm->height = params[1];
+ pnm->max = params[2];
+
+ switch (pnm->format) {
+ case PNM_FORMAT_BINARY: {
+ // files in the wild sometimes simply don't set max
+ pnm->max = 1;
+
+ pnm->buflen = pnm->height * ((pnm->width + 7) / 8);
+ pnm->buf = malloc(pnm->buflen);
+ size_t len = fread(pnm->buf, 1, pnm->buflen, f);
+ if (len != pnm->buflen)
+ goto error;
+
+ fclose(f);
+ return pnm;
+ }
+
+ case PNM_FORMAT_GRAY: {
+ if (pnm->max == 255)
+ pnm->buflen = pnm->width * pnm->height;
+ else if (pnm->max == 65535)
+ pnm->buflen = 2 * pnm->width * pnm->height;
+ else
+ assert(0);
+
+ pnm->buf = malloc(pnm->buflen);
+ size_t len = fread(pnm->buf, 1, pnm->buflen, f);
+ if (len != pnm->buflen)
+ goto error;
+
+ fclose(f);
+ return pnm;
+ }
+
+ case PNM_FORMAT_RGB: {
+ if (pnm->max == 255)
+ pnm->buflen = pnm->width * pnm->height * 3;
+ else if (pnm->max == 65535)
+ pnm->buflen = 2 * pnm->width * pnm->height * 3;
+ else
+ assert(0);
+
+ pnm->buf = malloc(pnm->buflen);
+ size_t len = fread(pnm->buf, 1, pnm->buflen, f);
+ if (len != pnm->buflen)
+ goto error;
+ fclose(f);
+ return pnm;
+ }
+ }
+
+error:
+ fclose(f);
+
+ if (pnm != NULL) {
+ free(pnm->buf);
+ free(pnm);
+ }
+
+ return NULL;
+}
+
+void pnm_destroy(pnm_t *pnm)
+{
+ if (pnm == NULL)
+ return;
+
+ free(pnm->buf);
+ free(pnm);
+}