diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index f1edf8a5fd9..bdf11de0f87 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -487,12 +487,15 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr if (u < 0.0f) u += 1.0f; if (v < 0.0f) v += 1.0f; - u = u * ibuf->x - 0.5f; - v = v * ibuf->y - 0.5f; + u = u * ibuf->x; + v = v * ibuf->y; if (ibuf->rect_float) { float rgba_f[4]; - bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); + if (U.gameflags & USER_DISABLE_MIPMAP) + nearest_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); + else + bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); straight_to_premul_v4(rgba_f); if (use_palette) { linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); @@ -504,7 +507,10 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr } else { unsigned char rgba[4]; - bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); + if (U.gameflags & USER_DISABLE_MIPMAP) + nearest_interpolation_color_wrap(ibuf, rgba, NULL, u, v); + else + bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); if (use_palette) { rgb_uchar_to_float(color->rgb, rgba); } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 4a2d05bdf61..ed16c670002 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -467,6 +467,7 @@ void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 90219461772..d44f0dc86f4 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -51,7 +51,7 @@ /* Only this one is used liberally here, and in imbuf */ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) { - int size; + size_t size; unsigned char rt, *cp = (unsigned char *)ibuf->rect; float rtf, *cpf = ibuf->rect_float; @@ -86,7 +86,7 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y) { - int offset = ibuf->x * y * 4 + 4 * x; + size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x; if (ibuf->rect) *outI = (unsigned char *)ibuf->rect + offset; @@ -172,10 +172,10 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], if (outF) { /* sample including outside of edges of image */ - row1 = in->rect_float + in->x * y1 * 4 + 4 * x1; - row2 = in->rect_float + in->x * y2 * 4 + 4 * x1; - row3 = in->rect_float + in->x * y1 * 4 + 4 * x2; - row4 = in->rect_float + in->x * y2 * 4 + 4 * x2; + row1 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1; + row2 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x1; + row3 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x2; + row4 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x2; outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1]; @@ -190,10 +190,10 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], } if (outI) { /* sample including outside of edges of image */ - row1I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1; - row2I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x1; - row3I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x2; - row4I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x2; + row1I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1; + row2I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x1; + row3I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x2; + row4I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x2; /* need to add 0.5 to avoid rounding down (causes darken with the smear brush) * tested with white images and this should not wrap back to zero */ @@ -256,14 +256,14 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float } } else { - dataI = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1; + dataI = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1; if (outI) { outI[0] = dataI[0]; outI[1] = dataI[1]; outI[2] = dataI[2]; outI[3] = dataI[3]; } - dataF = in->rect_float + in->x * y1 * 4 + 4 * x1; + dataF = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1; if (outF) { outF[0] = dataF[0]; outF[1] = dataF[1]; @@ -273,6 +273,41 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float } } + +void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) +{ + const float *dataF; + unsigned char *dataI; + int y, x; + + /* ImBuf in must have a valid rect or rect_float, assume this is already checked */ + + x = (int) floor(u); + y = (int) floor(v); + + x = x % in->x; + y = y % in->y; + + /* wrap interpolation pixels - main difference from nearest_interpolation_color */ + if (x < 0) x += in->x; + if (y < 0) y += in->y; + + dataI = (unsigned char *)in->rect + ((size_t)in->x) * y * 4 + 4 * x; + if (outI) { + outI[0] = dataI[0]; + outI[1] = dataI[1]; + outI[2] = dataI[2]; + outI[3] = dataI[3]; + } + dataF = in->rect_float + ((size_t)in->x) * y * 4 + 4 * x; + if (outF) { + outF[0] = dataF[0]; + outF[1] = dataF[1]; + outF[2] = dataF[2]; + outF[3] = dataF[3]; + } +} + void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) { unsigned char *outI = NULL;