Hi guys and girls
Having some spare time, I looked again into the Qcam code and made some
fixes to get the BW QuickCam working better.
The BW Qcam did only return one frame when operated from xcam. Somehow
the Cam needs to be resetted before getting a new frame. So I put a
qc_reset in sane_start for non-color Qcams. I remember that I read
something about a "special" treatment to get continous frames from a BW
Qcam. Is resetting it the right thing to do before getting the next
frame or was there any other magic? Unfortunatly I do not have the
specs.
There was also the problem of getting a "diagonal" picture with some
resolutions and bitdepths. I chose the "normal" framesize for BW
Qcams (320x240) and get a right picture with nearly every transferscale
and bitdepth (except bidir and a bitdepth of 4). I still do not
understand why this is so. When trying different framesizes you can
observe that some will result in diagonal pictures and some not. By now
I did not see any major differences between SANE and qcam-0.91 which I
use for comparison, but I try to investigate this further.
There is also one problem left when changing the bitdepth when xcam is
constantly aquiring images. After changing the bitdepth you just get
snow or it hangs.
I also disabled some options which are not supported by the BW Qcam and
chose some better default values for brightness, whitebalance and
contrast on the BW Qcam.
Hoping this makes the BW Qcam a bit more usable with SANE I attached
the diffs for qcam.h and qcam.c.
Ciao
Guido
-- __/\ ______________________________________ Guido Muesch \/ odiug@faho.rwth-aachen.de---2105130183-269167349-877292452=:579 Content-Type: TEXT/plain; CHARSET=US-ASCII Content-Description: qcam.h.diff
*** qcam.h.orig Fri Oct 17 14:37:22 1997 --- qcam.h Fri Oct 17 14:42:54 1997 *************** *** 76,88 **** QC_SET_NUM_V = 17, QC_SET_NUM_H = 19, QC_SEND_VERSION = 23, - QC_BW_SET_CONTRAST = 25, - QC_BW_AUTO_ADJUST_OFFSET = 27, QC_SET_BLACK = 29, QC_SET_WHITE = 31, - QC_BW_GET_OFFSET = 33, QC_SET_SATURATION = 35, - QC_SET_CONTRAST = 37, QC_SEND_STATUS = 41, QC_SET_SPEED = 45 } --- 76,84 ----
---2105130183-269167349-877292452=:579 Content-Type: TEXT/plain; CHARSET=US-ASCII Content-Description: qcam.c.diff
*** qcam.c.orig Fri Oct 17 14:37:16 1997 --- qcam.c Fri Oct 17 23:25:36 1997 *************** *** 191,196 **** --- 191,201 ---- {1, 499, 2}, /* billion mode */ }; + static const SANE_Range bw_x_range = {0, 334, 2}; + static const SANE_Range odd_bw_x_range = {1, 335, 2}; + static const SANE_Range bw_y_range = {0, 241, 1}; + static const SANE_Range odd_bw_y_range = {1, 242, 1}; + #ifdef __linux__ #if __GNU_LIBRARY__ - 0 < 6 *************** *** 799,806 **** --- 804,813 ---- /* Don't do this in sane_start() since there may be a long timespan between it and the first sane_read(), which would result in poor images. */ + qc_send (q, QC_SEND_VIDEO_FRAME); qc_send (q, req.mode); + if (req.despeckle && (!extra || buffer_size < num_bytes || buffer_size >= 2*num_bytes)) *************** *** 1185,1192 **** s->opt[OPT_DEPTH].type = SANE_TYPE_INT; s->opt[OPT_DEPTH].unit = SANE_UNIT_BIT; s->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; ! s->opt[OPT_DEPTH].constraint.word_list = mono_depth_list; ! s->val[OPT_DEPTH].w = mono_depth_list[NELEMS(mono_depth_list) - 1]; /* test */ s->opt[OPT_TEST].name = "test-image"; --- 1192,1199 ---- s->opt[OPT_DEPTH].type = SANE_TYPE_INT; s->opt[OPT_DEPTH].unit = SANE_UNIT_BIT; s->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; ! s->opt[OPT_DEPTH].constraint.word_list = color_depth_list; ! s->val[OPT_DEPTH].w = color_depth_list[NELEMS(color_depth_list) - 1]; /* test */ s->opt[OPT_TEST].name = "test-image"; *************** *** 1203,1209 **** s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; s->opt[OPT_GEOMETRY_GROUP].desc = ""; s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; ! s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; /* top-left x */ --- 1210,1216 ---- s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; s->opt[OPT_GEOMETRY_GROUP].desc = ""; s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; ! s->opt[OPT_GEOMETRY_GROUP].cap = 0; /*SANE_CAP_ADVANCED;*/ s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; /* top-left x */ *************** *** 1461,1472 **** if (s->hw->version == QC_COLOR) { s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE; - s->opt[OPT_DEPTH].constraint.word_list = color_depth_list; - s->val[OPT_DEPTH].w = color_depth_list[NELEMS(color_depth_list) - 1]; } else { s->opt[OPT_DESPECKLE].cap |= SANE_CAP_INACTIVE; } /* insert newly opened handle into list of open handles: */ --- 1468,1502 ---- if (s->hw->version == QC_COLOR) { s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE; } + /* Black level, Hue and Saturation are things the b&w cameras know nothing + about. + Despeckle might be useful, but this code seems to work for + color cameras only right now + The framesize seems to work better in these ranges.*/ else { s->opt[OPT_DESPECKLE].cap |= SANE_CAP_INACTIVE; + s->opt[OPT_BLACK_LEVEL].cap |= SANE_CAP_INACTIVE; + s->opt[OPT_HUE].cap |= SANE_CAP_INACTIVE; + s->opt[OPT_SATURATION].cap |= SANE_CAP_INACTIVE; + s->opt[OPT_RESOLUTION].cap |= SANE_CAP_INACTIVE; + s->opt[OPT_TEST].cap |= SANE_CAP_INACTIVE; + + s->opt[OPT_DEPTH].constraint.word_list = mono_depth_list; + s->val[OPT_DEPTH].w = mono_depth_list[NELEMS(mono_depth_list) - 1]; + s->opt[OPT_TL_X].constraint.range = &bw_x_range; + s->val[OPT_TL_X].w = 14; + s->opt[OPT_TL_Y].constraint.range = &bw_y_range; + s->val[OPT_TL_Y].w = 0; + s->opt[OPT_BR_X].constraint.range = &odd_bw_x_range; + s->val[OPT_BR_X].w = 333; + s->opt[OPT_BR_Y].constraint.range = &odd_bw_y_range; + s->val[OPT_BR_Y].w = 239; + + s->val[OPT_BRIGHTNESS].w = 170; + s->val[OPT_CONTRAST].w = 150; + s->val[OPT_WHITE_LEVEL].w = 150; } /* insert newly opened handle into list of open handles: */ *************** *** 1813,1823 **** } } if (s->value_changed & (1 << OPT_CONTRAST)) { s->value_changed &= ~(1 << OPT_CONTRAST); qc_send (q, ((q->version == QC_COLOR) ! ? QC_SET_CONTRAST : QC_BW_SET_CONTRAST)); qc_send (q, s->val[OPT_CONTRAST].w); } --- 1843,1856 ---- } } + if (q->version != QC_COLOR) + qc_reset(q); + if (s->value_changed & (1 << OPT_CONTRAST)) { s->value_changed &= ~(1 << OPT_CONTRAST); qc_send (q, ((q->version == QC_COLOR) ! ? QC_COL_SET_CONTRAST : QC_MONO_SET_CONTRAST)); qc_send (q, s->val[OPT_CONTRAST].w); } *************** *** 1860,1866 **** } else { ! val = undecimated_width * 4; val2 = ((q->port_mode == QC_BIDIR) ? 24 : 8) * s->val[OPT_XFER_SCALE].w; } --- 1893,1899 ---- } else { ! val = undecimated_width * s->val[OPT_DEPTH].w; val2 = ((q->port_mode == QC_BIDIR) ? 24 : 8) * s->val[OPT_XFER_SCALE].w; }
---2105130183-269167349-877292452=:579--
-- Source code, list archive, and docs: http://www.mostang.com/sane/ To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com