Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/zint/backend_tcl/zint.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/zint/backend_tcl/zint.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,1704 @@ +/* zint_tcl.c TCL binding for zint */ +/* + zint - the open source tcl binding to the zint barcode library + Copyright (C) 2014-2024 Harald Oehlmann <oehhar@users.sourceforge.net> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + History + + 2014-06-16 2.5.0 HaO + First implementation + 2016-09-14 2.5.1 HaO +- Added Codablock F options "-rows". +- Adopted to new image format of zint + 2016-10-14 2.5.2 HaO +- Include the upstream reverted image format + 2016-12-12 2.5.3 HaO +- No changes here, take 2.5.1 framework files + 2017-05-12 2.6.0 HaO +- No changes here, take 2.6 framework files + 2017-08-29 2.6.1 HaO +- Framework 2.6.1 extensions +- EAN/UPC Codes with included check digit +- UPNQR Code +- Misspelled symbology: AztecRunes + 2017-10-23 2.6.2 HaO +- Framework 2.6.2 bugfixes +- Allow dll unload + 2018-02-13 2.6.3 HaO + - Framework trunk update + - Added VIN and MailMark symbologies. + 2018-11-02 2.6.4 HaO + - Framework trunk update + - Add options -bold, -dotted, -dotsize, -dmre, -eci + - Implemented ECI logic + 2019-09-01 2.6.5 HaO + - Framework 2.6.5 update + - Add option -gssep + 2019-09-18 2.6.6 HaO + - Framework 2.6.6 update + 2019-10-07 2.6.7 HaO + - Framework 2.6.7 update + 2019-12-05 2.7.0 HaO + - Framework 2.7.0 update + - Add symbology rmqr + 2020-02-01 2.7.1 HaO + - Framework 2.7.1 update + 2020-04-06 HaO + - Added option -fullmultibyte + 2020-04-07 2.8.0 HaO + - Added symbology "UltraCode". + 2020-05-19 HaO + - Added option -separator to specify stacked symbology separator width + - -cols maximum changed from 66 to 67 + 2020-07-27 2.9.0 HaO + - added option "-addongap" + - Renamed symbology names: + - Matrix2of5 -> Standard2of5 + - PDF417Trunc -> PDF417Compact + - RSS14Stacked -> GS1DataBarStacked + - RSS14Stacked -> GS1DataBarStacked + - RSS14StackedOmni -> GS1DataBarSstackedOmni + - RSS14ExpandedStacked -> GS1DataBarExpandedStacked + - OneCode -> USPSIntelligentMail + - EAN128-CC -> GS1-128-CC + - RSS14-CC -> GS1DataBarOmni-CC + - RSSLimited-CC -> GS1DataBarLimited-CC + - RSSExpandedStacked-CC -> GS1DataBarExpanded-CC + - RSSEXPanded-CC -> GS1DataBarExpanded-CC + - RSS14Stacked-CC -> GS1DataBarStacked-CC + - RSS14Omni-CC -> GS1DataBarStackedOmni-CC + - RSSExpandedStacked-CC -> GS1DataBarExpandedStacked-CC + *** Potential incompatibility *** +2020-08-04 2.10.0 HaO +- added symbology "DPDCode" +- Alpha channel support added: + - added option -nobackground + - also allow RRGGBBAA for -fg and -bg options +2021-01-05 2.9.1 HaO +- Added options -reverse, -werror, -wzpl +- Use version number from zint.h (first 3 digits). Do not use an own one. +2021-01-14 GL +- Removed TCL native encoding of ECI's and replace by zint buildin mechanism. + The input is now UTF-8 for any ECI and zint cares about the encoding. +2021-01-14 HaO +- Added detection of presence of the Tk package and late initialization. + This is a preparation to add a TCL only mode to the DLL. +2021-01-22 GL +- -cols maximum changed from 67 to 108 (DotCode) +2021-05-10 GL +- Added -gs1parens option +2021-05-22 GL +- Added -vwhitesp option +2021-05-28 GL +- -cols maximum changed from 108 to 200 (DotCode) +2021-07-09 GL +- Removed -wzpl, added -gs1nocheck +- Made -format position independent +- Tabs -> spaces +2021-09-21 GL +- Added -guarddescent option +- iHeight check int -> double +2021-09-24 GL +- Added -quietzones and -noquietzones options +2021-09-27 GL +- Added -structapp +- Split up -to parsing (could seg fault if given non-int for X0 or Y0) +2021-10-05 GL +- Added -compliantheight option +2021-10-30 GL +- Added PDF417 -rows +2021-11-19 GL +- Added -heightperrow option +- Added DBAR_EXPSTK, CODE16K, CODE49 -rows +2021-12-17 GL +- Added -fast option +2022-04-08 GL +- Updated ECIs to AIM ITS/04-023:2022 + Note changed names "unicode" -> "utf-16be", "euc-cn" -> "gb2312" +2022-04-24 GL +- Added -segN options +- Added "invariant" and "binary" ECIs +- Tcl_GetIndexFromObj() flags arg -> 0 +2022-05-12 GL +- -vers maximum changed to 999 (DAFT) +2022-07-03 GL +- Added BC412 +2022-08-20 GL +- Added CEPNet +2022-11-10 GL +- Added -bindtop option +2022-12-02 GL +- Added -scalexdimdp option +- Renamed CODE128B to CODE128AB + *** Potential incompatibility *** +2022-12-08 GL +- Added MAILMARK_2D +- Renamed MAILMARK to MAILMARK_4S + *** Potential incompatibility *** +2022-12-09 GL +- Added UPU_S10 +2023-01-15 GL +- Added -esc and -extraesc options +2023-02-10 GL +- Added -textgap option +2023-08-11 GL +- Added -guardwhitespace option +2023-10-30 GL +- Added -dmiso144 option +2024-12-09 HaO +- TCL 9 compatibility +- support TCL buildinfo +- remove the zint command on dll unload +2024-12-23 GL +- Added DXFILMEDGE +*/ + +#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) +#pragma warning(disable : 4201 4214 4514) +#define STRICT +#define WIN32_LEAN_AND_MEAN +/* TCL Defines */ +#define DLL_BUILD + +#include <windows.h> + +/* Define ERROR_INVALID_DATA is also used by zint... */ +#ifdef ERROR_INVALID_DATA +#undef ERROR_INVALID_DATA +#endif +#endif + +#include <zint.h> +/* Load version defines */ +#include "../backend/zintconfig.h" +#include <string.h> + +#include <tcl.h> +#include <tk.h> + +/* TCL 9 compatibility for TCL 8.6 compile */ +#ifndef TCL_SIZE_MAX +#ifndef Tcl_Size +typedef int Tcl_Size; +#endif +# define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj +# define Tcl_NewSizeIntObj Tcl_NewIntObj +# define TCL_SIZE_MAX INT_MAX +# define TCL_SIZE_MODIFIER "" +#endif + +#undef EXPORT +#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + + +/*----------------------------------------------------------------------------*/ +/* >>>>> Helper defines */ + +/* Two macros are necessary to not include the define name, but the value */ +#define STRING(x) #x +#define TOSTRING(x) STRING(x) + +/* Define VERSION as the first 3 digits of the zint library version number */ +#define VERSION TOSTRING( ZINT_VERSION_MAJOR ) \ + "." TOSTRING( ZINT_VERSION_MINOR ) \ + "." TOSTRING( ZINT_VERSION_RELEASE ) + +/*----------------------------------------------------------------------------*/ +/* >>>> External Prototypes (exports) */ +DLLEXPORT int Zint_Init (Tcl_Interp *interp); +DLLEXPORT int Zint_Unload (Tcl_Interp *Interp, int Flags); +/*----------------------------------------------------------------------------*/ +/* >>>> local prototypes */ +static void InterpCleanupProc(ClientData clientData, Tcl_Interp *interp); +static int CheckForTk(Tcl_Interp *interp, int *tkFlagPtr); +static int ZintCmd(ClientData unused, Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static int Encode(Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +/*----------------------------------------------------------------------------*/ +/* >>>> File Global Variables */ + +/* >> List of Codes */ + +static const char *s_code_list[] = { + "Code11", + "Standard2of5", + "Interleaved2of5", + "IATAC2of5", + "Logic2of5", + "Ind2of5", + "Code39", + "Code39Extended", + "EAN", + "EAN+Check", + "GS1-128", + "Codabar", + "Code128", + "DPLeit", + "DPIdent", + "Code16K", + "Code49", + "Code93", + "Flat", + "GS1DataBar", + "GS1DataBarLimited", + "GS1DataBarExpanded", + "Telepen", + "UPC-A", + "UPC-A+Check", + "UPC-E", + "UPC-E+Check", + "POSTNET", + "MSIPlessey", + "FIM", + "Logmars", + "Pharma", + "PZN", + "PharmaTwo", + "CEPNet", + "PDF417", + "PDF417Compact", + "MaxiCode", + "QR", + "Code128AB", + "AusPost", + "AusReply", + "AusRoute", + "AusRedirect", + "ISBN", + "RM4SCC", + "Datamatrix", + "EAN14", + "VIN", + "CodablockF", + "NVE18", + "JapanPost", + "KoreaPost", + "GS1DataBarStacked", + "GS1DataBarSstackedOmni", + "GS1DataBarExpandedStacked", + "PLANET", + "DPDCode", + "MicroPDF417", + "USPSIntelligentMail", + "Plessey", + "TelepenNum", + "ITF14", + "KIX", + "Aztec", + "DAFT", + "MicroQR", + "HIBC-128", + "HIBC-39", + "HIBC-DM", + "HIBC-QR", + "HIBC-PDF", + "HIBC-MicroPDF", + "HIBC-CodablockF", + "HIBCAztec", + "DotCode", + "HanXin", + "MailMark-2D", + "UPU-S10", + "MailMark-4S", + "DXFilmEdge", + "AztecRunes", + "Code32", + "EAN-CC", + "GS1-128-CC", + "GS1DataBarOmni-CC", + "GS1DataBarLimited-CC", + "GS1DataBarExpanded-CC", + "UPCA-CC", + "UPCE-CC", + "GS1DataBarStacked-CC", + "GS1DataBarStackedOmni-CC", + "GS1DataBarExpandedStacked-CC", + "Channel", + "CodeOne", + "GridMatrix", + "UPNQR", + "UltraCode", + "rMQR", + "BC412", + NULL}; + +static const int s_code_number[] = { + BARCODE_CODE11, + BARCODE_C25STANDARD, + BARCODE_C25INTER, + BARCODE_C25IATA, + BARCODE_C25LOGIC, + BARCODE_C25IND, + BARCODE_CODE39, + BARCODE_EXCODE39, + BARCODE_EANX, + BARCODE_EANX_CHK, + BARCODE_GS1_128, + BARCODE_CODABAR, + BARCODE_CODE128, + BARCODE_DPLEIT, + BARCODE_DPIDENT, + BARCODE_CODE16K, + BARCODE_CODE49, + BARCODE_CODE93, + BARCODE_FLAT, + BARCODE_DBAR_OMN, + BARCODE_DBAR_LTD, + BARCODE_DBAR_EXP, + BARCODE_TELEPEN, + BARCODE_UPCA, + BARCODE_UPCA_CHK, + BARCODE_UPCE, + BARCODE_UPCE_CHK, + BARCODE_POSTNET, + BARCODE_MSI_PLESSEY, + BARCODE_FIM, + BARCODE_LOGMARS, + BARCODE_PHARMA, + BARCODE_PZN, + BARCODE_PHARMA_TWO, + BARCODE_CEPNET, + BARCODE_PDF417, + BARCODE_PDF417COMP, + BARCODE_MAXICODE, + BARCODE_QRCODE, + BARCODE_CODE128AB, + BARCODE_AUSPOST, + BARCODE_AUSREPLY, + BARCODE_AUSROUTE, + BARCODE_AUSREDIRECT, + BARCODE_ISBNX, + BARCODE_RM4SCC, + BARCODE_DATAMATRIX, + BARCODE_EAN14, + BARCODE_VIN, + BARCODE_CODABLOCKF, + BARCODE_NVE18, + BARCODE_JAPANPOST, + BARCODE_KOREAPOST, + BARCODE_DBAR_STK, + BARCODE_DBAR_OMNSTK, + BARCODE_DBAR_EXPSTK, + BARCODE_PLANET, + BARCODE_DPD, + BARCODE_MICROPDF417, + BARCODE_USPS_IMAIL, + BARCODE_PLESSEY, + BARCODE_TELEPEN_NUM, + BARCODE_ITF14, + BARCODE_KIX, + BARCODE_AZTEC, + BARCODE_DAFT, + BARCODE_MICROQR, + BARCODE_HIBC_128, + BARCODE_HIBC_39, + BARCODE_HIBC_DM, + BARCODE_HIBC_QR, + BARCODE_HIBC_PDF, + BARCODE_HIBC_MICPDF, + BARCODE_HIBC_BLOCKF, + BARCODE_HIBC_AZTEC, + BARCODE_DOTCODE, + BARCODE_HANXIN, + BARCODE_MAILMARK_2D, + BARCODE_UPU_S10, + BARCODE_MAILMARK_4S, + BARCODE_DXFILMEDGE, + BARCODE_AZRUNE, + BARCODE_CODE32, + BARCODE_EANX_CC, + BARCODE_GS1_128_CC, + BARCODE_DBAR_OMN_CC, + BARCODE_DBAR_LTD_CC, + BARCODE_DBAR_EXP_CC, + BARCODE_UPCA_CC, + BARCODE_UPCE_CC, + BARCODE_DBAR_STK_CC, + BARCODE_DBAR_OMNSTK_CC, + BARCODE_DBAR_EXPSTK_CC, + BARCODE_CHANNEL, + BARCODE_CODEONE, + BARCODE_GRIDMATRIX, + BARCODE_UPNQR, + BARCODE_ULTRA, + BARCODE_RMQR, + BARCODE_BC412, + 0}; + +/* ECI TCL encoding names. + * The ECI comments are given after the name. + * A ** indicates encodings where native data must be delivered and not utf-8 + */ +static const char *s_eci_list[] = { + "iso8859-1", /* 3: ISO-8859-1 - Latin alphabet No. 1 (default)*/ + "iso8859-2", /* 4: ISO-8859-2 - Latin alphabet No. 2*/ + "iso8859-3", /* 5: ISO-8859-3 - Latin alphabet No. 3*/ + "iso8859-4", /* 6: ISO-8859-4 - Latin alphabet No. 4*/ + "iso8859-5", /* 7: ISO-8859-5 - Latin/Cyrillic alphabet*/ + "iso8859-6", /* 8: ISO-8859-6 - Latin/Arabic alphabet*/ + "iso8859-7", /* 9: ISO-8859-7 - Latin/Greek alphabet*/ + "iso8859-9", /*10: ISO-8859-8 - Latin/Hebrew alphabet*/ + "iso8859-9", /*11: ISO-8859-9 - Latin alphabet No. 5*/ + "iso8859-10", /*12: ISO-8859-10 - Latin alphabet No. 6*/ + "iso8859-11", /*13: ISO-8859-11 - Latin/Thai alphabet*/ + "iso8859-13", /*15: ISO-8859-13 - Latin alphabet No. 7*/ + "iso8859-14", /*16: ISO-8859-14 - Latin alphabet No. 8 (Celtic)*/ + "iso8859-15", /*17: ISO-8859-15 - Latin alphabet No. 9*/ + "iso8859-16", /*18: ISO-8859-16 - Latin alphabet No. 10*/ + "jis0208", /*20: Shift JIS (JIS X 0208 and JIS X 0201)*/ + "cp1250", /*21: Windows-1250*/ + "cp1251", /*22: Windows-1251*/ + "cp1252", /*23: Windows-1252*/ + "cp1256", /*24: Windows-1256*/ + "utf-16be", /*25: UTF-16BE (High order byte first) Unicode*/ + "utf-8", /*26: Unicode (UTF-8)*/ + "ascii", /*27: ISO-646:1991 7-bit character set ASCII*/ + "big5", /*28: Big5 (Taiwan) Chinese Character Set*/ + "gb2312", /*29: GB 2312 (PRC) Chinese Character Set*/ + "iso2022-kr", /*30: Korean Character Set EUC-KR (KS X 1001:2002)*/ + "gbk", /*31: GBK Chinese Character Set*/ + "gb18030", /*32: GB 18030 Chinese Character Set*/ + "utf-16le", /*33: UTF-16LE (Low order byte first) Unicode*/ + "utf-32be", /*34: UTF-32BE (High order byte first) Unicode*/ + "utf-32le", /*35: UTF-32BE (Low order byte first) Unicode*/ + "invariant", /*170: ISO-646:1991 7-bit character set invariant*/ + "binary", /*899: 8-bit binary*/ + NULL +}; + +/* The ECI numerical number to pass to ZINT */ +static const int s_eci_number[] = { + 3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30, + 31,32,33,34,35,170,899 +}; + +/* Version information */ +static const char version_string[] = VERSION; +/* Help text */ +static const char help_message[] = "zint tcl(stub,obj) dll\n" + " Generate barcode in tk images\n" + "Usage:\n" + " zint encode data photo ?option value? ...\n" + " data: data to encode in the symbol\n" + " photo: a tcl photo image handle ('p' after 'image create photo p')\n" + " Available options:\n" + " -barcode choice: symbology, use 'zint symbology' to get a list\n" + " -addongap integer: (7..12, default: 9) set add-on gap in multiple of module size (EAN/UPC-CC)\n" + " -bg color: set background color as 6 or 8 hex rrggbbaa\n" + /* cli option --binary internally handled */ + " -bind bool: bars above/below the code, size set by -border\n" + " -bindtop bool: bar above the code, size set by -border\n" + " -bold bool: use bold text\n" + " -border integer: width of a border around the symbol. Use with -bind/-box/-bindtop 1\n" + " -box bool: box around bar code, size set by -border\n" + /* cli option --cmyk not supported as no corresponding output */ + " -cols integer: Codablock F, DotCode, PDF417: number of columns\n" + " -compliantheight bool: warn if height not compliant, and use standard default\n" + /* cli option --data is standard parameter */ + " -dmiso144 bool: Use ISO format for 144x144 Data Matrix symbols\n" + " -dmre bool: Allow Data Matrix Rectangular Extended\n" + " -dotsize number: radius ratio of dots from 0.01 to 1.0\n" + " -dotty bool: use dots instead of boxes for matrix codes\n" + /* cli option --dump not supported */ + /* cli option --ecinos not supported */ + " -eci choice: ECI to use\n" + /* cli option --embedfont not supported (vector output only) */ + " -esc bool: Process escape sequences in input data\n" + " -extraesc bool: Process symbology-specific escape sequences (Code 128 only)\n" + " -fast bool: use fast encodation (Data Matrix)\n" + " -fg color: set foreground color as 6 or 8 hex rrggbbaa\n" + /* replaces cli options --binary and --gs1 */ + " -format binary|unicode|gs1: input data format. Default:unicode\n" + " -fullmultibyte bool: allow multibyte compaction for xQR, HanXin, Gridmatrix\n" + /* cli option --gs1 replaced by -format */ + " -gs1nocheck bool: for gs1, do not check validity of data (allows non-standard symbols)\n" + " -gs1parens bool: for gs1, AIs enclosed in parentheses instead of square brackets\n" + " -gssep bool: for gs1, use gs as separator instead fnc1 (Datamatrix only)\n" + " -guarddescent double: Height of guard bar descent in modules (EAN/UPC only)\n" + " -guardwhitespace bool: add quiet zone indicators (EAN/UPC only)\n" + " -height double: Symbol height in modules\n" + " -heightperrow bool: treat height as per-row\n" + /* cli option --input not supported */ + " -init bool: Create reader initialisation symbol (Code 128, Data Matrix)\n" + " -mask integer: set masking pattern to use (QR/MicroQR/HanXin/DotCode)\n" + /* cli option --mirror not supported */ + " -mode integer: set encoding mode (MaxiCode, Composite)\n" + " -nobackground bool: set background transparent\n" + " -noquietzones bool: disable default quiet zones\n" + " -notext bool: no interpretation line\n" + /* cli option --output not supported */ + " -primary text: Structured primary data (MaxiCode, Composite)\n" + " -quietzones bool: add compliant quiet zones to whitespace\n" + " -reverse bool: Reverse colours (white on black)\n" + " -rotate angle: Image rotation by 0,90 or 270 degrees\n" + " -rows integer: Codablock F, PDF417: number of rows\n" + " -scale double: Scale the image to this factor\n" + " -scalexdimdp {xdim ?resolution?}: Scale with X-dimension mm, resolution dpmm\n" + " -scmvv integer: Prefix SCM with [)>\\R01\\Gvv (vv is integer) (MaxiCode)\n" + " -secure integer: EC Level (Aztec, GridMatrix, HanXin, PDF417, QR, UltraCode)\n" + " -segN {eci data}: Set the ECI & data content for segment N where N is 1 to 9\n" + " -separator 0..4 (default: 1) : Stacked symbologies: separator width\n" + /* cli option --small replaced by -smalltext */ + " -smalltext bool: tiny interpretation line font\n" + " -square bool: force Data Matrix symbols to be square\n" + " -structapp {index count ?id?}: set Structured Append info\n" + " -textgap double: Gap between barcode and text\n" + /* cli option --types not supported */ + " -vers integer: Symbology option\n" + /* cli option --version not supported */ + " -vwhitesp integer: vertical quiet zone in modules\n" + " -whitesp integer: horizontal quiet zone in modules\n" + " -werror bool: Convert all warnings into errors\n" + " -to {x0 y0 ?width? ?height?}: place to put in photo image\n" + "\n" + "zint symbologies: List available symbologies\n" + "zint eci: List available eci tables\n" + "zint help\n" + "zint version\n" + ; + +/*----------------------------------------------------------------------------*/ +/* Exported symbols */ +#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) +EXPORT BOOL WINAPI DllEntryPoint (HINSTANCE hInstance, + DWORD seginfo, LPVOID lpCmdLine) +{ + /* Don't do anything, so just return true */ + return TRUE; +} +#endif +/*----------------------------------------------------------------------------*/ +/* Initialisation Procedures */ +DLLEXPORT int Zint_Init (Tcl_Interp *interp) +{ + int * tkFlagPtr; + Tcl_CmdInfo info; + /*------------------------------------------------------------------------*/ + /* If TCL_STUB is not defined, the following only does a version check */ + if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) { + return TCL_ERROR; + } + /*------------------------------------------------------------------------*/ + /* Add build info */ + if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) { + Tcl_CreateObjCommand(interp, "::zint::build-info", + info.objProc, (void *)( + PACKAGE_VERSION "+" STRINGIFY(SAMPLE_VERSION_UUID) +#if defined(__clang__) && defined(__clang_major__) + ".clang-" STRINGIFY(__clang_major__) +#if __clang_minor__ < 10 + "0" +#endif + STRINGIFY(__clang_minor__) +#endif +#if defined(__cplusplus) && !defined(__OBJC__) + ".cplusplus" +#endif +#ifndef NDEBUG + ".debug" +#endif +#if !defined(__clang__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) + ".gcc-" STRINGIFY(__GNUC__) +#if __GNUC_MINOR__ < 10 + "0" +#endif + STRINGIFY(__GNUC_MINOR__) +#endif +#ifdef __INTEL_COMPILER + ".icc-" STRINGIFY(__INTEL_COMPILER) +#endif +#ifdef TCL_MEM_DEBUG + ".memdebug" +#endif +#if defined(_MSC_VER) + ".msvc-" STRINGIFY(_MSC_VER) +#endif +#ifdef USE_NMAKE + ".nmake" +#endif +#ifndef TCL_CFG_OPTIMIZED + ".no-optimize" +#endif +#ifdef __OBJC__ + ".objective-c" +#if defined(__cplusplus) + "plusplus" +#endif +#endif +#ifdef TCL_CFG_PROFILED + ".profile" +#endif +#ifdef PURIFY + ".purify" +#endif +#ifdef STATIC_BUILD + ".static" +#endif + ), NULL); + } + /*------------------------------------------------------------------------*/ + /* This procedure is called once per thread and any thread local data */ + /* should be allocated and initialized here (and not in static variables) */ + + /* Create a flag if Tk is loaded */ + tkFlagPtr = (int *)ckalloc(sizeof(int)); + *tkFlagPtr = 0; + Tcl_CallWhenDeleted(interp, InterpCleanupProc, (ClientData)tkFlagPtr); + /*------------------------------------------------------------------------*/ + Tcl_CreateObjCommand(interp, "zint", ZintCmd, (ClientData)tkFlagPtr, + (Tcl_CmdDeleteProc *)NULL); + Tcl_PkgProvide (interp, "zint", version_string); + /*------------------------------------------------------------------------*/ + return TCL_OK; +} +/*----------------------------------------------------------------------------*/ +/* >>>> Cleanup procedure */ +/*----------------------------------------------------------------------------*/ +/* This routine is called, if a thread is terminated */ +static void InterpCleanupProc(ClientData clientData, Tcl_Interp *interp) +{ + ckfree( (char *)clientData ); +} +/*----------------------------------------------------------------------------*/ +/* >>>> Unload Procedures */ +/*----------------------------------------------------------------------------*/ +DLLEXPORT int Zint_Unload (Tcl_Interp *Interp, int Flags) +{ + /* Remove created commands */ + Tcl_DeleteCommand(Interp, "::zint::build-info"); + Tcl_DeleteCommand(Interp, "zint"); + // Allow unload + return TCL_OK; +} +/*----------------------------------------------------------------------------*/ +/* >>>>> Called routine */ +/*----------------------------------------------------------------------------*/ +/* Decode tcl commands */ +static int ZintCmd(ClientData tkFlagPtr, Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]) +{ + /* Option list and indexes */ + enum iCommand {iEncode, iSymbologies, iECI, iVersion, iHelp}; + /* choice of option */ + int Index; + /*------------------------------------------------------------------------*/ + /* > Check if option argument is given and decode it */ + if (objc > 1) + { + char *subCmds[] = {"encode", "symbologies", "eci", "version", "help", NULL}; + if(Tcl_GetIndexFromObj(interp, objv[1], (const char **) subCmds, + "option", 0, &Index) + == TCL_ERROR) + { + return TCL_ERROR; + } + } else { + Tcl_WrongNumArgs(interp, 1, objv, "option"); + return TCL_ERROR; + } + /*------------------------------------------------------------------------*/ + /* > Call functions in dependency of Index */ + /*------------------------------------------------------------------------*/ + switch (Index) + { + case iEncode: + if (CheckForTk(interp, (int *)tkFlagPtr) != TCL_OK) { + return TCL_ERROR; + } + return Encode(interp, objc, objv); + case iSymbologies: + { + Tcl_Obj *oRes; + int posCur; + oRes = Tcl_NewObj(); + for (posCur = 0 ; s_code_list[posCur] != NULL; posCur++) { + if( ZBarcode_ValidID(s_code_number[posCur]) != 0) { + if (TCL_OK != Tcl_ListObjAppendElement(interp, + oRes, Tcl_NewStringObj(s_code_list[posCur],-1))) + { + return TCL_ERROR; + } + } + } + Tcl_SetObjResult(interp,oRes); + return TCL_OK; + } + case iECI: + { + Tcl_Obj *oRes; + int posCur; + oRes = Tcl_NewObj(); + for (posCur = 0 ; s_eci_list[posCur] != NULL; posCur++) { + if (TCL_OK != Tcl_ListObjAppendElement(interp, + oRes, Tcl_NewStringObj(s_eci_list[posCur],-1))) + { + return TCL_ERROR; + } + } + Tcl_SetObjResult(interp,oRes); + return TCL_OK; + } + case iVersion: + Tcl_SetObjResult(interp, + Tcl_NewStringObj(version_string, -1)); + return TCL_OK; + case iHelp: + default: + Tcl_SetObjResult(interp, + Tcl_NewStringObj(help_message, -1)); + return TCL_OK; + } +} +/*---------------------------------------------------------------------- + * Check availability of Tk. + *---------------------------------------------------------------------- + */ +static int CheckForTk(Tcl_Interp *interp, int *tkFlagPtr) +{ + if (*tkFlagPtr > 0) { + return TCL_OK; + } + if (*tkFlagPtr == 0) { + if ( ! Tcl_PkgPresent(interp, "Tk", "8.5-", 0) ) { + Tcl_SetResult(interp, "package Tk not loaded", TCL_STATIC); + return TCL_ERROR; + } + } +#ifdef USE_TK_STUBS + if (*tkFlagPtr < 0 || Tk_InitStubs(interp, "8.5-", 0) == NULL) { + *tkFlagPtr = -1; + Tcl_SetResult(interp, "error initializing Tk", TCL_STATIC); + return TCL_ERROR; + } +#endif + *tkFlagPtr = 1; + return TCL_OK; +}/*----------------------------------------------------------------------------*/ +/* >>>>> Encode */ +/*----------------------------------------------------------------------------*/ +/* Encode image */ +static int Encode(Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]) +{ + struct zint_symbol *my_symbol; + Tcl_DString dsInput; + char *pStr = NULL; + Tcl_Size lStr; + Tcl_Encoding hZINTEncoding; + int rotate_angle=0; + int fError = 0; + Tcl_DString dString; + int optionPos; + int destX0 = 0; + int destY0 = 0; + int destWidth = 0; + int destHeight = 0; + int ECIIndex = 0; + int fFullMultiByte = 0; + int addon_gap = 0; + int Separator = 1; + int Mask = 0; + int rows = 0; + unsigned int cap; + int seg_count = 0; + int seg_no; + Tcl_Obj *pSegDataObjs[10] = {0}; + Tcl_DString segInputs[10]; + struct zint_seg segs[10]; + double xdim = 0.0; + double resolution = 0.0; + /*------------------------------------------------------------------------*/ + /* >> Check if at least data and object is given and a pair number of */ + /* >> options */ + if ( objc < 4 || (objc % 2) != 0 ) + { + Tcl_WrongNumArgs(interp, 2, objv, "data photo ?-switch value?..."); + return TCL_ERROR; + } + /*------------------------------------------------------------------------*/ + /* >>> Prepare encoding */ + hZINTEncoding = Tcl_GetEncoding(interp, "utf-8"); + if (NULL == hZINTEncoding) { + return TCL_ERROR; + } + /*------------------------------------------------------------------------*/ + /* >>> Prepare zint object */ + my_symbol = ZBarcode_Create(); + my_symbol->input_mode = UNICODE_MODE; + my_symbol->option_3 = 0; + /*------------------------------------------------------------------------*/ + /* >> Decode options */ + for (optionPos = 4; optionPos < objc; optionPos+=2) { + /*--------------------------------------------------------------------*/ + /* Option list and indexes */ + static const char *optionList[] = { + "-addongap", "-barcode", "-bg", "-bind", "-bindtop", "-bold", "-border", "-box", + "-cols", "-compliantheight", "-dmiso144", "-dmre", "-dotsize", "-dotty", + "-eci", "-esc", "-extraesc", "-fast", "-fg", "-format", "-fullmultibyte", + "-gs1nocheck", "-gs1parens", "-gssep", "-guarddescent", "-guardwhitespace", + "-height", "-heightperrow", "-init", "-mask", "-mode", + "-nobackground", "-noquietzones", "-notext", "-primary", "-quietzones", + "-reverse", "-rotate", "-rows", "-scale", "-scalexdimdp", "-scmvv", "-secure", + "-seg1", "-seg2", "-seg3", "-seg4", "-seg5", "-seg6", "-seg7", "-seg8", "-seg9", + "-separator", "-smalltext", "-square", "-structapp", + "-textgap", "-to", "-vers", "-vwhitesp", "-werror", "-whitesp", + NULL}; + enum iOption { + iAddonGap, iBarcode, iBG, iBind, iBindTop, iBold, iBorder, iBox, + iCols, iCompliantHeight, iDMISO144, iDMRE, iDotSize, iDotty, + iECI, iEsc, iExtraEsc, iFast, iFG, iFormat, iFullMultiByte, + iGS1NoCheck, iGS1Parens, iGSSep, iGuardDescent, iGuardWhitespace, + iHeight, iHeightPerRow, iInit, iMask, iMode, + iNoBackground, iNoQuietZones, iNoText, iPrimary, iQuietZones, + iReverse, iRotate, iRows, iScale, iScaleXdimDp, iSCMvv, iSecure, + iSeg1, iSeg2, iSeg3, iSeg4, iSeg5, iSeg6, iSeg7, iSeg8, iSeg9, + iSeparator, iSmallText, iSquare, iStructApp, + iTextGap, iTo, iVers, iVWhiteSp, iWError, iWhiteSp + }; + int optionIndex; + int intValue; + double doubleValue; + /*--------------------------------------------------------------------*/ + if(Tcl_GetIndexFromObj(interp, objv[optionPos], + (const char **) optionList, + "zint option", 0, &optionIndex) + == TCL_ERROR) + { + fError = 1; + break; + } + /*--------------------------------------------------------------------*/ + /* >> Decode object */ + switch (optionIndex) { + case iBind: + case iBindTop: + case iBold: + case iBox: + case iCompliantHeight: + case iDMISO144: + case iDMRE: + case iDotty: + case iEsc: + case iExtraEsc: + case iFast: + case iGS1NoCheck: + case iGS1Parens: + case iGSSep: + case iGuardWhitespace: + case iHeightPerRow: + case iInit: + case iNoBackground: + case iNoQuietZones: + case iNoText: + case iQuietZones: + case iSmallText: + case iSquare: + case iFullMultiByte: + case iReverse: + case iWError: + /* >> Binary options */ + if (TCL_OK != Tcl_GetBooleanFromObj(interp, objv[optionPos+1], + &intValue)) + { + fError = 1; + } + break; + case iFG: + case iBG: + /* >> Colors */ + pStr = Tcl_GetStringFromObj(objv[optionPos+1],&lStr); + if (lStr != 6 && lStr != 8) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Color is not 6 or 8 hex",-1)); + fError = 1; + } + break; + case iHeight: + case iGuardDescent: + case iDotSize: + case iScale: + case iTextGap: + /* >> Float */ + if (TCL_OK != Tcl_GetDoubleFromObj(interp, objv[optionPos+1], + &doubleValue)) + { + fError = 1; + } + break; + case iAddonGap: + case iBorder: + case iCols: + case iMask: + case iMode: + case iRotate: + case iRows: + case iSecure: + case iSeparator: + case iSCMvv: + case iVers: + case iVWhiteSp: + case iWhiteSp: + /* >> Int */ + if (TCL_OK != Tcl_GetIntFromObj(interp, objv[optionPos+1], + &intValue)) + { + fError = 1; + } + break; + case iPrimary: + /* > Primary String up to 90 characters */ + /* > Output filename up to 250 characters */ + Tcl_DStringInit(& dString); + pStr = Tcl_GetStringFromObj(objv[optionPos+1], &lStr); + Tcl_UtfToExternalDString( hZINTEncoding, pStr, lStr, &dString); + if (Tcl_DStringLength(&dString) > (optionIndex==iPrimary?90:250)) { + Tcl_DStringFree(&dString); + Tcl_SetObjResult(interp,Tcl_NewStringObj("String too long", -1)); + fError = 1; + } + break; + case iSeg1: case iSeg2: case iSeg3: case iSeg4: case iSeg5: + case iSeg6: case iSeg7: case iSeg8: case iSeg9: + seg_no = optionIndex - iSeg1 + 1; + if (pSegDataObjs[seg_no]) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("duplicate segment", -1)); + fError = 1; + } else { + Tcl_Obj *poParam; + if (TCL_OK != Tcl_ListObjLength(interp, objv[optionPos+1], &lStr)) { + Tcl_SetObjResult(interp, Tcl_Format(interp, "option %s not a list", 1, objv + optionPos)); + fError = 1; + } else if (lStr != 2) { + Tcl_SetObjResult(interp, Tcl_Format(interp, "option %s not a list of 2", 1, objv + optionPos)); + fError = 1; + } else if (TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 0, &poParam) + || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 1, &pSegDataObjs[seg_no])) { + Tcl_SetObjResult(interp, Tcl_Format(interp, "option %s list format is {eci data}", 1, objv + optionPos)); + fError = 1; + } else if (Tcl_GetIndexFromObj(interp, poParam, + (const char **) s_eci_list, Tcl_GetString(objv[optionPos]), 0, &ECIIndex) + == TCL_ERROR) { + fError = 1; + } else { + segs[seg_no].eci = s_eci_number[ECIIndex]; + if (seg_no >= seg_count) { + seg_count = seg_no + 1; + } + } + } + break; + } + if (fError) { + break; + } + /*--------------------------------------------------------------------*/ + switch (optionIndex) { + case iAddonGap: + if (intValue < 7 || intValue > 12) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Invalid add-on gap value not within 7 to 12", -1)); + fError = 1; + } else { + addon_gap = intValue; + } + break; + case iBind: + if (intValue) { + my_symbol->output_options |= BARCODE_BIND; + } else { + my_symbol->output_options &= ~BARCODE_BIND; + } + break; + case iBindTop: + if (intValue) { + my_symbol->output_options |= BARCODE_BIND_TOP; + } else { + my_symbol->output_options &= ~BARCODE_BIND_TOP; + } + break; + case iBold: + if (intValue) { + my_symbol->output_options |= BOLD_TEXT; + } else { + my_symbol->output_options &= ~BOLD_TEXT; + } + break; + case iBox: + if (intValue) { + my_symbol->output_options |= BARCODE_BOX; + } else { + my_symbol->output_options &= ~BARCODE_BOX; + } + break; + case iCompliantHeight: + if (intValue) { + my_symbol->output_options |= COMPLIANT_HEIGHT; + } else { + my_symbol->output_options &= ~COMPLIANT_HEIGHT; + } + break; + case iDotSize: + if (doubleValue < 0.01) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Dot size below 0.01", -1)); + fError = 1; + } else { + my_symbol->dot_size = (float)doubleValue; + } + break; + case iDotty: + if (intValue) { + my_symbol->output_options |= BARCODE_DOTTY_MODE; + } else { + my_symbol->output_options &= ~BARCODE_DOTTY_MODE; + } + break; + case iEsc: + if (intValue) { + my_symbol->input_mode |= ESCAPE_MODE; + } else { + my_symbol->input_mode &= ~ESCAPE_MODE; + } + break; + case iExtraEsc: + if (intValue) { + my_symbol->input_mode |= EXTRA_ESCAPE_MODE; + } else { + my_symbol->input_mode &= ~EXTRA_ESCAPE_MODE; + } + break; + case iFast: + if (intValue) { + my_symbol->input_mode |= FAST_MODE; + } else { + my_symbol->input_mode &= ~FAST_MODE; + } + break; + case iGS1NoCheck: + if (intValue) { + my_symbol->input_mode |= GS1NOCHECK_MODE; + } else { + my_symbol->input_mode &= ~GS1NOCHECK_MODE; + } + break; + case iGS1Parens: + if (intValue) { + my_symbol->input_mode |= GS1PARENS_MODE; + } else { + my_symbol->input_mode &= ~GS1PARENS_MODE; + } + break; + case iGSSep: + if (intValue) { + my_symbol->output_options |= GS1_GS_SEPARATOR; + } else { + my_symbol->output_options &= ~GS1_GS_SEPARATOR; + } + break; + case iFullMultiByte: + fFullMultiByte = intValue; + break; + case iECI: + if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], + (const char **) s_eci_list, "-eci", 0, &ECIIndex) + == TCL_ERROR) + { + fError = 1; + } else { + my_symbol->eci = s_eci_number[ECIIndex]; + } + break; + case iGuardWhitespace: + if (intValue) { + my_symbol->output_options |= EANUPC_GUARD_WHITESPACE; + } else { + my_symbol->output_options &= ~EANUPC_GUARD_WHITESPACE; + } + break; + case iHeightPerRow: + if (intValue) { + my_symbol->input_mode |= HEIGHTPERROW_MODE; + } else { + my_symbol->input_mode &= ~HEIGHTPERROW_MODE; + } + break; + case iInit: + if (intValue) { + my_symbol->output_options |= READER_INIT; + } else { + my_symbol->output_options &= ~READER_INIT; + } + break; + case iSmallText: + if (intValue) { + my_symbol->output_options |= SMALL_TEXT; + } else { + my_symbol->output_options &= ~SMALL_TEXT; + } + break; + case iReverse: + if (intValue) { + strcpy(my_symbol->fgcolour, "ffffff"); + strcpy(my_symbol->bgcolour, "000000"); + } + break; + case iWError: + if (intValue) { + my_symbol->warn_level = WARN_FAIL_ALL; + } + break; + case iFG: + strncpy(my_symbol->fgcolour, pStr, lStr); + my_symbol->fgcolour[lStr]='\0'; + break; + case iBG: + strncpy(my_symbol->bgcolour, pStr, lStr); + my_symbol->bgcolour[lStr]='\0'; + break; + case iNoBackground: + if (intValue) { + strcpy(my_symbol->bgcolour, "ffffff00"); + } + break; + case iNoQuietZones: + if (intValue) { + my_symbol->output_options |= BARCODE_NO_QUIET_ZONES; + } else { + my_symbol->output_options &= ~BARCODE_NO_QUIET_ZONES; + } + break; + case iNoText: + my_symbol->show_hrt = (intValue?0:1); + break; + case iQuietZones: + if (intValue) { + my_symbol->output_options |= BARCODE_QUIET_ZONES; + } else { + my_symbol->output_options &= ~BARCODE_QUIET_ZONES; + } + break; + case iSquare: + /* DM_SQUARE overwrites DM_DMRE */ + if (intValue) + my_symbol->option_3 = DM_SQUARE | (my_symbol->option_3 & ~0x7F); + break; + case iDMRE: + /* DM_DMRE overwrites DM_SQUARE */ + if (intValue) + my_symbol->option_3 = DM_DMRE | (my_symbol->option_3 & ~0x7F); + break; + case iDMISO144: + if (intValue) + my_symbol->option_3 |= DM_ISO_144; + break; + case iScale: + if (doubleValue < 0.01) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Scale below 0.01", -1)); + fError = 1; + } else { + my_symbol->scale = (float)doubleValue; + } + break; + case iTextGap: + if (doubleValue < 0.0 || doubleValue > 5.0) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Text Gap out of range", -1)); + fError = 1; + } else { + my_symbol->text_gap = (float)doubleValue; + } + break; + case iScaleXdimDp: + /* >> Decode the -scalexdimdp parameter as list of xdim ?resolution? */ + { + Tcl_Obj *poParam; + xdim = resolution = 0.0; + if (TCL_OK != Tcl_ListObjLength(interp, + objv[optionPos+1], &lStr)) + { + fError = 1; + } else if ( ! ( lStr == 1 || lStr == 2 ) ) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj( + "option -scalexdimdp not a list of 1 or 2", -1)); + fError = 1; + } else { + if (TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 0, &poParam) + || TCL_OK != Tcl_GetDoubleFromObj(interp, poParam, &xdim) + || xdim < 0.0) + { + fError = 1; + } + if (!fError && lStr == 2 && ( + TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 1, &poParam) + || TCL_OK != Tcl_GetDoubleFromObj(interp, poParam, &resolution) + || resolution < 0.0)) + { + fError = 1; + } + if (!fError && resolution == 0.0) { + resolution = 12.0; /* Default 12 dpmm (~300 dpi) */ + } + } + } + break; + case iBorder: + if (intValue < 0 || intValue > 1000) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Border out of range", -1)); + fError = 1; + } else { + my_symbol->border_width = intValue; + } + break; + case iGuardDescent: + if ((float)doubleValue < 0.0f || (float)doubleValue > 50.0f) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Guard bar descent out of range", -1)); + fError = 1; + } else { + my_symbol->guard_descent = (float)doubleValue; + } + break; + case iHeight: + if ((float)doubleValue < 0.5f || (float)doubleValue > 2000.0f) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Height out of range", -1)); + fError = 1; + } else { + my_symbol->height = (float)doubleValue; + } + break; + case iSeparator: + if (intValue < 0 || intValue > 4) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Separator out of range", -1)); + fError = 1; + } else { + Separator = intValue; + } + break; + case iMask: + if (intValue < 0 || intValue > 7) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Mask out of range", -1)); + fError = 1; + } else { + Mask = intValue + 1; + } + break; + case iSCMvv: + if (intValue < 0 || intValue > 99) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("SCM version out of range", -1)); + fError = 1; + } else { + my_symbol->option_2 = intValue + 1; + } + break; + case iCols: + case iVers: + /* >> Int in Option 2 */ + if (intValue < 1 + || (optionIndex==iCols && intValue > 200) + || (optionIndex==iVers && intValue > 999)) + { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("cols/vers out of range", -1)); + fError = 1; + } else { + my_symbol->option_2 = intValue; + } + break; + case iSecure: + case iMode: + case iRows: + /* >> Int in Option 1 for Codablock, Option 3 for PDF417 */ + if ( (optionIndex==iSecure && (intValue < 1 || intValue > 8)) + || (optionIndex==iMode && (intValue < 0 || intValue > 6)) + || (optionIndex==iRows && (intValue < 0 || intValue > 90))) + { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("secure/mode/rows out of range", -1)); + fError = 1; + } else { + rows = intValue; + } + break; + case iPrimary: + strcpy(my_symbol->primary, Tcl_DStringValue( &dString ) ); + Tcl_DStringFree(&dString); + break; + case iRotate: + /* >> Rotate angle */ + /*----------------------------------------------------------------*/ + { + char *rotateList[] = {"0", "90", "180", "270", NULL}; + enum iRotate { iRotate0, iRotate90, iRotate180, iRotate270 }; + /*------------------------------------------------------------*/ + if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], + (const char **) rotateList, + "-rotate", 0, &intValue) + == TCL_ERROR) + { + fError = 1; + break; + } + switch (intValue) { + case iRotate90: rotate_angle = 90; break; + case iRotate180: rotate_angle = 180; break; + case iRotate270: rotate_angle = 270; break; + default: rotate_angle = 0; break; + } + } + break; + case iBarcode: + if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], + (const char **) s_code_list, "-barcode", 0, &intValue) + == TCL_ERROR) + { + fError = 1; + } else { + my_symbol->symbology = s_code_number[intValue]; + } + break; + case iVWhiteSp: + my_symbol->whitespace_height = intValue; + break; + case iWhiteSp: + my_symbol->whitespace_width = intValue; + break; + case iStructApp: + /* >> Decode the -structapp parameter as list of index count ?ID? */ + { + Tcl_Obj *poParam; + struct zint_structapp structapp = { 0, 0, "" }; + char *pStructAppId = NULL; + Tcl_Size lStructAppId = 0; + if (TCL_OK != Tcl_ListObjLength(interp, + objv[optionPos+1], &lStr)) + { + fError = 1; + } else if ( ! ( lStr == 2 || lStr == 3 ) ) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj( + "option -structapp not a list of 2 or 3", -1)); + fError = 1; + } else { + if (TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 0, &poParam) + || TCL_OK != Tcl_GetIntFromObj(interp, poParam, &structapp.index) + || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 1, &poParam) + || TCL_OK != Tcl_GetIntFromObj(interp, poParam, &structapp.count)) + { + fError = 1; + } + if (!fError && lStr == 3 && ( + TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 2, &poParam) + || !(pStructAppId = Tcl_GetStringFromObj(poParam, &lStructAppId)) + || lStructAppId > 32 + )) + { + if (lStructAppId > 32) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Structured Append ID too long", -1)); + } + fError = 1; + } + if (!fError) { + my_symbol->structapp = structapp; + if (lStr == 3 && pStructAppId && lStructAppId) { + strncpy(my_symbol->structapp.id, pStructAppId, lStructAppId); + } + } + } + } + break; + case iTo: + /* >> Decode the -to parameter as list of X0 Y0 ?Width Height? */ + { + Tcl_Obj *poParam; + if (TCL_OK != Tcl_ListObjLength(interp, + objv[optionPos+1], &lStr)) + { + fError = 1; + } else if ( ! ( lStr == 2 || lStr == 4 ) ) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj( + "option -to not a list of 2 or 4", -1)); + fError = 1; + } else { + if (TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 0, &poParam) + || TCL_OK != Tcl_GetIntFromObj(interp,poParam,&destX0) + || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 1, &poParam) + || TCL_OK != Tcl_GetIntFromObj(interp,poParam,&destY0)) + { + fError = 1; + } + if (!fError && lStr == 4 && ( + TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 2, &poParam) + || TCL_OK != Tcl_GetIntFromObj(interp,poParam, + &destWidth) + || TCL_OK != Tcl_ListObjIndex(interp, objv[optionPos+1], + 3, &poParam) + || TCL_OK != Tcl_GetIntFromObj(interp,poParam, + &destHeight) + )) + { + fError = 1; + } + } + } + break; + case iFormat: + /* >> Format of the input data */ + /*----------------------------------------------------------------*/ + { + char *formatList[] = {"binary", "gs1", "unicode",NULL}; + enum iFormat { iBinary, iGS1, iUnicode }; + /*------------------------------------------------------------*/ + if(Tcl_GetIndexFromObj(interp, objv[optionPos+1], + (const char **) formatList, + "-format", 0, &intValue) + == TCL_ERROR) + { + fError = 1; + break; + } + switch (intValue) { + case iBinary: my_symbol->input_mode = (my_symbol->input_mode & ~0x07) | DATA_MODE; break; + case iGS1: my_symbol->input_mode = (my_symbol->input_mode & ~0x07) | GS1_MODE; break; + default: my_symbol->input_mode = (my_symbol->input_mode & ~0x07) | UNICODE_MODE; break; + } + } + } + } + /*------------------------------------------------------------------------*/ + /* >>> Get symbology capability mask */ + cap = ZBarcode_Cap(my_symbol->symbology, + ZINT_CAP_STACKABLE | ZINT_CAP_EXTENDABLE | ZINT_CAP_FULL_MULTIBYTE + | ZINT_CAP_MASK); + /*------------------------------------------------------------------------*/ + /* >>> option_3 is set by three values depending on the symbology */ + /* On wrong symbology, the option is ignored(as does the zint program)*/ + if (fFullMultiByte && (cap & ZINT_CAP_FULL_MULTIBYTE)) { + my_symbol->option_3 = ZINT_FULL_MULTIBYTE; + } + if (Mask && (cap & ZINT_CAP_MASK)) { + my_symbol->option_3 |= Mask << 8; + } + if (Separator && (cap & ZINT_CAP_STACKABLE)) { + my_symbol->option_3 = Separator; + } + /*------------------------------------------------------------------------*/ + /* >>> option_2 is set by two values depending on the symbology */ + /* On wrong symbology, the option is ignored(as does the zint program)*/ + if (addon_gap && (cap & ZINT_CAP_EXTENDABLE)) { + my_symbol->option_2 = addon_gap; + } + /*------------------------------------------------------------------------*/ + if (rows) { + /* PDF417 and DBAR_EXPSTK use option 3 for rows */ + if (my_symbol->symbology == BARCODE_PDF417 + || my_symbol->symbology == BARCODE_PDF417COMP + || my_symbol->symbology == BARCODE_HIBC_PDF + || my_symbol->symbology == BARCODE_DBAR_EXPSTK + || my_symbol->symbology == BARCODE_DBAR_EXPSTK_CC) { + my_symbol->option_3 = rows; + } else if (my_symbol->symbology == BARCODE_CODABLOCKF + || my_symbol->symbology == BARCODE_HIBC_BLOCKF + || my_symbol->symbology == BARCODE_CODE16K + || my_symbol->symbology == BARCODE_CODE49) { + my_symbol->option_1 = rows; + } + } + if (resolution) { + float scale; + if (xdim == 0.0) { + xdim = ZBarcode_Default_Xdim(my_symbol->symbology); + } + scale = ZBarcode_Scale_From_XdimDp(my_symbol->symbology, (float)xdim, (float)resolution, NULL /*filetype*/); + if (scale > 0.0f) { + my_symbol->scale = scale; + } + } + /*------------------------------------------------------------------------*/ + /* >>> Prepare input dstring and encode it to ECI encoding*/ + Tcl_DStringInit(& dsInput); + /*------------------------------------------------------------------------*/ + if (!fError) { + /*--------------------------------------------------------------------*/ + /* >>> Get input mode */ + if ((my_symbol->input_mode & 0x07) == DATA_MODE) { + /* Binary data */ + pStr = (char *) Tcl_GetByteArrayFromObj(objv[2], &lStr); + } else { + /* UTF8 Data */ + pStr = Tcl_GetStringFromObj(objv[2], &lStr); + Tcl_UtfToExternalDString( hZINTEncoding, pStr, lStr, &dsInput); + pStr = Tcl_DStringValue( &dsInput ); + lStr = Tcl_DStringLength( &dsInput ); + } + if (seg_count) { + segs[0].source = (unsigned char *) pStr; + segs[0].length = (int)lStr; + segs[0].eci = my_symbol->eci; + for (seg_no = 1; seg_no < seg_count; seg_no++) { + if (!pSegDataObjs[seg_no]) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("Segments must be consecutive", -1)); + fError = 1; + break; + } + } + if (!fError) { + for (seg_no = 1; seg_no < seg_count; seg_no++) { + if ((my_symbol->input_mode & 0x07) == DATA_MODE) { + Tcl_Size LengthTemp; + segs[seg_no].source = (unsigned char *) Tcl_GetByteArrayFromObj(pSegDataObjs[seg_no], + &LengthTemp); + segs[seg_no].length = (int)LengthTemp; + } else { + pStr = Tcl_GetStringFromObj(pSegDataObjs[seg_no], &lStr); + Tcl_DStringInit(& segInputs[seg_no]); + Tcl_UtfToExternalDString( hZINTEncoding, pStr, lStr, &segInputs[seg_no]); + segs[seg_no].source = (unsigned char *) Tcl_DStringValue( &segInputs[seg_no] ); + segs[seg_no].length = (int)Tcl_DStringLength( &segInputs[seg_no] ); + } + } + } + } + } + /*------------------------------------------------------------------------*/ + /* >>> Build symbol graphic */ + if (! fError ) { + int ErrorNumber; + Tk_PhotoHandle hPhoto; + /*--------------------------------------------------------------------*/ + /* call zint graphic creation to buffer */ + if (seg_count) { + ErrorNumber = ZBarcode_Encode_Segs_and_Buffer(my_symbol, + segs, seg_count, rotate_angle); + } else { + ErrorNumber = ZBarcode_Encode_and_Buffer(my_symbol, + (unsigned char *) pStr, (int)lStr, rotate_angle); + } + /*--------------------------------------------------------------------*/ + /* >> Show a message */ + if( 0 != ErrorNumber ) + { + Tcl_SetObjResult(interp, Tcl_NewStringObj(my_symbol->errtxt, -1)); + } + if( ZINT_ERROR <= ErrorNumber ) + { + /* >> Encode error */ + fError = 1; + } else if ( + NULL == (hPhoto = Tk_FindPhoto(interp, Tcl_GetString(objv[3])))) + { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("Unknown photo image", -1)); + fError = 1; + } else { + Tk_PhotoImageBlock sImageBlock; + char * pImageRGBA = NULL; + if (my_symbol->alphamap == NULL) { + sImageBlock.pixelPtr = (unsigned char *) my_symbol->bitmap; + sImageBlock.width = my_symbol->bitmap_width; + sImageBlock.height = my_symbol->bitmap_height; + sImageBlock.pitch = 3*my_symbol->bitmap_width; + sImageBlock.pixelSize = 3; + sImageBlock.offset[0] = 0; + sImageBlock.offset[1] = 1; + sImageBlock.offset[2] = 2; + sImageBlock.offset[3] = 0; + } else { + int index; + /* Alpha channel present - prepare the image data in rgba order */ + pImageRGBA = ckalloc(my_symbol->bitmap_width*my_symbol->bitmap_height*4); + for (index = 0; index < my_symbol->bitmap_width*my_symbol->bitmap_height; index++) { + pImageRGBA[index*4] = my_symbol->bitmap[index*3]; + pImageRGBA[index*4+1] = my_symbol->bitmap[index*3+1]; + pImageRGBA[index*4+2] = my_symbol->bitmap[index*3+2]; + pImageRGBA[index*4+3] = my_symbol->alphamap[index]; + } + sImageBlock.pixelPtr = (unsigned char *) pImageRGBA; + sImageBlock.width = my_symbol->bitmap_width; + sImageBlock.height = my_symbol->bitmap_height; + sImageBlock.pitch = 4*my_symbol->bitmap_width; + sImageBlock.pixelSize = 4; + sImageBlock.offset[0] = 0; + sImageBlock.offset[1] = 1; + sImageBlock.offset[2] = 2; + sImageBlock.offset[3] = 3; + } + if (0 == destWidth) { + destWidth = my_symbol->bitmap_width; + } + if (0 == destHeight) { + destHeight = my_symbol->bitmap_height; + } + if (TCL_OK != Tk_PhotoPutBlock(interp, hPhoto, &sImageBlock, + destX0, destY0, destWidth, destHeight, + TK_PHOTO_COMPOSITE_OVERLAY)) + { + fError = 1; + } + if (pImageRGBA != NULL) { + ckfree(pImageRGBA); + } + } + } + /*------------------------------------------------------------------------*/ + Tcl_FreeEncoding(hZINTEncoding); + Tcl_DStringFree(& dsInput); + ZBarcode_Delete(my_symbol); + /*------------------------------------------------------------------------*/ + if (fError) { + return TCL_ERROR; + } + return TCL_OK; +} + +/* vim: set ts=4 sw=4 et : */
