00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #ifdef HAVE_UNISTD_H
00029 # include <unistd.h>
00030 #endif
00031 #ifdef HAVE_SYS_TIMES_H
00032 # include <sys/times.h>
00033 #endif
00034 #ifdef _WIN32
00035 # include <io.h>
00036 # include <fcntl.h>
00037 #endif
00038 #include <assert.h>
00039
00040 #include <zbar.h>
00041
00042
00043 #include "opencv/cv.h"
00044 #include "opencv/highgui.h"
00045
00046
00047
00048
00049
00050
00051 #if MagickLibVersion < 0x645
00052 # define MagickExportImagePixels MagickGetImagePixels
00053 #endif
00054
00055 static const char *note_usage =
00056 "usage: zbarimg [options] <image>...\n"
00057 "\n"
00058 "scan and decode bar codes from one or more image files\n"
00059 "\n"
00060 "options:\n"
00061 " -h, --help display this help text\n"
00062 " --version display version information and exit\n"
00063 " -q, --quiet minimal output, only print decoded symbol data\n"
00064 " -v, --verbose increase debug output level\n"
00065 " --verbose=N set specific debug output level\n"
00066 " -d, --display enable display of following images to the screen\n"
00067 " -D, --nodisplay disable display of following images (default)\n"
00068 " --xml, --noxml enable/disable XML output format\n"
00069 " --raw output decoded symbol data without symbology prefix\n"
00070 " -S<CONFIG>[=<VALUE>], --set <CONFIG>[=<VALUE>]\n"
00071 " set decoder/scanner <CONFIG> to <VALUE> (or 1)\n"
00072
00073 "\n"
00074 ;
00075
00076 static const char *warning_not_found =
00077 "\n"
00078 "WARNING: barcode data was not detected in some image(s)\n"
00079 " things to check:\n"
00080 " - is the barcode type supported?"
00081 " currently supported symbologies are:\n"
00082 " EAN/UPC (EAN-13, EAN-8, UPC-A, UPC-E, ISBN-10, ISBN-13),\n"
00083 " Code 128, Code 39 and Interleaved 2 of 5\n"
00084 " - is the barcode large enough in the image?\n"
00085 " - is the barcode mostly in focus?\n"
00086 " - is there sufficient contrast/illumination?\n"
00087 "\n";
00088
00089 static const char *xml_head =
00090 "<barcodes xmlns='http://zbar.sourceforge.net/2008/barcode'>\n";
00091 static const char *xml_foot =
00092 "</barcodes>\n";
00093
00094 static int notfound = 0, exit_code = 0;
00095 static int num_images = 1, num_symbols = 0;
00096 static int xmllvl = 0;
00097
00098 char *xmlbuf = NULL;
00099 unsigned xmlbuflen = 0;
00100
00101 static zbar_processor_t *processor = NULL;
00102
00103 static int scan_image (IplImage * image)
00104 {
00105 if(exit_code == 3)
00106 return(-1);
00107
00108 int found = 0;
00109 if(exit_code == 3)
00110 return(-1);
00111
00112 zbar_image_t *zimage = zbar_image_create();
00113 assert(zimage);
00114 zbar_image_set_format(zimage, *(unsigned long*)"Y800");
00115
00116
00117 int width = image->width;
00118 int height = image->height;
00119 zbar_image_set_size(zimage, width, height);
00120
00121
00122
00123
00124 size_t bloblen = width * height;
00125 unsigned char *blob = malloc(bloblen);
00126 zbar_image_set_data(zimage, blob, bloblen, zbar_image_free_data);
00127
00128
00129 memcpy(blob, image->imageData, image->imageSize);
00130
00131 if(xmllvl == 1)
00132 {
00133 xmllvl++;
00134
00135 }
00136
00137 zbar_process_image(processor, zimage);
00138
00139
00140 const zbar_symbol_t *sym = zbar_image_first_symbol(zimage);
00141 for(; sym; sym = zbar_symbol_next(sym))
00142 {
00143 zbar_symbol_type_t typ = zbar_symbol_get_type(sym);
00144 if(typ == ZBAR_PARTIAL)
00145 continue;
00146 else if(!xmllvl)
00147 printf("%s%s:%s\n",
00148 zbar_get_symbol_name(typ),
00149 zbar_get_addon_name(typ),
00150 zbar_symbol_get_data(sym));
00151 else if(xmllvl < 0)
00152 printf("%s\n", zbar_symbol_get_data(sym));
00153 else {
00154 if(xmllvl < 3)
00155 {
00156 xmllvl++;
00157
00158 }
00159 zbar_symbol_xml(sym, &xmlbuf, &xmlbuflen);
00160 printf("%s\n", xmlbuf);
00161 }
00162 found++;
00163 num_symbols++;
00164 }
00165 if(xmllvl > 2)
00166 {
00167 xmllvl--;
00168 printf("</index>\n");
00169 }
00170 fflush(stdout);
00171
00172 zbar_image_destroy(zimage);
00173
00174 num_images++;
00175 if(zbar_processor_is_visible(processor))
00176 {
00177 printf("waiting for q\n");
00178 int rc = zbar_processor_user_wait(processor, -1);
00179 if(rc < 0 || rc == 'q' || rc == 'Q')
00180 exit_code = 3;
00181 }
00182
00183
00184 if(xmllvl > 1)
00185 {
00186 xmllvl--;
00187 printf("</source>\n");
00188 }
00189
00190 if(!found)
00191 notfound++;
00192
00193
00194 return(0);
00195 }
00196
00197 int usage (int rc,
00198 const char *msg,
00199 const char *arg)
00200 {
00201 FILE *out = (rc) ? stderr : stdout;
00202 if(msg) {
00203 fprintf(out, "%s", msg);
00204 if(arg)
00205 fprintf(out, "%s", arg);
00206 fprintf(out, "\n\n");
00207 }
00208 fprintf(out, "%s", note_usage);
00209 return(rc);
00210 }
00211
00212 static inline int parse_config (const char *cfgstr, const char *arg)
00213 {
00214 if(!cfgstr || !cfgstr[0])
00215 return(usage(1, "ERROR: need argument for option: ", arg));
00216
00217 if(zbar_processor_parse_config(processor, cfgstr))
00218 return(usage(1, "ERROR: invalid configuration setting: ", cfgstr));
00219
00220 return(0);
00221 }
00222
00223 int main (int argc, const char *argv[])
00224 {
00225
00226 int quiet = 0;
00227 int display = 1;
00228
00229 MagickWandGenesis();
00230
00231 processor = zbar_processor_create(0);
00232 assert(processor);
00233 if(zbar_processor_init(processor, NULL, display))
00234 {
00235 zbar_processor_error_spew(processor, 0);
00236 return(1);
00237 }
00238
00239 if(display)
00240 zbar_processor_set_visible(processor, 1);
00241
00242 IplImage * image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
00243
00244 if(scan_image(image))
00245 return (exit_code);
00246
00247 if(num_images && !quiet && xmllvl <= 0)
00248 {
00249 fprintf(stderr, "scanned %d barcode symbols from %d images",
00250 num_symbols, num_images);
00251 #ifdef HAVE_SYS_TIMES_H
00252 #ifdef HAVE_UNISTD_H
00253 long clk_tck = sysconf(_SC_CLK_TCK);
00254 struct tms tms;
00255 if(clk_tck > 0 && times(&tms) >= 0)
00256 {
00257 double secs = tms.tms_utime + tms.tms_stime;
00258 secs /= clk_tck;
00259 fprintf(stderr, " in %.2g seconds\n", secs);
00260 }
00261 #endif
00262 #endif
00263 fprintf(stderr, "\n");
00264 if(notfound)
00265 fprintf(stderr, "%s", warning_not_found);
00266 }
00267 if(num_images && notfound && !exit_code)
00268 exit_code = 4;
00269
00270 zbar_processor_destroy(processor);
00271 MagickWandTerminus();
00272 return(exit_code);
00273 }
00274