ZBar bar code reader . http://zbar.sourceforge.net/ ZBar is licensed under the GNU LGPL 2.1 to enable development of both open source and commercial projects.

Dependents:   GR-PEACH_Camera_in_barcode levkov_ov7670

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers image.c Source File

image.c

00001 /*------------------------------------------------------------------------
00002  *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
00003  *
00004  *  This file is part of the ZBar Bar Code Reader.
00005  *
00006  *  The ZBar Bar Code Reader is free software; you can redistribute it
00007  *  and/or modify it under the terms of the GNU Lesser Public License as
00008  *  published by the Free Software Foundation; either version 2.1 of
00009  *  the License, or (at your option) any later version.
00010  *
00011  *  The ZBar Bar Code Reader is distributed in the hope that it will be
00012  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00013  *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU Lesser Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Lesser Public License
00017  *  along with the ZBar Bar Code Reader; if not, write to the Free
00018  *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
00019  *  Boston, MA  02110-1301  USA
00020  *
00021  *  http://sourceforge.net/projects/zbar
00022  *------------------------------------------------------------------------*/
00023 
00024 #include "error.h"
00025 #include "image.h"
00026 #include "refcnt.h"
00027 
00028 zbar_image_t *zbar_image_create ()
00029 {
00030     zbar_image_t *img = calloc(1, sizeof(zbar_image_t));
00031     _zbar_refcnt_init();
00032     _zbar_image_refcnt(img, 1);
00033     img->srcidx = -1;
00034     return(img);
00035 }
00036 
00037 void _zbar_image_free (zbar_image_t *img)
00038 {
00039     if(img->syms) {
00040         zbar_symbol_set_ref(img->syms, -1);
00041         img->syms = NULL;
00042     }
00043     free(img);
00044 }
00045 
00046 void zbar_image_destroy (zbar_image_t *img)
00047 {
00048     _zbar_image_refcnt(img, -1);
00049 }
00050 
00051 void zbar_image_ref (zbar_image_t *img,
00052                      int refs)
00053 {
00054     _zbar_image_refcnt(img, refs);
00055 }
00056 
00057 unsigned long zbar_image_get_format (const zbar_image_t *img)
00058 {
00059     return(img->format);
00060 }
00061 
00062 unsigned zbar_image_get_sequence (const zbar_image_t *img)
00063 {
00064     return(img->seq);
00065 }
00066 
00067 unsigned zbar_image_get_width (const zbar_image_t *img)
00068 {
00069     return(img->width);
00070 }
00071 
00072 unsigned zbar_image_get_height (const zbar_image_t *img)
00073 {
00074     return(img->height);
00075 }
00076 
00077 const void *zbar_image_get_data (const zbar_image_t *img)
00078 {
00079     return(img->data);
00080 }
00081 
00082 unsigned long zbar_image_get_data_length (const zbar_image_t *img)
00083 {
00084     return(img->datalen);
00085 }
00086 
00087 void zbar_image_set_format (zbar_image_t *img,
00088                             unsigned long fmt)
00089 {
00090     img->format = fmt;
00091 }
00092 
00093 void zbar_image_set_sequence (zbar_image_t *img,
00094                               unsigned seq)
00095 {
00096     img->seq = seq;
00097 }
00098 
00099 void zbar_image_set_size (zbar_image_t *img,
00100                           unsigned w,
00101                           unsigned h)
00102 {
00103     img->width = w;
00104     img->height = h;
00105 }
00106 
00107 inline void zbar_image_free_data (zbar_image_t *img)
00108 {
00109     if(!img)
00110         return;
00111     if(img->src) {
00112         /* replace video image w/new copy */
00113         assert(img->refcnt); /* FIXME needs lock */
00114         zbar_image_t *newimg = zbar_image_create();
00115         memcpy(newimg, img, sizeof(zbar_image_t));
00116         /* recycle video image */
00117         newimg->cleanup(newimg);
00118         /* detach old image from src */
00119         img->cleanup = NULL;
00120         img->src = NULL;
00121         img->srcidx = -1;
00122     }
00123     else if(img->cleanup && img->data) {
00124         if(img->cleanup != zbar_image_free_data) {
00125             /* using function address to detect this case is a bad idea;
00126              * windows link libraries add an extra layer of indirection...
00127              * this works around that problem (bug #2796277)
00128              */
00129             zbar_image_cleanup_handler_t *cleanup = img->cleanup;
00130             img->cleanup = zbar_image_free_data;
00131             cleanup(img);
00132         }
00133 #if (1) /* img->data is static address, not need free() */
00134 #else
00135         else {
00136             free((void*)img->data);
00137         }
00138 #endif
00139     }
00140     img->data = NULL;
00141 }
00142 
00143 void zbar_image_set_data (zbar_image_t *img,
00144                           const void *data,
00145                           unsigned long len,
00146                           zbar_image_cleanup_handler_t *cleanup)
00147 {
00148     zbar_image_free_data(img);
00149     img->data = data;
00150     img->datalen = len;
00151     img->cleanup = cleanup;
00152 }
00153 
00154 void zbar_image_set_userdata (zbar_image_t *img,
00155                               void *userdata)
00156 {
00157     img->userdata = userdata;
00158 }
00159 
00160 void *zbar_image_get_userdata (const zbar_image_t *img)
00161 {
00162     return(img->userdata);
00163 }
00164 
00165 zbar_image_t *zbar_image_copy (const zbar_image_t *src)
00166 {
00167     zbar_image_t *dst = zbar_image_create();
00168     dst->format = src->format;
00169     dst->width = src->width;
00170     dst->height = src->height;
00171     dst->datalen = src->datalen;
00172     dst->data = malloc(src->datalen);
00173     assert(dst->data);
00174     memcpy((void*)dst->data, src->data, src->datalen);
00175     dst->cleanup = zbar_image_free_data;
00176     return(dst);
00177 }
00178 
00179 const zbar_symbol_set_t *zbar_image_get_symbols (const zbar_image_t *img)
00180 {
00181     return(img->syms);
00182 }
00183 
00184 void zbar_image_set_symbols (zbar_image_t *img,
00185                              const zbar_symbol_set_t *syms)
00186 {
00187     if(img->syms)
00188         zbar_symbol_set_ref(img->syms, -1);
00189     img->syms = (zbar_symbol_set_t*)syms;
00190     if(syms)
00191         zbar_symbol_set_ref(img->syms, 1);
00192 }
00193 
00194 const zbar_symbol_t *zbar_image_first_symbol (const zbar_image_t *img)
00195 {
00196     return((img->syms) ? img->syms->head : NULL);
00197 }
00198 
00199 typedef struct zimg_hdr_s {
00200     uint32_t magic, format;
00201     uint16_t width, height;
00202     uint32_t size;
00203 } zimg_hdr_t;
00204 
00205 int zbar_image_write (const zbar_image_t *img,
00206                       const char *filebase)
00207 {
00208     int len = strlen(filebase) + 16;
00209     char filename[len];
00210     strcpy(filename, filebase);
00211     int n = 0;
00212     if(*(char*)&img->format >= ' ')
00213         n = snprintf(filename, len, "%s.%.4s.zimg",
00214                      filebase, (char*)&img->format);
00215     else
00216         n = snprintf(filename, len, "%s.%08" PRIx32 ".zimg",
00217                      filebase, img->format);
00218     assert(n < len);
00219     filename[len] = '\0';
00220 
00221     zprintf(1, "dumping %.4s(%08" PRIx32 ") image to %s\n",
00222             (char*)&img->format, img->format, filename);
00223 
00224     FILE *f = fopen(filename, "w");
00225     if(!f) {
00226         int rc = errno;
00227         zprintf(1, "ERROR opening %s: %s\n", filename, strerror(rc));
00228         return(rc);
00229     }
00230 
00231     zimg_hdr_t hdr;
00232     hdr.magic = 0x676d697a;
00233     hdr.format = img->format;
00234     hdr.width = img->width;
00235     hdr.height = img->height;
00236     hdr.size = img->datalen;
00237 
00238     if(fwrite(&hdr, sizeof(hdr), 1, f) != 1 ||
00239        fwrite(img->data, 1, img->datalen, f) != img->datalen) {
00240         int rc = errno;
00241         zprintf(1, "ERROR writing %s: %s\n", filename, strerror(rc));
00242         fclose(f);
00243         return(rc);
00244     }
00245     return(fclose(f));
00246 }
00247 
00248 #ifdef DEBUG_SVG
00249 # include <png.h>
00250 
00251 int zbar_image_write_png (const zbar_image_t *img,
00252                           const char *filename)
00253 {
00254     int rc = -1;
00255     FILE *file = NULL;
00256     png_struct *png = NULL;
00257     png_info *info = NULL;
00258     const uint8_t **rows = NULL;
00259 
00260     rows = malloc(img->height * sizeof(*rows));
00261     if(!rows)
00262         goto done;
00263 
00264     rows[0] = img->data;
00265     int y;
00266     for(y = 1; y < img->height; y++)
00267         rows[y] = rows[y - 1] + img->width;
00268 
00269     file = fopen(filename, "wb");
00270     if(!file)
00271         goto done;
00272 
00273     png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00274     if(!png)
00275         goto done;
00276 
00277     info = png_create_info_struct(png);
00278     if(!info)
00279         goto done;
00280 
00281     if(setjmp(png_jmpbuf(png)))
00282         goto done;
00283 
00284     png_init_io(png, file);
00285     png_set_compression_level(png, 9);
00286     png_set_IHDR(png, info, img->width, img->height, 8, PNG_COLOR_TYPE_GRAY,
00287                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
00288                  PNG_FILTER_TYPE_DEFAULT);
00289 
00290     png_set_rows(png, info, (void*)rows);
00291     png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
00292 
00293     png_write_end(png,info);
00294     rc = 0;
00295 
00296 done:
00297     if(png)
00298         png_destroy_write_struct(&png, &info);
00299     if(rows)
00300         free(rows);
00301     if(file)
00302         fclose(file);
00303     return(rc);
00304 }
00305 
00306 #endif
00307