diff --git a/README.md b/README.md index 8a6453d..9ceeae8 100644 --- a/README.md +++ b/README.md @@ -5,5 +5,15 @@ Install libdmtx and ImageMagick and run the following commands: phpize ./configure + +If configure gives + + checking for libdmtx... configure: error: Unable to find libdmtx installation + +Try using the `PKG_CONFIG_PATH` flag to provide the folder location containing `libdmtx.pc` + + ./configure PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + + make make install \ No newline at end of file diff --git a/dmtx.c b/dmtx.c index 6d29d0e..8d8f282 100644 --- a/dmtx.c +++ b/dmtx.c @@ -177,10 +177,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(dmtxwrite_save_args, 0, 0, 1) ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, symbol) ZEND_ARG_INFO(0, module) ZEND_ARG_INFO(0, margin) - ZEND_ARG_INFO(0, symbol) - ZEND_ARG_INFO(0, type) ZEND_END_ARG_INFO() static zend_function_entry php_dmtx_write_class_methods[] = @@ -717,7 +717,7 @@ PHP_METHOD(dmtxread, getinfo) /* Let's see how it goes */ if (intern->options.timeout_ms >= 0) { - timeout = dmtxTimeAdd(dmtxTimeNow(), intern->options.timeout_ms); + timeout = dmtxTimeAdd(dmtxTimeNow(), intern->options.timeout_ms); region = dmtxRegionFindNext(decode, &timeout); } else { region = dmtxRegionFindNext(decode, NULL); @@ -840,17 +840,167 @@ PHP_METHOD(dmtxwrite, getscheme) } /* }}} */ -/* {{{ proto bool dmtxWrite::save(string filename[, int module, int margin, int symbol, int type]) +static char * +GetImageFormat(char *filename) +{ + char *ptr = NULL; + + /* Derive format from filename extension */ + if (filename != NULL) { + ptr = strrchr(filename, '.'); + if (ptr != NULL) + ptr++; + } + + /* If still undefined then use format argument */ + if (ptr == NULL || strlen(ptr) == 0) + ptr = "png"; + + return ptr; +} + +static DmtxBoolean +StrNCmpI(const char *s1, const char *s2, size_t n) +{ + size_t i; + + if (s1 == NULL || s2 == NULL || n == 0) + return DmtxFalse; + + for (i = 0; i < n; i++) { + if (tolower(s1[i]) != tolower(s2[i])) + return DmtxFalse; + if (s1[i] == '\0' || s2[i] == '\0') + break; + } + + return DmtxTrue; +} + +static void +WriteImageFile(php_dmtx_write_object *intern, DmtxEncode *enc, char *filename) +{ + long width, height; + + width = dmtxImageGetProp(enc->image, DmtxPropWidth); + height = dmtxImageGetProp(enc->image, DmtxPropHeight); + + /* Clear if previous images */ + if (MagickGetNumberImages(intern->magick_wand) > 0) { + ClearMagickWand(intern->magick_wand); + } + + /* Import the pixels */ + if (MagickConstituteImage(intern->magick_wand, width, height, "RGB", CharPixel, enc->image->pxl) == MagickFalse) { + dmtxEncodeDestroy(&enc); + PHP_DMTX_THROW_IMAGE_EXCEPTION(intern->magick_wand, "Failed to import image"); + } + + if (MagickWriteImage(intern->magick_wand, filename) == MagickFalse) { + dmtxEncodeDestroy(&enc); + PHP_DMTX_THROW_GENERIC_EXCEPTION("Failed to write image"); + } +} + +static void +WriteSvgFile(DmtxEncode *enc, char *filename, char *format, int type) +{ + int col, row, rowInv; + int symbolCols, symbolRows; + int width, height, module; + int defineOnly = DmtxFalse; + unsigned char mosaicRed, mosaicGrn, mosaicBlu; + char *idString = NULL; + char style[100]; + FILE *fp; + + fp = fopen(filename, "wb"); + if (fp == NULL) { + PHP_DMTX_THROW_GENERIC_EXCEPTION("Unable to create output file."); + } + + + width = 2 * enc->marginSize + (enc->region.symbolCols * enc->moduleSize); + height = 2 * enc->marginSize + (enc->region.symbolRows * enc->moduleSize); + + symbolCols = dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, enc->region.sizeIdx); + symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, enc->region.sizeIdx); + + /* Print SVG Header */ + if (defineOnly == DmtxFalse) { + fprintf(fp, "\ +\n\ +\n\ +\n\ + \n", width, height); + } + + fprintf(fp, " \n", idString); + fprintf(fp, " Layout:%dx%d Symbol:%dx%d Data Matrix\n", + width, height, symbolCols, symbolRows); + + /* Write Data Matrix ON modules */ + for (row = 0; row < enc->region.symbolRows; row++) { + rowInv = enc->region.symbolRows - row - 1; + for (col = 0; col < enc->region.symbolCols; col++) { + module = dmtxSymbolModuleStatus(enc->message, enc->region.sizeIdx, row, col); + if (type == PHP_DMTX_MOSAIC) { + mosaicRed = (module & DmtxModuleOnRed) ? 0x00 : 0xff; + mosaicGrn = (module & DmtxModuleOnGreen) ? 0x00 : 0xff; + mosaicBlu = (module & DmtxModuleOnBlue) ? 0x00 : 0xff; + snprintf(style, 100, "style=\"fill:#%02x%02x%02x;fill-opacity:1;stroke:none\" ", + mosaicRed, mosaicGrn, mosaicBlu); + } else { + style[0] = '\0'; + } + + if (module & DmtxModuleOn) { + fprintf(fp, " \n", + enc->moduleSize, enc->moduleSize, + col * enc->moduleSize + enc->marginSize, + rowInv * enc->moduleSize + enc->marginSize, style); + } + } + } + + fprintf(fp, " \n"); + + /* Close SVG document */ + if (defineOnly == DmtxFalse) { + fprintf(fp, "\ + \n\ +\n\ + \n\ +\n\ +\n", idString); + } + + fclose(fp); +} + +/* {{{ proto bool dmtxWrite::save(string filename[,int type, int symbol, int module, int margin]) Saves the message into a file */ PHP_METHOD(dmtxwrite, save) { - php_dmtx_write_object *intern; + php_dmtx_write_object *intern; char *filename; - int filename_len, status; - long symbol = DmtxSymbolSquareAuto, width, height, type = PHP_DMTX_MATRIX, module = 2, margin = 5; + int filename_len; + int status; + long symbol = DmtxSymbolSquareAuto; + long type = PHP_DMTX_MATRIX; + int module = 2; + int margin = 5; + char *format; DmtxEncode *encode; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls!", &filename, &filename_len, &module, &margin, &symbol, &type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|llll", &filename, &filename_len, &type, &symbol, &module, &margin) == FAILURE) { return; } @@ -868,14 +1018,13 @@ PHP_METHOD(dmtxwrite, save) /* Pack as RGB */ dmtxEncodeSetProp(encode, DmtxPropPixelPacking, DmtxPack24bppRGB); + /* Set Symbol shape/size */ dmtxEncodeSetProp(encode, DmtxPropSizeRequest, symbol); + /* Set module size */ + dmtxEncodeSetProp(encode, DmtxPropModuleSize, module); + /* Set margin size */ + dmtxEncodeSetProp(encode, DmtxPropMarginSize, margin); - /* Set module size */ - dmtxEncodeSetProp(encode, DmtxPropModuleSize, module); - - /* Set margin size */ - dmtxEncodeSetProp(encode, DmtxPropMarginSize, margin); - /** * Sets selected encoding scheme */ @@ -892,23 +1041,16 @@ PHP_METHOD(dmtxwrite, save) PHP_DMTX_THROW_GENERIC_EXCEPTION("Failed to encode the image"); } - width = dmtxImageGetProp(encode->image, DmtxPropWidth); - height = dmtxImageGetProp(encode->image, DmtxPropHeight); - - /* Clear if previous images */ - if (MagickGetNumberImages(intern->magick_wand) > 0) { - ClearMagickWand(intern->magick_wand); - } - - /* Import the pixels */ - if (MagickConstituteImage(intern->magick_wand, width, height, "RGB", CharPixel, encode->image->pxl) == MagickFalse) { - dmtxEncodeDestroy(&encode); - PHP_DMTX_THROW_IMAGE_EXCEPTION(intern->magick_wand, "Failed to import image"); + format = GetImageFormat(filename); + if (format == NULL) { + format = "png"; } - if (MagickWriteImage(intern->magick_wand, filename) == MagickFalse) { - dmtxEncodeDestroy(&encode); - PHP_DMTX_THROW_GENERIC_EXCEPTION("Failed to write image"); + /* @todo pass through correct required params */ + if (StrNCmpI(format, "svg", 3) == DmtxTrue) { + WriteSvgFile(encode, filename, format, type); + } else { + WriteImageFile(intern, encode, filename); } dmtxEncodeDestroy(&encode); @@ -1063,11 +1205,45 @@ PHP_MINIT_FUNCTION(dmtx) php_dmtx_sc_entry = zend_register_internal_class(&ce TSRMLS_CC); /* Register constants */ + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_SQUARE_COUNT", DmtxSymbolSquareCount); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_RECT_COUNT", DmtxSymbolRectCount); + + /** Auto Shapes */ PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_SHAPE_AUTO", DmtxSymbolShapeAuto); PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_SQUARE_AUTO", DmtxSymbolSquareAuto); - PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_SQUARE_COUNT", DmtxSymbolSquareCount); PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_RECT_AUTO", DmtxSymbolRectAuto); - PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_RECT_COUNT", DmtxSymbolRectCount); + + /** Defined Shapes */ + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_10_BY_10", DmtxSymbol10x10); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_12_BY_12", DmtxSymbol12x12); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_14_BY_14", DmtxSymbol14x14); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_16_BY_16", DmtxSymbol16x16); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_18_BY_18", DmtxSymbol18x18); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_20_BY_20", DmtxSymbol20x20); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_22_BY_22", DmtxSymbol22x22); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_24_BY_24", DmtxSymbol24x24); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_26_BY_26", DmtxSymbol26x26); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_32_BY_32", DmtxSymbol32x32); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_36_BY_36", DmtxSymbol36x36); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_40_BY_40", DmtxSymbol40x40); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_44_BY_44", DmtxSymbol44x44); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_48_BY_48", DmtxSymbol48x48); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_52_BY_52", DmtxSymbol52x52); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_64_BY_64", DmtxSymbol64x64); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_72_BY_72", DmtxSymbol72x72); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_80_BY_80", DmtxSymbol80x80); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_88_BY_88", DmtxSymbol88x88); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_96_BY_96", DmtxSymbol96x96); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_104_BY_104", DmtxSymbol104x104); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_120_BY_120", DmtxSymbol120x120); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_132_BY_132", DmtxSymbol132x132); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_144_BY_144", DmtxSymbol144x144); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_8_BY_18", DmtxSymbol8x18); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_8_BY_32", DmtxSymbol8x32); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_12_BY_260", DmtxSymbol12x26); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_12_BY_360", DmtxSymbol12x36); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_16_BY_360", DmtxSymbol16x36); + PHP_DMTX_REGISTER_CONST_LONG("SYMBOL_16_BY_480", DmtxSymbol16x48); /* Different types */ PHP_DMTX_REGISTER_CONST_LONG("TYPE_MATRIX", PHP_DMTX_MATRIX); @@ -1140,6 +1316,4 @@ zend_module_entry dmtx_module_entry = #ifdef COMPILE_DL_DMTX ZEND_GET_MODULE(dmtx) -#endif - - +#endif \ No newline at end of file diff --git a/docs/old-wrapper-docs.md b/docs/old-wrapper-docs.md new file mode 100644 index 0000000..9bb3b7f --- /dev/null +++ b/docs/old-wrapper-docs.md @@ -0,0 +1,72 @@ +README for libdmtx-php version 0.7.3 - September 4, 2009 +----------------------------------------------------------------- + +***************************************************************** + +IMPORTANT: A new set of PHP bindings for libdmtx named php-dmtx +has been released by Mikko Koppanen. Mikko's bindings perform +both encoding and decoding of Data Matrix barcodes, and the old +PHP bindings bundled with libdmtx (libdmtx-php) will likely be +deprecated soon. Please try out Mikko's package, available at: + + http://github.com/mkoppanen/php-dmtx + +***************************************************************** + +libdmtx-php is a PHP wrapper for libdmtx that was written by +Christian Hentschel and is distributed as part of the libdmtx +package. + + +1. libdmtx Installation +----------------------------------------------------------------- + +libdmtx must be installed on your system before trying to install +and run libdmtx-php. Refer to the INSTALL file in the main +libdmtx directory for instructions on how to do this. + + +2. libdmtx-php Installation +----------------------------------------------------------------- + + 1) $ phpize + + 2) $ ./configure [--prefix install directory]; + + 3) $ make install + + 3) Edit system php.ini file to include "extension=dmtx.so" + + 4) Test with dmtx.php + (e.g., Browse http://localhost/dmtx.php?d=123456) + + +3. Dependencies +----------------------------------------------------------------- + +These packages are required to install and run libdmtx-php: + + PHP: http://www.php.net + +If you are using an RPM-based system then you can test for the +following packages: + + php + php-cli + php-common + php-devel + +Some systems may also require: + + php-gd + + +4. This Document +----------------------------------------------------------------- + +This document is derived from the wiki page located at: + + http://libdmtx.wikidot.com/libdmtx-php-wrapper + +If you find an error or have additional helpful information, +please edit the wiki directly with your updates. diff --git a/docs/stubs.php b/docs/stubs.php new file mode 100644 index 0000000..f596eb4 --- /dev/null +++ b/docs/stubs.php @@ -0,0 +1,274 @@ + + */ + +//dmtx +class dmtx +{ + const TYPE_MATRIX = 1; + const TYPE_MOSAIC = 2; + + const SCHEME_ASCII = 0; + const SCHEME_C40 = 1; + const SCHEME_TEXT = 2; + const SCHEME_X12 = 3; + const SCHEME_EDITFACT = 4; + const SCHEME_BASE256 = 5; + + const SYMBOL_SQUARE_COUNT = 24; + const SYMBOL_RECT_COUNT = 6; + + const SYMBOL_SHAPE_AUTO = -1; + const SYMBOL_SQUARE_AUTO = -2; + const SYMBOL_RECT_AUTO = -3; + + const SYMBOL_10_BY_10 = 0; + const SYMBOL_12_BY_12 = 1; + const SYMBOL_14_BY_14 = 2; + const SYMBOL_16_BY_16 = 3; + const SYMBOL_18_BY_18 = 4; + const SYMBOL_20_BY_20 = 5; + const SYMBOL_22_BY_22 = 6; + const SYMBOL_24_BY_24 = 7; + const SYMBOL_26_BY_26 = 8; + const SYMBOL_32_BY_32 = 9; + const SYMBOL_36_BY_36 = 10; + const SYMBOL_40_BY_40 = 11; + const SYMBOL_44_BY_44 = 12; + const SYMBOL_48_BY_48 = 13; + const SYMBOL_52_BY_52 = 14; + const SYMBOL_64_BY_64 = 15; + const SYMBOL_72_BY_72 = 16; + const SYMBOL_80_BY_80 = 17; + const SYMBOL_88_BY_88 = 18; + const SYMBOL_96_BY_96 = 19; + const SYMBOL_104_BY_104 = 20; + const SYMBOL_120_BY_120 = 21; + const SYMBOL_132_BY_132 = 22; + const SYMBOL_144_BY_144 = 23; + const SYMBOL_8_BY_18 = 24; + const SYMBOL_8_BY_32 = 25; + const SYMBOL_12_BY_260 = 26; + const SYMBOL_12_BY_360 = 27; + const SYMBOL_16_BY_360 = 28; + const SYMBOL_16_BY_480 = 29; +} + +//dmtxException +class dmtxException extends \Exception {} + +//dmtxWrite +class dmtxWrite +{ + /** + * Constructs the dmtxWrite object + * @param string $message + */ + public function __construct($message) {} + + /** + * Sets the message on the object + * @param string $string + */ + public function setMessage($string) {} + + /** + * Sets the encoding scheme on the object + * @param type $dmtxSCHEME + */ + public function setScheme($dmtxSCHEME) {} + + /** + * Returns encoding scheme on the object + * @return integer + */ + public function getScheme() {} + + /** + * + * @param string $filename + * @param integer|CONST $dmtxTYPE + * @param integer|CONST $dmtxSYMBOL + * @param integer $module + * @param integer $margin + * @throws dmtxException + */ + public function save($filename, $dmtxTYPE=1, $dmtxSYMBOL=-2, $module=2, $margin=5) {} +} + +//dmtxRead +class dmtxRead +{ + /** + * Fetches the information from the image + * @param integer $scan_gap + * @param integer $corrections + * @param integer|CONST $type + * @return array + * e.g. array(1) { + * [0] => + * array(1) { + * [0] => + * array(10) { + * 'message' => + * string(205) "barcode string message" + * 'codewords' => + * int(205) + * 'rotation_angle' => + * int(0) + * 'matrix_width' => + * int(44) + * 'matrix_height' => + * int(44) + * 'data_regions_horizontal' => + * int(2) + * 'data_regions_vertical' => + * int(2) + * 'interleaved_blocks' => + * int(1) + * 'edges' => + * array(4) { + * 'left' => + * string(4) "3x36" + * 'bottom' => + * string(4) "11x3" + * 'top' => + * string(4) "4x69" + * 'right' => + * string(4) "69x3" + * } + * 'bounds' => + * array(2) { + * 'bound_min' => + * string(3) "3x3" + * 'bound_max' => + * string(5) "69x69" + * } + * } + * } + * } + * + */ + public function getInfo($scan_gap=1, $corrections=-1, $dmtxTYPE=1) {} + + /** + * get scan region + * + * @return array + */ + public function getScanRegion() {} + + /** + * Set scan region + * @param integer $x_min + * @param integer $x_max + * @param integer $y_min + * @param integer $y_max + * @return bool + */ + public function setScanRegion($x_min, $x_max, $y_min, $y_max) {} + + /** + * Unset scan region + * + * @return bool + */ + public function unsetScanRegion() {} + + /** + * Returns encoding scheme on the object + * + * @return integer|CONST dmtx::SCHEME_* + */ + public function getScheme() {} + + /** + * Sets the encoding scheme on the object + * + * @param integer|CONST dmtx::SCHEME_* $dmtxSCHEME + * @return bool + */ + public function setScheme($dmtxSCHEME) {} + + /** + * set shrink + * + * @param integer $shrink + * @return bool + */ + public function setShrink($shrink) {} + + /** + * Symbol shape + * + * @param integer $shape + * @return bool + */ + public function setSymbolShape($shape) {} + + /** + * Limit which pages to scan + * + * @param integer $start + * @param integer $limit + * @return bool + */ + public function setLimit($start, $limit) {} + + /** + * Set timeout for reading. Negative number unsets timeout + * + * @param integer $timeout timeout in ms + * @return bool + */ + public function setTimeout($timeout) {} + + /** + * @return integer + */ + public function getShrink() {} + + /** + * @return integer + */ + public function getSymbolShape() {} + + /** + * @return array + */ + public function getLimit() {} + + /** + * @return integer + */ + public function getTimeout() {} + + /** + * Loads a string into the object + * + * @param string $fileContent + * @return bool + */ + public function loadString($fileContent) {} + + /** + * Loads a file into the object + * + * @param string $filename + * @return bool + */ + public function loadFile($filename) {} + + /** + * + * Assumes scheme PhpDmtxSchemeBase256 + * @param string $filename + * @throws \dmtxException + */ + public function __construct($filename) {} +}