<NME> debug.h
<BEF> ADDFILE
<MSG>   * image format conversion fixes
    - fix format size roundoff (NB now rounds *down*)
    - add convert and resize API to pad/crop image to specific size
      (eg, to handle Xv min/max image size)
      NB this is still not implemented for many conversions
  * fix window deletion visibility inconsistency
  * add couple processor commands
    - 'q' to delete window
    - 'd' to dump displayed image for debug
  * remove problematic includes used for v4l2 configure test
  * address compiler portability concerns w/debug print vararg macro
  * workaround v4l1_set_format() failed consistency check for broken drivers
    - change from error to warning w/more useful message
    - calc expected image size using expected value instead of driver value
  * add missing example scripts to distribution

<DFF> @@ -0,0 +1,50 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2008 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the Zebra Barcode Library.
+ *
+ *  The Zebra Barcode Library is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The Zebra Barcode Library is distributed in the hope that it will be
+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the Zebra Barcode Library; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zebra
+ *------------------------------------------------------------------------*/
+
+/* varargs variations on compile time debug spew */
+
+#ifndef DEBUG_LEVEL
+
+# ifdef __GNUC__
+    /* older versions of gcc (< 2.95) require a named varargs parameter */
+#  define dprintf(args...)
+# else
+    /* unfortunately named vararg parameter is a gcc-specific extension */
+#  define dprintf(...)
+# endif
+
+#else
+
+# include <stdio.h>
+
+# ifdef __GNUC__
+#  define dprintf(level, args...) \
+    if((level) <= DEBUG_LEVEL)    \
+        fprintf(stderr, args)
+# else
+#  define dprintf(level, ...)     \
+    if((level) <= DEBUG_LEVEL)    \
+        fprintf(stderr, __VA_ARGS__)
+# endif
+
+#endif /* DEBUG_LEVEL */

