Henning Meier-Geinitz wrote:

>[segfault of xscanimage with avision backend]
>
>On Sat, Sep 24, 2005 at 07:39:51AM -0500, Dan McGhee wrote:
>  
>
>>Starting program: /usr/bin/xscanimage
>>
>>*[This is the point at which I clicked "scan" in the preview window]*
>>
>>Program received signal SIGSEGV, Segmentation fault.
>>0x08057467 in gsg_sync (dialog=0x80ef4f0) at gtkglue.c:1424
>>1424 curve = GTK_GAMMA_CURVE (dialog->element[i].widget)->curve;
>>(gdb) bt
>>#0 0x08057467 in gsg_sync (dialog=0x80ef4f0) at gtkglue.c:1424
>>    
>>
>
>The code is:
>
>
>      if (opt->type != SANE_TYPE_INT && opt->type != SANE_TYPE_FIXED)
>        continue;
>
>      if (opt->size == sizeof (SANE_Word))
>        continue;
>
>      /* ok, we're dealing with an active vector */
>
>      optlen = opt->size / sizeof (SANE_Word);
>      optval = alloca (optlen * sizeof (optval[0]));
>      vector = alloca (optlen * sizeof (vector[0]));
>
>      curve = GTK_GAMMA_CURVE (dialog->element[i].widget)->curve;
>
>So I looked into the avision backend for a SANE_TYPE_INT or
>SANE_TYPE_FIXED option with a length != SANE_Word. There are the four
>gamma vectors but they look ok. The only thing that looks fishy is
>this (avision.c):
>
>  s->opt[OPT_NUM_OPTS].name = "";
>  s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
>  s->opt[OPT_NUM_OPTS].desc = "";
>  s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
>  s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
>  s->opt[OPT_NUM_OPTS].size = sizeof(SANE_TYPE_INT);
>
>The last line is wrong (it must be sizeof(SANE_Word)). SANE_TYPE_INT
>is an enum. Is this automatically and "int" or can it be shorter? I'm
>not sure if this is actually the problem but you could try that:
>
>  s->opt[OPT_NUM_OPTS].size = sizeof (SANE_Word);
>
>in avision.c and recompile+install.
>  
>
Just to remind you, I'm not using the version of avision released in 
backends-1.0.16. I'm using Rev. 280 of avision from SVN. It is patched 
with the file Falk Rohsiepe sent me and then Rene posted a patch here 
last month.

I'm really a "noob" at reading code, so right now about the only thing I 
can do is gather and report data. In the version of avision.c that I 
currently have--the patched one--I ran:

'grep -in -A 5 -B 5 SANE_Word avision.c'

I have attached the resulting file. I know there's probably a lot of 
extraneous info there, but I don't know how to filter out the extra stuff.

I also ran:
` grep -in \-A 5 -B 5 sizof\(SANE_Word\) avision.c`
with no results.

`grep -in \-A 5 -B 5 OPT_NUM_OPTS avision.c` yielded

899- dev->speed_range.min = (SANE_Int)0;
5900- dev->speed_range.max = (SANE_Int)4;
5901- dev->speed_range.quant = (SANE_Int)1;
5902-
5903: init_option_int (s, OPT_NUM_OPTS, "", SANE_TITLE_NUM_OPTIONS, "",
5904- SANE_UNIT_NONE, SANE_CAP_SOFT_DETECT, 0, 0,
5905- NUM_OPTIONS);
5906-
5907- /* "Mode" group: */
5908- init_option_group (s, OPT_MODE_GROUP, SANE_TITLE_SCAN_MODE);
--
7605- case OPT_SPEED:
7606- case OPT_TL_X:
7607- case OPT_TL_Y:
7608- case OPT_BR_X:
7609- case OPT_BR_Y:
7610: case OPT_NUM_OPTS:
7611-
7612- case OPT_BRIGHTNESS:
7613- case OPT_CONTRAST:
7614- case OPT_QSCAN:
7615- case OPT_QCALIB:

>If that's not the problem, I guess Rene has to do some debugging
>because without a scanner supported by the avision backend I can't
>help more.
>
>  
>
If you give me specific directions, I can run the commands and post back.

@Rene and Falk I can do the same for both of you too.

>Does the segfault also occur with sane-backends 1.0.16?
>  
>
I'm going by memory, which fails as I age, and I think there may be a 
regression between avision released in backends-1.0.15 and Rev 280. I 
THINK I remember xscanimage working with the patch applied to avision in 
1.0.15, but I'm not sure. If I have the time I will rebuild it and report.

Thanks for the help, Henning.

Dan

