예제 #1
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int *info)
{
  Tamarack_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;

  if (info)
    *info = 0;

  if (s->scanning)
    return SANE_STATUS_DEVICE_BUSY;

  if (option >= NUM_OPTIONS)
    return SANE_STATUS_INVAL;

  cap = s->opt[option].cap;

  if (!SANE_OPTION_IS_ACTIVE (cap))
    return SANE_STATUS_INVAL;

  if (action == SANE_ACTION_GET_VALUE) {
    switch (option) {
      /* word options: */
    case OPT_PREVIEW:
    case OPT_GRAY_PREVIEW:
    case OPT_RESOLUTION:
    case OPT_TL_X:
    case OPT_TL_Y:
    case OPT_BR_X:
    case OPT_BR_Y:
    case OPT_NUM_OPTS:
    case OPT_TRANS:
    case OPT_BRIGHTNESS:
    case OPT_CONTRAST:
    case OPT_THRESHOLD:
#if 0
    case OPT_CUSTOM_GAMMA:
#endif
      *(SANE_Word *) val = s->val[option].w;
      return SANE_STATUS_GOOD;

#if 0
      /* word-array options: */
    case OPT_GAMMA_VECTOR:
    case OPT_GAMMA_VECTOR_R:
    case OPT_GAMMA_VECTOR_G:
    case OPT_GAMMA_VECTOR_B:
      memcpy (val, s->val[option].wa, s->opt[option].size);
      return SANE_STATUS_GOOD;
#endif

      /* string options: */
    case OPT_MODE:
      strcpy (val, s->val[option].s);
      return SANE_STATUS_GOOD;
    }
  } else if (action == SANE_ACTION_SET_VALUE) {
    if (!SANE_OPTION_IS_SETTABLE (cap))
      return SANE_STATUS_INVAL;

    status = constrain_value (s, option, val, info);
    if (status != SANE_STATUS_GOOD)
      return status;
    
    switch (option)
      {
	/* (mostly) side-effect-free word options: */
      case OPT_RESOLUTION:
      case OPT_TL_X:
      case OPT_TL_Y:
      case OPT_BR_X:
      case OPT_BR_Y:
	if (info)
	  *info |= SANE_INFO_RELOAD_PARAMS;
	/* fall through */
      case OPT_PREVIEW:
      case OPT_GRAY_PREVIEW:
      case OPT_BRIGHTNESS:
      case OPT_CONTRAST:
      case OPT_THRESHOLD:
      case OPT_TRANS:
	s->val[option].w = *(SANE_Word *) val;
	return SANE_STATUS_GOOD;

#if 0
	/* side-effect-free word-array options: */
      case OPT_GAMMA_VECTOR:
      case OPT_GAMMA_VECTOR_R:
      case OPT_GAMMA_VECTOR_G:
      case OPT_GAMMA_VECTOR_B:
	memcpy (s->val[option].wa, val, s->opt[option].size);
	return SANE_STATUS_GOOD;

	/* options with side-effects: */

      case OPT_CUSTOM_GAMMA:
	w = *(SANE_Word *) val;
	if (w == s->val[OPT_CUSTOM_GAMMA].w)
	  return SANE_STATUS_GOOD;		/* no change */

	s->val[OPT_CUSTOM_GAMMA].w = w;
	if (w) {
	  s->mode = make_mode (s->val[OPT_MODE].s);

	  if (s->mode == GREYSCALE) {
	    s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
	  } else if (s->mode == TRUECOLOR) {
	    s->opt[OPT_GAMMA_VECTOR].cap   &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
	  }
	} else {
	  s->opt[OPT_GAMMA_VECTOR].cap   |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
	}
	if (info)
	  *info |= SANE_INFO_RELOAD_OPTIONS;
	return SANE_STATUS_GOOD;
#endif

      case OPT_MODE:
	{

	  if (s->val[option].s)
	    free (s->val[option].s);
	  s->val[option].s = strdup (val);

	  s->mode = make_mode (s->val[OPT_MODE].s);

	  if (info)
	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;

	  s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_CONTRAST].cap   |= SANE_CAP_INACTIVE;
	  s->opt[OPT_THRESHOLD].cap  |= SANE_CAP_INACTIVE;
#if 0
	  s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
#endif


	  if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0) 
	    s->opt[OPT_THRESHOLD].cap  &= ~SANE_CAP_INACTIVE;
	  else {
	    s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
	    s->opt[OPT_CONTRAST].cap   &= ~SANE_CAP_INACTIVE;
	  }
#if 0
	  if (!binary)
	    s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;

	  if (s->val[OPT_CUSTOM_GAMMA].w) {
	    if (strcmp (val, SANE_VALUE_SCAN_MODE_GRAY) == 0)
	      s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
	    else if (strcmp (val, SANE_VALUE_SCAN_MODE_COLOR) == 0) {
	      s->opt[OPT_GAMMA_VECTOR].cap   &= ~SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
	    }
	  }
#endif
	  return SANE_STATUS_GOOD;
	}
      }
    }
  return SANE_STATUS_INVAL;
}
예제 #2
0
TEST(MathTest, Constrain)
{
    for (int i = 0; i < 1000; i++) {
        if (i < 250) {
            EXPECT_EQ(250, constrain_float(i, 250, 500));
            EXPECT_EQ(250, constrain_int16(i, 250, 500));
            EXPECT_EQ(250, constrain_int32(i, 250, 500));
        } else if (i > 500) {
            EXPECT_EQ(500, constrain_float(i, 250, 500));
            EXPECT_EQ(500, constrain_int16(i, 250, 500));
            EXPECT_EQ(500, constrain_int32(i, 250, 500));
        } else {
            EXPECT_EQ(i, constrain_float(i, 250, 500));
            EXPECT_EQ(i, constrain_int16(i, 250, 500));
            EXPECT_EQ(i, constrain_int32(i, 250, 500));
        }
    }

    for (int i = 0; i <= 1000; i++) {
        int c = i - 1000;
        if (c < -250) {
            EXPECT_EQ(-250, constrain_float(c, -250, -50));
            EXPECT_EQ(-250, constrain_int16(c, -250, -50));
            EXPECT_EQ(-250, constrain_int32(c, -250, -50));
        } else if(c > -50) {
            EXPECT_EQ(-50, constrain_float(c, -250, -50));
            EXPECT_EQ(-50, constrain_int16(c, -250, -50));
            EXPECT_EQ(-50, constrain_int32(c, -250, -50));
        } else {
            EXPECT_EQ(c, constrain_float(c, -250, -50));
            EXPECT_EQ(c, constrain_int16(c, -250, -50));
            EXPECT_EQ(c, constrain_int32(c, -250, -50));
        }
    }

    for (int i = 0; i <= 2000; i++) {
        int c = i - 1000;
        if (c < -250) {
            EXPECT_EQ(-250, constrain_float(c, -250, 50));
            EXPECT_EQ(-250, constrain_int16(c, -250, 50));
            EXPECT_EQ(-250, constrain_int32(c, -250, 50));
        } else if(c > 50) {
            EXPECT_EQ(50, constrain_float(c, -250, 50));
            EXPECT_EQ(50, constrain_int16(c, -250, 50));
            EXPECT_EQ(50, constrain_int32(c, -250, 50));
        } else {
            EXPECT_EQ(c, constrain_float(c, -250, 50));
            EXPECT_EQ(c, constrain_int16(c, -250, 50));
            EXPECT_EQ(c, constrain_int32(c, -250, 50));
        }
    }

    EXPECT_EQ(20.0, constrain_value(20.0, 19.9, 20.1));
    EXPECT_EQ(20.0, constrain_value(20.0f, 19.9f, 20.1f));

    EXPECT_EQ(19.9, constrain_value(19.9, 19.9, 20.1));
    EXPECT_EQ(19.9f, constrain_value(19.9f, 19.9f, 20.1f));

    EXPECT_EQ(19.9, constrain_value(19.8, 19.9, 20.1));
    EXPECT_EQ(19.9f, constrain_value(19.8f, 19.9f, 20.1f));
}