[sane-devel] Plans for an updated avision backend (HP7400+HP5300+Minolta Scan Dual II+???)
Martin Jelínek
mates at sirrah.troja.mff.cuni.cz
Wed Nov 14 14:05:20 GMT 2001
Oh no!
Once more, now with attachment.
m.
Martin Jelínek, Wed Nov 14, 2001 at 02:58:
> I attach a attach.c source with parsed output at debug level 3, raw bytes
> moved to debug level 5.
>
> mates
>
> Jose Paulo Moitinho de Almeida, Wed Nov 14, 2001 at 11:20:
> > On Tuesday 13 November 2001 20:49, you wrote:
> >
> > > > Hi all friends of avision!
> > >
> > > So, I applied changes, the hp7400 is in lowercase -> a little modification,
> > > otherwise, the inquiry result is (partially parsed) attached.
> > >
> > > The basic resolution of scanner is reported to be 1200, Ex res. is reported
> > > 2400.
> > >
> >
> > Hello
> >
> > I liked your parsed output! We can add a vector with (at least) the comments
> > for each byte, and put it front of the formated numbers!
> >
> > Regarding bytes 77 to 88 I had the idea that pixels should be used as units,
> > ie where the specs say (units: inches*300) we must read (units:
> > inches*max_res). You got the right dimensions. Did you change the code?
> >
> > Regards
> >
> > Ze Paulo
> _______________________________________________
> Sane-devel mailing list
> Sane-devel at www.mostang.com
> http://www.mostang.com/mailman/listinfo/sane-devel
-------------- next part --------------
static SANE_Status
attach (const char* devname, Avision_Device** devp)
{
unsigned char result [INQ_LEN];
int fd;
Avision_Device* dev;
SANE_Status status;
size_t size;
char mfg[9];
char model[17];
char rev[5];
int i;
double x_range;
double y_range;
DBG (3, "attach\n");
for (dev = first_dev; dev; dev = dev->next)
if (strcmp (dev->sane.name, devname) == 0) {
if (devp)
*devp = dev;
return SANE_STATUS_GOOD;
}
DBG (3, "attach: opening %s\n", devname);
status = sanei_scsi_open (devname, &fd, sense_handler, 0);
if (status != SANE_STATUS_GOOD) {
DBG (1, "attach: open failed (%s)\n", sane_strstatus (status));
return SANE_STATUS_INVAL;
}
DBG (3, "attach: sending INQUIRY\n");
size = sizeof (result);
status = sanei_scsi_cmd (fd, inquiry, sizeof (inquiry), result, &size);
if (status != SANE_STATUS_GOOD || size != INQ_LEN) {
DBG (1, "attach: inquiry failed (%s)\n", sane_strstatus (status));
sanei_scsi_close (fd);
return status;
}
status = wait_ready (fd);
sanei_scsi_close (fd);
if (status != SANE_STATUS_GOOD)
return status;
/* copy string information - and build zero terminated c-strings */
memcpy (&mfg, result + 8, 8);
mfg [8] = 0;
memcpy (&model, result + 16, 16);
model [16] = 0;
memcpy (&rev, result + 32, 4);
rev [4] = 0;
// shorten strings ( -1 for last index; -1 for last 0; >0 becasue one char at least))
for (i = sizeof (mfg) - 2; i > 0; i--) {
if (mfg[i] == 0x20)
mfg[i] = 0;
else
break;
}
for (i = sizeof (model) - 2; i > 0; i--) {
if (model[i] == 0x20)
model[i] = 0;
else
break;
}
DBG (1, "attach: Inquiry gives mfg=%s, model=%s, product revision=%s.\n", &mfg, &model, &rev);
if (strcmp (mfg, "AVISION") != 0 &&
strcmp (mfg, "HP") != 0 &&
strcmp (mfg, "hp") != 0 &&
strcmp (mfg, "MINOLTA") != 0)
{
DBG (1, "attach: device doesn't look like an AVISION (or OEM) scanner!\n");
return SANE_STATUS_INVAL;
}
if (strcmp (model, "AV630CS") != 0 &&
strcmp (model, "AV620CS") != 0 &&
strcmp (model, "ScanJet 5370C") != 0 &&
strcmp (model, "scanjet 7400c") != 0 &&
strcmp (model, "FS-V1") != 0)
{
DBG (1, "attach: model is not in the list of supported model!\n");
DBG (1, "attach You might want to report this output.\n");
return SANE_STATUS_INVAL;
}
dev = malloc (sizeof (*dev));
if (!dev)
return SANE_STATUS_NO_MEM;
memset (dev, 0x0, sizeof (*dev));
dev->sane.name = strdup (devname);
dev->sane.vendor = strdup (mfg);
dev->sane.model = strdup (model);
if (strcmp (model, "FS-V1") != 0)
{
dev->sane.type = "flatbed scanner";
}
else
{
/* The coolscan backend says "slide scanner", the canon says "film scanner"
deciding on a name would be useful? */
dev->sane.type = "slide scanner";
}
# define BIT(n, p) ((n & ( 1 << p))?1:0)
for (i=0; i<sizeof(result); i++) {
DBG (6, "result[%3d] %1d%1d%1d%1d%1d%1d%1d%1db %3oo %3dd %2xx\n", i, BIT(result[i],7),
BIT(result[i],6), BIT(result[i],5), BIT(result[i],4), BIT(result[i],3), BIT(result[i],2),
BIT(result[i],1), BIT(result[i],0), result[i], result[i], result[i]);
}
DBG (3, "attach: [8-15] Vendor id.: \"%8.8s\"\n", result+8);
DBG (3, "attach: [16-31] Product id.: \"%8.8s\"\n", result+16);
DBG (3, "attach: [32-35] Product rev.: \"%4.4s\"\n", result+32);
// [36]
DBG (3, "attach: [37] Optical res.: %d00dpi\n", result[37]);
DBG (3, "attach: [38] Maximum res.: %d00dpi\n", result[38]);
// [39]
DBG (3, "attach: [40-41] X res. in gray: %ddpi\n", (result[40]<<8)+result[41]);
DBG (3, "attach: [42-43] Y res. in gray: %ddpi\n", (result[42]<<8)+result[43]);
DBG (3, "attach: [44-45] X res. in color: %ddpi\n", (result[44]<<8)+result[45]);
DBG (3, "attach: [46-47] Y res. in color: %ddpi\n", (result[46]<<8)+result[47]);
DBG (3, "attach: [48-49] USB max read: %d\n", (result[48]<<8)+result[49]);
DBG (3, "attach: [50] ESA1:%s%s%s%s%s%s%s%s\n",
BIT(result[50],7)?" LIGHT":"",
BIT(result[50],6)?" BUTTON":"",
BIT(result[50],5)?" NEED_SW_COLORPACK":"",
BIT(result[50],4)?" SW_CALIB":"",
BIT(result[50],3)?" NEED_SW_GAMMA":"",
BIT(result[50],2)?" KEEPS_GAMMA":"",
BIT(result[50],1)?" KEEPS_WINDOW_CMD":"",
BIT(result[50],0)?" XYRES_DIFFERENT":"");
DBG (3, "attach: [51] ESA2:%s%s%s%s%s%s%s%s\n",
BIT(result[51],7)?" EXPOSURE_CTRL":"",
BIT(result[51],6)?" NEED_SW_TRIGGER_CAL":"",
BIT(result[51],5)?" NEED_WHITE_PAPER":"",
BIT(result[51],4)?" SUPP_QUALITY_SPEED_CAL":"",
BIT(result[51],3)?" NEED_TRANSP_CAL":"",
BIT(result[51],2)?" HAS_PUSH_BUTTON":"",
BIT(result[51],1)?" NEW_CAL_METHOD":"",
BIT(result[51],0)?" ADF_MIRRORS":"");
DBG (3, "attach: [52] ESA3:%s%s%s%s%s%s%s\n",
BIT(result[52],7)?" GRAY_WHITE":"",
BIT(result[52],5)?" TET":"",
BIT(result[52],4)?" 3x3COL_TABLE":"",
BIT(result[52],3)?" 1x3FILTER":"",
BIT(result[52],2)?" INDEX_COLOR":"",
BIT(result[52],1)?" POWER_SAVING_TIMER":"",
BIT(result[52],0)?" NVM_DATA_REC":"");
/* print some more scanner features/params */
DBG (3, "attach: [53] line difference (software color pack): %d\n", result[53]);
DBG (3, "attach: [54] color mode pixel boundary: %d\n", result[54]);
DBG (3, "attach: [55] grey mode pixel boundary: %d\n", result[55]);
DBG (3, "attach: [60] channels per pixel:%s%s\n",
BIT(result[60],7)?" 1":"",
BIT(result[60],6)?" 3":"");
DBG (3, "attach: [61] bits per channel:%s%s%s%s%s%s%s\n",
BIT(result[61],7)?" 1":"",
BIT(result[61],6)?" 4":"",
BIT(result[61],5)?" 6":"",
BIT(result[61],4)?" 8":"",
BIT(result[61],3)?" 10":"",
BIT(result[61],2)?" 12":"",
BIT(result[61],1)?" 16":"");
DBG (3, "attach: [89-90] Res. in Ex. mode: %ddpi\n", (result[89]<<8)+result[90]);
/* Get max X and max Y ...*/
/* Instead of dividing by 300 I would divide by
( optical_resolution = ((unsigned int)result[89] << 8) + (unsigned int)result[90] )
I would assume that the document is not correct.
For my scanner optical_resolution is (11<<8+4)=2820
Is this correct for other scanners? The 7400 does 2400dpi I think. What values are reported?
*/
x_range = ( ( ( (unsigned int)result[81] << 8) + (unsigned int)result[82] ) / 300 ) * MM_PER_INCH;
y_range = ( ( ( (unsigned int)result[83] << 8) + (unsigned int)result[84] ) / 300 ) * MM_PER_INCH;
dev->x_range.max = SANE_FIX (x_range);
dev->y_range.max = SANE_FIX (y_range);
dev->x_range.quant = 0;
dev->y_range.quant = 0;
dev->dpi_range.min = 50;
dev->dpi_range.quant = 1;
dev->dpi_range.max = 1200; /* Change as above? */
DBG (3, "attach: found AVISION scanner model %s (%s)\n", dev->sane.model, dev->sane.type);
DBG (3, " X-Range: %fmm, Y-Range: %fmm (Raw-Range: %d, %d, %d, %d)\n",
SANE_UNFIX (dev->x_range.max),
SANE_UNFIX (dev->y_range.max),
(int)result[81], (int)result[82], (int)result[83], (int)result[84]);
DBG (5, "RAW.Result:\n");
for (i = 0; i < sizeof (result); i++)
{
DBG (5, "[%d]:%x->""%c""\n", i, (unsigned char) result[i], result[i]);
}
/* check if x/y range is vaild :-((( */
/* These checks are very dangerous for a negative (24x36 mm!!)
What is the best approach? Use dev->sane.type or a variable?
Then use a large if that controls this ? */
if (dev->x_range.max == 0 || dev->y_range.max == 0)
{
DBG (1, "Inquiry x/y-range is invaild! Using defauld %fx%finch (ISO A4).\n", MAX_X_RANGE, MAX_Y_RANGE);
dev->x_range.max = SANE_FIX (MAX_X_RANGE * MM_PER_INCH);
dev->y_range.max = SANE_FIX (MAX_Y_RANGE * MM_PER_INCH);
}
else
DBG (3, "Inquiry x/y-range is vaild?!?\n");
if (force_a4)
{
DBG (1, "option: \"force_a4\" found! Using defauld %fx%finch (ISO A4).\n",
MAX_X_RANGE, MAX_Y_RANGE);
dev->x_range.max = SANE_FIX (MAX_X_RANGE * MM_PER_INCH);
dev->y_range.max = SANE_FIX (MAX_Y_RANGE * MM_PER_INCH);
}
++num_devices;
dev->next = first_dev;
first_dev = dev;
if (devp)
*devp = dev;
return SANE_STATUS_GOOD;
}
More information about the sane-devel
mailing list