{'commit': 'diff --git a/ChangeLog b/ChangeLog\nindex 2f329ee..4b60ac9 100644\n--- a/ChangeLog\n+++ b/ChangeLog\n@@ -1,4 +1,19 @@\n current:\n+  * image format conversion fixes\n+    - fix format size roundoff (NB now rounds *down*)\n+    - add convert and resize API to pad/crop image to specific size\n+      (eg, to handle Xv min/max image size)\n+      NB this is still not implemented for many conversions\n+  * fix window deletion visibility inconsistency\n+  * add couple processor commands\n+    - \'q\' to delete window\n+    - \'d\' to dump displayed image for debug\n+  * remove problematic includes used for v4l2 configure test\n+  * address compiler portability concerns w/debug print vararg macro\n+  * workaround v4l1_set_format() failed consistency check for broken drivers\n+    - change from error to warning w/more useful message\n+    - calc expected image size using expected value instead of driver value\n+  * add missing example scripts to distribution\n   * add missing files for Interleaved 2 of 5\n   * add support for Interleaved 2 of 5 symbology!\n     - again no check digit option yet\ndiff --git a/Makefile.am b/Makefile.am\nindex c942cb0..1bf6e32 100644\n--- a/Makefile.am\n+++ b/Makefile.am\n@@ -22,7 +22,8 @@ endif\n include $(srcdir)/test/Makefile.am.inc\n include $(srcdir)/doc/Makefile.am.inc\n \n-EXTRA_DIST += zebra.spec.in zebra.spec \\\n+EXTRA_DIST += examples/upcrpc.pl examples/upcrpc.py \\\n+    zebra.spec.in zebra.spec \\\n     debian/changelog debian/compat debian/control debian/copyright \\\n     debian/docs debian/libzebra0.install debian/libzebra-dev.install \\\n     debian/rules debian/shlibs.local debian/zebra-tools.install\ndiff --git a/TODO b/TODO\nindex 705b430..4fb8875 100644\n--- a/TODO\n+++ b/TODO\n@@ -1,3 +1,6 @@\n+next release:\n+  * finish format conversion resize cases\n+\n general:\n   * finish error handling\n   * handle video destroyed w/images outstanding\n@@ -12,9 +15,10 @@ symbologies:\n   * finish UPC-E and addon decoding\n \n decoder:\n-  * option configuration API\n   * symbology/feature enable/disable compile/runtime\n+  * option configuration API\n   * option to emit check digit (default?)\n+  * option to return UPC-A\n \n image scanner:\n   * extract and track symbol polygons\ndiff --git a/configure.ac b/configure.ac\nindex f8d8307..e8fb3c6 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -82,9 +82,7 @@ rebuild your kernel to include video4linux support or\n configure --disable-video to skip building video support.])])\n    AC_CHECK_HEADERS([linux/videodev2.h], [with_video="v4l2"],\n      [AC_MSG_WARN([v4l2 API not detected, upgrade your kernel!])],\n-     [[#include <linux/types.h>\n-#include <linux/time.h>\n-#include <linux/videodev.h>\n+     [[#include <linux/videodev.h>\n ]])\n ])\n AM_CONDITIONAL([HAVE_VIDEO], [test "x$enable_video" != "xno"])\ndiff --git a/include/zebra.h b/include/zebra.h\nindex 3d618e2..f61cc46 100644\n--- a/include/zebra.h\n+++ b/include/zebra.h\n@@ -225,13 +225,33 @@ extern void zebra_image_destroy(zebra_image_t *image);\n \n /** image format conversion.  refer to the documentation for supported\n  * image formats\n- * @returns a *new* image with the sample data from the original image\n+ * @returns a @em new image with the sample data from the original image\n  * converted to the requested format.  the original image is\n  * unaffected.\n+ * @note the converted image size may be rounded (up) due to format\n+ * constraints\n  */\n extern zebra_image_t *zebra_image_convert(const zebra_image_t *image,\n                                           unsigned long format);\n \n+/** image format conversion with crop/pad.\n+ * if the requested size is larger than the image, the last row/column\n+ * are duplicated to cover the difference.  if the requested size is\n+ * smaller than the image, the extra rows/columns are dropped from the\n+ * right/bottom.\n+ * @returns a @em new image with the sample data from the original\n+ * image converted to the requested format and size.\n+ * @note the image is @em not scaled\n+ * @note both the crop and pad will be changed to center the image in\n+ * a future release\n+ * @version 0.4\n+ * @see zebra_image_convert()\n+ */\n+extern zebra_image_t *zebra_image_convert_resize(const zebra_image_t *image,\n+                                                 unsigned long format,\n+                                                 unsigned width,\n+                                                 unsigned height);\n+\n /** retrieve the image format.\n  * @returns the fourcc describing the format of the image sample data\n  */\n@@ -304,7 +324,7 @@ extern void zebra_image_free_data(zebra_image_t *image);\n  * ImageMagick, eg:\n  * @verbatim\n        display -size 640x480+16 [-depth ?] [-sampling-factor ?x?] \\\n-           {GRAY,RGB,UYUV,YUV}:[file]\n+           {GRAY,RGB,UYVY,YUV}:[file]\n @endverbatim\n  *\n  * @param image the image object to dump\ndiff --git a/include/zebra/Image.h b/include/zebra/Image.h\nindex 96cb758..3bbbf13 100644\n--- a/include/zebra/Image.h\n+++ b/include/zebra/Image.h\n@@ -236,6 +236,19 @@ public:\n         throw FormatError();\n     }\n \n+    /// image format conversion with crop/pad.\n+    /// see zebra_image_convert_resize()\n+    Image convert (unsigned long format,\n+                   unsigned width,\n+                   unsigned height) const\n+    {\n+        zebra_image_t *img =\n+            zebra_image_convert_resize(_img, format, width, height);\n+        if(img)\n+            return(Image(img));\n+        throw FormatError();\n+    }\n+\n     /// create a new SymbolIterator over decoded results.\n     SymbolIterator symbol_begin() const {\n         return(SymbolIterator(this));\ndiff --git a/test/test_decode.c b/test/test_decode.c\nindex 045d9e1..98c53df 100644\n--- a/test/test_decode.c\n+++ b/test/test_decode.c\n@@ -211,7 +211,8 @@ static void encode_code39 (unsigned char *data)\n     encode_char39(\'*\');\n     int i;\n     for(i = 0; data[i]; i++)\n-        encode_char39(data[i]);\n+        if(data[i] != \'*\') /* skip (FIXME) */\n+            encode_char39(data[i]);\n     encode_char39(\'*\');\n     encode(0xa, 0);  /* trailing quiet */\n     printf("------------------------------------------------------------\\n");\ndiff --git a/zebra/convert.c b/zebra/convert.c\nindex 68f2600..cde6f48 100644\n--- a/zebra/convert.c\n+++ b/zebra/convert.c\n@@ -223,6 +223,15 @@ static inline int verify_format_sort ()\n     return(-1);\n }\n \n+static inline void uv_round (zebra_image_t *img,\n+                             const zebra_format_def_t *fmt)\n+{\n+    img->width >>= fmt->p.yuv.xsub2;\n+    img->width <<= fmt->p.yuv.xsub2;\n+    img->height >>= fmt->p.yuv.ysub2;\n+    img->height <<= fmt->p.yuv.ysub2;\n+}\n+\n static inline void uv_roundup (zebra_image_t *img,\n                                const zebra_format_def_t *fmt)\n {\n@@ -291,6 +300,8 @@ static void convert_copy (zebra_image_t *dst,\n                           const zebra_image_t *src,\n                           const zebra_format_def_t *srcfmt)\n {\n+    assert(src->width == dst->width);\n+    assert(src->height == dst->height);\n     dst->data = src->data;\n     dst->datalen = src->datalen;\n     dst->cleanup = cleanup_ref;\n@@ -298,6 +309,40 @@ static void convert_copy (zebra_image_t *dst,\n     ((zebra_image_t*)src)->refcnt++;\n }\n \n+/* resize y plane, drop extra columns/rows from the right/bottom,\n+ * or duplicate last column/row to pad missing data\n+ */\n+static inline void convert_y_resize (zebra_image_t *dst,\n+                                     const zebra_format_def_t *dstfmt,\n+                                     const zebra_image_t *src,\n+                                     const zebra_format_def_t *srcfmt)\n+{\n+    uint8_t *psrc = (void*)src->data;\n+    uint8_t *pdst = (void*)dst->data;\n+    unsigned width = (dst->width > src->width) ? src->width : dst->width;\n+    unsigned xpad = (dst->width > src->width) ? dst->width - src->width : 0;\n+    unsigned height = (dst->height > src->height) ? src->height : dst->height;\n+    unsigned y;\n+    for(y = 0; y < height; y++) {\n+        memcpy(pdst, psrc, width);\n+        pdst += width;\n+        psrc += src->width;\n+        if(xpad) {\n+            memset(pdst, *(psrc - 1), xpad);\n+            pdst += xpad;\n+        }\n+    }\n+    psrc -= src->width;\n+    for(; y < dst->height; y++) {\n+        memcpy(pdst, psrc, width);\n+        pdst += width;\n+        if(xpad) {\n+            memset(pdst, *(psrc - 1), xpad);\n+            pdst += xpad;\n+        }\n+    }\n+}\n+\n /* append neutral UV plane to grayscale image */\n static void convert_uvp_append (zebra_image_t *dst,\n                                 const zebra_format_def_t *dstfmt,\n@@ -308,10 +353,16 @@ static void convert_uvp_append (zebra_image_t *dst,\n     dst->datalen = uvp_size(dst, dstfmt) * 2;\n     unsigned long n = dst->width * dst->height;\n     dst->datalen += n;\n-    assert(src->datalen >= n);\n+    assert(src->datalen >= src->width * src->height);\n+    zprintf(24, "dst=%dx%d (%lx) %lx src=%dx%d %lx\\n",\n+            dst->width, dst->height, n, dst->datalen,\n+            src->width, src->height, src->datalen);\n     dst->data = malloc(dst->datalen);\n     if(!dst->data) return;\n-    memcpy((void*)dst->data, src->data, n);\n+    if(dst->width == src->width && dst->height == src->height)\n+        memcpy((void*)dst->data, src->data, n);\n+    else\n+        convert_y_resize(dst, dstfmt, src, srcfmt);\n     memset((void*)dst->data + n, 0x80, dst->datalen - n);\n }\n \n@@ -347,21 +398,32 @@ static void convert_yuv_pack (zebra_image_t *dst,\n     unsigned xmask = (1 << srcfmt->p.yuv.xsub2) - 1;\n     unsigned ymask = (1 << srcfmt->p.yuv.ysub2) - 1;\n     unsigned x, y;\n-    signed u, v;\n+    uint8_t y0, y1, u, v;\n     for(y = 0; y < src->height; y++) {\n+        if(y >= dst->height)\n+            break;\n         if(y & ymask) {\n             srcu -= srcl;  srcv -= srcl;\n         }\n-        for(x = 0; x < src->width; x += 2) {\n-            if(!(x & xmask)) {\n-                u = *(srcu++);  v = *(srcv++);\n+        for(x = 0; x < dst->width; x += 2) {\n+            if(x < src->width) {\n+                y0 = *(srcy++);  y1 = *(srcy++);\n+                if(!(x & xmask)) {\n+                    u = *(srcu++);  v = *(srcv++);\n+                }\n             }\n             if(flags) {\n-                *(dstp++) = *(srcy++);  *(dstp++) = u;\n-                *(dstp++) = *(srcy++);  *(dstp++) = v;\n+                *(dstp++) = y0;  *(dstp++) = u;\n+                *(dstp++) = y1;  *(dstp++) = v;\n             } else {\n-                *(dstp++) = u;  *(dstp++) = *(srcy++);\n-                *(dstp++) = v;  *(dstp++) = *(srcy++);\n+                *(dstp++) = u;  *(dstp++) = y0;\n+                *(dstp++) = v;  *(dstp++) = y1;\n+            }\n+        }\n+        for(; x < src->width; x += 2) {\n+            y0 = *(srcy++);  y1 = *(srcy++);\n+            if(!(x & xmask)) {\n+                u = *(srcu++);  v = *(srcv++);\n             }\n         }\n     }\n@@ -393,6 +455,7 @@ static void convert_yuv_unpack (zebra_image_t *dst,\n     if(flags)\n         srcp++;\n \n+    /* FIXME handle resize */\n     unsigned long i;\n     for(i = dstn / 2; i; i--) {\n         *(dsty++) = *(srcp++);  srcp++;\n@@ -700,14 +763,18 @@ const zebra_format_def_t *_zebra_format_lookup (uint32_t fmt)\n     return(NULL);\n }\n \n-zebra_image_t *zebra_image_convert (const zebra_image_t *src,\n-                                    unsigned long fmt)\n+zebra_image_t *zebra_image_convert_resize (const zebra_image_t *src,\n+                                           unsigned long fmt,\n+                                           unsigned width,\n+                                           unsigned height)\n {\n     zebra_image_t *dst = zebra_image_create();\n     dst->format = fmt;\n-    dst->width = src->width;\n-    dst->height = src->height;\n-    if(src->format == fmt) {\n+    dst->width = width;\n+    dst->height = height;\n+    if(src->format == fmt &&\n+       src->width == width &&\n+       src->height == height) {\n         convert_copy(dst, NULL, src, NULL);\n         return(dst);\n     }\n@@ -715,10 +782,13 @@ zebra_image_t *zebra_image_convert (const zebra_image_t *src,\n     const zebra_format_def_t *srcfmt = _zebra_format_lookup(src->format);\n     const zebra_format_def_t *dstfmt = _zebra_format_lookup(dst->format);\n     if(!srcfmt || !dstfmt)\n+        /* FIXME free dst */\n         return(NULL);\n \n     if(srcfmt->group == dstfmt->group &&\n-       srcfmt->p.cmp == dstfmt->p.cmp) {\n+       srcfmt->p.cmp == dstfmt->p.cmp &&\n+       src->width == width &&\n+       src->height == height) {\n         convert_copy(dst, NULL, src, NULL);\n         return(dst);\n     }\n@@ -731,6 +801,12 @@ zebra_image_t *zebra_image_convert (const zebra_image_t *src,\n     return(dst);\n }\n \n+zebra_image_t *zebra_image_convert (const zebra_image_t *src,\n+                                    unsigned long fmt)\n+{\n+    return(zebra_image_convert_resize(src, fmt, src->width, src->height));\n+}\n+\n static inline int has_format (uint32_t fmt,\n                               const uint32_t *fmts)\n {\ndiff --git a/zebra/debug.h b/zebra/debug.h\nnew file mode 100644\nindex 0000000..11325b5\n--- /dev/null\n+++ b/zebra/debug.h\n@@ -0,0 +1,50 @@\n+/*------------------------------------------------------------------------\n+ *  Copyright 2007-2008 (c) Jeff Brown <spadix@users.sourceforge.net>\n+ *\n+ *  This file is part of the Zebra Barcode Library.\n+ *\n+ *  The Zebra Barcode Library is free software; you can redistribute it\n+ *  and/or modify it under the terms of the GNU Lesser Public License as\n+ *  published by the Free Software Foundation; either version 2.1 of\n+ *  the License, or (at your option) any later version.\n+ *\n+ *  The Zebra Barcode Library is distributed in the hope that it will be\n+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty\n+ *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ *  GNU Lesser Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU Lesser Public License\n+ *  along with the Zebra Barcode Library; if not, write to the Free\n+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,\n+ *  Boston, MA  02110-1301  USA\n+ *\n+ *  http://sourceforge.net/projects/zebra\n+ *------------------------------------------------------------------------*/\n+\n+/* varargs variations on compile time debug spew */\n+\n+#ifndef DEBUG_LEVEL\n+\n+# ifdef __GNUC__\n+    /* older versions of gcc (< 2.95) require a named varargs parameter */\n+#  define dprintf(args...)\n+# else\n+    /* unfortunately named vararg parameter is a gcc-specific extension */\n+#  define dprintf(...)\n+# endif\n+\n+#else\n+\n+# include <stdio.h>\n+\n+# ifdef __GNUC__\n+#  define dprintf(level, args...) \\\n+    if((level) <= DEBUG_LEVEL)    \\\n+        fprintf(stderr, args)\n+# else\n+#  define dprintf(level, ...)     \\\n+    if((level) <= DEBUG_LEVEL)    \\\n+        fprintf(stderr, __VA_ARGS__)\n+# endif\n+\n+#endif /* DEBUG_LEVEL */\ndiff --git a/zebra/decoder.c b/zebra/decoder.c\nindex 8c0ed39..74e6fb2 100644\n--- a/zebra/decoder.c\n+++ b/zebra/decoder.c\n@@ -22,9 +22,6 @@\n  *------------------------------------------------------------------------*/\n \n #include <config.h>\n-#ifdef DEBUG_DECODER\n-# include <stdio.h>     /* fprintf */\n-#endif\n #include <stdlib.h>     /* malloc, free */\n #include <string.h>     /* memset */\n #include <assert.h>\n@@ -32,12 +29,11 @@\n #include <zebra.h>\n #include "decoder.h"\n \n-#ifdef DEBUG_DECODER\n-# define dprintf(...) \\\n-    fprintf(stderr, __VA_ARGS__)\n-#else\n-# define dprintf(...)\n+#if defined(DEBUG_DECODER) || defined(DEBUG_EAN) || defined(DEBUG_CODE128) || \\\n+    defined(DEBUG_CODE39) || defined(DEBUG_I25)\n+# define DEBUG_LEVEL 1\n #endif\n+#include "debug.h"\n \n zebra_decoder_t *zebra_decoder_create ()\n {\n@@ -130,7 +126,7 @@ zebra_symbol_type_t zebra_decode_width (zebra_decoder_t *dcode,\n                                         unsigned w)\n {\n     dcode->w[dcode->idx & (DECODE_WINDOW - 1)] = w;\n-    dprintf("    decode[%x]: w=%d (%g)\\n", dcode->idx, w, (w / 32.));\n+    dprintf(1, "    decode[%x]: w=%d (%g)\\n", dcode->idx, w, (w / 32.));\n \n     /* each decoder processes width stream in parallel */\n     zebra_symbol_type_t sym = dcode->type = ZEBRA_NONE;\ndiff --git a/zebra/decoder/code128.c b/zebra/decoder/code128.c\nindex 4aa17c3..04b5c54 100644\n--- a/zebra/decoder/code128.c\n+++ b/zebra/decoder/code128.c\n@@ -22,9 +22,6 @@\n  *------------------------------------------------------------------------*/\n \n #include <config.h>\n-#ifdef DEBUG_CODE128\n-# include <stdio.h>     /* fprintf */\n-#endif\n #include <string.h>     /* memmove */\n #include <assert.h>\n \n@@ -32,12 +29,9 @@\n #include "decoder.h"\n \n #ifdef DEBUG_CODE128\n-# define dprintf(level, ...) \\\n-    if(level <= DEBUG_CODE128) \\\n-        fprintf(stderr, __VA_ARGS__)\n-#else\n-# define dprintf(...)\n+# define DEBUG_LEVEL (DEBUG_CODE128)\n #endif\n+#include "debug.h"\n \n #define NUM_CHARS 108           /* total number of character codes */\n \ndiff --git a/zebra/decoder/code39.c b/zebra/decoder/code39.c\nindex a55facc..c3b9e8f 100644\n--- a/zebra/decoder/code39.c\n+++ b/zebra/decoder/code39.c\n@@ -22,9 +22,6 @@\n  *------------------------------------------------------------------------*/\n \n #include <config.h>\n-#ifdef DEBUG_CODE39\n-# include <stdio.h>     /* fprintf */\n-#endif\n #include <string.h>     /* memmove */\n #include <assert.h>\n \n@@ -32,12 +29,9 @@\n #include "decoder.h"\n \n #ifdef DEBUG_CODE39\n-# define dprintf(level, ...) \\\n-    if(level <= DEBUG_CODE39) \\\n-        fprintf(stderr, __VA_ARGS__)\n-#else\n-# define dprintf(...)\n+# define DEBUG_LEVEL (DEBUG_CODE39)\n #endif\n+#include "debug.h"\n \n #define NUM_CHARS (0x2c)\n \ndiff --git a/zebra/decoder/ean.c b/zebra/decoder/ean.c\nindex 50dcdda..2c67e54 100644\n--- a/zebra/decoder/ean.c\n+++ b/zebra/decoder/ean.c\n@@ -22,21 +22,15 @@\n  *------------------------------------------------------------------------*/\n \n #include <config.h>\n-#ifdef DEBUG_EAN\n-# include <stdio.h>     /* fprintf */\n-#endif\n #include <assert.h>\n \n #include <zebra.h>\n #include "decoder.h"\n \n #ifdef DEBUG_EAN\n-# define dprintf(level, ...) \\\n-    if(level <= DEBUG_EAN) \\\n-        fprintf(stderr, __VA_ARGS__)\n-#else\n-# define dprintf(...)\n+# define DEBUG_LEVEL (DEBUG_EAN)\n #endif\n+#include "debug.h"\n \n /* partial decode symbol location */\n typedef enum symbol_partial_e {\ndiff --git a/zebra/decoder/i25.c b/zebra/decoder/i25.c\nindex a9fb72e..03a86ae 100644\n--- a/zebra/decoder/i25.c\n+++ b/zebra/decoder/i25.c\n@@ -22,9 +22,6 @@\n  *------------------------------------------------------------------------*/\n \n #include <config.h>\n-#ifdef DEBUG_I25\n-# include <stdio.h>     /* fprintf */\n-#endif\n #include <string.h>     /* memmove */\n #include <assert.h>\n \n@@ -32,12 +29,9 @@\n #include "decoder.h"\n \n #ifdef DEBUG_I25\n-# define dprintf(level, ...) \\\n-    if(level <= DEBUG_I25) \\\n-        fprintf(stderr, __VA_ARGS__)\n-#else\n-# define dprintf(...)\n+# define DEBUG_LEVEL (DEBUG_I25)\n #endif\n+#include "debug.h"\n \n static inline unsigned char i25_decode1 (unsigned char enc,\n                                          unsigned e,\ndiff --git a/zebra/processor.c b/zebra/processor.c\nindex d6fea08..a7a0b76 100644\n--- a/zebra/processor.c\n+++ b/zebra/processor.c\n@@ -584,9 +584,8 @@ int zebra_processor_set_visible (zebra_processor_t *proc,\n             rc = _zebra_window_resize(proc,\n                                       zebra_video_get_width(proc->video),\n                                       zebra_video_get_height(proc->video));\n-        if(!rc &&\n-           !(rc = _zebra_window_set_visible(proc, visible)))\n-            proc->visible = visible != 0;\n+        if(!rc)\n+            rc = _zebra_window_set_visible(proc, visible);\n     }\n     else if(visible)\n         rc = err_capture(proc, SEV_ERROR, ZEBRA_ERR_INVALID, __func__,\ndiff --git a/zebra/scanner.c b/zebra/scanner.c\nindex 77750ee..a5c9c3d 100644\n--- a/zebra/scanner.c\n+++ b/zebra/scanner.c\n@@ -22,9 +22,6 @@\n  *------------------------------------------------------------------------*/\n \n #include <config.h>\n-#ifdef DEBUG_SCANNER\n-# include <stdio.h>     /* fprintf */\n-#endif\n #include <stdlib.h>     /* malloc, free, abs */\n #include <string.h>     /* memset */\n #include <assert.h>\n@@ -32,11 +29,9 @@\n #include <zebra.h>\n \n #ifdef DEBUG_SCANNER\n-# define dprintf(...) \\\n-    fprintf(stderr, __VA_ARGS__)\n-#else\n-# define dprintf(...)\n+# define DEBUG_LEVEL (DEBUG_SCANNER)\n #endif\n+#include "debug.h"\n \n #ifndef ZEBRA_FIXED\n # define ZEBRA_FIXED 5\n@@ -118,7 +113,7 @@ static inline unsigned calc_thresh (zebra_scanner_t *scn)\n     /* threshold 1st to improve noise rejection */\n     unsigned thresh = scn->y1_thresh;\n     if((thresh <= scn->y1_min_thresh) || !scn->width) {\n-        dprintf(" tmin=%d", scn->y1_min_thresh);\n+        dprintf(1, " tmin=%d", scn->y1_min_thresh);\n         return(scn->y1_min_thresh);\n     }\n     /* slowly return threshold to min */\n@@ -126,7 +121,7 @@ static inline unsigned calc_thresh (zebra_scanner_t *scn)\n     unsigned long t = thresh * dx;\n     t /= scn->width;\n     t /= ZEBRA_SCANNER_THRESH_FADE;\n-    dprintf(" thr=%d t=%ld x=%d last=%d.%d (%d)",\n+    dprintf(1, " thr=%d t=%ld x=%d last=%d.%d (%d)",\n             thresh, t, scn->x, scn->last_edge >> ZEBRA_FIXED,\n             scn->last_edge & ((1 << ZEBRA_FIXED) - 1), dx);\n     if(thresh > t) {\n@@ -142,7 +137,7 @@ static inline zebra_symbol_type_t process_edge (zebra_scanner_t *scn,\n                                                 int y1)\n {\n     scn->width = scn->cur_edge - scn->last_edge;\n-    dprintf(" sgn=%d cur=%d.%d w=%d (%s)\\n",\n+    dprintf(1, " sgn=%d cur=%d.%d w=%d (%s)\\n",\n             scn->y1_sign, scn->cur_edge >> ZEBRA_FIXED,\n             scn->cur_edge & ((1 << ZEBRA_FIXED) - 1), scn->width,\n             ((y1 > 0) ? "SPACE" : "BAR"));\n@@ -202,7 +197,7 @@ zebra_symbol_type_t zebra_scan_y (zebra_scanner_t *scn,\n     register int y2_1 = y0_0 - (y0_1 * 2) + y0_2;\n     register int y2_2 = y0_1 - (y0_2 * 2) + y0_3;\n \n-    dprintf("scan: y=%d y0=%d y1=%d y2=%d", y, y0_1, y1_1, y2_1);\n+    dprintf(1, "scan: y=%d y0=%d y1=%d y2=%d", y, y0_1, y1_1, y2_1);\n \n     zebra_symbol_type_t edge = ZEBRA_NONE;\n     /* 2nd zero-crossing is 1st local min/max - could be edge */\n@@ -216,7 +211,7 @@ zebra_symbol_type_t zebra_scan_y (zebra_scanner_t *scn,\n             /* intensity change reversal - finalize previous edge */\n             edge = process_edge(scn, y1_1);\n         else\n-            dprintf("\\n");\n+            dprintf(1, "\\n");\n \n         if(y1_rev || (abs(scn->y1_sign) < abs(y1_1))) {\n             scn->y1_sign = y1_1;\n@@ -224,7 +219,7 @@ zebra_symbol_type_t zebra_scan_y (zebra_scanner_t *scn,\n             /* adaptive thresholding */\n             /* start at multiple of new min/max */\n             scn->y1_thresh = (abs(y1_1) * THRESH_INIT + ROUND) >> ZEBRA_FIXED;\n-            dprintf(" thr=%d", scn->y1_thresh);\n+            dprintf(1, " thr=%d", scn->y1_thresh);\n             if(scn->y1_thresh < scn->y1_min_thresh)\n                 scn->y1_thresh = scn->y1_min_thresh;\n \n@@ -240,7 +235,7 @@ zebra_symbol_type_t zebra_scan_y (zebra_scanner_t *scn,\n         }\n     }\n     else\n-        dprintf("\\n");\n+        dprintf(1, "\\n");\n     /* FIXME add fall-thru pass to decoder after heuristic "idle" period\n        (eg, 6-8 * last width) */\n     scn->x++;\ndiff --git a/zebra/video/v4l1.c b/zebra/video/v4l1.c\nindex 4a81d94..2c17f92 100644\n--- a/zebra/video/v4l1.c\n+++ b/zebra/video/v4l1.c\n@@ -229,12 +229,18 @@ static inline int v4l1_set_format (zebra_video_t *vdo,\n         return(err_capture(vdo, SEV_ERROR, ZEBRA_ERR_SYSTEM, __func__,\n                            "querying video format (VIDIOCGPICT)"));\n \n-    if(vpic.palette != ifmt || vpic.depth != v4l1_formats[ifmt].bpp)\n-        return(err_capture_int(vdo, SEV_ERROR, ZEBRA_ERR_INVALID, __func__,\n-                               "failed to set format (%08x)", fmt));\n+    if(vpic.palette != ifmt || vpic.depth != v4l1_formats[ifmt].bpp) {\n+        fprintf(stderr,\n+                "WARNING: set v4l1 palette %d which should have depth %d bpp\\n"\n+                "    but probed palette %d with depth %d bpp?"\n+                "  ...continuing anyway\\n",\n+                ifmt, v4l1_formats[ifmt].bpp, vpic.palette, vpic.depth);\n+        err_capture_int(vdo, SEV_WARNING, ZEBRA_ERR_INVALID, __func__,\n+                        "driver format (%x) inconsistency", fmt);\n+    }\n     vdo->format = fmt;\n     vdo->palette = ifmt;\n-    vdo->datalen = (vdo->width * vdo->height * vpic.depth + 7) >> 3;\n+    vdo->datalen = (vdo->width * vdo->height * v4l1_formats[ifmt].bpp + 7) >> 3;\n \n     zprintf(1, "set new format: %.4s(%08x) depth=%d palette=%d size=0x%lx\\n",\n             (char*)&vdo->format, vdo->format, vpic.depth, vdo->palette,\ndiff --git a/zebra/window.h b/zebra/window.h\nindex b4c2a98..3a85c7a 100644\n--- a/zebra/window.h\n+++ b/zebra/window.h\n@@ -69,7 +69,10 @@ struct zebra_window_s {\n         XvImage *xv;\n #endif\n     } img;\n-    uint32_t img_format;        /* current input format */\n+    uint32_t src_format;        /* current input format */\n+    unsigned src_width;         /* last displayed image size */\n+    unsigned src_height;\n+    unsigned dst_width;         /* conversion target */\n     XID img_port;               /* current format port */\n \n     XID *xv_ports;              /* best port for format */\ndiff --git a/zebra/window/x.c b/zebra/window/x.c\nindex db37381..b8caf52 100644\n--- a/zebra/window/x.c\n+++ b/zebra/window/x.c\n@@ -121,7 +121,7 @@ static int x_handle_event (zebra_processor_t *proc)\n            (ev.xclient.data.l[0] ==\n             XInternAtom(proc->display, "WM_DELETE_WINDOW", 0))) {\n             zprintf(3, "WM_DELETE_WINDOW\\n");\n-            XUnmapWindow(proc->display, proc->xwin);\n+            _zebra_window_set_visible(proc, 0);\n             return(err_capture(proc, SEV_WARNING, ZEBRA_ERR_CLOSED, __func__,\n                                "user closed display window"));\n         }\n@@ -156,6 +156,23 @@ int _zebra_window_handle_events (zebra_processor_t *proc,\n         proc->input = x_handle_event(proc);\n         rc = proc->input;\n     }\n+\n+    switch(rc) {\n+    case \'q\':\n+        _zebra_window_set_visible(proc, 0);\n+        rc = err_capture(proc, SEV_WARNING, ZEBRA_ERR_CLOSED, __func__,\n+                         "user closed display window");\n+        break;\n+\n+    case \'d\': {\n+        /* FIXME localtime not threadsafe */\n+        /* FIXME need ms resolution */\n+        /*struct tm *t = localtime(time(NULL));*/\n+        zebra_image_write(proc->window->image, "zebra");\n+        break;\n+    }\n+    }\n+\n     if(rc)\n         emit(proc, EVENT_INPUT);\n     return(rc);\n@@ -267,6 +284,7 @@ int _zebra_window_set_visible (zebra_processor_t *proc,\n     else\n         XUnmapWindow(proc->display, proc->xwin);\n     XFlush(proc->display);\n+    proc->visible = visible != 0;\n     return(0);\n }\n \ndiff --git a/zebra/window/ximage.c b/zebra/window/ximage.c\nindex 3a684dd..47e105e 100644\n--- a/zebra/window/ximage.c\n+++ b/zebra/window/ximage.c\n@@ -38,7 +38,7 @@ static inline int ximage_init (zebra_window_t *w,\n         free(w->img.x);\n         w->img.x = NULL;\n     }\n-    if(w->img_format != img->format &&\n+    if(w->src_format != img->format &&\n        w->format != img->format) {\n         _zebra_best_format(img->format, &w->format, w->formats);\n         if(!w->format) {\n@@ -47,7 +47,7 @@ static inline int ximage_init (zebra_window_t *w,\n                             img->format);\n             return(-1);\n         }\n-        w->img_format = img->format;\n+        w->src_format = img->format;\n     }\n     XImage *ximg = w->img.x = calloc(1, sizeof(XImage));\n     ximg->width = img->width;\n@@ -93,7 +93,7 @@ static int ximage_draw (zebra_window_t *w,\n {\n     XImage *ximg = w->img.x;\n     if(!ximg ||\n-       (w->img_format != img->format &&\n+       (w->src_format != img->format &&\n         w->format != img->format) ||\n        ximg->width != img->width ||\n        ximg->height != img->height) {\ndiff --git a/zebra/window/xv.c b/zebra/window/xv.c\nindex 463481d..d57029c 100644\n--- a/zebra/window/xv.c\n+++ b/zebra/window/xv.c\n@@ -49,7 +49,7 @@ static inline int xv_init (zebra_window_t *w,\n         XFree(w->img.xv);\n         w->img.xv = NULL;\n     }\n-    if(w->img_format != img->format &&\n+    if(w->src_format != img->format &&\n        w->format != img->format) {\n         _zebra_best_format(img->format, &w->format, w->formats);\n         if(!w->format) {\n@@ -58,7 +58,7 @@ static inline int xv_init (zebra_window_t *w,\n                             img->format);\n             return(-1);\n         }\n-        w->img_format = img->format;\n+        w->src_format = img->format;\n         /* lookup port for format */\n         w->img_port = -1;\n         int i;\n@@ -69,20 +69,31 @@ static inline int xv_init (zebra_window_t *w,\n             }\n         assert(w->img_port >= 0);\n     }\n+    w->src_width = img->width;\n+    w->src_height = img->height;\n     XvImage *xvimg = XvCreateImage(w->display, w->img_port, w->format,\n                                    NULL, img->width, img->height);\n-    zprintf(3, "new XvImage %.4s(%08x) %dx%d from %.4s(%08x) %dx%d\\n",\n-            (char*)&w->format, w->format, xvimg->width, xvimg->height,\n+    zprintf(3, "new XvImage %.4s(%08x) %dx%d(%d) from %.4s(%08x) %dx%d\\n",\n+            (char*)&w->format, w->format,\n+            xvimg->width, xvimg->height, xvimg->pitches[0],\n             (char*)&img->format, img->format, img->width, img->height);\n \n     /* FIXME datalen check */\n-    if(xvimg->width != img->width || xvimg->height != img->height) {\n+    if(xvimg->width < img->width || xvimg->height < img->height) {\n         XFree(xvimg);\n         /* FIXME fallback to XImage... */\n         return(err_capture(w, SEV_ERROR, ZEBRA_ERR_UNSUPPORTED, __func__,\n                            "output image size mismatch (XvCreateImage)"));\n     }\n     w->img.xv = xvimg;\n+\n+    /* FIXME not sure this simple check is always correct\n+     * should lookup format to decode/sanitize target width from pitch & bpp\n+     */\n+    w->dst_width = ((xvimg->num_planes <= 1)\n+                    ? xvimg->width\n+                    : xvimg->pitches[0]);\n+\n     return(0);\n }\n \n@@ -92,24 +103,28 @@ static int xv_draw (zebra_window_t *w,\n     XvImage *xvimg = w->img.xv;\n     /* FIXME preserve aspect ratio (config?) */\n     if(!xvimg ||\n-       (w->img_format != img->format &&\n+       (w->src_format != img->format &&\n         w->format != img->format)||\n-       xvimg->width != img->width ||\n-       xvimg->height != img->height) {\n+       w->src_width != img->width ||\n+       w->src_height != img->height) {\n         if(xv_init(w, img))\n             return(-1);\n         xvimg = w->img.xv;\n     }\n-    if(img->format != w->format) {\n+    if(img->format != w->format ||\n+       img->width != xvimg->pitches[0] ||\n+       img->height != xvimg->height) {\n         /* save *converted* image for redraw */\n-        w->image = zebra_image_convert(img, w->format);\n+        w->image = zebra_image_convert_resize(img, w->format,\n+                                              w->dst_width,\n+                                              xvimg->height);\n         zebra_image_destroy(img);\n         img = w->image;\n     }\n \n     xvimg->data = (void*)img->data;\n     XvPutImage(w->display, w->img_port, w->xwin, w->gc, xvimg,\n-               0, 0, img->width, img->height,\n+               0, 0, w->src_width, w->src_height,\n                0, 0, w->width, w->height);\n     xvimg->data = NULL;  /* FIXME hold shm image until completion */\n     return(0);\n', 'commit_subject': "  * image format conversion fixes     - fix format size roundoff (NB now rounds *down*)     - add convert and resize API to pad/crop image to specific size       (eg, to handle Xv min/max image size)       NB this is still not implemented for many conversions   * fix window deletion visibility inconsistency   * add couple processor commands     - 'q' to delete window     - 'd' to dump displayed image for debug   * remove problematic includes used for v4l2 configure test   * address compiler portability concerns w/debug print vararg macro   * workaround v4l1_set_format() failed consistency check for broken drivers     - change from error to warning w/more useful message     - calc expected image size using expected value instead of driver value   * add missing example scripts to distribution", 'repo_name': 'ZBar/ZBar', 'committer': {'name': 'spadix', 'email': 'fa55c88d4fdac03abbb2a7186fbcaa90c3a00540@users.sf.net', 'time_sec': '1209321896', 'tz_offset': '0', 'date': {'seconds': '1209321896'}}, 'commit_tree': '9fcfc14bef08810b86c974a80c1e1e0234284ede', 'commit_message': "  * image format conversion fixes\n    - fix format size roundoff (NB now rounds *down*)\n    - add convert and resize API to pad/crop image to specific size\n      (eg, to handle Xv min/max image size)\n      NB this is still not implemented for many conversions\n  * fix window deletion visibility inconsistency\n  * add couple processor commands\n    - 'q' to delete window\n    - 'd' to dump displayed image for debug\n  * remove problematic includes used for v4l2 configure test\n  * address compiler portability concerns w/debug print vararg macro\n  * workaround v4l1_set_format() failed consistency check for broken drivers\n    - change from error to warning w/more useful message\n    - calc expected image size using expected value instead of driver value\n  * add missing example scripts to distribution\n", 'language_name': 'C', 'license': 'lgpl-2.1', 'hunks': '@@ -0,0 +1,50 @@\n+/*------------------------------------------------------------------------\n+ *  Copyright 2007-2008 (c) Jeff Brown <spadix@users.sourceforge.net>\n+ *\n+ *  This file is part of the Zebra Barcode Library.\n+ *\n+ *  The Zebra Barcode Library is free software; you can redistribute it\n+ *  and/or modify it under the terms of the GNU Lesser Public License as\n+ *  published by the Free Software Foundation; either version 2.1 of\n+ *  the License, or (at your option) any later version.\n+ *\n+ *  The Zebra Barcode Library is distributed in the hope that it will be\n+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty\n+ *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ *  GNU Lesser Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU Lesser Public License\n+ *  along with the Zebra Barcode Library; if not, write to the Free\n+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,\n+ *  Boston, MA  02110-1301  USA\n+ *\n+ *  http://sourceforge.net/projects/zebra\n+ *------------------------------------------------------------------------*/\n+\n+/* varargs variations on compile time debug spew */\n+\n+#ifndef DEBUG_LEVEL\n+\n+# ifdef __GNUC__\n+    /* older versions of gcc (< 2.95) require a named varargs parameter */\n+#  define dprintf(args...)\n+# else\n+    /* unfortunately named vararg parameter is a gcc-specific extension */\n+#  define dprintf(...)\n+# endif\n+\n+#else\n+\n+# include <stdio.h>\n+\n+# ifdef __GNUC__\n+#  define dprintf(level, args...) \\\n+    if((level) <= DEBUG_LEVEL)    \\\n+        fprintf(stderr, args)\n+# else\n+#  define dprintf(level, ...)     \\\n+    if((level) <= DEBUG_LEVEL)    \\\n+        fprintf(stderr, __VA_ARGS__)\n+# endif\n+\n+#endif /* DEBUG_LEVEL */\n', 'addition_count': 50, 'deletion_count': 0, 'src_file': '/dev/null', 'tgt_file': 'b/zebra/debug.h', 'file_extension': '.h', 'before_file': 'ADDFILE', 'message': "  * image format conversion fixes\n    - fix format size roundoff (NB now rounds *down*)\n    - add convert and resize API to pad/crop image to specific size\n      (eg, to handle Xv min/max image size)\n      NB this is still not implemented for many conversions\n  * fix window deletion visibility inconsistency\n  * add couple processor commands\n    - 'q' to delete window\n    - 'd' to dump displayed image for debug\n  * remove problematic includes used for v4l2 configure test\n  * address compiler portability concerns w/debug print vararg macro\n  * workaround v4l1_set_format() failed consistency check for broken drivers\n    - change from error to warning w/more useful message\n    - calc expected image size using expected value instead of driver value\n  * add missing example scripts to distribution\n", 'author_name': 'spadix', 'lang': 'h'}