📄 dmtxread.c
字号:
break; case 'M': opt->mosaic = 1; break; case 'N': err = StringToInt(&(opt->stopAfter), optarg, &ptr); if(err != DMTX_SUCCESS || opt->stopAfter < 1 || *ptr != '\0') FatalError(EX_USAGE, _("Invalid count specified \"%s\""), optarg); break; case 'P': opt->pageNumber = 1; break; case 'R': opt->corners = 1; break; case 'S': err = StringToInt(&(opt->shrinkMax), optarg, &ptr); if(err != DMTX_SUCCESS || opt->shrinkMax < 1 || *ptr != '\0') FatalError(EX_USAGE, _("Invalid shrink factor specified \"%s\""), optarg); /* XXX later also popular shrinkMin based on N-N range */ break; case 'V': fprintf(stdout, "%s version %s\n", programName, DMTX_VERSION); fprintf(stdout, "libdmtx version %s\n", dmtxVersion()); exit(EX_OK); break; default: return DMTX_FAILURE; break; } } *fileIndex = optind; return DMTX_SUCCESS;}/** * @brief Display program usage and exit with received status. * @param status error code returned to OS * @return void */static voidShowUsage(int status){ if(status != 0) { fprintf(stderr, _("Usage: %s [OPTION]... [FILE]...\n"), programName); fprintf(stderr, _("Try `%s --help' for more information.\n"), programName); } else { fprintf(stdout, _("Usage: %s [OPTION]... [FILE]...\n"), programName); fprintf(stdout, _("\Scan image FILE for Data Matrix barcodes and print decoded results to\n\standard output. Note that %s may find multiple barcodes in one image.\n\\n\Example: Scan top third of IMAGE001.png and stop after first barcode is found:\n\\n\ %s -n -Y33%% -N1 IMAGE001.png\n\\n\OPTIONS:\n"), programName, programName); fprintf(stdout, _("\ -c, --codewords print codewords extracted from barcode pattern\n\ -e, --minimum-edge=N pixel length of smallest expected edge in image\n\ -E, --maximum-edge=N pixel length of largest expected edge in image\n\ -g, --gap=NUM use scan grid with gap of NUM pixels between lines\n\ -l, --list-formats list supported image formats\n\ -m, --milliseconds=N stop scan after N milliseconds (per image)\n\ -n, --newline print newline character at the end of decoded data\n\ -q, --square-deviation=N allow non-squareness of corners in degrees (0-90)\n")); fprintf(stdout, _("\ -r, --resolution=N resolution for vector images (PDF, SVG, etc...)\n\ -s, --symbol-size=[asr|RxC] only consider barcodes of specific size or shape\n\ a = All sizes [default]\n\ s = Only squares\n\ r = Only rectangles\n\ RxC = Exactly this many rows and columns (10x10, 8x18, etc...)\n\ -t, --threshold=N ignore weak edges below threshold N (1-100)\n")); fprintf(stdout, _("\ -x, --x-range-min=N[%%] do not scan pixels to the left of N (or N%%)\n\ -X, --x-range-max=N[%%] do not scan pixels to the right of N (or N%%)\n\ -y, --y-range-min=N[%%] do not scan pixels above N (or N%%)\n\ -Y, --y-range-max=N[%%] do not scan pixels below N (or N%%)\n\ -C, --corrections-max=N correct at most N errors (0 = correction disabled)\n\ -D, --diagnose make copy of image with additional diagnostic data\n\ -M, --mosaic interpret detected regions as Data Mosaic barcodes\n")); fprintf(stdout, _("\ -N, --stop-after=N stop scanning after Nth barcode is returned\n\ -P, --page-number prefix decoded message with fax/tiff page number\n\ -R, --corners prefix decoded message with corner locations\n\ -S, --shrink=N internally shrink image by a factor of N\n\ -v, --verbose use verbose messages\n\ -V, --version print program version information\n\ --help display this help and exit\n")); fprintf(stdout, _("\nReport bugs to <mike@dragonflylogic.com>.\n")); } exit(status);}/** * * */static intScaleNumberString(char *s, int extent){ int err; int numValue; int scaledValue; char *terminate; assert(s != NULL); err = StringToInt(&numValue, s, &terminate); if(err != DMTX_SUCCESS) FatalError(EX_USAGE, _("Integer value required")); scaledValue = (*terminate == '%') ? (int)(0.01 * numValue * extent + 0.5) : numValue; if(scaledValue < 0) scaledValue = 0; if(scaledValue >= extent) scaledValue = extent - 1; return scaledValue;}/** * @brief List supported input image formats on stdout * @return void */static voidListImageFormats(void){ int i; MagickInfo **formats; ExceptionInfo exception; GetExceptionInfo(&exception); formats=GetMagickInfoArray(&exception); CatchException(&exception); if(formats) { fprintf(stdout, " Format Description\n"); fprintf(stdout, "--------- ------------------------------------------------------\n"); for(i=0; formats[i] != 0; i++) { if(formats[i]->stealth || !formats[i]->decoder) continue; fprintf(stdout, "%9s", formats[i]->name ? formats[i]->name : ""); if(formats[i]->description != (char *)NULL) fprintf(stdout, " %s\n",formats[i]->description); } free(formats); } DestroyExceptionInfo(&exception);}/** * @brief Open an image input file * @param reader Pointer to ImageReader struct * @param imagePath Image path or "-" for stdin * @return DMTX_SUCCESS | DMTX_FAILURE */static intOpenImage(ImageReader *reader, char *imagePath, char *resolution){ reader->image = NULL; GetExceptionInfo(&reader->exception); reader->info = CloneImageInfo((ImageInfo *) NULL); strcpy((reader->info)->filename, imagePath); if(resolution) { reader->info->density = strdup(resolution); reader->info->units = PixelsPerInchResolution; } reader->image = ReadImage(reader->info, &reader->exception); switch(reader->exception.severity) { case UndefinedException: break; case OptionError: case MissingDelegateError: fprintf(stderr, "%s: unsupported file format. Use -l to for a list of available formats.\n", imagePath); break; default: CatchException(&reader->exception); break; } if(!reader->image) CloseImage(reader); return (reader->image) ? DMTX_SUCCESS : DMTX_FAILURE;}/** * @brief Read an image page * @param reader pointer to ImageReader struct * @param index page index * @return pointer to allocated DmtxImage or NULL */static DmtxImage *ReadImagePage(ImageReader *reader, int index){ unsigned int dispatchResult; int pageCount; DmtxImage *image; image = NULL; if(reader->image) { pageCount = GetImageListLength(reader->image); if(index < pageCount) { reader->image = GetImageFromList(reader->image, index); image = dmtxImageMalloc(reader->image->columns, reader->image->rows); if(image) { image->pageCount = pageCount; dispatchResult = DispatchImage(reader->image, 0, 0, reader->image->columns, reader->image->rows, "RGB", CharPixel, image->pxl, &reader->exception); if(dispatchResult == MagickFail) { dmtxImageFree(&image); CatchException(&reader->exception); } } else { perror(programName); } } } return image;}/** * @brief Close an image * @param reader pointer to ImageReader struct * @return void */static voidCloseImage(ImageReader * reader){ if(reader->image) { DestroyImage(reader->image); reader->image = NULL; } DestroyImageInfo(reader->info); DestroyExceptionInfo(&reader->exception);}/** * @brief Print decoded message to standard output * @param opt runtime options from defaults or command line * @param dec pointer to DmtxDecode struct * @return DMTX_SUCCESS | DMTX_FAILURE */static intPrintDecodedOutput(UserOptions *opt, DmtxImage *image, DmtxRegion *reg, DmtxMessage *msg, int pageIndex){ int i; int height; int dataWordLength; int rotateInt; double rotate; DmtxVector2 p00, p10, p11, p01; height = dmtxImageGetProp(image, DmtxPropScaledHeight); p00.X = p00.Y = p10.Y = p01.X = 0.0; p10.X = p01.Y = p11.X = p11.Y = 1.0; dmtxMatrix3VMultiplyBy(&p00, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p10, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p11, reg->fit2raw); dmtxMatrix3VMultiplyBy(&p01, reg->fit2raw); dataWordLength = dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, reg->sizeIdx); if(opt->verbose) { rotate = (2 * M_PI) + (atan2(reg->fit2raw[0][1], reg->fit2raw[1][1]) - atan2(reg->fit2raw[1][0], reg->fit2raw[0][0])) / 2.0; rotateInt = (int)(rotate * 180/M_PI + 0.5); if(rotateInt >= 360) rotateInt -= 360; fprintf(stdout, "--------------------------------------------------\n"); fprintf(stdout, " Matrix Size: %d x %d\n", dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, reg->sizeIdx), dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, reg->sizeIdx)); fprintf(stdout, " Data Codewords: %d (capacity %d)\n", msg->outputIdx, dataWordLength); fprintf(stdout, " Error Codewords: %d\n", dmtxGetSymbolAttribute(DmtxSymAttribSymbolErrorWords, reg->sizeIdx)); fprintf(stdout, " Data Regions: %d x %d\n", dmtxGetSymbolAttribute(DmtxSymAttribHorizDataRegions, reg->sizeIdx), dmtxGetSymbolAttribute(DmtxSymAttribVertDataRegions, reg->sizeIdx)); fprintf(stdout, "Interleaved Blocks: %d\n", dmtxGetSymbolAttribute(DmtxSymAttribInterleavedBlocks, reg->sizeIdx)); fprintf(stdout, " Rotation Angle: %d\n", rotateInt); fprintf(stdout, " Corner 0: (%0.1f, %0.1f)\n", p00.X, height - 1 - p00.Y); fprintf(stdout, " Corner 1: (%0.1f, %0.1f)\n", p10.X, height - 1 - p10.Y); fprintf(stdout, " Corner 2: (%0.1f, %0.1f)\n", p11.X, height - 1 - p11.Y); fprintf(stdout, " Corner 3: (%0.1f, %0.1f)\n", p01.X, height - 1 - p01.Y); fprintf(stdout, "--------------------------------------------------\n"); } if(opt->pageNumber) fprintf(stdout, "%d:", pageIndex + 1); if(opt->corners) { fprintf(stdout, "%d,%d:", (int)(p00.X + 0.5), height - 1 - (int)(p00.Y + 0.5)); fprintf(stdout, "%d,%d:", (int)(p10.X + 0.5), height - 1 - (int)(p10.Y + 0.5)); fprintf(stdout, "%d,%d:", (int)(p11.X + 0.5), height - 1 - (int)(p11.Y + 0.5)); fprintf(stdout, "%d,%d:", (int)(p01.X + 0.5), height - 1 - (int)(p01.Y + 0.5)); } if(opt->codewords) { for(i = 0; i < msg->codeSize; i++) { fprintf(stdout, "%c:%03d\n", (i < dataWordLength) ? 'd' : 'e', msg->code[i]); } } else { fwrite(msg->output, sizeof(char), msg->outputIdx, stdout); if(opt->newline) fputc('\n', stdout); } fflush(stdout); return DMTX_SUCCESS;}/** * * */static voidWriteDiagnosticImage(DmtxDecode *dec, DmtxRegion *reg, char *imagePath){ int row, col; int width, height; int offset; double shade; FILE *fp; DmtxRgb rgb; fp = fopen(imagePath, "wb"); if(fp == NULL) { perror(programName); FatalError(EX_CANTCREAT, _("Unable to write image \"%s\""), imagePath); } width = dmtxImageGetProp(dec->image, DmtxPropScaledWidth); height = dmtxImageGetProp(dec->image, DmtxPropScaledHeight); /* Test each pixel of input image to see if it lies in region */ fprintf(fp, "P6\n%d %d\n255\n", width, height); for(row = height - 1; row >= 0; row--) { for(col = 0; col < width; col++) { offset = dmtxImageGetOffset(dec->image, col, row); if(offset == DMTX_BAD_OFFSET) { rgb[0] = 0; rgb[1] = 0; rgb[2] = 128; } else { dmtxImageGetRgb(dec->image, col, row, rgb); if(dec->image->cache[offset] & 0x40) { rgb[0] = 255; rgb[1] = 0; rgb[2] = 0; } else { shade = (dec->image->cache[offset] & 0x80) ? 0.0 : 0.7; rgb[0] += (shade * (255 - rgb[0])); rgb[1] += (shade * (255 - rgb[1])); rgb[2] += (shade * (255 - rgb[2])); } } fwrite(rgb, sizeof(char), 3, fp); } } fclose(fp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -