flood_fill_seed: Simplify the flow by having a single "return point".

This commit is contained in:
YAMAMOTO Takashi 2021-05-11 13:46:31 +09:00
parent 1fa9b0c109
commit 38f882b3d6
2 changed files with 26 additions and 30 deletions

View file

@ -169,75 +169,72 @@ static void flood_fill_seed(struct quirc *q,
struct quirc_flood_fill_vars *vars; struct quirc_flood_fill_vars *vars;
struct quirc_flood_fill_vars *next_vars; struct quirc_flood_fill_vars *next_vars;
int i;
quirc_pixel_t *row; quirc_pixel_t *row;
/* Set up the first context */ /* Set up the first context */
next_vars = stack; next_vars = stack;
next_vars->left = x0; next_vars->left_up = x0;
next_vars->y = y0; next_vars->y = y0;
call: call:
vars = next_vars; vars = next_vars;
/*
* Note about inputs:
*
* - vars->left_up contains x value to look at.
* - vars->left_down is still a garbage here.
*/
/* Fill the extent */ /* Fill the extent */
flood_fill_line(q, vars->left, vars->y, from, to, &vars->left, flood_fill_line(q, vars->left_up, vars->y, from, to, &vars->left_up,
&vars->right); &vars->right);
if (func) if (func)
func(user_data, vars->y, vars->left, vars->right); func(user_data, vars->y, vars->left_up, vars->right);
if (vars == last_vars) { if (vars == last_vars) {
return; return;
} }
vars->left_down = vars->left_up;
/* Seed new flood-fills */ /* Seed new flood-fills */
return_from_call:
if (vars->y > 0) { if (vars->y > 0) {
row = q->pixels + (vars->y - 1) * q->w; row = q->pixels + (vars->y - 1) * q->w;
for (i = vars->left; i <= vars->right; i++) while (vars->left_up <= vars->right) {
if (row[i] == from) { if (row[vars->left_up] == from) {
/* Save the current context */
vars->i = i;
vars->pc = 1;
/* Set up the next context */ /* Set up the next context */
next_vars = vars + 1; next_vars = vars + 1;
next_vars->left = i; next_vars->left_up = vars->left_up;
next_vars->y = vars->y - 1; next_vars->y = vars->y - 1;
goto call; goto call;
return_from_call1: ;
} }
vars->left_up++;
}
} }
if (vars->y < q->h - 1) { if (vars->y < q->h - 1) {
row = q->pixels + (vars->y + 1) * q->w; row = q->pixels + (vars->y + 1) * q->w;
for (i = vars->left; i <= vars->right; i++) while (vars->left_down <= vars->right) {
if (row[i] == from) { if (row[vars->left_down] == from) {
/* Save the current context */
vars->i = i;
vars->pc = 2;
/* Set up the next context */ /* Set up the next context */
next_vars = vars + 1; next_vars = vars + 1;
next_vars->left = i; next_vars->left_up = vars->left_down;
next_vars->y = vars->y + 1; next_vars->y = vars->y + 1;
goto call; goto call;
return_from_call2: ;
} }
vars->left_down++;
}
} }
if (vars > stack) { if (vars > stack) {
/* Restore the previous context */ /* Restore the previous context */
vars--; vars--;
i = vars->i; goto return_from_call;
if (vars->pc == 1) {
row = q->pixels + (vars->y - 1) * q->w;
goto return_from_call1;
}
row = q->pixels + (vars->y + 1) * q->w;
goto return_from_call2;
} }
} }

View file

@ -83,9 +83,8 @@ struct quirc_grid {
struct quirc_flood_fill_vars { struct quirc_flood_fill_vars {
int y; int y;
int right; int right;
int left; int left_up;
int i; int left_down;
int pc; /* caller id */
}; };
struct quirc { struct quirc {