509 int16_t array_origin;
511 int16_t projection_offset;
515 int16_t best_left_x = 0;
516 int16_t best_right_x = 0;
525 FPSEGPT_IT seg_it = seg_list;
527 end = (end - start) % pitch;
530 if ((pitch - 3) / 2 < pitch_error)
531 pitch_error = (pitch - 3) / 2;
534 for (left_edge = projection_left; projection->
pile_count (left_edge) == 0
535 && left_edge < projection_right; left_edge++);
536 for (right_edge = projection_right; projection->
pile_count (right_edge) == 0
537 && right_edge > left_edge; right_edge--);
538 array_origin = left_edge - pitch;
540 std::vector<FPCUTPT> cutpts(right_edge - left_edge + pitch * 2 + 1);
542 std::vector<BOOL8> mins(pitch_error * 2 + 1);
543 for (x = array_origin; x < left_edge; x++)
545 cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
546 zero_count, pitch, x, 0);
547 prev_zero = left_edge - 1;
548 for (offset = 0; offset <= pitch_error; offset++, x++)
550 cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
551 zero_count, pitch, x, offset);
555 for (offset = -pitch_error, minindex = 0; offset < pitch_error;
556 offset++, minindex++)
557 mins[minindex] = projection->
local_min (x + offset);
558 next_zero = x + zero_offset + 1;
559 for (offset = next_zero - 1; offset >= x; offset--) {
560 if (projection->
pile_count (offset) <= zero_count) {
565 while (x < right_edge - pitch_error) {
566 mins[minindex] = projection->
local_min (x + pitch_error);
568 if (minindex > pitch_error * 2)
573 if (projection->
pile_count (x) <= zero_count) {
577 for (offset = 1; offset <= pitch_error; offset++)
578 if (projection->
pile_count (x + offset) <= zero_count
579 || projection->
pile_count (x - offset) <= zero_count)
582 if (offset > pitch_error) {
583 if (x - prev_zero > zero_offset && next_zero - x > zero_offset) {
584 for (offset = 0; offset <= pitch_error; offset++) {
585 test_index = minindex + pitch_error + offset;
586 if (test_index > pitch_error * 2)
587 test_index -= pitch_error * 2 + 1;
588 if (mins[test_index])
590 test_index = minindex + pitch_error - offset;
591 if (test_index > pitch_error * 2)
592 test_index -= pitch_error * 2 + 1;
593 if (mins[test_index])
597 if (offset > pitch_error) {
603 (int16_t) (projection->
pile_count (x) / projection_scale);
604 if (projection_offset > offset)
605 offset = projection_offset;
609 if ((start == 0 && end == 0)
611 || (x - projection_left - start) % pitch <= end)
612 cutpts[x - array_origin].assign(&cutpts[0], array_origin, x,
613 faking, mid_cut, offset, projection,
614 projection_scale, zero_count, pitch,
617 cutpts[x - array_origin].assign_cheap(&cutpts[0], array_origin, x,
618 faking, mid_cut, offset,
619 projection, projection_scale,
623 if (next_zero < x || next_zero == x + zero_offset)
624 next_zero = x + zero_offset + 1;
625 if (projection->
pile_count (x + zero_offset) <= zero_count)
626 next_zero = x + zero_offset;
629 best_fake = INT16_MAX;
630 best_cost = INT32_MAX;
631 best_count = INT16_MAX;
632 while (x < right_edge + pitch) {
633 offset = x < right_edge ? right_edge - x : 0;
634 cutpts[x - array_origin].assign(&cutpts[0], array_origin, x,
635 false,
false, offset, projection,
636 projection_scale, zero_count, pitch,
638 cutpts[x - array_origin].terminal =
true;
639 if (cutpts[x - array_origin].index () +
640 cutpts[x - array_origin].fake_count <= best_count + best_fake) {
641 if (cutpts[x - array_origin].fake_count < best_fake
642 || (cutpts[x - array_origin].fake_count == best_fake
643 && cutpts[x - array_origin].cost_function () < best_cost)) {
644 best_fake = cutpts[x - array_origin].fake_count;
645 best_cost = cutpts[x - array_origin].cost_function ();
648 best_count = cutpts[x - array_origin].index ();
650 else if (cutpts[x - array_origin].fake_count == best_fake
651 && x == best_right_x + 1
652 && cutpts[x - array_origin].cost_function () == best_cost) {
661 best_end = &cutpts[(best_left_x + best_right_x) / 2 - array_origin];
670 occupation_count = -1;
672 for (x = best_end->
position () - pitch + pitch_error;
673 x < best_end->
position () - pitch_error
675 if (x < best_end->position () - pitch_error)
678 segpt =
new FPSEGPT (best_end);
679 seg_it.add_before_then_move (segpt);
682 while (best_end !=
nullptr);
683 seg_it.move_to_last ();
684 mean_sum = seg_it.data ()->
sum ();
685 mean_sum = mean_sum * mean_sum / best_count;
686 if (seg_it.data ()->squares () - mean_sum < 0)
687 tprintf (
"Impossible sqsum=%g, mean=%g, total=%d\n",
688 seg_it.data ()->squares (), seg_it.data ()->sum (), best_count);
689 return seg_it.data ()->squares () - mean_sum;
EXTERN bool textord_fast_pitch_test
int32_t pile_count(int32_t value) const
double pitsync_joined_edge
bool local_min(int32_t x) const
DLLSYM void tprintf(const char *format,...)