Lines Matching refs:scanner

77 static void pieusb_calculate_shading(struct Pieusb_Scanner *scanner, SANE_Byte* buffer);
88 static void updateGain(Pieusb_Scanner *scanner, int color_index);
90 static void updateGain2(Pieusb_Scanner *scanner, int color_index, double gain_increase);
104 /* Settings for scanner capabilities */
111 /* Available scanner options */
261 DBG (DBG_error, "sanei_pieusb_find_device_callback: get scanner properties (5 bytes) failed with %d\n", status.pieusb_status);
269 DBG (DBG_error, "sanei_pieusb_find_device_callback: get scanner properties failed\n");
295 /* Found a supported scanner, put it in the definitions list*/
339 dev->sane.type = "film scanner";
615 * Initiaize scanner options from the device definition and from exposure,
617 * optimized settings are available yet. The scanner object is fully
620 * @param scanner Scanner to initialize
624 sanei_pieusb_init_options (Pieusb_Scanner* scanner)
630 memset (scanner->opt, 0, sizeof (scanner->opt));
631 memset (scanner->val, 0, sizeof (scanner->val));
634 scanner->opt[i].size = sizeof (SANE_Word);
635 scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
639 scanner->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
640 scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
641 scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
642 scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
643 scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
644 scanner->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
647 scanner->opt[OPT_MODE_GROUP].title = "Scan Mode";
648 scanner->opt[OPT_MODE_GROUP].desc = "";
649 scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
650 scanner->opt[OPT_MODE_GROUP].cap = 0;
651 scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
654 scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
655 scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
656 scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
657 scanner->opt[OPT_MODE].type = SANE_TYPE_STRING;
658 scanner->opt[OPT_MODE].size = max_string_size ((SANE_String_Const const *) scanner->device->scan_mode_list);
659 scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
660 scanner->opt[OPT_MODE].constraint.string_list = (SANE_String_Const const *) scanner->device->scan_mode_list;
661 scanner->val[OPT_MODE].s = (SANE_Char *) strdup (scanner->device->scan_mode_list[3]); /* default RGB */
664 scanner->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
665 scanner->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
666 scanner->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
667 scanner->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT;
668 scanner->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
669 scanner->opt[OPT_BIT_DEPTH].size = sizeof (SANE_Word);
670 scanner->opt[OPT_BIT_DEPTH].constraint.word_list = scanner->device->bpp_list;
671 scanner->val[OPT_BIT_DEPTH].w = scanner->device->bpp_list[2];
674 scanner->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
675 scanner->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
676 scanner->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
677 scanner->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
678 scanner->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
679 scanner->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
680 scanner->opt[OPT_RESOLUTION].constraint.range = &scanner->device->dpi_range;
681 scanner->val[OPT_RESOLUTION].w = scanner->device->fast_preview_resolution << SANE_FIXED_SCALE_SHIFT;
684 scanner->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN;
685 scanner->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN;
686 scanner->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN;
687 scanner->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING;
688 scanner->opt[OPT_HALFTONE_PATTERN].size = max_string_size ((SANE_String_Const const *) scanner->device->halftone_list);
689 scanner->opt[OPT_HALFTONE_PATTERN].constraint_type = SANE_CONSTRAINT_STRING_LIST;
690 scanner->opt[OPT_HALFTONE_PATTERN].constraint.string_list = (SANE_String_Const const *) scanner->device->halftone_list;
691 scanner->val[OPT_HALFTONE_PATTERN].s = (SANE_Char *) strdup (scanner->device->halftone_list[6]);
692 scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE; /* Not implemented, and only meaningful at depth 1 */
695 scanner->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
696 scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
697 scanner->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
698 scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED;
699 scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT;
700 scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
701 scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100;
702 scanner->val[OPT_THRESHOLD].w = SANE_FIX (50);
703 /* scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; Not implemented, and only meaningful at depth 1 */
706 scanner->opt[OPT_SHARPEN].name = "sharpen";
707 scanner->opt[OPT_SHARPEN].title = "Sharpen scan";
708 scanner->opt[OPT_SHARPEN].desc = "Sharpen scan by taking more time to discharge the CCD.";
709 scanner->opt[OPT_SHARPEN].type = SANE_TYPE_BOOL;
710 scanner->opt[OPT_SHARPEN].unit = SANE_UNIT_NONE;
711 scanner->opt[OPT_SHARPEN].constraint_type = SANE_CONSTRAINT_NONE;
712 scanner->val[OPT_SHARPEN].b = SANE_FALSE;
713 scanner->opt[OPT_SHARPEN].cap |= SANE_CAP_SOFT_SELECT;
716 scanner->opt[OPT_SHADING_ANALYSIS].name = "shading-analysis";
717 scanner->opt[OPT_SHADING_ANALYSIS].title = "Perform shading analysis";
718 scanner->opt[OPT_SHADING_ANALYSIS].desc = "Collect shading reference data before scanning the image. If set to 'no', this option may be overridden by the scanner.";
719 scanner->opt[OPT_SHADING_ANALYSIS].type = SANE_TYPE_BOOL;
720 scanner->opt[OPT_SHADING_ANALYSIS].unit = SANE_UNIT_NONE;
721 scanner->opt[OPT_SHADING_ANALYSIS].constraint_type = SANE_CONSTRAINT_NONE;
722 scanner->val[OPT_SHADING_ANALYSIS].b = SANE_FALSE;
723 scanner->opt[OPT_SHADING_ANALYSIS].cap |= SANE_CAP_SOFT_SELECT;
726 scanner->opt[OPT_CALIBRATION_MODE].name = "calibration";
727 scanner->opt[OPT_CALIBRATION_MODE].title = "Calibration mode";
728 scanner->opt[OPT_CALIBRATION_MODE].desc = "How to calibrate the scanner.";
729 scanner->opt[OPT_CALIBRATION_MODE].type = SANE_TYPE_STRING;
730 scanner->opt[OPT_CALIBRATION_MODE].size = max_string_size ((SANE_String_Const const *) scanner->device->calibration_mode_list);
731 scanner->opt[OPT_CALIBRATION_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
732 scanner->opt[OPT_CALIBRATION_MODE].constraint.string_list = (SANE_String_Const const *) scanner->device->calibration_mode_list;
733 scanner->val[OPT_CALIBRATION_MODE].s = (SANE_Char *) strdup (scanner->device->calibration_mode_list[1]); /* default auto */
736 scanner->opt[OPT_GAIN_ADJUST].name = "gain-adjust";
737 scanner->opt[OPT_GAIN_ADJUST].title = "Adjust gain";
738 scanner->opt[OPT_GAIN_ADJUST].desc = "Adjust gain determined by calibration procedure.";
739 scanner->opt[OPT_GAIN_ADJUST].type = SANE_TYPE_STRING;
740 scanner->opt[OPT_GAIN_ADJUST].size = max_string_size ((SANE_String_Const const *) scanner->device->gain_adjust_list);
741 scanner->opt[OPT_GAIN_ADJUST].constraint_type = SANE_CONSTRAINT_STRING_LIST;
742 scanner->opt[OPT_GAIN_ADJUST].constraint.string_list = (SANE_String_Const const *) scanner->device->gain_adjust_list;
743 scanner->val[OPT_GAIN_ADJUST].s = (SANE_Char *) strdup (scanner->device->gain_adjust_list[2]); /* x 1.0 (no change) */
746 scanner->opt[OPT_FAST_INFRARED].name = "fast-infrared";
747 scanner->opt[OPT_FAST_INFRARED].title = "Fast infrared scan";
748 scanner->opt[OPT_FAST_INFRARED].desc = "Do not reposition scan head before scanning infrared line. Results in an infrared offset which may deteriorate IR dust and scratch removal.";
749 scanner->opt[OPT_FAST_INFRARED].type = SANE_TYPE_BOOL;
750 scanner->opt[OPT_FAST_INFRARED].unit = SANE_UNIT_NONE;
751 scanner->opt[OPT_FAST_INFRARED].constraint_type = SANE_CONSTRAINT_NONE;
752 scanner->val[OPT_FAST_INFRARED].b = SANE_FALSE;
753 scanner->opt[OPT_FAST_INFRARED].cap |= SANE_CAP_SOFT_SELECT;
756 scanner->opt[OPT_ADVANCE_SLIDE].name = "advance";
757 scanner->opt[OPT_ADVANCE_SLIDE].title = "Advance slide";
758 scanner->opt[OPT_ADVANCE_SLIDE].desc = "Automatically advance to next slide after scan";
759 scanner->opt[OPT_ADVANCE_SLIDE].type = SANE_TYPE_BOOL;
760 scanner->opt[OPT_ADVANCE_SLIDE].unit = SANE_UNIT_NONE;
761 scanner->opt[OPT_ADVANCE_SLIDE].constraint_type = SANE_CONSTRAINT_NONE;
762 scanner->val[OPT_ADVANCE_SLIDE].w = SANE_TRUE;
763 scanner->opt[OPT_ADVANCE_SLIDE].cap |= SANE_CAP_SOFT_SELECT;
766 scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
767 scanner->opt[OPT_GEOMETRY_GROUP].desc = "";
768 scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
769 scanner->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
770 scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
773 scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
774 scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
775 scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
776 scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
777 scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM;
778 scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
779 scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range);
780 scanner->val[OPT_TL_X].w = 0;
783 scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
784 scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
785 scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
786 scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
787 scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
788 scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
789 scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range);
790 scanner->val[OPT_TL_Y].w = 0;
793 scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
794 scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
795 scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
796 scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
797 scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM;
798 scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
799 scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range);
800 scanner->val[OPT_BR_X].w = scanner->device->x_range.max;
803 scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
804 scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
805 scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
806 scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
807 scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
808 scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
809 scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range);
810 scanner->val[OPT_BR_Y].w = scanner->device->y_range.max;
813 scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
814 scanner->opt[OPT_ENHANCEMENT_GROUP].desc = "";
815 scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
816 scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
817 scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
820 scanner->opt[OPT_CORRECT_SHADING].name = "correct-shading";
821 scanner->opt[OPT_CORRECT_SHADING].title = "Correct shading";
822 scanner->opt[OPT_CORRECT_SHADING].desc = "Correct data for lamp variations (shading)";
823 scanner->opt[OPT_CORRECT_SHADING].type = SANE_TYPE_BOOL;
824 scanner->opt[OPT_CORRECT_SHADING].unit = SANE_UNIT_NONE;
825 scanner->val[OPT_CORRECT_SHADING].w = SANE_TRUE;
828 scanner->opt[OPT_CORRECT_INFRARED].name = "correct-infrared";
829 scanner->opt[OPT_CORRECT_INFRARED].title = "Correct infrared";
830 scanner->opt[OPT_CORRECT_INFRARED].desc = "Correct infrared for red crosstalk";
831 scanner->opt[OPT_CORRECT_INFRARED].type = SANE_TYPE_BOOL;
832 scanner->opt[OPT_CORRECT_INFRARED].unit = SANE_UNIT_NONE;
833 scanner->val[OPT_CORRECT_INFRARED].w = SANE_FALSE;
836 scanner->opt[OPT_CLEAN_IMAGE].name = "clean-image";
837 scanner->opt[OPT_CLEAN_IMAGE].title = "Clean image";
838 scanner->opt[OPT_CLEAN_IMAGE].desc = "Detect and remove dust and scratch artifacts";
839 scanner->opt[OPT_CLEAN_IMAGE].type = SANE_TYPE_BOOL;
840 scanner->opt[OPT_CLEAN_IMAGE].unit = SANE_UNIT_NONE;
841 scanner->val[OPT_CLEAN_IMAGE].w = SANE_FALSE;
844 scanner->opt[OPT_SMOOTH_IMAGE].name = "smooth";
845 scanner->opt[OPT_SMOOTH_IMAGE].title = "Attenuate film grain";
846 scanner->opt[OPT_SMOOTH_IMAGE].desc = "Amount of smoothening";
847 scanner->opt[OPT_SMOOTH_IMAGE].type = SANE_TYPE_INT;
848 scanner->opt[OPT_SMOOTH_IMAGE].constraint_type = SANE_CONSTRAINT_WORD_LIST;
849 scanner->opt[OPT_SMOOTH_IMAGE].size = sizeof (SANE_Word);
850 scanner->opt[OPT_SMOOTH_IMAGE].constraint.word_list = scanner->device->grain_sw_list;
851 scanner->val[OPT_SMOOTH_IMAGE].w = scanner->device->grain_sw_list[1];
852 if (scanner->opt[OPT_SMOOTH_IMAGE].constraint.word_list[0] < 2) {
853 scanner->opt[OPT_SMOOTH_IMAGE].cap |= SANE_CAP_INACTIVE;
857 scanner->opt[OPT_TRANSFORM_TO_SRGB].name = "srgb";
858 scanner->opt[OPT_TRANSFORM_TO_SRGB].title = "sRGB colors";
859 scanner->opt[OPT_TRANSFORM_TO_SRGB].desc = "Transform image to approximate sRGB color space";
860 scanner->opt[OPT_TRANSFORM_TO_SRGB].type = SANE_TYPE_BOOL;
861 scanner->opt[OPT_TRANSFORM_TO_SRGB].unit = SANE_UNIT_NONE;
862 scanner->val[OPT_TRANSFORM_TO_SRGB].w = SANE_FALSE;
863 scanner->opt[OPT_TRANSFORM_TO_SRGB].cap |= SANE_CAP_INACTIVE;
866 scanner->opt[OPT_INVERT_IMAGE].name = "invert";
867 scanner->opt[OPT_INVERT_IMAGE].title = "Invert colors";
868 scanner->opt[OPT_INVERT_IMAGE].desc = "Correct for generic negative film";
869 scanner->opt[OPT_INVERT_IMAGE].type = SANE_TYPE_BOOL;
870 scanner->opt[OPT_INVERT_IMAGE].unit = SANE_UNIT_NONE;
871 scanner->val[OPT_INVERT_IMAGE].w = SANE_FALSE;
872 scanner->opt[OPT_INVERT_IMAGE].cap |= SANE_CAP_INACTIVE;
875 scanner->opt[OPT_CROP_IMAGE].name = "crop";
876 scanner->opt[OPT_CROP_IMAGE].title = "Cropping";
877 scanner->opt[OPT_CROP_IMAGE].desc = "How to crop the image";
878 scanner->opt[OPT_CROP_IMAGE].type = SANE_TYPE_STRING;
879 scanner->opt[OPT_CROP_IMAGE].size = max_string_size ((SANE_String_Const const *)(void*) scanner->device->crop_sw_list);
880 scanner->opt[OPT_CROP_IMAGE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
881 scanner->opt[OPT_CROP_IMAGE].constraint.string_list = (SANE_String_Const const *)(void*) scanner->device->crop_sw_list;
882 scanner->val[OPT_CROP_IMAGE].s = (SANE_Char *) strdup (scanner->device->crop_sw_list[2]);
885 scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced";
886 scanner->opt[OPT_ADVANCED_GROUP].desc = "";
887 scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
888 scanner->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED;
889 scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
892 scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
893 scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
894 scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
895 scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
896 scanner->val[OPT_PREVIEW].w = SANE_FALSE;
899 scanner->opt[OPT_SAVE_SHADINGDATA].name = "save-shading-data";
900 scanner->opt[OPT_SAVE_SHADINGDATA].title = "Save shading data";
901 scanner->opt[OPT_SAVE_SHADINGDATA].desc = "Save shading data in 'pieusb.shading'";
902 scanner->opt[OPT_SAVE_SHADINGDATA].type = SANE_TYPE_BOOL;
903 scanner->val[OPT_SAVE_SHADINGDATA].w = SANE_FALSE;
906 scanner->opt[OPT_SAVE_CCDMASK].name = "save-ccdmask";
907 scanner->opt[OPT_SAVE_CCDMASK].title = "Save CCD mask";
908 scanner->opt[OPT_SAVE_CCDMASK].desc = "Save CCD mask 'pieusb.ccd'";
909 scanner->opt[OPT_SAVE_CCDMASK].type = SANE_TYPE_BOOL;
910 scanner->val[OPT_SAVE_CCDMASK].w = SANE_FALSE;
912 scanner->opt[OPT_LIGHT].name = "light";
913 scanner->opt[OPT_LIGHT].title = "Light";
914 scanner->opt[OPT_LIGHT].desc = "Light";
915 scanner->opt[OPT_LIGHT].type = SANE_TYPE_INT;
916 scanner->opt[OPT_LIGHT].unit = SANE_UNIT_MICROSECOND;
917 scanner->opt[OPT_LIGHT].cap |= SANE_CAP_SOFT_SELECT;
918 scanner->opt[OPT_LIGHT].size = sizeof(SANE_Word);
919 scanner->val[OPT_LIGHT].w = DEFAULT_LIGHT;
921 scanner->opt[OPT_DOUBLE_TIMES].name = "double-times";
922 scanner->opt[OPT_DOUBLE_TIMES].title = "Double times";
923 scanner->opt[OPT_DOUBLE_TIMES].desc = "Double times";
924 scanner->opt[OPT_DOUBLE_TIMES].type = SANE_TYPE_INT;
925 scanner->opt[OPT_DOUBLE_TIMES].unit = SANE_UNIT_MICROSECOND;
926 scanner->opt[OPT_DOUBLE_TIMES].cap |= SANE_CAP_SOFT_SELECT;
927 scanner->opt[OPT_DOUBLE_TIMES].size = sizeof(SANE_Word);
928 scanner->val[OPT_DOUBLE_TIMES].w = DEFAULT_DOUBLE_TIMES;
931 scanner->opt[OPT_SET_EXPOSURE_R].name = SANE_NAME_EXPOSURE_R;
932 scanner->opt[OPT_SET_EXPOSURE_R].title = SANE_TITLE_EXPOSURE_R;
933 scanner->opt[OPT_SET_EXPOSURE_R].desc = SANE_DESC_EXPOSURE_R;
934 scanner->opt[OPT_SET_EXPOSURE_G].name = SANE_NAME_EXPOSURE_G;
935 scanner->opt[OPT_SET_EXPOSURE_G].title = SANE_TITLE_EXPOSURE_G;
936 scanner->opt[OPT_SET_EXPOSURE_G].desc = SANE_DESC_EXPOSURE_G;
937 scanner->opt[OPT_SET_EXPOSURE_B].name = SANE_NAME_EXPOSURE_B;
938 scanner->opt[OPT_SET_EXPOSURE_B].title = SANE_TITLE_EXPOSURE_B;
939 scanner->opt[OPT_SET_EXPOSURE_B].desc = SANE_DESC_EXPOSURE_B;
940 scanner->opt[OPT_SET_EXPOSURE_I].name = SANE_NAME_EXPOSURE_I;
941 scanner->opt[OPT_SET_EXPOSURE_I].title = SANE_TITLE_EXPOSURE_I;
942 scanner->opt[OPT_SET_EXPOSURE_I].desc = SANE_DESC_EXPOSURE_I;
944 scanner->opt[i].type = SANE_TYPE_INT;
945 scanner->opt[i].unit = SANE_UNIT_MICROSECOND;
946 scanner->opt[i].cap |= SANE_CAP_SOFT_SELECT;
947 scanner->opt[i].constraint_type = SANE_CONSTRAINT_RANGE;
948 scanner->opt[i].constraint.range = &(scanner->device->exposure_range);
949 scanner->opt[i].size = sizeof(SANE_Word);
950 scanner->val[i].w = SANE_EXPOSURE_DEFAULT;
954 scanner->opt[OPT_SET_GAIN_R].name = SANE_NAME_GAIN_R;
955 scanner->opt[OPT_SET_GAIN_R].title = SANE_TITLE_GAIN_R;
956 scanner->opt[OPT_SET_GAIN_R].desc = SANE_DESC_GAIN_R;
957 scanner->opt[OPT_SET_GAIN_G].name = SANE_NAME_GAIN_G;
958 scanner->opt[OPT_SET_GAIN_G].title = SANE_TITLE_GAIN_G;
959 scanner->opt[OPT_SET_GAIN_G].desc = SANE_DESC_GAIN_G;
960 scanner->opt[OPT_SET_GAIN_B].name = SANE_NAME_GAIN_B;
961 scanner->opt[OPT_SET_GAIN_B].title = SANE_TITLE_GAIN_B;
962 scanner->opt[OPT_SET_GAIN_B].desc = SANE_DESC_GAIN_B;
963 scanner->opt[OPT_SET_GAIN_I].name = SANE_NAME_GAIN_I;
964 scanner->opt[OPT_SET_GAIN_I].title = SANE_TITLE_GAIN_I;
965 scanner->opt[OPT_SET_GAIN_I].desc = SANE_DESC_GAIN_I;
967 scanner->opt[i].type = SANE_TYPE_INT;
968 scanner->opt[i].unit = SANE_UNIT_NONE;
969 scanner->opt[i].constraint_type = SANE_CONSTRAINT_RANGE;
970 scanner->opt[i].constraint.range = &gain_range;
971 scanner->opt[i].size = sizeof(SANE_Word);
972 scanner->val[i].w = SANE_GAIN_DEFAULT;
975 scanner->opt[OPT_SET_OFFSET_R].name = SANE_NAME_OFFSET_R;
976 scanner->opt[OPT_SET_OFFSET_R].title = SANE_TITLE_OFFSET_R;
977 scanner->opt[OPT_SET_OFFSET_R].desc = SANE_DESC_OFFSET_R;
978 scanner->opt[OPT_SET_OFFSET_G].name = SANE_NAME_OFFSET_G;
979 scanner->opt[OPT_SET_OFFSET_G].title = SANE_TITLE_OFFSET_G;
980 scanner->opt[OPT_SET_OFFSET_G].desc = SANE_DESC_OFFSET_G;
981 scanner->opt[OPT_SET_OFFSET_B].name = SANE_NAME_OFFSET_B;
982 scanner->opt[OPT_SET_OFFSET_B].title = SANE_TITLE_OFFSET_B;
983 scanner->opt[OPT_SET_OFFSET_B].desc = SANE_DESC_OFFSET_B;
984 scanner->opt[OPT_SET_OFFSET_I].name = SANE_NAME_OFFSET_I;
985 scanner->opt[OPT_SET_OFFSET_I].title = SANE_TITLE_OFFSET_I;
986 scanner->opt[OPT_SET_OFFSET_I].desc = SANE_DESC_OFFSET_I;
988 scanner->opt[i].type = SANE_TYPE_INT;
989 scanner->opt[i].unit = SANE_UNIT_NONE;
990 scanner->opt[i].constraint_type = SANE_CONSTRAINT_RANGE;
991 scanner->opt[i].constraint.range = &offset_range;
992 scanner->opt[i].size = sizeof(SANE_Word);
993 scanner->val[i].w = SANE_OFFSET_DEFAULT;
1154 * @param scanner scanner to stop scanning
1158 sanei_pieusb_on_cancel (Pieusb_Scanner * scanner)
1164 sanei_pieusb_cmd_stop_scan (scanner->device_number, &status);
1165 sanei_pieusb_cmd_set_scan_head (scanner->device_number, 1, 0, &status);
1166 sanei_pieusb_buffer_delete (&scanner->buffer);
1167 scanner->scanning = SANE_FALSE;
1198 * Correct the given buffer for shading using shading data in scanner.
1203 * @param scanner Scanner
1207 sanei_pieusb_correct_shading(struct Pieusb_Scanner *scanner, struct Pieusb_Read_Buffer *buffer)
1219 for (i = 0; i < scanner->ccd_mask_size; i++) {
1220 if (scanner->ccd_mask[i] == 0) {
1232 val = lround((double)scanner->shading_mean[c] / scanner->shading_ref[c][width_to_loc[j]] * val_org);
1246 * @param scanner
1253 sanei_pieusb_post (Pieusb_Scanner *scanner, uint16_t **in_img, int planes)
1262 memcpy (&parameters, &scanner->scan_parameters, sizeof (SANE_Parameters));
1271 parameters.depth, planes, scanner->mode.resolution);
1285 smooth = scanner->val[OPT_SMOOTH_IMAGE].w;
1286 winsize_smooth = (scanner->mode.resolution / 540) | 1;
1301 if (scanner->val[OPT_CORRECT_INFRARED].b) /* (scanner->processing & POST_SW_IRED_MASK) */
1304 status = sanei_ir_spectral_clean (&parameters, scanner->ln_lut, cplane[0], cplane[3]);
1314 if (scanner->cancel_request) /* asynchronous cancel ? */
1316 } /* scanner-> processing & POST_SW_IRED_MASK */
1319 if (scanner->val[OPT_CLEAN_IMAGE].b) /* (scanner->processing & POST_SW_DIRT) */
1328 winsize_filter = (int) (5.0 * (double) scanner->mode.resolution / 300.0) | 1;
1332 size_dilate = scanner->mode.resolution / 1000 + 1;
1370 if (scanner->cancel_request) { /* asynchronous cancel ? */
1388 pieusb_write_pnm_file ("/tmp/RGBi-img.pnm", scanner->buffer.data,
1389 scanner->scan_parameters.depth, 3, scanner->scan_parameters.pixels_per_line,
1390 scanner->scan_parameters.lines);
1483 sanei_pieusb_analyse_options(struct Pieusb_Scanner *scanner)
1486 if (scanner->val[OPT_TL_X].w > scanner->val[OPT_BR_X].w) {
1488 scanner->opt[OPT_TL_X].title,
1489 SANE_UNFIX (scanner->val[OPT_TL_X].w),
1490 scanner->opt[OPT_BR_X].title,
1491 SANE_UNFIX (scanner->val[OPT_BR_X].w));
1494 if (scanner->val[OPT_TL_Y].w > scanner->val[OPT_BR_Y].w) {
1496 scanner->opt[OPT_TL_Y].title,
1497 SANE_UNFIX (scanner->val[OPT_TL_Y].w),
1498 scanner->opt[OPT_BR_Y].title,
1499 SANE_UNFIX (scanner->val[OPT_BR_Y].w));
1503 if (scanner->val[OPT_PREVIEW].b) {
1505 if (scanner->val[OPT_RESOLUTION].w != (scanner->device->fast_preview_resolution << SANE_FIXED_SCALE_SHIFT)) {
1506 DBG (DBG_info_sane, "Option %s = %f ignored during preview\n", scanner->opt[OPT_RESOLUTION].name, SANE_UNFIX(scanner->val[OPT_RESOLUTION].w));
1508 if (scanner->val[OPT_SHARPEN].b) {
1509 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_SHARPEN].name, scanner->val[OPT_SHARPEN].b);
1511 if (!scanner->val[OPT_FAST_INFRARED].b) {
1512 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_FAST_INFRARED].name, scanner->val[OPT_FAST_INFRARED].b);
1514 if (scanner->val[OPT_CORRECT_INFRARED].b) {
1515 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_CORRECT_INFRARED].name, scanner->val[OPT_CORRECT_INFRARED].b);
1517 if (scanner->val[OPT_CLEAN_IMAGE].b) {
1518 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_CLEAN_IMAGE].name, scanner->val[OPT_CLEAN_IMAGE].b);
1520 if (scanner->val[OPT_SMOOTH_IMAGE].w != 0) {
1521 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_SMOOTH_IMAGE].name, scanner->val[OPT_SMOOTH_IMAGE].w);
1523 if (strcmp(scanner->val[OPT_CROP_IMAGE].s, scanner->device->crop_sw_list[0]) != 0) {
1524 DBG (DBG_info_sane, "Option %s = %s ignored during preview\n", scanner->opt[OPT_CROP_IMAGE].name, scanner->val[OPT_CROP_IMAGE].s);
1526 if (scanner->val[OPT_TRANSFORM_TO_SRGB].b) {
1527 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_TRANSFORM_TO_SRGB].name, scanner->val[OPT_TRANSFORM_TO_SRGB].w);
1529 if (scanner->val[OPT_INVERT_IMAGE].w) {
1530 DBG (DBG_info_sane, "Option %s = %d ignored during preview\n", scanner->opt[OPT_INVERT_IMAGE].name, scanner->val[OPT_INVERT_IMAGE].w);
1532 } else if (strcmp(scanner->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_LINEART)==0) {
1534 if (scanner->val[OPT_BIT_DEPTH].w != 1) {
1535 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (will use 1)\n", scanner->opt[OPT_BIT_DEPTH].name, scanner->val[OPT_BIT_DEPTH].w);
1537 if (!scanner->val[OPT_FAST_INFRARED].b) {
1538 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_FAST_INFRARED].name, scanner->val[OPT_FAST_INFRARED].b);
1540 if (!scanner->val[OPT_CORRECT_SHADING].b) {
1541 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_CORRECT_SHADING].name, scanner->val[OPT_CORRECT_SHADING].b);
1543 if (!scanner->val[OPT_CORRECT_INFRARED].b) {
1544 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_CORRECT_INFRARED].name, scanner->val[OPT_CORRECT_INFRARED].b);
1546 if (scanner->val[OPT_CLEAN_IMAGE].b) {
1547 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_CLEAN_IMAGE].name, scanner->val[OPT_CLEAN_IMAGE].b);
1549 if (scanner->val[OPT_SMOOTH_IMAGE].w != 0) {
1550 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_SMOOTH_IMAGE].name, scanner->val[OPT_SMOOTH_IMAGE].w);
1552 if (strcmp(scanner->val[OPT_CROP_IMAGE].s, scanner->device->crop_sw_list[0]) != 0) {
1553 DBG (DBG_info_sane, "Option %s = %s ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_CROP_IMAGE].name, scanner->val[OPT_CROP_IMAGE].s);
1555 if (scanner->val[OPT_TRANSFORM_TO_SRGB].b) {
1556 DBG (DBG_info_sane, "Option %s = %d ignored in lineart mode (irrelevant)\n", scanner->opt[OPT_TRANSFORM_TO_SRGB].name, scanner->val[OPT_TRANSFORM_TO_SRGB].w);
1558 } else if (strcmp(scanner->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_HALFTONE)==0) {
1560 if (scanner->val[OPT_BIT_DEPTH].w != 1) {
1561 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (will use 1)\n", scanner->opt[OPT_BIT_DEPTH].name, scanner->val[OPT_BIT_DEPTH].w);
1563 if (!scanner->val[OPT_FAST_INFRARED].b) {
1564 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_FAST_INFRARED].name, scanner->val[OPT_FAST_INFRARED].b);
1566 if (!scanner->val[OPT_CORRECT_SHADING].b) {
1567 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_CORRECT_SHADING].name, scanner->val[OPT_CORRECT_SHADING].b);
1569 if (!scanner->val[OPT_CORRECT_INFRARED].b) {
1570 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_CORRECT_INFRARED].name, scanner->val[OPT_CORRECT_INFRARED].b);
1572 if (scanner->val[OPT_CLEAN_IMAGE].b) {
1573 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_CLEAN_IMAGE].name, scanner->val[OPT_CLEAN_IMAGE].b);
1575 if (scanner->val[OPT_SMOOTH_IMAGE].w != 0) {
1576 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_SMOOTH_IMAGE].name, scanner->val[OPT_SMOOTH_IMAGE].w);
1578 if (strcmp(scanner->val[OPT_CROP_IMAGE].s, scanner->device->crop_sw_list[0]) != 0) {
1579 DBG (DBG_info_sane, "Option %s = %s ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_CROP_IMAGE].name, scanner->val[OPT_CROP_IMAGE].s);
1581 if (scanner->val[OPT_TRANSFORM_TO_SRGB].b) {
1582 DBG (DBG_info_sane, "Option %s = %d ignored in halftone mode (irrelevant)\n", scanner->opt[OPT_TRANSFORM_TO_SRGB].name, scanner->val[OPT_TRANSFORM_TO_SRGB].w);
1584 } else if (strcmp(scanner->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_GRAY)==0) {
1590 if (scanner->val[OPT_BIT_DEPTH].w == 1) {
1591 DBG (DBG_info_sane, "Option %s = %d ignored in gray mode (will use 8)\n", scanner->opt[OPT_BIT_DEPTH].name, scanner->val[OPT_BIT_DEPTH].w);
1593 if (!scanner->val[OPT_FAST_INFRARED].b) {
1594 DBG (DBG_info_sane, "Option %s = %d ignored in gray mode (irrelevant)\n", scanner->opt[OPT_FAST_INFRARED].name, scanner->val[OPT_FAST_INFRARED].b);
1596 if (!scanner->val[OPT_CORRECT_INFRARED].b) {
1597 DBG (DBG_info_sane, "Option %s = %d ignored in gray mode (irrelevant)\n", scanner->opt[OPT_CORRECT_INFRARED].name, scanner->val[OPT_CORRECT_INFRARED].b);
1599 if (scanner->val[OPT_CLEAN_IMAGE].b) {
1600 DBG (DBG_info_sane, "Option %s = %d ignored in gray mode (irrelevant)\n", scanner->opt[OPT_CLEAN_IMAGE].name, scanner->val[OPT_CLEAN_IMAGE].b);
1602 if (scanner->val[OPT_TRANSFORM_TO_SRGB].b) {
1603 DBG (DBG_info_sane, "Option %s = %d ignored in gray mode (irrelevant)\n", scanner->opt[OPT_TRANSFORM_TO_SRGB].name, scanner->val[OPT_TRANSFORM_TO_SRGB].w);
1605 } else if (strcmp(scanner->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_COLOR)==0) {
1608 if (scanner->val[OPT_BIT_DEPTH].w == 1) {
1609 DBG (DBG_info_sane, "Option %s = %d ignored in color mode (will use 8)\n", scanner->opt[OPT_BIT_DEPTH].name, scanner->val[OPT_BIT_DEPTH].w);
1611 } else if (strcmp(scanner->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_RGBI)==0) {
1613 if (scanner->val[OPT_BIT_DEPTH].w == 1) {
1614 DBG (DBG_info_sane, "Option %s = %d ignored in color mode (will use 8)\n", scanner->opt[OPT_BIT_DEPTH].name, scanner->val[OPT_BIT_DEPTH].w);
1624 * @param scanner
1627 sanei_pieusb_print_options(struct Pieusb_Scanner *scanner)
1631 DBG (DBG_info, "Num options = %d\n", scanner->val[OPT_NUM_OPTS].w);
1632 for (k = 1; k < scanner->val[OPT_NUM_OPTS].w; k++) {
1633 switch (scanner->opt[k].type) {
1635 DBG(DBG_info," Option %d: %s = %d\n", k, scanner->opt[k].name, scanner->val[k].b);
1638 DBG(DBG_info," Option %d: %s = %d\n", k, scanner->opt[k].name, scanner->val[k].w);
1641 DBG(DBG_info," Option %d: %s = %f\n", k, scanner->opt[k].name, SANE_UNFIX (scanner->val[k].w));
1644 DBG(DBG_info," Option %d: %s = %s\n", k, scanner->opt[k].name, scanner->val[k].s);
1647 DBG(DBG_info," Option %d: %s = %s\n", k, scanner->opt[k].title, scanner->val[k].s);
1650 DBG(DBG_info," Option %d: %s unknown type %d\n", k, scanner->opt[k].name, scanner->opt[k].type);
1662 * @param scanner
1665 static void pieusb_calculate_shading(struct Pieusb_Scanner *scanner, SANE_Byte* buffer)
1670 SANE_Int shading_width = scanner->device->shading_parameters[0].pixelsPerLine;
1671 SANE_Int shading_height = scanner->device->shading_parameters[0].nLines;
1675 scanner->shading_max[k] = 0;
1676 scanner->shading_mean[k] = 0;
1677 memset(scanner->shading_ref[k], 0, shading_width * sizeof (SANE_Int));
1681 switch (scanner->mode.colorFormat) {
1688 scanner->shading_ref[ci][m] += val;
1689 scanner->shading_max[ci] = scanner->shading_max[ci] < val ? val : scanner->shading_max[ci];
1710 scanner->shading_ref[ci][m] += val;
1711 scanner->shading_max[ci] = scanner->shading_max[ci] < val ? val : scanner->shading_max[ci];
1712 /* DBG(DBG_error,"%02d Shading_ref[%d][%d] = %d\n",k,ci,m,scanner->shading_ref[ci][m]); */
1720 DBG (DBG_error,"sane_start(): color format %d not implemented\n",scanner->mode.colorFormat);
1726 scanner->shading_ref[k][m] = lround((double)scanner->shading_ref[k][m]/shading_height);
1727 /* DBG(DBG_error,"Shading_ref[%d][%d] = %d\n",k,m,scanner->shading_ref[k][m]); */
1733 scanner->shading_mean[k] += scanner->shading_ref[k][m];
1735 scanner->shading_mean[k] = lround((double)scanner->shading_mean[k]/shading_width);
1736 DBG (DBG_error,"Shading_mean[%d] = %d\n",k,scanner->shading_mean[k]);
1740 scanner->shading_data_present = SANE_TRUE;
1744 if (scanner->val[OPT_SAVE_SHADINGDATA].b) {
1767 * Set frame (from scanner options)
1771 sanei_pieusb_set_frame_from_options(Pieusb_Scanner * scanner)
1776 dpmm = (double) scanner->device->maximum_resolution / MM_PER_INCH;
1777 scanner->frame.x0 = SANE_UNFIX(scanner->val[OPT_TL_X].w) * dpmm;
1778 scanner->frame.y0 = SANE_UNFIX(scanner->val[OPT_TL_Y].w) * dpmm;
1779 scanner->frame.x1 = SANE_UNFIX(scanner->val[OPT_BR_X].w) * dpmm;
1780 scanner->frame.y1 = SANE_UNFIX(scanner->val[OPT_BR_Y].w) * dpmm;
1781 scanner->frame.index = 0x80; /* 0x80: value from cyberview */
1782 sanei_pieusb_cmd_set_scan_frame (scanner->device_number, scanner->frame.index, &(scanner->frame), &status);
1788 * Set mode (from scanner options)
1792 sanei_pieusb_set_mode_from_options(Pieusb_Scanner * scanner)
1798 mode = scanner->val[OPT_MODE].s;
1800 scanner->mode.passes = SCAN_FILTER_GREEN; /* G */
1801 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_PIXEL;
1803 scanner->mode.passes = SCAN_FILTER_GREEN; /* G */
1804 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_PIXEL;
1806 scanner->mode.passes = SCAN_FILTER_GREEN; /* G=gray; unable to get R & B & I to work */
1807 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_PIXEL;
1808 } else if(scanner->val[OPT_PREVIEW].b) {
1810 scanner->mode.passes = SCAN_ONE_PASS_COLOR;
1811 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_INDEX; /* pixel format might be an alternative */
1813 scanner->mode.passes = SCAN_ONE_PASS_RGBI;
1814 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_INDEX;
1815 } else if(strcmp (mode, SANE_VALUE_SCAN_MODE_COLOR) == 0 && scanner->val[OPT_CLEAN_IMAGE].b) {
1816 scanner->mode.passes = SCAN_ONE_PASS_RGBI; /* Need infrared for cleaning */
1817 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_INDEX;
1819 scanner->mode.passes = SCAN_ONE_PASS_COLOR;
1820 scanner->mode.colorFormat = SCAN_COLOR_FORMAT_INDEX; /* pixel format might be an alternative */
1823 if (scanner->val[OPT_PREVIEW].b) {
1824 scanner->mode.resolution = scanner->device->fast_preview_resolution;
1825 DBG (DBG_info_sane, "sanei_pieusb_set_mode_from_options(): resolution fast preview (%d)\n", scanner->mode.resolution);
1827 scanner->mode.resolution = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w);
1828 DBG (DBG_info_sane, "sanei_pieusb_set_mode_from_options(): resolution from option setting (%d)\n", scanner->mode.resolution);
1831 switch (scanner->val[OPT_BIT_DEPTH].w) {
1832 case 1: scanner->mode.colorDepth = SCAN_COLOR_DEPTH_1; break;
1833 case 8: scanner->mode.colorDepth = SCAN_COLOR_DEPTH_8; break;
1834 case 16: scanner->mode.colorDepth = SCAN_COLOR_DEPTH_16; break;
1836 DBG (DBG_error, "sanei_pieusb_set_mode_from_options(): sanei_pieusb_cmd_set_scan_frame untested bit depth %d\n", scanner->val[OPT_BIT_DEPTH].w);
1839 scanner->mode.byteOrder = 0x01; /* 0x01 = Intel; only bit 0 used */
1840 scanner->mode.sharpen = scanner->val[OPT_SHARPEN].b && !scanner->val[OPT_PREVIEW].b;
1841 scanner->mode.skipShadingAnalysis = !scanner->val[OPT_SHADING_ANALYSIS].b;
1842 scanner->mode.fastInfrared = scanner->val[OPT_FAST_INFRARED].b && !scanner->val[OPT_PREVIEW].b;
1843 if (strcmp (scanner->val[OPT_HALFTONE_PATTERN].s, "53lpi 45d ROUND") == 0) {
1844 scanner->mode.halftonePattern = 0;
1846 scanner->mode.halftonePattern = 0;
1848 scanner->mode.lineThreshold = SANE_UNFIX (scanner->val[OPT_THRESHOLD].w) / 100 * 0xFF; /* 0xFF = 100% */
1849 sanei_pieusb_cmd_set_mode (scanner->device_number, &(scanner->mode), &status);
1852 res = sanei_pieusb_wait_ready (scanner, 0);
1865 * @param scanner
1869 sanei_pieusb_set_gain_offset(Pieusb_Scanner * scanner, const char *calibration_mode)
1880 scanner->settings.exposureTime[0] = DEFAULT_EXPOSURE;
1881 scanner->settings.exposureTime[1] = DEFAULT_EXPOSURE;
1882 scanner->settings.exposureTime[2] = DEFAULT_EXPOSURE;
1883 scanner->settings.exposureTime[3] = DEFAULT_EXPOSURE;
1884 scanner->settings.offset[0] = DEFAULT_OFFSET;
1885 scanner->settings.offset[1] = DEFAULT_OFFSET;
1886 scanner->settings.offset[2] = DEFAULT_OFFSET;
1887 scanner->settings.offset[3] = DEFAULT_OFFSET;
1888 scanner->settings.gain[0] = DEFAULT_GAIN;
1889 scanner->settings.gain[1] = DEFAULT_GAIN;
1890 scanner->settings.gain[2] = DEFAULT_GAIN;
1891 scanner->settings.gain[3] = DEFAULT_GAIN;
1892 scanner->settings.light = DEFAULT_LIGHT;
1893 scanner->settings.extraEntries = DEFAULT_ADDITIONAL_ENTRIES;
1894 scanner->settings.doubleTimes = DEFAULT_DOUBLE_TIMES;
1897 && scanner->preview_done) {
1900 DBG (DBG_info, "sanei_pieusb_set_gain_offset(): get calibration data from preview. scanner->mode.passes %d\n", scanner->mode.passes);
1901 switch (scanner->mode.passes) {
1904 dgi = ((double)scanner->settings.saturationLevel[0] / 65536) / ((double)scanner->preview_upper_bound[0] / HISTOGRAM_SIZE);
1906 dgi = ((double)scanner->settings.saturationLevel[1] / 65536) / ((double)scanner->preview_upper_bound[1] / HISTOGRAM_SIZE);
1908 dgi = ((double)scanner->settings.saturationLevel[2] / 65536) / ((double)scanner->preview_upper_bound[2] / HISTOGRAM_SIZE);
1910 updateGain2(scanner, 0, dg);
1911 updateGain2(scanner, 1, dg);
1912 updateGain2(scanner, 2, dg);
1916 dgi = ((double)scanner->settings.saturationLevel[0] / 65536) / ((double)scanner->preview_upper_bound[0] / HISTOGRAM_SIZE);
1918 dgi = ((double)scanner->settings.saturationLevel[1] / 65536) / ((double)scanner->preview_upper_bound[1] / HISTOGRAM_SIZE);
1920 dgi = ((double)scanner->settings.saturationLevel[2] / 65536) / ((double)scanner->preview_upper_bound[2] / HISTOGRAM_SIZE);
1922 updateGain2(scanner, 0, dg);
1923 updateGain2(scanner, 1, dg);
1924 updateGain2(scanner, 2, dg);
1928 dgi = ((double)scanner->settings.saturationLevel[2] / 65536) / ((double)scanner->preview_upper_bound[2] / HISTOGRAM_SIZE);
1930 updateGain2(scanner, 2, dg);
1934 dgi = ((double)scanner->settings.saturationLevel[1] / 65536) / ((double)scanner->preview_upper_bound[1] / HISTOGRAM_SIZE);
1936 updateGain2(scanner, 1, dg);
1940 dgi = ((double)scanner->settings.saturationLevel[0] / 65536) / ((double)scanner->preview_upper_bound[0] / HISTOGRAM_SIZE);
1942 updateGain2(scanner, 0, dg);
1951 scanner->settings.exposureTime[0] = scanner->val[OPT_SET_EXPOSURE_R].w;
1952 scanner->settings.exposureTime[1] = scanner->val[OPT_SET_EXPOSURE_G].w;
1953 scanner->settings.exposureTime[2] = scanner->val[OPT_SET_EXPOSURE_B].w;
1954 scanner->settings.exposureTime[3] = scanner->val[OPT_SET_EXPOSURE_I].w; /* Infrared */
1956 scanner->settings.offset[0] = scanner->val[OPT_SET_OFFSET_R].w;
1957 scanner->settings.offset[1] = scanner->val[OPT_SET_OFFSET_G].w;
1958 scanner->settings.offset[2] = scanner->val[OPT_SET_OFFSET_B].w;
1959 scanner->settings.offset[3] = scanner->val[OPT_SET_OFFSET_I].w; /* Infrared */
1961 scanner->settings.gain[0] = scanner->val[OPT_SET_GAIN_R].w;
1962 scanner->settings.gain[1] = scanner->val[OPT_SET_GAIN_G].w;
1963 scanner->settings.gain[2] = scanner->val[OPT_SET_GAIN_B].w;
1964 scanner->settings.gain[3] = scanner->val[OPT_SET_GAIN_I].w; /* Infrared */
1966 scanner->settings.light = scanner->val[OPT_LIGHT].w;
1967 scanner->settings.extraEntries = DEFAULT_ADDITIONAL_ENTRIES;
1968 scanner->settings.doubleTimes = scanner->val[OPT_DOUBLE_TIMES].w;
1971 DBG (DBG_info_sane, "sanei_pieusb_set_gain_offset(): get calibration data from scanner\n");
1972 sanei_pieusb_cmd_get_gain_offset (scanner->device_number, &scanner->settings, &status);
1976 ret = sanei_pieusb_wait_ready (scanner, 0);
1987 if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_03) == 0) {
1989 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_05) == 0) {
1991 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_08) == 0) {
1993 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_10) == 0) {
1995 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_12) == 0) {
1997 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_16) == 0) {
1999 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_19) == 0) {
2001 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_24) == 0) {
2003 } else if (strcmp (scanner->val[OPT_GAIN_ADJUST].s, SCAN_GAIN_ADJUST_30) == 0) {
2006 switch (scanner->mode.passes) {
2009 updateGain2 (scanner, 0, gain);
2010 updateGain2 (scanner, 1, gain);
2011 updateGain2 (scanner, 2, gain);
2015 updateGain2 (scanner, 3, gain);
2018 updateGain2 (scanner, 2, gain);
2021 updateGain2 (scanner, 1, gain);
2024 updateGain2 (scanner, 0, gain);
2030 sanei_pieusb_cmd_set_gain_offset (scanner->device_number, &(scanner->settings), &status);
2042 sanei_pieusb_get_shading_data(Pieusb_Scanner * scanner)
2054 shading_width = scanner->device->shading_parameters[0].pixelsPerLine;
2055 shading_height = scanner->device->shading_parameters[0].nLines;
2060 switch (scanner->mode.colorFormat) {
2070 DBG (DBG_error, "sanei_pieusb_get_shading_data(): color format %d not implemented\n", scanner->mode.colorFormat);
2079 sanei_pieusb_cmd_get_scanned_lines (scanner->device_number, buffer, 4, cols * 4, &status);
2081 res = sanei_pieusb_wait_ready (scanner, 0);
2083 sanei_pieusb_cmd_get_scanned_lines (scanner->device_number, buffer + cols*4, lines - 4, (lines - 4) * cols, &status);
2085 pieusb_calculate_shading (scanner, buffer);
2102 sanei_pieusb_get_ccd_mask(Pieusb_Scanner * scanner)
2108 sanei_pieusb_cmd_get_ccd_mask(scanner->device_number, scanner->ccd_mask, scanner->ccd_mask_size, &status);
2111 if (scanner->val[OPT_SAVE_CCDMASK].b) {
2113 fwrite (scanner->ccd_mask, 1, scanner->ccd_mask_size, fs);
2122 * Read parameters from scanner
2125 * @param scanner
2129 sanei_pieusb_get_parameters(Pieusb_Scanner * scanner, SANE_Int *parameter_bytes)
2137 sanei_pieusb_cmd_get_parameters (scanner->device_number, &parameters, &status);
2148 mode = scanner->val[OPT_MODE].s;
2150 scanner->scan_parameters.format = SANE_FRAME_GRAY;
2151 scanner->scan_parameters.depth = 1;
2152 scanner->scan_parameters.bytes_per_line = parameters.bytes/3;
2154 scanner->scan_parameters.format = SANE_FRAME_GRAY;
2155 scanner->scan_parameters.depth = 1;
2156 scanner->scan_parameters.bytes_per_line = parameters.bytes/3;
2158 scanner->scan_parameters.format = SANE_FRAME_GRAY;
2159 scanner->scan_parameters.depth = scanner->val[OPT_BIT_DEPTH].w;
2160 scanner->scan_parameters.bytes_per_line = parameters.bytes/3;
2162 scanner->scan_parameters.format = SANE_FRAME_RGB; /* was: SANE_FRAME_RGBI */
2163 scanner->scan_parameters.depth = scanner->val[OPT_BIT_DEPTH].w;
2164 scanner->scan_parameters.bytes_per_line = 4*parameters.bytes;
2166 scanner->scan_parameters.format = SANE_FRAME_RGB;
2167 scanner->scan_parameters.depth = scanner->val[OPT_BIT_DEPTH].w;
2168 scanner->scan_parameters.bytes_per_line = 3*parameters.bytes;
2170 scanner->scan_parameters.lines = parameters.lines;
2171 scanner->scan_parameters.pixels_per_line = parameters.width;
2172 scanner->scan_parameters.last_frame = SANE_TRUE;
2175 DBG (DBG_info_sane," format = %d\n", scanner->scan_parameters.format);
2176 DBG (DBG_info_sane," depth = %d\n", scanner->scan_parameters.depth);
2177 DBG (DBG_info_sane," bytes_per_line = %d\n", scanner->scan_parameters.bytes_per_line);
2178 DBG (DBG_info_sane," lines = %d\n", scanner->scan_parameters.lines);
2179 DBG (DBG_info_sane," pixels_per_line = %d\n", scanner->scan_parameters.pixels_per_line);
2180 DBG (DBG_info_sane," last_frame = %d\n", scanner->scan_parameters.last_frame);
2186 sanei_pieusb_get_scan_data(Pieusb_Scanner * scanner, SANE_Int parameter_bytes)
2189 SANE_Parameters *parameters = &scanner->scan_parameters;
2196 switch (scanner->mode.colorFormat) {
2198 lines_to_read = scanner->buffer.height;
2201 lines_to_read = scanner->buffer.colors * scanner->buffer.height;
2204 DBG(DBG_error, "sanei_pieusb_get_scan_data(): color format %d not implemented\n",scanner->mode.colorFormat);
2208 DBG (DBG_info_proc, "sanei_pieusb_get_scan_data(colorFormat %d), lines_to_read %d, bytes %d\n", scanner->mode.colorFormat, lines_to_read, parameter_bytes);
2221 switch (scanner->mode.colorFormat) {
2229 DBG(DBG_error, "sanei_pieusb_get_scan_data(): color format %d not implemented\n", scanner->mode.colorFormat);
2235 sanei_pieusb_cmd_get_scanned_lines(scanner->device_number, linebuf, lines, lines * bpl, &status);
2249 * Sometimes the scanner returns too many lines. Take care not to
2252 switch (scanner->mode.colorFormat) {
2254 /* The scanner may return lines with 3 colors even though only
2259 if (scanner->buffer.colors == 1
2260 && (bpl * scanner->buffer.packing_density / ppl) == (3 * scanner->buffer.packet_size_bytes)) {
2266 int ps = scanner->buffer.packet_size_bytes;
2267 for (k = 0; k < scanner->buffer.line_size_packets; k++) {
2273 if (sanei_pieusb_buffer_put_full_color_line(&scanner->buffer, lboff, bpl/3) == 0) {
2283 if (sanei_pieusb_buffer_put_single_color_line(&scanner->buffer, *lboff, lboff+2, bpl-2) == 0) {
2291 DBG(DBG_error, "sanei_pieusb_get_scan_data(): store color format %d not implemented\n", scanner->mode.colorFormat);
2306 * Wait for scanner to get ready
2310 * @param scanner
2311 * @param device_number, used if scanner == NULL
2316 sanei_pieusb_wait_ready(Pieusb_Scanner * scanner, SANE_Int device_number)
2324 if (scanner)
2325 device_number = scanner->device_number;
2341 DBG (DBG_error, "scanner not ready after 2 minutes\n");
2345 DBG (DBG_info, "still waiting for scanner to get ready\n");
2352 SANE_Status sanei_pieusb_analyze_preview(Pieusb_Scanner * scanner)
2363 scanner->preview_done = SANE_TRUE;
2365 scanner->preview_exposure[k] = scanner->settings.exposureTime[k];
2366 scanner->preview_gain[k] = scanner->settings.gain[k];
2367 scanner->preview_offset[k] = scanner->settings.offset[k];
2370 N = scanner->buffer.width * scanner->buffer.height;
2372 params.depth = scanner->buffer.depth;
2373 params.pixels_per_line = scanner->buffer.width;
2374 params.lines = scanner->buffer.height;
2375 for (k = 0; k < scanner->buffer.colors; k++) {
2377 sanei_ir_create_norm_histogram (&params, scanner->buffer.data + k * N, &norm_histo);
2384 scanner->preview_lower_bound[k] = n;
2387 scanner->preview_upper_bound[k] = n;
2390 DBG(DBG_info,"sanei_pieusb_analyze_preview(): 1%%-99%% levels for color %d: %d - %d\n", k, scanner->preview_lower_bound[k], scanner->preview_upper_bound[k]);
2393 for (k = scanner->buffer.colors; k < 4; k++) {
2394 scanner->preview_lower_bound[k] = 0;
2395 scanner->preview_upper_bound[k] = 0;
2459 switch (scanner->mode.passes) {
2461 updateGain(scanner,0);
2462 updateGain(scanner,1);
2463 updateGain(scanner,2);
2464 updateGain(scanner,3);
2467 updateGain(scanner,0);
2468 updateGain(scanner,1);
2469 updateGain(scanner,2);
2472 updateGain(scanner,3);
2475 updateGain(scanner,2);
2478 updateGain(scanner,1);
2481 updateGain(scanner,0);
2486 * @param scanner
2489 static void updateGain(Pieusb_Scanner *scanner, int color_index)
2493 DBG(DBG_info_sane,"updateGain(): color %d preview used G=%d Exp=%d\n", color_index, scanner->preview_gain[color_index], scanner->preview_exposure[color_index]);
2495 dg = ((double)scanner->settings.saturationLevel[color_index] / 65536) / ((double)scanner->preview_upper_bound[color_index] / HISTOGRAM_SIZE);
2499 g = getGain(scanner->preview_gain[color_index]);
2500 DBG(DBG_info_sane,"updateGain(): preview had gain %d => %f\n",scanner->preview_gain[color_index],g);
2503 scanner->settings.gain[color_index] = getGainSetting(g*sqrt(dg));
2504 DBG(DBG_info_sane,"updateGain(): optimized gain setting %d => %f\n",scanner->settings.gain[color_index],getGain(scanner->settings.gain[color_index]));
2506 DBG(DBG_info_sane,"updateGain(): remains for exposure %f\n",dg/(getGain(scanner->settings.gain[color_index])/g));
2507 scanner->settings.exposureTime[color_index] = lround( g / getGain(scanner->settings.gain[color_index]) * dg * scanner->preview_exposure[color_index] );
2508 DBG(DBG_info_sane,"updateGain(): new setting G=%d Exp=%d\n", scanner->settings.gain[color_index], scanner->settings.exposureTime[color_index]);
2512 static void updateGain2(Pieusb_Scanner *scanner, int color_index, double gain_increase)
2516 DBG(DBG_info,"updateGain2(): color %d preview used G=%d Exp=%d\n", color_index, scanner->settings.gain[color_index], scanner->settings.exposureTime[color_index]);
2521 g = getGain(scanner->settings.gain[color_index]);
2522 DBG(DBG_info,"updateGain2(): preview had gain %d => %f\n", scanner->settings.gain[color_index], g);
2525 scanner->settings.gain[color_index] = getGainSetting(g * sqrt(gain_increase));
2526 DBG(DBG_info,"updateGain2(): optimized gain setting %d => %f\n", scanner->settings.gain[color_index], getGain(scanner->settings.gain[color_index]));
2528 DBG(DBG_info,"updateGain2(): remains for exposure %f\n", gain_increase / (getGain(scanner->settings.gain[color_index]) / g));
2529 scanner->settings.exposureTime[color_index] = lround( g / getGain(scanner->settings.gain[color_index]) * gain_increase * scanner->settings.exposureTime[color_index] );
2530 DBG(DBG_info,"updateGain2(): new setting G=%d Exp=%d\n", scanner->settings.gain[color_index], scanner->settings.exposureTime[color_index]);