diff -uprN gimp-texturize.orig/src/compter.c gimp-texturize/src/compter.c --- gimp-texturize.orig/src/compter.c 2019-11-17 05:55:05.624700700 +0900 +++ gimp-texturize/src/compter.c 2019-11-17 06:55:10.151409100 +0900 @@ -48,9 +48,6 @@ pixel_to_fill (guchar **filled, int widt // 2 m. gint modulo (gint x, gint m) { - if (x >= m) return x - m; - else { - if (x >= 0) return x; - else return x + m; - } + int v = (x - (m * (x / m))); + return (v >= 0)? v : v + m; } diff -uprN gimp-texturize.orig/src/main.c gimp-texturize/src/main.c --- gimp-texturize.orig/src/main.c 2019-11-17 05:55:05.671572400 +0900 +++ gimp-texturize/src/main.c 2019-11-17 08:26:08.692023300 +0900 @@ -198,10 +198,12 @@ run (const gchar *name, values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; - // If new_image_id = -1, there has been an error (indexed colors ?). - if (new_image_id != -1) - gimp_display_new(new_image_id); - else { - g_message(_("There was a problem when opening the new image.")); + if (status != GIMP_PDB_CANCEL) { + // If new_image_id = -1, there has been an error (indexed colors ?). + if (new_image_id != -1) + gimp_display_new(new_image_id); + else { + g_message(_("There was a problem when opening the new image.")); + } } } diff -uprN gimp-texturize.orig/src/offset.c gimp-texturize/src/offset.c --- gimp-texturize.orig/src/offset.c 2019-11-17 05:55:05.693706200 +0900 +++ gimp-texturize/src/offset.c 2019-11-18 08:29:22.520045600 +0900 @@ -24,32 +24,100 @@ difference (gint width_i, gint height_i, gint posn_x, gint posn_y, gint x_min, gint y_min, gint x_max, gint y_max, gint channels, guchar ** filled) { - gint somme = 0, zone=0, x_i, y_i, k; + + gint somme = 0, zone=0; + gint x_i, y_i, k; guchar *image_ptr, *patch_ptr; - gint real_y_i, real_x_i; - for (y_i = y_min; y_i < y_max; y_i++) { - real_y_i = modulo (y_i, height_i); + // slow + + // gint real_y_i, real_x_i; + // for (y_i = y_min; y_i < y_max; y_i++) { + // real_y_i = modulo (y_i, height_i); + // for (x_i = x_min; x_i < x_max; x_i++) { + // real_x_i = modulo (x_i, width_i); + // if (filled[real_x_i][real_y_i]) { + // image_ptr = image + (real_y_i * width_i + real_x_i) * channels; + // patch_ptr = patch + (modulo(real_y_i - posn_y, height_p) * width_p + // + modulo(real_x_i - posn_x, width_p)) * channels; + // for (k = 0 ; k < channels; k++) { + // somme += abs (*image_ptr++ - *patch_ptr++); + // zone ++; + // } + // } + // } + // } + + // fast + + gint x_p, y_p; + gint x_i_start, x_p_start; + gint xcount, ycount; + gint iy, ix; + guchar *image_ptr_x, *patch_ptr_x; + gint image_add_y, patch_add_y; + + ycount = y_max - y_min; + xcount = x_max - x_min; + + y_i = modulo(y_min, height_i); + y_p = modulo(y_i - posn_y, height_p); + + image_add_y = width_i * channels; + patch_add_y = width_p * channels; + + image_ptr_x = image + y_i * image_add_y; + patch_ptr_x = patch + y_p * patch_add_y; + + x_i_start = modulo(x_min, width_i); + x_p_start = modulo(x_i_start - posn_x, width_p); + + for(iy = 0; iy < ycount; iy++) { - image_ptr = image + (real_y_i * width_i - + modulo (x_min, width_i)) * channels; - patch_ptr = patch + ((real_y_i - posn_y) * width_p - + modulo (x_min, width_i) - posn_x) * channels; + x_i = x_i_start; + x_p = x_p_start; - for (x_i = x_min; x_i < x_max; x_i++) { - real_x_i = modulo (x_i, width_i); + image_ptr = image_ptr_x + x_i * channels; + patch_ptr = patch_ptr_x + x_p * channels; - if (filled[real_x_i][real_y_i]) { + for (ix = 0; ix < xcount; ix++) { + if (filled[x_i][y_i]) { for (k = 0 ; k < channels; k++) { - somme += abs (*image_ptr++ - *patch_ptr++); - zone ++; + somme += abs (*image_ptr - *patch_ptr); + image_ptr++; + patch_ptr++; + zone++; } } else { image_ptr += channels; patch_ptr += channels; } + + if (++x_i >= width_i) { + x_i = 0; + image_ptr = image_ptr_x; + } + + if (++x_p >= width_p) { + x_p = 0; + patch_ptr = patch_ptr_x; + } + } + + image_ptr_x += image_add_y; + patch_ptr_x += patch_add_y; + + if (++y_i >= height_i) { + y_i = 0; + image_ptr_x = image; + } + + if (++y_p >= height_p) { + y_p = 0; + patch_ptr_x = patch; } } + if (zone == 0) {printf("Bug: Zone = 0\n"); exit(-1);} return (((float) somme) / ((float) zone)); } @@ -64,28 +132,36 @@ offset_optimal (gint *resultat, gint x_i, y_i; float best_difference = INFINITY, tmp_difference; - for (x_i = x_patch_posn_min; x_i < x_patch_posn_max; x_i++) { - for (y_i = y_patch_posn_min; y_i < y_patch_posn_max; y_i++) { - if (tileable) { /* Move this test outside the loops? */ + if (tileable) { + for (x_i = x_patch_posn_min; x_i < x_patch_posn_max; x_i++) { + for (y_i = y_patch_posn_min; y_i < y_patch_posn_max; y_i++) { tmp_difference = difference ( - width_i, height_i, - width_p, height_p, - image, patch, + width_i, height_i, width_p, height_p, image, patch, x_i, y_i, - MAX (0, x_i), MAX (0, y_i), x_i + width_p, y_i + height_p, + MAX (0, x_i), MAX (0, y_i), + x_i + width_p, y_i + height_p, channels, filled); - } else { + + if (tmp_difference < best_difference) { + best_difference = tmp_difference; + resultat[0] = x_i; resultat[1] = y_i; + } + } + } + } else { + for (x_i = x_patch_posn_min; x_i < x_patch_posn_max; x_i++) { + for (y_i = y_patch_posn_min; y_i < y_patch_posn_max; y_i++) { tmp_difference = difference ( - width_i, height_i, - width_p, height_p, - image, patch, + width_i, height_i, width_p, height_p, image, patch, x_i, y_i, - MAX (0,x_i), MAX (0,y_i), MIN (x_i + width_p, width_i), MIN (y_i + height_p, height_i), + MAX (0, x_i), MAX (0, y_i), + MIN (x_i + width_p, width_i), MIN (y_i + height_p, height_i), channels, filled); - } - if (tmp_difference < best_difference) { - best_difference = tmp_difference; - resultat[0] = x_i; resultat[1] = y_i; + + if (tmp_difference < best_difference) { + best_difference = tmp_difference; + resultat[0] = x_i; resultat[1] = y_i; + } } } } diff -uprN gimp-texturize.orig/src/render.c gimp-texturize/src/render.c --- gimp-texturize.orig/src/render.c 2019-11-17 05:55:05.709337700 +0900 +++ gimp-texturize/src/render.c 2019-11-17 05:12:59.746245800 +0900 @@ -183,8 +183,12 @@ render (gint32 image_ID, // The current position : (0,0) cur_posn[0] = 0; cur_posn[1] = 0; + int count = count_filled_pixels (filled,width_i,height_i); + int count_max = width_i * height_i; - while (count_filled_pixels (filled,width_i,height_i) < (width_i * height_i)) { + while (1) { + if (count >= count_max) break; + /* Update the current position: it's the next pixel to fill. */ if (pixel_to_fill (filled, width_i, height_i, cur_posn) == NULL) { g_message (_("There was a problem when filling the new image.")); @@ -213,7 +217,9 @@ render (gint32 image_ID, FALSE); // Display progress to the user. - progress = ((float) count_filled_pixels (filled, width_i, height_i)) / ((float)(width_i * height_i)); + count = count_filled_pixels (filled, width_i, height_i); + progress = ((float) count) / ((float) count_max); + progress = (progress > 1.0f)? 1.0f : ((progress < 0.0f)? 0.0f : progress); gimp_progress_update(progress); }