Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* quirc -- QR-code recognition library
  2.  * Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
  3.  *
  4.  * Permission to use, copy, modify, and/or distribute this software for any
  5.  * purpose with or without fee is hereby granted, provided that the above
  6.  * copyright notice and this permission notice appear in all copies.
  7.  *
  8.  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9.  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10.  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11.  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13.  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15.  */
  16.  
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include "quirc_internal.h"
  20.  
  21. const char *quirc_version(void)
  22. {
  23.         return "1.0";
  24. }
  25.  
  26. struct quirc *quirc_new(void)
  27. {
  28.         struct quirc *q = malloc(sizeof(*q));
  29.  
  30.         if (!q)
  31.                 return NULL;
  32.  
  33.         memset(q, 0, sizeof(*q));
  34.         return q;
  35. }
  36.  
  37. void quirc_destroy(struct quirc *q)
  38. {
  39.         free(q->image);
  40.         /* q->pixels may alias q->image when their type representation is of the
  41.            same size, so we need to be careful here to avoid a double free */
  42.         if (!QUIRC_PIXEL_ALIAS_IMAGE)
  43.                 free(q->pixels);
  44.         free(q);
  45. }
  46.  
  47. int quirc_resize(struct quirc *q, int w, int h)
  48. {
  49.         uint8_t         *image  = NULL;
  50.         quirc_pixel_t   *pixels = NULL;
  51.  
  52.         /*
  53.          * XXX: w and h should be size_t (or at least unsigned) as negatives
  54.          * values would not make much sense. The downside is that it would break
  55.          * both the API and ABI. Thus, at the moment, let's just do a sanity
  56.          * check.
  57.          */
  58.         if (w < 0 || h < 0)
  59.                 goto fail;
  60.  
  61.         /*
  62.          * alloc a new buffer for q->image. We avoid realloc(3) because we want
  63.          * on failure to be leave `q` in a consistant, unmodified state.
  64.          */
  65.         image = calloc(w, h);
  66.         if (!image)
  67.                 goto fail;
  68.  
  69.         /* compute the "old" (i.e. currently allocated) and the "new"
  70.            (i.e. requested) image dimensions */
  71.         size_t olddim = q->w * q->h;
  72.         size_t newdim = w * h;
  73.         size_t min = (olddim < newdim ? olddim : newdim);
  74.  
  75.         /*
  76.          * copy the data into the new buffer, avoiding (a) to read beyond the
  77.          * old buffer when the new size is greater and (b) to write beyond the
  78.          * new buffer when the new size is smaller, hence the min computation.
  79.          */
  80.         (void)memcpy(image, q->image, min);
  81.  
  82.         /* alloc a new buffer for q->pixels if needed */
  83.         if (!QUIRC_PIXEL_ALIAS_IMAGE) {
  84.                 pixels = calloc(newdim, sizeof(quirc_pixel_t));
  85.                 if (!pixels)
  86.                         goto fail;
  87.         }
  88.  
  89.         /* alloc succeeded, update `q` with the new size and buffers */
  90.         q->w = w;
  91.         q->h = h;
  92.         free(q->image);
  93.         q->image = image;
  94.         if (!QUIRC_PIXEL_ALIAS_IMAGE) {
  95.                 free(q->pixels);
  96.                 q->pixels = pixels;
  97.         }
  98.  
  99.         return 0;
  100.         /* NOTREACHED */
  101. fail:
  102.         free(image);
  103.         free(pixels);
  104.  
  105.         return -1;
  106. }
  107.  
  108. int quirc_count(const struct quirc *q)
  109. {
  110.         return q->num_grids;
  111. }
  112.  
  113. static const char *const error_table[] = {
  114.         [QUIRC_SUCCESS] = "Success",
  115.         [QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
  116.         [QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
  117.         [QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
  118.         [QUIRC_ERROR_DATA_ECC] = "ECC failure",
  119.         [QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
  120.         [QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
  121.         [QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"
  122. };
  123.  
  124. const char *quirc_strerror(quirc_decode_error_t err)
  125. {
  126.         if (err >= 0 && err < sizeof(error_table) / sizeof(error_table[0]))
  127.                 return error_table[err];
  128.  
  129.         return "Unknown error";
  130. }
  131.