-------------- next part --------------
1462-    SANE_FIX (0), /* minimum */
1463-    SANE_FIX (100), /* maximum */
1464-    SANE_FIX (1) /* quantization */
1465-  };
1466-
1467:static const SANE_Word bool_list[] =
1468-  {
1469-    2, /* 2 members */
1470-    SANE_FALSE,
1471-    SANE_TRUE
1472-  };
--
1524-      DBG (3, "constrain_value: while trying to set %.3f\n",
1525-      SANE_UNFIX(*(SANE_Fixed*)value));
1526-    }
1527-    else {
1528-      DBG (3, "constrain_value: while trying to set %lu\n",
1529:      (u_long)*(SANE_Word*)value);
1530-    }
1531-  }
1532-  return r;
1533-}
1534-
--
3221-  
3222-  return SANE_STATUS_GOOD;
3223-}
3224-
3225-static SANE_Status
3226:set_frame (Avision_Scanner* s, SANE_Word frame)
3227-{
3228-  struct {
3229-    struct command_send cmd;
3230-    u_int8_t data[8];
3231-  } scmd;
--
5681-  
5682-static void
5683-init_option_int (Avision_Scanner *s, int idx,
5684-            const char* name, const char* title, const char* desc,
5685-            SANE_Unit unit, SANE_Int cap,
5686:            const SANE_Word* valid_list, const SANE_Range* valid_range,
5687-            SANE_Int value)
5688-{
5689-  s->opt[idx].name = name;
5690-  s->opt[idx].title = title;
5691-  s->opt[idx].desc = desc;
5692-  s->opt[idx].type = SANE_TYPE_INT;
5693-  s->opt[idx].unit = unit;
5694:  s->opt[idx].size = sizeof (SANE_Word);
5695-  s->opt[idx].cap = cap;
5696-  if (valid_list) {
5697-    s->opt[idx].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5698-    s->opt[idx].constraint.word_list = valid_list;
5699-  }
--
5709-  
5710-static void
5711-init_option_int_vec (Avision_Scanner *s, int idx,
5712-                const char* name, const char* title, const char* desc,
5713-                SANE_Unit unit, SANE_Int cap,
5714:                const SANE_Word* valid_list, const SANE_Range* valid_range,
5715-                SANE_Int* value, SANE_Int value_len)
5716-{
5717-  s->opt[idx].name = name;
5718-  s->opt[idx].title = title;
5719-  s->opt[idx].desc = desc;
5720-  s->opt[idx].type = SANE_TYPE_INT;
5721-  s->opt[idx].unit = unit;
5722:  s->opt[idx].size = value_len * sizeof (SANE_Word);
5723-  s->opt[idx].cap = cap;
5724-  if (valid_list) {
5725-    s->opt[idx].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5726-    s->opt[idx].constraint.word_list = valid_list;
5727-  }
--
5737-  
5738-static void
5739-init_option_fix (Avision_Scanner *s, int idx,
5740-            const char* name, const char* title, const char* desc,
5741-            SANE_Unit unit, SANE_Int cap,
5742:            const SANE_Word* valid_list, const SANE_Range* valid_range,
5743-            SANE_Fixed value)
5744-{
5745-  s->opt[idx].name = name;
5746-  s->opt[idx].title = title;
5747-  s->opt[idx].desc = desc;
5748-  s->opt[idx].type = SANE_TYPE_FIXED;
5749-  s->opt[idx].unit = unit;
5750:  s->opt[idx].size = sizeof (SANE_Word);
5751-  s->opt[idx].cap = cap;
5752-  if (valid_list) {
5753-    s->opt[idx].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5754-    s->opt[idx].constraint.word_list = valid_list;
5755-  }
--
5766-#ifdef NEEDED
5767-static void
5768-init_option_fix_vec (Avision_Scanner *s, int idx,
5769-                const char* name, const char* title, const char* desc,
5770-                SANE_Unit unit, SANE_Int cap,
5771:                const SANE_Word* valid_list, const SANE_Range* valid_range,
5772-                SANE_Fixed* value, SANE_Int value_len)
5773-{
5774-  s->opt[idx].name = name;
5775-  s->opt[idx].title = title;
5776-  s->opt[idx].desc = desc;
--
5846-  s->opt[idx].name = name;
5847-  s->opt[idx].title = title;
5848-  s->opt[idx].desc = desc;
5849-  s->opt[idx].type = SANE_TYPE_BOOL;
5850-  s->opt[idx].unit = SANE_UNIT_NONE;
5851:  s->opt[idx].size = sizeof (SANE_Word);
5852-  s->opt[idx].cap = cap;
5853-  s->opt[idx].constraint_type = SANE_CONSTRAINT_NONE;
5854-  s->val[idx].w = value;
5855-}
5856-
--
5873-  
5874-  memset (s->opt, 0, sizeof (s->opt));
5875-  memset (s->val, 0, sizeof (s->val));
5876-
5877-  for (i = 0; i < NUM_OPTIONS; ++ i) {
5878:    s->opt[i].size = sizeof (SANE_Word);
5879-    s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
5880-  }
5881-  
5882-  /* Init the SANE option from the scanner inquiry data */
5883-  
--
7536-                SANE_Action action, void* val, SANE_Int* info)
7537-{
7538-  Avision_Scanner* s = handle;
7539-  Avision_Device* dev = s->hw;
7540-  SANE_Status status;
7541:  SANE_Word cap;
7542-  
7543-  DBG (3, "sane_control_option: option=%d, action=%d\n",
7544-       (int)option, (int)action);
7545-
7546-  if (info)
--
7577-            DBG (3, "sane_control_option: queried for %d (%s): %.3f\n",
7578-            option, s->opt[option].name,
7579-            (double)SANE_UNFIX(s->val[option].w));
7580-     break;
7581-   case SANE_TYPE_INT:
7582:     if (s->opt[option].size > (int)sizeof (SANE_Word)) {
7583-       int i;
7584-            DBG (3, "sane_control_option: queried for %d (%s):\n",
7585-            option, s->opt[option].name);
7586:       for (i = 0; i < (int)(s->opt[option].size/sizeof(SANE_Word)); ++i)
7587-              DBG (3, "sane_control_option:         %lu\n",
7588-              (long)s->val[option].wa[i]);
7589-     }
7590-     else
7591-            DBG (3, "sane_control_option: queried for %d (%s): %lu\n",
--
7624-   case OPT_CCT_7:
7625-   case OPT_CCT_8:
7626-   case OPT_CCT_9:
7627-   case OPT_CCT_HW:
7628-     
7629:     *(SANE_Word*) val = s->val[option].w;
7630-     return SANE_STATUS_GOOD;
7631-     
7632-     /* specially treated word options */
7633-     /* FR: shouldn't this better be a string, word array or bitmask?
7634-        having to query in order is counter-intuitive. */
--
7644-   case OPT_BUTTON_5:
7645-   case OPT_BUTTON_6:
7646-   case OPT_BUTTON_7:
7647-     
7648-     /* copy the button state */
7649:     *(SANE_Word*) val = s->val[option].w;
7650-     /* clear the button state */
7651-     s->val[option].w = SANE_FALSE;
7652-
7653-     return SANE_STATUS_GOOD;
7654-     
--
7689-            DBG (3, "sane_control_option: ordered to set %d (%s) to 
%.3f\n",
7690-            option, s->opt[option].name,
7691-            (double)SANE_UNFIX(*(SANE_Fixed*)val));
7692-     break;
7693-   case SANE_TYPE_INT:
7694:     if (s->opt[option].size > (int)sizeof (SANE_Word)) {
7695-       int i;
7696-            DBG (3, "sane_control_option: ordered to set %d (%s) to:\n",
7697-            option, s->opt[option].name);
7698:       for (i = 0; i < (int)(s->opt[option].size/sizeof(SANE_Word)); ++i)
7699-              DBG (3, "sane_control_option:         %lu\n",
7700:              (long)((SANE_Word*)val)[i]);
7701-     }
7702-     else
7703-            DBG (3, "sane_control_option: ordered to set %d (%s) to %lu\n",
7704:            option, s->opt[option].name, (long)*(SANE_Word*)val);
7705-     break;
7706-   case SANE_TYPE_BUTTON:
7707-     DBG (3, "sane_control_option: button %d (%s) activated\n",
7708-          option, s->opt[option].name);
7709-     break;
7710-   default:
7711-          DBG (3, "sane_control_option: ordered to set %d (%s) to %lu\n",
7712:          option, s->opt[option].name, (long)*(SANE_Word*)val);
7713-     break;
7714-      }
7715-      if (!SANE_OPTION_IS_SETTABLE (cap))
7716-   return SANE_STATUS_INVAL;
7717-      
--
7728-   case OPT_CONTRAST:
7729-   case OPT_QSCAN:
7730-   case OPT_QCALIB:
7731-   case OPT_CCT_HW:
7732-
7733:     s->val[option].w = *(SANE_Word*) val;
7734-     return SANE_STATUS_GOOD;
7735-
7736-   case OPT_CCT_1:
7737-   case OPT_CCT_2:
7738-   case OPT_CCT_3:
--
7740-   case OPT_CCT_5:
7741-   case OPT_CCT_6:
7742-   case OPT_CCT_7:
7743-   case OPT_CCT_8:
7744-   case OPT_CCT_9:
7745:     s->val[option].w = *(SANE_Word*) val;
7746-     set_3x3_matrix (s);
7747-     return SANE_STATUS_GOOD;
7748-     
7749-     /* side-effect-free word-array options: */
7750-   case OPT_GAMMA_VECTOR:
--
7759-   case OPT_TL_X:
7760-   case OPT_TL_Y:
7761-   case OPT_BR_X:
7762-   case OPT_BR_Y:
7763-
7764:     s->val[option].w = *(SANE_Word*) val;
7765-
7766-     if (dev->hw->feature_type & AV_WINDOW_BUG) {
7767-       if ((s->scale_mode == AV_SCALE_HWONLY) && adjust_hwdpi (s)) {
7768-         if (info)
7769-           *info |= SANE_INFO_INEXACT | SANE_INFO_RELOAD_OPTIONS;
--
7775-
7776-     return SANE_STATUS_GOOD;
7777-
7778-   case OPT_GAMMA_RELATIVE:
7779-     
7780:     if (s->val[option].w != *(SANE_Word*) val) {
7781-       int i, j;
7782-       SANE_Int* tt;
7783:       s->val[option].w = *(SANE_Word*) val;
7784-       
7785-       if (s->val[option].w)
7786-         tt = default_gamma ();
7787-       else
7788-         tt = default_inverse_gamma ();
--
7857-         *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
7858-       return SANE_STATUS_GOOD;
7859-     }
7860-   case OPT_FRAME:
7861-     {
7862:       SANE_Word frame = *((SANE_Word  *) val);
7863-       
7864-       status = set_frame (s, frame);
7865-       if (status == SANE_STATUS_GOOD) {
7866-         s->val[OPT_FRAME].w = frame;
7867-         dev->current_frame = frame;
From henn...@meier-geinitz.de  Sun Sep 25 16:41:37 2005
From: henn...@meier-geinitz.de (Henning Meier-Geinitz)
Date: Sun Sep 25 16:42:14 2005
Subject: [sane-devel] Lexmark X1100 backend available
In-Reply-To: <4335e529.9020...@rogers.com>
References: <4335e529.9020...@rogers.com>
Message-ID: <20050925164137.gd29...@meier-geinitz.de>

Hi,

On Sat, Sep 24, 2005 at 07:45:45PM -0400, Fred Odendaal wrote:
> I've put a patch file for the Lexmark X1100 backend on my website. 
> Instructions for getting it are at 
> http://ca.geocities.com/freshsh...@rogers.com/scanner_driver/download.html

Ok, let's have a look (I only mention stuff that hasn't already been
listed by other people):

AUTHORS:
  - your email address is missing

configure.in
  - is missing (ok, for now it's ok but the final patch that should go
    to CVS should have configure.in patched, not configure)

backend/Makefile.in:
  | libsane-lexmark.la: $(addsuffix .lo,$(EXTRA_lexmark))
  See below for comments.

  | libsane-lexmark.la: ../sanei/sanei_config2.lo
  Are you sure that you need this (this is used for SCSI devices) 

backend/lexmark.c
  | static SANE_String_Const mode_list[] = {
  |   "Color", "Gray", "Black & White", NULL
  | };  
  "Lineart" is used in most backends instead of "Black & White". See
  also include/saneopts.h:
  #define SANE_VALUE_SCAN_MODE_COLOR              SANE_I18N("Color")
  #define SANE_VALUE_SCAN_MODE_GRAY               SANE_I18N("Gray")
  #define SANE_VALUE_SCAN_MODE_LINEART            SANE_I18N("Lineart")

  | SANE_Status
  | init_options (Lexmark_Device * lexmark_device)
  All functions that are not part of the SANE API must be either
  static or start with "sanei_lexmark_". I would make everything
  static and only rename the functions in lexmark-x1100.c that are
  called from lexmark.c "sanei_lexmark_". Or, as a workaround, just
  #include lexmark-x1100.c in lexmark.c and make everything but the
  API functions static. See doc/backend-writing.txt for details.

  | sane_init
  In my experience it's a good idea to print the version/build number of
  the backend in a DBG message. That way you always know what version
  was used when you get a bug report. For an example, see gt68xx.c.

  | in sane_start
  | sane_get_parameters (handle, 0);
  check return value?  
  |if ((lexmark_device->params.lines == 0) ||
  |    (lexmark_device->params.pixels_per_line == 0) ||
  |    (lexmark_device->params.bytes_per_line == 0))
  |  return SANE_STATUS_INVAL;      
  A DBG message twelling what's wrong would be nice.

backend/lexmark-x1100.c:
  - no problems found
  
One additional thing: You could write a test for the chipset used in
these scanners in tools/check-usb-chip.c. That way it's easy to find
out which other scanners also use the same chipset.

Once you have implemented the changes mentioned here and you have a
manual page, please provide another patch so the backend can be
included into CVS.

Bye,
  Henning

Reply via email to