kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			genesys: Reduce duplication of scanner read methods on gl846
							rodzic
							
								
									d74c4b6b68
								
							
						
					
					
						commit
						8bd8174cc9
					
				|  | @ -891,8 +891,6 @@ void CommandSetGl846::search_start_position(Genesys_Device* dev) const | |||
|     // send to scanner
 | ||||
|     dev->interface->write_registers(local_reg); | ||||
| 
 | ||||
|     std::vector<uint8_t> data(session.output_total_bytes); | ||||
| 
 | ||||
|     begin_scan(dev, sensor, &local_reg, true); | ||||
| 
 | ||||
|     if (is_testing_mode()) { | ||||
|  | @ -905,11 +903,10 @@ void CommandSetGl846::search_start_position(Genesys_Device* dev) const | |||
|     wait_until_buffer_non_empty(dev); | ||||
| 
 | ||||
|     // now we're on target, we can read data
 | ||||
|     sanei_genesys_read_data_from_scanner(dev, data.data(), session.output_total_bytes); | ||||
|     auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
| 
 | ||||
|     if (DBG_LEVEL >= DBG_data) { | ||||
|         sanei_genesys_write_pnm_file("gl846_search_position.pnm", data.data(), 8, 1, pixels, | ||||
|                                      dev->model->search_lines); | ||||
|         sanei_genesys_write_pnm_file("gl846_search_position.pnm", image); | ||||
|     } | ||||
| 
 | ||||
|     end_scan(dev, &local_reg, true); | ||||
|  | @ -922,8 +919,8 @@ void CommandSetGl846::search_start_position(Genesys_Device* dev) const | |||
|     for (auto& sensor_update : | ||||
|             sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) | ||||
|     { | ||||
|         sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, dpi, pixels, | ||||
|                                              dev->model->search_lines); | ||||
|         sanei_genesys_search_reference_point(dev, sensor_update, image.get_row_ptr(0), 0, dpi, | ||||
|                                              pixels, dev->model->search_lines); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -1190,9 +1187,7 @@ SensorExposure CommandSetGl846::led_calibration(Genesys_Device* dev, const Genes | |||
|     DBG_HELPER(dbg); | ||||
|   int num_pixels; | ||||
|   int used_res; | ||||
|   int i, j; | ||||
|   int val; | ||||
|     int channels; | ||||
|     int i; | ||||
|   int avg[3], top[3], bottom[3]; | ||||
|   int turn; | ||||
|   uint16_t exp[3]; | ||||
|  | @ -1207,7 +1202,7 @@ SensorExposure CommandSetGl846::led_calibration(Genesys_Device* dev, const Genes | |||
|   DBG(DBG_io, "%s: move=%f steps\n", __func__, move); | ||||
| 
 | ||||
|   /* offset calibration is always done in color mode */ | ||||
|   channels = 3; | ||||
|     unsigned channels = 3; | ||||
|     used_res = sensor.get_register_hwdpi(dev->settings.xres); | ||||
|     const auto& calib_sensor = sanei_genesys_find_sensor(dev, used_res, channels, | ||||
|                                                          dev->settings.scan_method); | ||||
|  | @ -1236,8 +1231,6 @@ SensorExposure CommandSetGl846::led_calibration(Genesys_Device* dev, const Genes | |||
| 
 | ||||
|     init_regs_for_scan_session(dev, calib_sensor, ®s, session); | ||||
| 
 | ||||
|     std::vector<uint8_t> line(session.output_line_bytes); | ||||
| 
 | ||||
|   /* initial loop values and boundaries */ | ||||
|     exp[0] = calib_sensor.exposure.red; | ||||
|     exp[1] = calib_sensor.exposure.green; | ||||
|  | @ -1276,37 +1269,24 @@ SensorExposure CommandSetGl846::led_calibration(Genesys_Device* dev, const Genes | |||
|             return calib_sensor.exposure; | ||||
|         } | ||||
| 
 | ||||
|         sanei_genesys_read_data_from_scanner(dev, line.data(), session.output_line_bytes); | ||||
|         auto image = read_unshuffled_image_from_scanner(dev, session, session.output_line_bytes); | ||||
| 
 | ||||
|         // stop scanning
 | ||||
|         scanner_stop_action(*dev); | ||||
| 
 | ||||
|       if (DBG_LEVEL >= DBG_data) | ||||
|         { | ||||
|           char fn[30]; | ||||
|         if (DBG_LEVEL >= DBG_data) { | ||||
|             char fn[30]; | ||||
|             std::snprintf(fn, 30, "gl846_led_%02d.pnm", turn); | ||||
|             sanei_genesys_write_pnm_file(fn, line.data(), session.params.depth, | ||||
|                                          channels, num_pixels, 1); | ||||
|             sanei_genesys_write_pnm_file(fn, image); | ||||
|         } | ||||
| 
 | ||||
|       /* compute average */ | ||||
|       for (j = 0; j < channels; j++) | ||||
|         { | ||||
|           avg[j] = 0; | ||||
|           for (i = 0; i < num_pixels; i++) | ||||
|             { | ||||
|               if (dev->model->is_cis) | ||||
|                 val = | ||||
|                   line[i * 2 + j * 2 * num_pixels + 1] * 256 + | ||||
|                   line[i * 2 + j * 2 * num_pixels]; | ||||
|               else | ||||
|                 val = | ||||
|                   line[i * 2 * channels + 2 * j + 1] * 256 + | ||||
|                   line[i * 2 * channels + 2 * j]; | ||||
|               avg[j] += val; | ||||
|         // compute average
 | ||||
|         for (unsigned ch = 0; ch < channels; ch++) { | ||||
|             avg[ch] = 0; | ||||
|             for (std::size_t x = 0; x < image.get_width(); x++) { | ||||
|                 avg[ch] += image.get_raw_channel(x, 0, ch); | ||||
|             } | ||||
| 
 | ||||
|           avg[j] /= num_pixels; | ||||
|             avg[ch] /= image.get_width(); | ||||
|         } | ||||
| 
 | ||||
|       DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); | ||||
|  | @ -1536,7 +1516,7 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se | |||
|     DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse"); | ||||
|   unsigned int pixels, lines, channels; | ||||
|   Genesys_Register_Set local_reg; | ||||
|   unsigned int pass, count, found, x, y; | ||||
|     unsigned int pass, count, found; | ||||
|   char title[80]; | ||||
| 
 | ||||
|     set_fe(dev, sensor, AFE_SET); | ||||
|  | @ -1577,8 +1557,6 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se | |||
| 
 | ||||
|     init_regs_for_scan_session(dev, sensor, &local_reg, session); | ||||
| 
 | ||||
|     std::vector<uint8_t> data(session.output_total_bytes); | ||||
| 
 | ||||
|     dev->interface->write_registers(local_reg); | ||||
| 
 | ||||
|     begin_scan(dev, sensor, &local_reg, true); | ||||
|  | @ -1592,7 +1570,7 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se | |||
|     wait_until_buffer_non_empty(dev); | ||||
| 
 | ||||
|     // now we're on target, we can read data
 | ||||
|     sanei_genesys_read_data_from_scanner(dev, data.data(), session.output_total_bytes); | ||||
|     auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
| 
 | ||||
|     scanner_stop_action(*dev); | ||||
| 
 | ||||
|  | @ -1601,8 +1579,7 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se | |||
|     { | ||||
|         std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm", | ||||
|                      black ? "black" : "white", forward ? "fwd" : "bwd", pass); | ||||
|         sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, | ||||
|                                      channels, pixels, lines); | ||||
|         sanei_genesys_write_pnm_file(title, image); | ||||
|     } | ||||
| 
 | ||||
|   /* loop until strip is found or maximum pass number done */ | ||||
|  | @ -1617,7 +1594,7 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se | |||
|         wait_until_buffer_non_empty(dev); | ||||
| 
 | ||||
|         // now we're on target, we can read data
 | ||||
|         sanei_genesys_read_data_from_scanner(dev, data.data(), session.output_total_bytes); | ||||
|         image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
| 
 | ||||
|         scanner_stop_action(*dev); | ||||
| 
 | ||||
|  | @ -1625,86 +1602,81 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se | |||
|         { | ||||
|             std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm", | ||||
|                          black ? "black" : "white", forward ? "fwd" : "bwd", pass); | ||||
|             sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, | ||||
|                                          channels, pixels, lines); | ||||
|             sanei_genesys_write_pnm_file(title, image); | ||||
|         } | ||||
| 
 | ||||
|         unsigned white_level = 90; | ||||
|         unsigned black_level = 60; | ||||
| 
 | ||||
|       /* search data to find black strip */ | ||||
|       /* when searching forward, we only need one line of the searched color since we
 | ||||
|        * will scan forward. But when doing backward search, we need all the area of the | ||||
|        * same color */ | ||||
|       if (forward) | ||||
|         { | ||||
|           for (y = 0; y < lines && !found; y++) | ||||
|             { | ||||
|               count = 0; | ||||
|               /* count of white/black pixels depending on the color searched */ | ||||
|               for (x = 0; x < pixels; x++) | ||||
|                 { | ||||
|                   /* when searching for black, detect white pixels */ | ||||
|                   if (black && data[y * pixels + x] > 90) | ||||
|                     { | ||||
|                       count++; | ||||
|         if (forward) { | ||||
| 
 | ||||
|             for (std::size_t y = 0; y < image.get_height() && !found; y++) { | ||||
|                 count = 0; | ||||
| 
 | ||||
|                 // count of white/black pixels depending on the color searched
 | ||||
|                 for (std::size_t x = 0; x < image.get_width(); x++) { | ||||
| 
 | ||||
|                     // when searching for black, detect white pixels
 | ||||
|                     if (black && image.get_raw_channel(x, y, 0) > white_level) { | ||||
|                         count++; | ||||
|                     } | ||||
|                   /* when searching for white, detect black pixels */ | ||||
|                   if (!black && data[y * pixels + x] < 60) | ||||
|                     { | ||||
|                       count++; | ||||
| 
 | ||||
|                     // when searching for white, detect black pixels
 | ||||
|                     if (!black && image.get_raw_channel(x, y, 0) < black_level) { | ||||
|                         count++; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|               /* at end of line, if count >= 3%, line is not fully of the desired color
 | ||||
|                * so we must go to next line of the buffer */ | ||||
|               /* count*100/pixels < 3 */ | ||||
|               if ((count * 100) / pixels < 3) | ||||
|                 { | ||||
|                   found = 1; | ||||
|                   DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, | ||||
|                       pass, y); | ||||
|                 auto found_percentage = (count * 100 / image.get_width()); | ||||
|                 if (found_percentage < 3) { | ||||
|                     found = 1; | ||||
|                     DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__, | ||||
|                         pass, y); | ||||
|                 } | ||||
|               else | ||||
|                 { | ||||
|                   DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, | ||||
|                       (100 * count) / pixels); | ||||
|                     DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(), | ||||
|                         count, found_percentage); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|       else			/* since calibration scans are done forward, we need the whole area
 | ||||
|                                    to be of the required color when searching backward */ | ||||
|         { | ||||
|           count = 0; | ||||
|           for (y = 0; y < lines; y++) | ||||
|             { | ||||
|               /* count of white/black pixels depending on the color searched */ | ||||
|               for (x = 0; x < pixels; x++) | ||||
|                 { | ||||
|                   /* when searching for black, detect white pixels */ | ||||
|                   if (black && data[y * pixels + x] > 90) | ||||
|                     { | ||||
|                       count++; | ||||
|         } else { | ||||
|             /* since calibration scans are done forward, we need the whole area
 | ||||
|                to be of the required color when searching backward | ||||
|             */ | ||||
| 
 | ||||
|             count = 0; | ||||
|             for (std::size_t y = 0; y < image.get_height(); y++) { | ||||
|                 // count of white/black pixels depending on the color searched
 | ||||
|                 for (std::size_t x = 0; x < image.get_width(); x++) { | ||||
|                     // when searching for black, detect white pixels
 | ||||
|                     if (black && image.get_raw_channel(x, y, 0) > white_level) { | ||||
|                         count++; | ||||
|                     } | ||||
|                   /* when searching for white, detect black pixels */ | ||||
|                   if (!black && data[y * pixels + x] < 60) | ||||
|                     { | ||||
|                       count++; | ||||
|                     // when searching for white, detect black pixels
 | ||||
|                     if (!black && image.get_raw_channel(x, y, 0) < black_level) { | ||||
|                         count++; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|           /* at end of area, if count >= 3%, area is not fully of the desired color
 | ||||
|            * so we must go to next buffer */ | ||||
|           if ((count * 100) / (pixels * lines) < 3) | ||||
|             { | ||||
|               found = 1; | ||||
|               DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, | ||||
|                   (100 * count) / pixels); | ||||
|             auto found_percentage = count * 100 / (image.get_width() * image.get_height()); | ||||
|             if (found_percentage < 3) { | ||||
|                 found = 1; | ||||
|                  DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); | ||||
|             } else { | ||||
|                 DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(), | ||||
|                     count, found_percentage); | ||||
|             } | ||||
|         } | ||||
|       pass++; | ||||
|         pass++; | ||||
|     } | ||||
| 
 | ||||
|   if (found) | ||||
|  | @ -1799,9 +1771,6 @@ void CommandSetGl846::offset_calibration(Genesys_Device* dev, const Genesys_Sens | |||
| 
 | ||||
|   sanei_genesys_set_motor_power(regs, false); | ||||
| 
 | ||||
|     std::vector<uint8_t> first_line(session.output_total_bytes); | ||||
|     std::vector<uint8_t> second_line(session.output_total_bytes); | ||||
| 
 | ||||
|   /* init gain */ | ||||
|   dev->frontend.set_gain(0, 0); | ||||
|   dev->frontend.set_gain(1, 0); | ||||
|  | @ -1823,16 +1792,15 @@ void CommandSetGl846::offset_calibration(Genesys_Device* dev, const Genesys_Sens | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     sanei_genesys_read_data_from_scanner(dev, first_line.data(), session.output_total_bytes); | ||||
|     auto first_line = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
|   if (DBG_LEVEL >= DBG_data) | ||||
|    { | ||||
|       char fn[30]; | ||||
|         std::snprintf(fn, 30, "gl846_offset%03d.pnm", bottom); | ||||
|         sanei_genesys_write_pnm_file(fn, first_line.data(), session.params.depth, | ||||
|                                      channels, pixels, lines); | ||||
|         sanei_genesys_write_pnm_file(fn, first_line); | ||||
|    } | ||||
| 
 | ||||
|   bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels); | ||||
|     bottomavg = dark_average(first_line.get_row_ptr(0), pixels, lines, channels, black_pixels); | ||||
|   DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); | ||||
| 
 | ||||
|   /* now top value */ | ||||
|  | @ -1844,9 +1812,9 @@ void CommandSetGl846::offset_calibration(Genesys_Device* dev, const Genesys_Sens | |||
|     dev->interface->write_registers(regs); | ||||
|   DBG(DBG_info, "%s: starting second line reading\n", __func__); | ||||
|     begin_scan(dev, sensor, ®s, true); | ||||
|     sanei_genesys_read_data_from_scanner(dev, second_line.data(), session.output_total_bytes); | ||||
|     auto second_line = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
| 
 | ||||
|   topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); | ||||
|     topavg = dark_average(second_line.get_row_ptr(0), pixels, lines, channels, black_pixels); | ||||
|   DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); | ||||
| 
 | ||||
|   /* loop until acceptable level */ | ||||
|  | @ -1864,17 +1832,15 @@ void CommandSetGl846::offset_calibration(Genesys_Device* dev, const Genesys_Sens | |||
|         dev->interface->write_registers(regs); | ||||
|       DBG(DBG_info, "%s: starting second line reading\n", __func__); | ||||
|         begin_scan(dev, sensor, ®s, true); | ||||
|         sanei_genesys_read_data_from_scanner(dev, second_line.data(), session.output_total_bytes); | ||||
|         second_line = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
| 
 | ||||
|       if (DBG_LEVEL >= DBG_data) | ||||
|         { | ||||
|           char fn[30]; | ||||
|         if (DBG_LEVEL >= DBG_data) { | ||||
|             char fn[30]; | ||||
|             std::snprintf(fn, 30, "gl846_offset%03d.pnm", dev->frontend.get_offset(1)); | ||||
|             sanei_genesys_write_pnm_file(fn, second_line.data(), session.params.depth, | ||||
|                                          channels, pixels, lines); | ||||
|             sanei_genesys_write_pnm_file(fn, second_line); | ||||
|         } | ||||
| 
 | ||||
|       avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); | ||||
|         avg = dark_average(second_line.get_row_ptr(0), pixels, lines, channels, black_pixels); | ||||
|       DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); | ||||
| 
 | ||||
|       /* compute new boundaries */ | ||||
|  | @ -1900,10 +1866,8 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys | |||
| { | ||||
|     DBG_HELPER(dbg); | ||||
|   int pixels; | ||||
|   int i, j, channels; | ||||
|   int max[3]; | ||||
|   float gain[3],coeff; | ||||
|   int val, code, lines; | ||||
|     int code, lines; | ||||
| 
 | ||||
|   DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); | ||||
| 
 | ||||
|  | @ -1914,7 +1878,7 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys | |||
|     } | ||||
| 
 | ||||
|   /* coarse gain calibration is always done in color mode */ | ||||
|   channels = 3; | ||||
|     unsigned channels = 3; | ||||
| 
 | ||||
|   /* follow CKSEL */ | ||||
|   if(dev->settings.xres<sensor.optical_res) | ||||
|  | @ -1957,8 +1921,6 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys | |||
| 
 | ||||
|     dev->interface->write_registers(regs); | ||||
| 
 | ||||
|     std::vector<uint8_t> line(session.output_total_bytes); | ||||
| 
 | ||||
|     set_fe(dev, sensor, AFE_SET); | ||||
|     begin_scan(dev, sensor, ®s, true); | ||||
| 
 | ||||
|  | @ -1969,40 +1931,33 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     sanei_genesys_read_data_from_scanner(dev, line.data(), session.output_total_bytes); | ||||
|     auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes); | ||||
| 
 | ||||
|     if (DBG_LEVEL >= DBG_data) { | ||||
|         sanei_genesys_write_pnm_file("gl846_gain.pnm", line.data(), session.params.depth, | ||||
|                                      channels, pixels, lines); | ||||
|         sanei_genesys_write_pnm_file("gl846_gain.pnm", image); | ||||
|     } | ||||
| 
 | ||||
|   /* average value on each channel */ | ||||
|   for (j = 0; j < channels; j++) | ||||
|     { | ||||
|       max[j] = 0; | ||||
|       for (i = pixels/4; i < (pixels*3/4); i++) | ||||
|         { | ||||
|           if (dev->model->is_cis) | ||||
|             val = line[i + j * pixels]; | ||||
|           else | ||||
|             val = line[i * channels + j]; | ||||
|     for (unsigned ch = 0; ch < channels; ch++) { | ||||
| 
 | ||||
|           max[j] += val; | ||||
|         auto width = image.get_width(); | ||||
| 
 | ||||
|         std::uint64_t total = 0; | ||||
|         for (std::size_t x = width / 4; x < (width * 3 / 4); x++) { | ||||
|             total += image.get_raw_channel(x, 0, ch); | ||||
|         } | ||||
|       max[j] = max[j] / (pixels/2); | ||||
| 
 | ||||
|         gain[j] = (static_cast<float>(sensor.gain_white_ref) * coeff) / max[j]; | ||||
|         total /= width / 2; | ||||
| 
 | ||||
|         gain[ch] = (static_cast<float>(sensor.gain_white_ref) * coeff) / total; | ||||
| 
 | ||||
|       /* turn logical gain value into gain code, checking for overflow */ | ||||
|         code = static_cast<int>(283 - 208 / gain[j]); | ||||
|       if (code > 255) | ||||
|         code = 255; | ||||
|       else if (code < 0) | ||||
|         code = 0; | ||||
|       dev->frontend.set_gain(j, code); | ||||
|         code = static_cast<int>(283 - 208 / gain[ch]); | ||||
|         code = clamp(code, 0, 255); | ||||
|         dev->frontend.set_gain(ch, code); | ||||
| 
 | ||||
|       DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], | ||||
|           dev->frontend.get_gain(j)); | ||||
|         DBG(DBG_proc, "%s: channel %d, total=%d, gain = %f, setting:%d\n", __func__, ch, | ||||
|             static_cast<unsigned>(total), gain[ch], dev->frontend.get_gain(ch)); | ||||
|     } | ||||
| 
 | ||||
|     if (dev->model->is_cis) { | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Povilas Kanapickas
						Povilas Kanapickas