// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // // Copyright (C) 2013-2016, The Regents of The University of Michigan. // // 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. // // 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. #ifndef _OPENCV_ZARRAY_HPP_ #define _OPENCV_ZARRAY_HPP_ #include <stdlib.h> #include <string.h> namespace cv { namespace aruco { struct sQuad{ float p[4][2]; // corners }; /** * Defines a structure which acts as a resize-able array ala Java's ArrayList. */ typedef struct zarray zarray_t; struct zarray{ size_t el_sz; // size of each element int size; // how many elements? int alloc; // we've allocated storage for how many elements? char *data; }; /** * Creates and returns a variable array structure capable of holding elements of * the specified size. It is the caller's responsibility to call zarray_destroy() * on the returned array when it is no longer needed. */ inline static zarray_t *_zarray_create(size_t el_sz){ zarray_t *za = (zarray_t*) calloc(1, sizeof(zarray_t)); za->el_sz = el_sz; return za; } /** * Frees all resources associated with the variable array structure which was * created by zarray_create(). After calling, 'za' will no longer be valid for storage. */ inline static void _zarray_destroy(zarray_t *za){ if (za == NULL) return; if (za->data != NULL) free(za->data); memset(za, 0, sizeof(zarray_t)); free(za); } /** * Retrieves the number of elements currently being contained by the passed * array, which may be different from its capacity. The index of the last element * in the array will be one less than the returned value. */ inline static int _zarray_size(const zarray_t *za){ return za->size; } /** * Allocates enough internal storage in the supplied variable array structure to * guarantee that the supplied number of elements (capacity) can be safely stored. */ inline static void _zarray_ensure_capacity(zarray_t *za, int capacity){ if (capacity <= za->alloc) return; while (za->alloc < capacity) { za->alloc *= 2; if (za->alloc < 8) za->alloc = 8; } za->data = (char*) realloc(za->data, za->alloc * za->el_sz); } /** * Adds a new element to the end of the supplied array, and sets its value * (by copying) from the data pointed to by the supplied pointer 'p'. * Automatically ensures that enough storage space is available for the new element. */ inline static void _zarray_add(zarray_t *za, const void *p){ _zarray_ensure_capacity(za, za->size + 1); memcpy(&za->data[za->size*za->el_sz], p, za->el_sz); za->size++; } /** * Retrieves the element from the supplied array located at the zero-based * index of 'idx' and copies its value into the variable pointed to by the pointer * 'p'. */ inline static void _zarray_get(const zarray_t *za, int idx, void *p){ CV_DbgAssert(idx >= 0); CV_DbgAssert(idx < za->size); memcpy(p, &za->data[idx*za->el_sz], za->el_sz); } /** * Similar to zarray_get(), but returns a "live" pointer to the internal * storage, avoiding a memcpy. This pointer is not valid across * operations which might move memory around (i.e. zarray_remove_value(), * zarray_remove_index(), zarray_insert(), zarray_sort(), zarray_clear()). * 'p' should be a pointer to the pointer which will be set to the internal address. */ inline static void _zarray_get_volatile(const zarray_t *za, int idx, void *p){ CV_DbgAssert(idx >= 0); CV_DbgAssert(idx < za->size); *((void**) p) = &za->data[idx*za->el_sz]; } inline static void _zarray_truncate(zarray_t *za, int sz){ za->size = sz; } /** * Sets the value of the current element at index 'idx' by copying its value from * the data pointed to by 'p'. The previous value of the changed element will be * copied into the data pointed to by 'outp' if it is not null. */ static inline void _zarray_set(zarray_t *za, int idx, const void *p, void *outp){ CV_DbgAssert(idx >= 0); CV_DbgAssert(idx < za->size); if (outp != NULL) memcpy(outp, &za->data[idx*za->el_sz], za->el_sz); memcpy(&za->data[idx*za->el_sz], p, za->el_sz); } } } #endif