diff options
Diffstat (limited to 'backend/genesys_conv.c')
| -rw-r--r-- | backend/genesys_conv.c | 478 | 
1 files changed, 0 insertions, 478 deletions
| diff --git a/backend/genesys_conv.c b/backend/genesys_conv.c deleted file mode 100644 index 61f466e..0000000 --- a/backend/genesys_conv.c +++ /dev/null @@ -1,478 +0,0 @@ -/* sane - Scanner Access Now Easy. - -   Copyright (C) 2005, 2006 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> -   Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - -   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. -*/ - -/* - * Conversion filters for genesys backend - */ - - -/*8 bit*/ -#define SINGLE_BYTE -#define BYTES_PER_COMPONENT 1 -#define COMPONENT_TYPE uint8_t - -#define FUNC_NAME(f) f ## _8 - -#include "genesys_conv_hlp.c" - -#undef FUNC_NAME - -#undef COMPONENT_TYPE -#undef BYTES_PER_COMPONENT -#undef SINGLE_BYTE - -/*16 bit*/ -#define DOUBLE_BYTE -#define BYTES_PER_COMPONENT 2 -#define COMPONENT_TYPE uint16_t - -#define FUNC_NAME(f) f ## _16 - -#include "genesys_conv_hlp.c" - -#undef FUNC_NAME - -#undef COMPONENT_TYPE -#undef BYTES_PER_COMPONENT -#undef DOUBLE_BYTE - -static SANE_Status -genesys_reverse_bits( -    uint8_t *src_data, -    uint8_t *dst_data, -    size_t bytes) -{ -    size_t i; -    for(i = 0; i < bytes; i++) { -	*dst_data++ = ~ *src_data++; -    } -    return SANE_STATUS_GOOD; -} - -/** - * uses the threshold/threshold_curve to control software binarization - * This code was taken from the epjistsu backend by m. allan noah - * @param dev device set up for the scan - * @param src pointer to raw data - * @param dst pointer where to store result - * @param width width of the processed line - * */ -static SANE_Status -binarize_line(Genesys_Device * dev, uint8_t *src, uint8_t *dst, int width) -{ -  int j, windowX, sum = 0; -  int thresh; -  int offset, addCol, dropCol; -  unsigned char mask; - -  int x; -  uint8_t min, max; - -  /* normalize line */ -  min = 255; -  max = 0; -    for (x = 0; x < width; x++) -      { -	if (src[x] > max) -	  { -	    max = src[x]; -	  } -	if (src[x] < min) -	  { -	    min = src[x]; -	  } -      } - -    /* safeguard against dark or white areas */ -    if(min>80) -	    min=0; -    if(max<80) -	    max=255; -    for (x = 0; x < width; x++) -      { -	src[x] = ((src[x] - min) * 255) / (max - min); -      } - -  /* ~1mm works best, but the window needs to have odd # of pixels */ -  windowX = (6 * dev->settings.xres) / 150; -  if (!(windowX % 2)) -    windowX++; - -  /* second, prefill the sliding sum */ -  for (j = 0; j < windowX; j++) -    sum += src[j]; - -  /* third, walk the input buffer, update the sliding sum, */ -  /* determine threshold, output bits */ -  for (j = 0; j < width; j++) -    { -      /* output image location */ -      offset = j % 8; -      mask = 0x80 >> offset; -      thresh = dev->settings.threshold; - -      /* move sum/update threshold only if there is a curve */ -      if (dev->settings.threshold_curve) -	{ -	  addCol = j + windowX / 2; -	  dropCol = addCol - windowX; - -	  if (dropCol >= 0 && addCol < width) -	    { -	      sum -= src[dropCol]; -	      sum += src[addCol]; -	    } -	  thresh = dev->lineart_lut[sum / windowX]; -	} - -      /* use average to lookup threshold */ -      if (src[j] > thresh) -	*dst &= ~mask;		/* white */ -      else -	*dst |= mask;		/* black */ - -      if (offset == 7) -	dst++; -    } - -  return SANE_STATUS_GOOD; -} - -/** - * software lineart using data from a 8 bit gray scan. We assume true gray - * or monochrome scan as input. - */ -static SANE_Status -genesys_gray_lineart( -    Genesys_Device *dev, -    uint8_t *src_data, -    uint8_t *dst_data, -    size_t pixels, -    size_t lines, -    uint8_t threshold) -{ -  size_t y; - -  DBG (DBG_io2, "genesys_gray_lineart: converting %lu lines of %lu pixels\n", -       (unsigned long)lines, (unsigned long)pixels); -  DBG (DBG_io2, "genesys_gray_lineart: threshold=%d\n",threshold); - -  for (y = 0; y < lines; y++) -    { -      binarize_line (dev, src_data + y * pixels, dst_data, pixels); -      dst_data += pixels / 8; -    } -  return SANE_STATUS_GOOD; -} - -/** @brief shrink or grow scanned data to fit the final scan size - * This function shrinks the scanned data it the required resolution is lower than the hardware one, - * or grows it in case it is the opposite like when motor resolution is higher than - * sensor's one. - */ -static SANE_Status -genesys_shrink_lines_1 ( -    uint8_t *src_data, -    uint8_t *dst_data, -    unsigned int lines, -    unsigned int src_pixels, -    unsigned int dst_pixels, -    unsigned int channels) -{ -  unsigned int dst_x, src_x, y, c, cnt; -  unsigned int avg[3], val; -  uint8_t *src = (uint8_t *) src_data; -  uint8_t *dst = (uint8_t *) dst_data; - -  /* choose between case where me must reduce or grow the scanned data */ -  if (src_pixels > dst_pixels) -    { -      /* shrink data */ -      /* TODO action must be taken at bit level, no bytes */ -      src_pixels /= 8; -      dst_pixels /= 8; -      /*take first _byte_ */ -      for (y = 0; y < lines; y++) -	{ -	  cnt = src_pixels / 2; -	  src_x = 0; -	  for (dst_x = 0; dst_x < dst_pixels; dst_x++) -	    { -	      while (cnt < src_pixels && src_x < src_pixels) -		{ -		  cnt += dst_pixels; - -		  for (c = 0; c < channels; c++) -		    avg[c] = *src++; -		  src_x++; -		} -	      cnt -= src_pixels; - -	      for (c = 0; c < channels; c++) -		*dst++ = avg[c]; -	    } -	} -    } -  else -    { -      /* common case where y res is double x res */ -      for (y = 0; y < lines; y++) -	{ -	  if (2 * src_pixels == dst_pixels) -	    { -	      /* double and interleave on line */ -	      for (c = 0; c < src_pixels/8; c++) -		{ -		  /* first 4 bits */ -		  val = 0; -		  val |= (*src & 0x80) >> 0;	/* X___ ____ --> X___ ____ */ -		  val |= (*src & 0x80) >> 1;	/* X___ ____ --> _X__ ____ */ -		  val |= (*src & 0x40) >> 1;	/* _X__ ____ --> __X_ ____ */ -		  val |= (*src & 0x40) >> 2;	/* _X__ ____ --> ___X ____ */ -		  val |= (*src & 0x20) >> 2;	/* __X_ ____ --> ____ X___ */ -		  val |= (*src & 0x20) >> 3;	/* __X_ ____ --> ____ _X__ */ -		  val |= (*src & 0x10) >> 3;	/* ___X ____ --> ____ __X_ */ -		  val |= (*src & 0x10) >> 4;	/* ___X ____ --> ____ ___X */ -		  *dst = val; -		  dst++; - -		  /* last for bits */ -		  val = 0; -		  val |= (*src & 0x08) << 4;	/* ____ X___ --> X___ ____ */ -		  val |= (*src & 0x08) << 3;	/* ____ X___ --> _X__ ____ */ -		  val |= (*src & 0x04) << 3;	/* ____ _X__ --> __X_ ____ */ -		  val |= (*src & 0x04) << 2;	/* ____ _X__ --> ___X ____ */ -		  val |= (*src & 0x02) << 2;	/* ____ __X_ --> ____ X___ */ -		  val |= (*src & 0x02) << 1;	/* ____ __X_ --> ____ _X__ */ -		  val |= (*src & 0x01) << 1;	/* ____ ___X --> ____ __X_ */ -		  val |= (*src & 0x01) << 0;	/* ____ ___X --> ____ ___X */ -		  *dst = val; -		  dst++; -		  src++; -		} -	    } -	  else -	    { -	      /* TODO: since depth is 1, we must interpolate bit within bytes */ -	      DBG (DBG_warn, "%s: inaccurate bit expansion!\n", __func__); -	      cnt = dst_pixels / 2; -	      dst_x = 0; -	      for (src_x = 0; src_x < src_pixels; src_x++) -		{ -		  for (c = 0; c < channels; c++) -		    avg[c] = *src++; -		  while (cnt < dst_pixels && dst_x < dst_pixels) -		    { -		      cnt += src_pixels; -		      for (c = 0; c < channels; c++) -			*dst++ = avg[c]; -		      dst_x++; -		    } -		  cnt -= dst_pixels; -		} -	    } -	} -    } - -  return SANE_STATUS_GOOD; -} - - -/** Look in image for likely left/right/bottom paper edges, then crop image. - * Since failing to crop isn't fatal, we always return SANE_STATUS_GOOD . - */ -static SANE_Status -genesys_crop(Genesys_Scanner *s) -{ -  SANE_Status status; -  Genesys_Device *dev = s->dev; -  int top = 0; -  int bottom = 0; -  int left = 0; -  int right = 0; - -  DBG (DBG_proc, "%s: start\n", __func__); - -  /* first find edges if any */ -  status = sanei_magic_findEdges (&s->params, -				  dev->img_buffer, -				  dev->settings.xres, -				  dev->settings.yres, -				  &top, -                                  &bottom, -                                  &left, -                                  &right); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_info, "%s: bad or no edges, bailing\n", __func__); -      goto cleanup; -    } -  DBG (DBG_io, "%s: t:%d b:%d l:%d r:%d\n", __func__, top, bottom, left, -       right); - -  /* now crop the image */ -  status = -    sanei_magic_crop (&(s->params), dev->img_buffer, top, bottom, left, right); -  if (status) -    { -      DBG (DBG_warn, "%s: failed to crop\n", __func__); -      goto cleanup; -    } - -  /* update counters to new image size */ -  dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines; - -cleanup: -  DBG (DBG_proc, "%s: completed\n", __func__); -  return SANE_STATUS_GOOD; -} - -/** Look in image for likely upper and left paper edges, then rotate - * image so that upper left corner of paper is upper left of image. - * @return since failure doens't prevent scanning, we always return - * SANE_STATUS_GOOD - */ -static SANE_Status -genesys_deskew(Genesys_Scanner *s) -{ -  SANE_Status status; -  Genesys_Device *dev = s->dev; - -  int x = 0, y = 0, bg; -  double slope = 0; - -  DBG (DBG_proc, "%s: start\n", __func__); - -  bg=0; -  if(s->params.format==SANE_FRAME_GRAY && s->params.depth == 1) -    { -      bg=0xff; -    } -  status = sanei_magic_findSkew (&s->params, -				 dev->img_buffer, -				 dev->sensor.optical_res, -				 dev->sensor.optical_res, -                                 &x, -                                 &y, -                                 &slope); -  if (status!=SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: bad findSkew, bailing\n", __func__); -      return SANE_STATUS_GOOD; -    } -  DBG(DBG_info, "%s: slope=%f => %f\n",__func__,slope, (slope/M_PI_2)*90); -  /* rotate image slope is in [-PI/2,PI/2] -   * positive values rotate trigonometric direction wise */ -  status = sanei_magic_rotate (&s->params, -			       dev->img_buffer, -                               x, -                               y, -                               slope, -                               bg); -  if (status!=SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: rotate error: %s", __func__, sane_strstatus(status)); -    } - -  DBG (DBG_proc, "%s: completed\n", __func__); -  return SANE_STATUS_GOOD; -} - -/** remove lone dots - * @return since failure doens't prevent scanning, we always return - * SANE_STATUS_GOOD - */ -static SANE_Status -genesys_despeck(Genesys_Scanner *s) -{ -  if(sanei_magic_despeck(&s->params, -                         s->dev->img_buffer, -                         s->val[OPT_DESPECK].w)!=SANE_STATUS_GOOD) -  { -    DBG (DBG_error, "%s: bad despeck, bailing\n",__func__); -  } - -  return SANE_STATUS_GOOD; -} - -/** Look if image needs rotation and apply it - * */ -static SANE_Status -genesys_derotate (Genesys_Scanner * s) -{ -  SANE_Status status; -  int angle = 0; -  int resolution = s->val[OPT_RESOLUTION].w; - -  DBGSTART; -  status = sanei_magic_findTurn (&s->params, -				 s->dev->img_buffer, -				 resolution, -                                 resolution, -                                 &angle); - -  if (status) -    { -      DBG (DBG_warn, "%s: failed : %d\n", __func__, status); -      DBGCOMPLETED; -      return SANE_STATUS_GOOD; -    } - -  /* apply rotation angle found */ -  status = sanei_magic_turn (&s->params, s->dev->img_buffer, angle); -  if (status) -    { -      DBG (DBG_warn, "%s: failed : %d\n", __func__, status); -      DBGCOMPLETED; -      return SANE_STATUS_GOOD; -    } - -  /* update counters to new image size */ -  s->dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines; - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */ | 
