diff options
Diffstat (limited to 'backend/plustek-usbcalfile.c')
-rw-r--r-- | backend/plustek-usbcalfile.c | 845 |
1 files changed, 845 insertions, 0 deletions
diff --git a/backend/plustek-usbcalfile.c b/backend/plustek-usbcalfile.c new file mode 100644 index 0000000..5638b2e --- /dev/null +++ b/backend/plustek-usbcalfile.c @@ -0,0 +1,845 @@ +/*............................................................................. + * Project : SANE library for Plustek flatbed scanners. + *............................................................................. + */ + +/** @file plustek-usbcalfile.c + * @brief Functions for saving/restoring calibration settings + * + * Copyright (C) 2001-2007 Gerhard Jaeger <gerhard@gjaeger.de> + * + * History: + * - 0.46 - first version + * - 0.47 - no changes + * - 0.48 - no changes + * - 0.49 - a_bRegs is now part of the device structure + * - 0.50 - cleanup + * - 0.51 - added functions for saving, reading and restoring + * fine calibration data + * - 0.52 - no changes + * . + * <hr> + * This file is part of the SANE package. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + * + * As a special exception, the authors of SANE give permission for + * additional uses of the libraries contained in this release of SANE. + * + * The exception is that, if you link a SANE library with other files + * to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public + * License. Your use of that executable is in no way restricted on + * account of linking the SANE library code into it. + * + * This exception does not, however, invalidate any other reasons why + * the executable file might be covered by the GNU General Public + * License. + * + * If you submit changes to SANE to the maintainers to be included in + * a subsequent release, you agree by submitting the changes that + * those changes may be distributed with this exception intact. + * + * If you write modifications of your own for SANE, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * <hr> + */ + +typedef struct { + u_long red_light_on; + u_long red_light_off; + u_long green_light_on; + u_long green_light_off; + u_long blue_light_on; + u_long blue_light_off; + u_long green_pwm_duty; + +} LightCtrl; + +typedef struct { + u_short version; + + u_short red_gain; + u_short green_gain; + u_short blue_gain; + + u_short red_offs; + u_short green_offs; + u_short blue_offs; + + LightCtrl light; + +} CalData; + +/* our shading buffers */ +static u_short a_wWhiteShading[_SHADING_BUF] = {0}; +static u_short a_wDarkShading[_SHADING_BUF] = {0}; + +/* the version the the calibration files */ +#define _PT_CF_VERSION 0x0002 + +/** function to read a text file and returns the string which starts which + * 'id' string. + * no duplicate entries where detected, always the first occurance will be + * red. + * @param fp - file pointer of file to read + * @param id - what to search for + * @param res - where to store the result upon success + * @return SANE_TRUE on success, SANE_FALSE on any error + */ +static SANE_Bool +usb_ReadSpecLine( FILE *fp, char *id, char* res ) +{ + char tmp[1024]; + char *ptr; + + /* rewind file pointer */ + if( 0 != fseek( fp, 0L, SEEK_SET)) { + DBG( _DBG_ERROR, "fseek: %s\n", strerror(errno)); + return SANE_FALSE; + } + + /* roam through the file and examine each line... */ + while( !feof( fp )) { + + memset( tmp, 0, sizeof(tmp)); + if( NULL != fgets( tmp, 1024, fp )) { + + if( 0 == strncmp( tmp, id, strlen(id))) { + + ptr = &tmp[strlen(id)]; + if( '\0' == *ptr ) + break; + + strcpy( res, ptr ); + res[strlen(res)-1] = '\0'; + return SANE_TRUE; + } + } + } + return SANE_FALSE; +} + +/** function to read data from a file and excluding certain stuff like + * the version lines + * @param fp - file pointer of file to read + * @param except - what to exclude + * @return Pointer to the allocated memory for the data, NULL on any error. + */ +static char* +usb_ReadOtherLines( FILE *fp, char *except ) +{ + char tmp[1024]; + char *ptr, *ptr_base; + int ignore; + int len; + + if( 0 != fseek( fp, 0L, SEEK_END)) + return NULL; + + len = ftell(fp); + + /* rewind file pointer */ + if( 0 != fseek( fp, 0L, SEEK_SET)) + return NULL; + + if( len == 0 ) + return NULL; + + ptr = (char*)malloc(len); + if( NULL == ptr ) + return NULL; + + ptr_base = ptr; + *ptr = '\0'; + ignore = 0; + + /* roam through the file and examine each line... */ + while( !feof( fp )) { + + if( NULL != fgets( tmp, 1024, fp )) { + + /* we ignore the version line... */ + if( 0 == strncmp( tmp, "version=", 8 )) + continue; + + if( !ignore ) { + if(0 != strncmp(tmp, except, strlen(except))) { + + if( strlen( tmp ) > 0 ) { + strcpy( ptr, tmp ); + ptr += strlen(tmp); + *ptr = '\0'; + } + } else { + ignore = 1; + } + } + + /* newline in tmp string resets ignore flag */ + if( strrchr(tmp, '\n')) { + ignore = 0; + } + } + } + return ptr_base; +} + +/** + */ +static SANE_Bool +usb_ReadSamples( FILE *fp, char *which, u_long *dim, u_short *buffer ) +{ + char *p, *next, *rb; + char tmp[1024+30]; + int ignore, diml, c; + u_long val; + + /* rewind file pointer */ + if( 0 != fseek( fp, 0L, SEEK_SET)) + return SANE_FALSE; + + ignore = 0; + diml = 0; + c = 0; + rb = tmp; + *dim = 0; + + /* roam through the file and examine each line... */ + while( !feof( fp )) { + + if( NULL != fgets( rb, 1024, fp )) { + + /* we ignore the version line... */ + if( 0 == strncmp( tmp, "version=", 8 )) + continue; + + p = tmp; + if( !ignore && diml == 0) { + if(0 == strncmp(tmp, which, strlen(which))) { + + /* get dimension */ + diml = strtol(&tmp[strlen(which)], NULL, 10); + p = strchr( &tmp[strlen(which)], ':' ); + p++; + } else { + ignore = 1; + } + } + + /* parse the values... */ + if( !ignore ) { + + rb = tmp; + while( *p ) { + val = strtoul( p, &next, 10 ); + + /* check for error condition */ + if( val == 0 ) { + if( p == next ) { + if( c+1 == diml ) { + *dim = diml; + return SANE_TRUE; + } + break; + } + } + + buffer[c] = (u_short)val; + + /* more values? */ + if( *next == ',') { + p = next+1; + c++; + } else { + p = next; + } + /* reached the end? */ + if( *next == '\0' ) { + + /* we probably have only parsed a part of a value + * so we copy that back to the input buffer and + * parse it the next time... + */ + if( c < diml ) { + sprintf( tmp, "%u", buffer[c] ); + rb = &tmp[strlen(tmp)]; + } + } + } + } + + /* newline in tmp string resets ignore flag */ + if( strrchr(tmp, '\n')) { + ignore = 0; + } + } + } + return SANE_FALSE; +} + +/** + */ +static void +usb_RestoreCalData( Plustek_Device *dev, CalData *cal ) +{ + HWDef *hw = &dev->usbDev.HwSetting; + u_char *regs = dev->usbDev.a_bRegs; + + regs[0x3b] = (u_char)cal->red_gain; + regs[0x3c] = (u_char)cal->green_gain; + regs[0x3d] = (u_char)cal->blue_gain; + regs[0x38] = (u_char)cal->red_offs; + regs[0x39] = (u_char)cal->green_offs; + regs[0x3a] = (u_char)cal->blue_offs; + + regs[0x2a] = _HIBYTE((u_short)cal->light.green_pwm_duty); + regs[0x2b] = _LOBYTE((u_short)cal->light.green_pwm_duty); + + regs[0x2c] = _HIBYTE((u_short)cal->light.red_light_on); + regs[0x2d] = _LOBYTE((u_short)cal->light.red_light_on); + regs[0x2e] = _HIBYTE((u_short)cal->light.red_light_off); + regs[0x2f] = _LOBYTE((u_short)cal->light.red_light_off); + + regs[0x30] = _HIBYTE((u_short)cal->light.green_light_on); + regs[0x31] = _LOBYTE((u_short)cal->light.green_light_on); + regs[0x32] = _HIBYTE((u_short)cal->light.green_light_off); + regs[0x33] = _LOBYTE((u_short)cal->light.green_light_off); + + regs[0x34] = _HIBYTE((u_short)cal->light.blue_light_on); + regs[0x35] = _LOBYTE((u_short)cal->light.blue_light_on); + regs[0x36] = _HIBYTE((u_short)cal->light.blue_light_off); + regs[0x37] = _LOBYTE((u_short)cal->light.blue_light_off); + + hw->red_lamp_on = (u_short)cal->light.red_light_on; + hw->red_lamp_off = (u_short)cal->light.red_light_off; + hw->green_lamp_on = (u_short)cal->light.green_light_on; + hw->green_lamp_off = (u_short)cal->light.green_light_off; + hw->blue_lamp_on = (u_short)cal->light.blue_light_on; + hw->blue_lamp_off = (u_short)cal->light.blue_light_off; +} + +/** + */ +static void +usb_CreatePrefix( Plustek_Device *dev, char *pfx, SANE_Bool add_bitdepth ) +{ + char bd[5]; + ScanDef *scanning = &dev->scanning; + ScanParam *param = &scanning->sParam; + + switch( scanning->sParam.bSource ) { + + case SOURCE_Transparency: strcpy( pfx, "tpa-" ); break; + case SOURCE_Negative: strcpy( pfx, "neg-" ); break; + case SOURCE_ADF: strcpy( pfx, "adf-" ); break; + default: pfx[0] = '\0'; break; + } + + sprintf( bd, "%u=", param->bBitDepth ); + if( param->bDataType == SCANDATATYPE_Color ) + strcat( pfx, "color" ); + else + strcat( pfx, "gray" ); + + if( add_bitdepth ) + strcat( pfx, bd ); +} + +/** function to read and set the calibration data from external file + */ +static SANE_Bool +usb_ReadAndSetCalData( Plustek_Device *dev ) +{ + char pfx[20]; + char tmp[1024]; + u_short version; + int res; + FILE *fp; + CalData cal; + SANE_Bool ret; + + DBG( _DBG_INFO, "usb_ReadAndSetCalData()\n" ); + + if( usb_InCalibrationMode(dev)) { + DBG( _DBG_INFO, "- we are in calibration mode!\n" ); + return SANE_FALSE; + } + + if( NULL == dev->calFile ) { + DBG( _DBG_ERROR, "- No calibration filename set!\n" ); + return SANE_FALSE; + } + + sprintf( tmp, "%s-coarse.cal", dev->calFile ); + DBG( _DBG_INFO, "- Reading coarse calibration data from file\n"); + DBG( _DBG_INFO, " %s\n", tmp ); + + fp = fopen( tmp, "r" ); + if( NULL == fp ) { + DBG( _DBG_ERROR, "File %s not found\n", tmp ); + return SANE_FALSE; + } + + /* check version */ + if( !usb_ReadSpecLine( fp, "version=", tmp )) { + DBG( _DBG_ERROR, "Could not find version info!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp ); + if( 1 != sscanf( tmp, "0x%04hx", &version )) { + DBG( _DBG_ERROR, "Could not decode version info!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + if( version != _PT_CF_VERSION ) { + DBG( _DBG_ERROR, "Versions do not match!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + usb_CreatePrefix( dev, pfx, SANE_TRUE ); + + ret = SANE_FALSE; + if( usb_ReadSpecLine( fp, pfx, tmp )) { + DBG( _DBG_INFO, "- Calibration data: %s\n", tmp ); + + res = sscanf( tmp, "%hu,%hu,%hu,%hu,%hu,%hu," + "%lu,%lu,%lu,%lu,%lu,%lu,%lu\n", + &cal.red_gain, &cal.red_offs, + &cal.green_gain, &cal.green_offs, + &cal.blue_gain, &cal.blue_offs, + &cal.light.red_light_on, &cal.light.red_light_off, + &cal.light.green_light_on, &cal.light.green_light_off, + &cal.light.blue_light_on, &cal.light.blue_light_off, + &cal.light.green_pwm_duty ); + + if( 13 == res ) { + usb_RestoreCalData( dev, &cal ); + ret = SANE_TRUE; + } else { + DBG( _DBG_ERROR, "Error reading coarse-calibration data, only " + "%d elements available!\n", res ); + } + } else { + DBG( _DBG_ERROR, "Error reading coarse-calibration data for " + "PFX: >%s<!\n", pfx ); + } + + fclose( fp ); + DBG( _DBG_INFO, "usb_ReadAndSetCalData() done -> %u\n", ret ); + + return ret; +} + +/** + */ +static void +usb_PrepCalData( Plustek_Device *dev, CalData *cal ) +{ + u_char *regs = dev->usbDev.a_bRegs; + + memset( cal, 0, sizeof(CalData)); + cal->version = _PT_CF_VERSION; + + cal->red_gain = (u_short)regs[0x3b]; + cal->green_gain = (u_short)regs[0x3c]; + cal->blue_gain = (u_short)regs[0x3d]; + cal->red_offs = (u_short)regs[0x38]; + cal->green_offs = (u_short)regs[0x39]; + cal->blue_offs = (u_short)regs[0x3a]; + + cal->light.green_pwm_duty = regs[0x2a] * 256 + regs[0x2b]; + + cal->light.red_light_on = regs[0x2c] * 256 + regs[0x2d]; + cal->light.red_light_off = regs[0x2e] * 256 + regs[0x2f]; + cal->light.green_light_on = regs[0x30] * 256 + regs[0x31]; + cal->light.green_light_off = regs[0x32] * 256 + regs[0x33]; + cal->light.blue_light_on = regs[0x34] * 256 + regs[0x35]; + cal->light.blue_light_off = regs[0x36] * 256 + regs[0x37]; +} + +/** function to save/update the calibration data + */ +static void +usb_SaveCalData( Plustek_Device *dev ) +{ + char pfx[20]; + char fn[1024]; + char tmp[1024]; + char set_tmp[1024]; + char *other_tmp; + u_short version; + FILE *fp; + CalData cal; + ScanDef *scanning = &dev->scanning; + + DBG( _DBG_INFO, "usb_SaveCalData()\n" ); + + /* no new data, so skip this step too */ + if( SANE_TRUE == scanning->skipCoarseCalib ) { + DBG( _DBG_INFO, "- No calibration data to save!\n" ); + return; + } + + if( NULL == dev->calFile ) { + DBG( _DBG_ERROR, "- No calibration filename set!\n" ); + return; + } + + sprintf( fn, "%s-coarse.cal", dev->calFile ); + DBG( _DBG_INFO, "- Saving coarse calibration data to file\n" ); + DBG( _DBG_INFO, " %s\n", fn ); + + usb_PrepCalData ( dev, &cal ); + usb_CreatePrefix( dev, pfx, SANE_TRUE ); + DBG( _DBG_INFO2, "- PFX: >%s<\n", pfx ); + + sprintf( set_tmp, "%s%u,%u,%u,%u,%u,%u," + "%lu,%lu,%lu,%lu,%lu,%lu,%lu\n", pfx, + cal.red_gain, cal.red_offs, + cal.green_gain, cal.green_offs, + cal.blue_gain, cal.blue_offs, + cal.light.red_light_on, cal.light.red_light_off, + cal.light.green_light_on, cal.light.green_light_off, + cal.light.blue_light_on, cal.light.blue_light_off, + cal.light.green_pwm_duty ); + + /* read complete old file if compatible... */ + other_tmp = NULL; + fp = fopen( fn, "r+" ); + if( NULL != fp ) { + + if( usb_ReadSpecLine( fp, "version=", tmp )) { + DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp ); + + if( 1 == sscanf( tmp, "0x%04hx", &version )) { + + if( version == cal.version ) { + + DBG( _DBG_INFO, "- Versions do match\n" ); + + /* read the rest... */ + other_tmp = usb_ReadOtherLines( fp, pfx ); + } else { + DBG( _DBG_INFO2, "- Versions do not match (0x%04x)\n", version ); + } + } else { + DBG( _DBG_INFO2, "- cannot decode version\n" ); + } + } else { + DBG( _DBG_INFO2, "- Version not found\n" ); + } + fclose( fp ); + } + fp = fopen( fn, "w+" ); + if( NULL == fp ) { + DBG( _DBG_ERROR, "- Cannot create file %s\n", fn ); + DBG( _DBG_ERROR, "- -> %s\n", strerror(errno)); + if( other_tmp ) + free( other_tmp ); + return; + } + + /* rewrite the file again... */ + fprintf( fp, "version=0x%04X\n", cal.version ); + if( strlen( set_tmp )) + fprintf( fp, "%s", set_tmp ); + + if( other_tmp ) { + fprintf( fp, "%s", other_tmp ); + free( other_tmp ); + } + fclose( fp ); + DBG( _DBG_INFO, "usb_SaveCalData() done.\n" ); +} + +/** + */ +static void +usb_SaveFineCalData( Plustek_Device *dev, int dpi, + u_short *dark, u_short *white, u_long vals ) +{ + char pfx[30]; + char fn[1024]; + char tmp[1024]; + char *other_tmp; + u_short version; + u_long i; + FILE *fp; + + if( NULL == dev->calFile ) { + DBG( _DBG_ERROR, "- No calibration filename set!\n" ); + return; + } + + sprintf( fn, "%s-fine.cal", dev->calFile ); + DBG( _DBG_INFO, "- Saving fine calibration data to file\n" ); + DBG( _DBG_INFO, " %s\n", fn ); + + usb_CreatePrefix( dev, pfx, SANE_FALSE ); + sprintf( tmp, "%s:%u", pfx, dpi ); + strcpy( pfx, tmp ); + DBG( _DBG_INFO2, "- PFX: >%s<\n", pfx ); + + /* read complete old file if compatible... */ + other_tmp = NULL; + fp = fopen( fn, "r+" ); + if( NULL != fp ) { + + if( usb_ReadSpecLine( fp, "version=", tmp )) { + DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp ); + + if( 1 == sscanf( tmp, "0x%04hx", &version )) { + + if( version == _PT_CF_VERSION ) { + DBG( _DBG_INFO, "- Versions do match\n" ); + + /* read the rest... */ + other_tmp = usb_ReadOtherLines( fp, pfx ); + } else { + DBG( _DBG_INFO2, "- Versions do not match (0x%04x)\n", version ); + } + } else { + DBG( _DBG_INFO2, "- cannot decode version\n" ); + } + } else { + DBG( _DBG_INFO2, "- Version not found\n" ); + } + fclose( fp ); + } + + fp = fopen( fn, "w+" ); + if( NULL == fp ) { + DBG( _DBG_ERROR, "- Cannot create file %s\n", fn ); + return; + } + + /* rewrite the file again... */ + fprintf( fp, "version=0x%04X\n", _PT_CF_VERSION ); + + if( other_tmp ) { + fprintf( fp, "%s", other_tmp ); + free( other_tmp ); + } + + fprintf( fp, "%s:dark:dim=%lu:", pfx, vals ); + for( i=0; i<vals-1; i++ ) + fprintf( fp, "%u,", dark[i]); + fprintf( fp, "%u\n", dark[vals-1]); + + fprintf( fp, "%s:white:dim=%lu:", pfx, vals ); + for( i=0; i<vals-1; i++ ) + fprintf( fp, "%u,", white[i]); + fprintf( fp, "%u\n", white[vals-1]); + + fclose( fp ); +} + +/** function to read and set the calibration data from external file + */ +static SANE_Bool +usb_ReadFineCalData( Plustek_Device *dev, int dpi, + u_long *dim_d, u_short *dark, + u_long *dim_w, u_short *white ) +{ + char pfx[30]; + char tmp[1024]; + u_short version; + FILE *fp; + + DBG( _DBG_INFO, "usb_ReadFineCalData()\n" ); + if( usb_InCalibrationMode(dev)) { + DBG( _DBG_INFO, "- we are in calibration mode!\n" ); + return SANE_FALSE; + } + + if( NULL == dev->calFile ) { + DBG( _DBG_ERROR, "- No calibration filename set!\n" ); + return SANE_FALSE; + } + + sprintf( tmp, "%s-fine.cal", dev->calFile ); + DBG( _DBG_INFO, "- Reading fine calibration data from file\n"); + DBG( _DBG_INFO, " %s\n", tmp ); + + *dim_d = *dim_w = 0; + + fp = fopen( tmp, "r" ); + if( NULL == fp ) { + DBG( _DBG_ERROR, "File %s not found\n", tmp ); + return SANE_FALSE; + } + + /* check version */ + if( !usb_ReadSpecLine( fp, "version=", tmp )) { + DBG( _DBG_ERROR, "Could not find version info!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp ); + if( 1 != sscanf( tmp, "0x%04hx", &version )) { + DBG( _DBG_ERROR, "Could not decode version info!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + if( version != _PT_CF_VERSION ) { + DBG( _DBG_ERROR, "Versions do not match!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + usb_CreatePrefix( dev, pfx, SANE_FALSE ); + + sprintf( tmp, "%s:%u:%s:dim=", pfx, dpi, "dark" ); + if( !usb_ReadSamples( fp, tmp, dim_d, dark )) { + DBG( _DBG_ERROR, "Error reading dark-calibration data!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + sprintf( tmp, "%s:%u:%s:dim=", pfx, dpi, "white" ); + if( !usb_ReadSamples( fp, tmp, dim_w, white )) { + DBG( _DBG_ERROR, "Error reading white-calibration data!\n" ); + fclose( fp ); + return SANE_FALSE; + } + + fclose( fp ); + return SANE_TRUE; +} + +/** + */ +static void +usb_get_shading_part(u_short *buf, u_long offs, u_long src_len, int dst_len) +{ + u_short *p_src, *p_dst; + int i, j; + + if (src_len == 0 || dst_len == 0) + return; + + p_dst = buf; + for (i=0; i<3; i++) { + + p_src = buf + src_len * i + offs; + + for (j=0; j<dst_len; j++) { + + *(p_dst++) = *(p_src++); + } + } +} + +/** function to read the fine calibration results from file + * and to set the correct part of the calibration buffers for + * storing in the device + * @param dev - the almigthy device structure + * @returns SANE_FALSE when the reading fails or SANE_TRUE on success + */ +static SANE_Bool +usb_FineShadingFromFile( Plustek_Device *dev ) +{ + ScanDef *scan = &dev->scanning; + ScanParam *sp = &scan->sParam; + u_short xdpi; + u_long dim_w, dim_d, offs; + + xdpi = usb_SetAsicDpiX( dev, sp->UserDpi.x ); + + if( !usb_ReadFineCalData( dev, xdpi, &dim_d, a_wDarkShading, + &dim_w, a_wWhiteShading)) { + return SANE_FALSE; + } + + /* now we need to get the correct part of the line... */ + dim_d /= 3; + dim_w /= 3; + + offs = ((u_long)sp->Origin.x * xdpi) / 300; + + usb_GetPhyPixels( dev, sp ); + + DBG( _DBG_INFO2, "FINE Calibration from file:\n" ); + DBG( _DBG_INFO2, "XDPI = %u\n", xdpi ); + DBG( _DBG_INFO2, "Dim = %lu\n", dim_d ); + DBG( _DBG_INFO2, "Pixels = %lu\n", sp->Size.dwPixels ); + DBG( _DBG_INFO2, "PhyPixels = %lu\n", sp->Size.dwPhyPixels ); + DBG( _DBG_INFO2, "Origin.X = %u\n", sp->Origin.x ); + DBG( _DBG_INFO2, "Offset = %lu\n", offs ); + + usb_get_shading_part(a_wDarkShading, offs, dim_d, sp->Size.dwPhyPixels); + usb_get_shading_part(a_wWhiteShading, offs, dim_w, sp->Size.dwPhyPixels); + + return SANE_TRUE; +} + +/** function to save the fine calibration results and to set the correct part + * of the calibration buffers for storing in the device + * @param dev - the almigthy device structure + * @param tmp_sp - intermediate scan parameter + */ +static void +usb_SaveCalSetShading( Plustek_Device *dev, ScanParam *tmp_sp ) +{ + ScanParam *sp = &dev->scanning.sParam; + u_short xdpi; + u_long offs; + + if( !dev->adj.cacheCalData ) + return; + + /* save the values */ + xdpi = usb_SetAsicDpiX( dev, tmp_sp->UserDpi.x ); + + usb_SaveFineCalData( dev, xdpi, a_wDarkShading, + a_wWhiteShading, tmp_sp->Size.dwPixels*3 ); + + /* now we need to get the correct part of the line... */ + xdpi = usb_SetAsicDpiX( dev, sp->UserDpi.x ); + offs = ((u_long)sp->Origin.x * xdpi) / 300; + usb_GetPhyPixels( dev, sp ); + + DBG( _DBG_INFO2, "FINE Calibration area after saving:\n" ); + DBG( _DBG_INFO2, "XDPI = %u\n", xdpi ); + DBG( _DBG_INFO2, "Dim = %lu\n", tmp_sp->Size.dwPixels ); + DBG( _DBG_INFO2, "Pixels = %lu\n", sp->Size.dwPixels ); + DBG( _DBG_INFO2, "PhyPixels = %lu\n", sp->Size.dwPhyPixels ); + DBG( _DBG_INFO2, "Origin.X = %u\n", sp->Origin.x ); + DBG( _DBG_INFO2, "Offset = %lu\n", offs ); + + if (!usb_InCalibrationMode(dev)) { + + usb_get_shading_part( a_wDarkShading, offs, + tmp_sp->Size.dwPixels, sp->Size.dwPhyPixels ); + usb_get_shading_part( a_wWhiteShading, offs, + tmp_sp->Size.dwPixels, sp->Size.dwPhyPixels ); + + memcpy( tmp_sp, sp, sizeof(ScanParam)); + tmp_sp->bBitDepth = 16; + + usb_GetPhyPixels( dev, tmp_sp ); + } +} + +/* END PLUSTEK-USBCALFILE.C .................................................*/ |